Fields Summary |
---|
private static final String | COMMAND_MEMSTATThe text string for the MEMSTAT command |
private static final String | COMMAND_ADDUSERThe text string for the ADDUSER command |
private static final String | COMMAND_SETPASSWORDThe text string for the SETPASSWORD command |
private static final String | COMMAND_DELUSERThe text string for the DELUSER command |
private static final String | COMMAND_LISTUSERSThe text string for the LISTUSERS command |
private static final String | COMMAND_COUNTUSERSThe text string for the COUNTUSERS command |
private static final String | COMMAND_VERIFYThe text string for the VERIFY command |
private static final String | COMMAND_HELPThe text string for the HELP command |
private static final String | COMMAND_SETFORWARDINGThe text string for the SETFORWARDING command |
private static final String | COMMAND_SHOWFORWARDINGThe text string for the SHOWFORWARDING command |
private static final String | COMMAND_UNSETFORWARDINGThe text string for the UNSETFORWARDING command |
private static final String | COMMAND_SETALIASThe text string for the SETALIAS command |
private static final String | COMMAND_SHOWALIASThe text string for the SHOWALIAS command |
private static final String | COMMAND_UNSETALIASThe text string for the UNSETALIAS command |
private static final String | COMMAND_USERThe text string for the USER command |
private static final String | COMMAND_QUITThe text string for the QUIT command |
private static final String | COMMAND_SHUTDOWNThe text string for the SHUTDOWN command |
private RemoteManagerHandlerConfigurationData | theConfigDataThe per-service configuration data that applies to all handlers |
private org.apache.james.services.UsersRepository | usersThe current UsersRepository being managed/viewed/modified |
private BufferedReader | inThe reader associated with incoming commands. |
private PrintWriter | outThe writer to which outgoing messages are written. |
private Thread | handlerThreadThe thread executing this handler |
private Socket | socketThe TCP/IP socket over which the RemoteManager interaction
is occurring |
private org.apache.james.util.watchdog.Watchdog | theWatchdogThe watchdog being used by this handler to deal with idle timeouts. |
private org.apache.james.util.watchdog.WatchdogTarget | theWatchdogTargetThe watchdog target that idles out this handler. |
Methods Summary |
---|
private boolean | doADDUSER(java.lang.String argument)Handler method called upon receipt of an ADDUSER command.
Returns whether further commands should be read off the wire.
int breakIndex = -1;
if ((argument == null) ||
(argument.equals("")) ||
((breakIndex = argument.indexOf(" ")) < 0)) {
writeLoggedFlushedResponse("Usage: adduser [username] [password]");
return true;
}
String username = argument.substring(0,breakIndex);
String passwd = argument.substring(breakIndex + 1);
if (username.equals("") || passwd.equals("")) {
writeLoggedFlushedResponse("Usage: adduser [username] [password]");
return true;
}
boolean success = false;
if (users.contains(username)) {
StringBuffer responseBuffer =
new StringBuffer(64)
.append("User ")
.append(username)
.append(" already exists");
String response = responseBuffer.toString();
writeLoggedResponse(response);
} else {
success = users.addUser(username, passwd);
}
if ( success ) {
StringBuffer responseBuffer =
new StringBuffer(64)
.append("User ")
.append(username)
.append(" added");
String response = responseBuffer.toString();
out.println(response);
getLogger().info(response);
} else {
out.println("Error adding user " + username);
getLogger().error("Error adding user " + username);
}
out.flush();
return true;
|
private boolean | doCOUNTUSERS(java.lang.String argument)Handler method called upon receipt of an COUNTUSERS command.
Returns whether further commands should be read off the wire.
writeLoggedFlushedResponse("Existing accounts " + users.countUsers());
return true;
|
private boolean | doDELUSER(java.lang.String argument)Handler method called upon receipt of an DELUSER command.
Returns whether further commands should be read off the wire.
String user = argument;
if ((user == null) || (user.equals(""))) {
writeLoggedFlushedResponse("Usage: deluser [username]");
return true;
}
if (users.contains(user)) {
try {
users.removeUser(user);
StringBuffer responseBuffer =
new StringBuffer(64)
.append("User ")
.append(user)
.append(" deleted");
String response = responseBuffer.toString();
out.println(response);
getLogger().info(response);
} catch (Exception e) {
StringBuffer exceptionBuffer =
new StringBuffer(128)
.append("Error deleting user ")
.append(user)
.append(" : ")
.append(e.getMessage());
String exception = exceptionBuffer.toString();
out.println(exception);
getLogger().error(exception);
}
} else {
StringBuffer responseBuffer =
new StringBuffer(64)
.append("User ")
.append(user)
.append(" doesn't exist");
String response = responseBuffer.toString();
out.println(response);
}
out.flush();
return true;
|
private boolean | doHELP(java.lang.String argument)Handler method called upon receipt of an HELP command.
Returns whether further commands should be read off the wire.
out.println("Currently implemented commands:");
out.println("help display this help");
out.println("listusers display existing accounts");
out.println("countusers display the number of existing accounts");
out.println("adduser [username] [password] add a new user");
out.println("verify [username] verify if specified user exist");
out.println("deluser [username] delete existing user");
out.println("setpassword [username] [password] sets a user's password");
out.println("setalias [user] [alias] locally forwards all email for 'user' to 'alias'");
out.println("showalias [username] shows a user's current email alias");
out.println("unsetalias [user] unsets an alias for 'user'");
out.println("setforwarding [username] [emailaddress] forwards a user's email to another email address");
out.println("showforwarding [username] shows a user's current email forwarding");
out.println("unsetforwarding [username] removes a forward");
out.println("user [repositoryname] change to another user repository");
out.println("shutdown kills the current JVM (convenient when James is run as a daemon)");
out.println("quit close connection");
out.flush();
return true;
|
private boolean | doLISTUSERS(java.lang.String argument)Handler method called upon receipt of an LISTUSERS command.
Returns whether further commands should be read off the wire.
writeLoggedResponse("Existing accounts " + users.countUsers());
for (Iterator it = users.list(); it.hasNext();) {
writeLoggedResponse("user: " + (String) it.next());
}
out.flush();
return true;
|
private boolean | doMEMSTAT(java.lang.String argument)Handler method called upon receipt of an MEMSTAT command.
Returns whether further commands should be read off the wire.
writeLoggedFlushedResponse("Current memory statistics:");
writeLoggedFlushedResponse("\tFree Memory: " + Runtime.getRuntime().freeMemory());
writeLoggedFlushedResponse("\tTotal Memory: " + Runtime.getRuntime().totalMemory());
writeLoggedFlushedResponse("\tMax Memory: " + Runtime.getRuntime().maxMemory());
if ("-gc".equalsIgnoreCase(argument)) {
System.gc();
writeLoggedFlushedResponse("And after System.gc():");
writeLoggedFlushedResponse("\tFree Memory: " + Runtime.getRuntime().freeMemory());
writeLoggedFlushedResponse("\tTotal Memory: " + Runtime.getRuntime().totalMemory());
writeLoggedFlushedResponse("\tMax Memory: " + Runtime.getRuntime().maxMemory());
}
return true;
|
private boolean | doQUIT(java.lang.String argument)Handler method called upon receipt of a QUIT command.
Returns whether further commands should be read off the wire.
writeLoggedFlushedResponse("Bye");
return false;
|
private boolean | doSETALIAS(java.lang.String argument)Handler method called upon receipt of an SETALIAS command.
Returns whether further commands should be read off the wire.
int breakIndex = -1;
if ((argument == null) ||
(argument.equals("")) ||
((breakIndex = argument.indexOf(" ")) < 0)) {
writeLoggedFlushedResponse("Usage: setalias [username] [emailaddress]");
return true;
}
String username = argument.substring(0,breakIndex);
String alias = argument.substring(breakIndex + 1);
if (username.equals("") || alias.equals("")) {
writeLoggedFlushedResponse("Usage: setalias [username] [alias]");
return true;
}
User baseuser = users.getUserByName(username);
if (baseuser == null) {
writeLoggedFlushedResponse("No such user " + username);
return true;
}
if (! (baseuser instanceof JamesUser ) ) {
writeLoggedFlushedResponse("Can't set alias for this user type.");
return true;
}
JamesUser user = (JamesUser) baseuser;
JamesUser aliasUser = (JamesUser) users.getUserByName(alias);
if (aliasUser == null) {
writeLoggedFlushedResponse("Alias unknown to server - create that user first.");
return true;
}
boolean success = user.setAlias(alias);
if (success) {
user.setAliasing(true);
users.updateUser(user);
StringBuffer responseBuffer =
new StringBuffer(64)
.append("Alias for ")
.append(username)
.append(" set to:")
.append(alias);
String response = responseBuffer.toString();
out.println(response);
getLogger().info(response);
} else {
out.println("Error setting alias");
getLogger().error("Error setting alias");
}
out.flush();
return true;
|
private boolean | doSETFORWARDING(java.lang.String argument)Handler method called upon receipt of an SETFORWARDING command.
Returns whether further commands should be read off the wire.
int breakIndex = -1;
if ((argument == null) ||
(argument.equals("")) ||
((breakIndex = argument.indexOf(" ")) < 0)) {
writeLoggedFlushedResponse("Usage: setforwarding [username] [emailaddress]");
return true;
}
String username = argument.substring(0,breakIndex);
String forward = argument.substring(breakIndex + 1);
if (username.equals("") || forward.equals("")) {
writeLoggedFlushedResponse("Usage: setforwarding [username] [emailaddress]");
return true;
}
// Verify user exists
User baseuser = users.getUserByName(username);
if (baseuser == null) {
writeLoggedFlushedResponse("No such user " + username);
return true;
} else if (! (baseuser instanceof JamesUser ) ) {
writeLoggedFlushedResponse("Can't set forwarding for this user type.");
return true;
}
JamesUser user = (JamesUser)baseuser;
// Verify acceptable email address
MailAddress forwardAddr;
try {
forwardAddr = new MailAddress(forward);
} catch(ParseException pe) {
writeLoggedResponse("Parse exception with that email address: " + pe.getMessage());
writeLoggedFlushedResponse("Forwarding address not added for " + username);
return true;
}
boolean success = user.setForwardingDestination(forwardAddr);
if (success) {
user.setForwarding(true);
users.updateUser(user);
StringBuffer responseBuffer =
new StringBuffer(64)
.append("Forwarding destination for ")
.append(username)
.append(" set to:")
.append(forwardAddr.toString());
String response = responseBuffer.toString();
out.println(response);
getLogger().info(response);
} else {
out.println("Error setting forwarding");
getLogger().error("Error setting forwarding");
}
out.flush();
return true;
|
private boolean | doSETPASSWORD(java.lang.String argument)Handler method called upon receipt of an SETPASSWORD command.
Returns whether further commands should be read off the wire.
int breakIndex = -1;
if ((argument == null) ||
(argument.equals("")) ||
((breakIndex = argument.indexOf(" ")) < 0)) {
writeLoggedFlushedResponse("Usage: setpassword [username] [password]");
return true;
}
String username = argument.substring(0,breakIndex);
String passwd = argument.substring(breakIndex + 1);
if (username.equals("") || passwd.equals("")) {
writeLoggedFlushedResponse("Usage: adduser [username] [password]");
return true;
}
User user = users.getUserByName(username);
if (user == null) {
writeLoggedFlushedResponse("No such user " + username);
return true;
}
boolean success = user.setPassword(passwd);
if (success) {
users.updateUser(user);
StringBuffer responseBuffer =
new StringBuffer(64)
.append("Password for ")
.append(username)
.append(" reset");
String response = responseBuffer.toString();
out.println(response);
getLogger().info(response);
} else {
out.println("Error resetting password");
getLogger().error("Error resetting password");
}
out.flush();
return true;
|
private boolean | doSHOWALIAS(java.lang.String username)Handler method called upon receipt of an SHOWALIAS command.
Returns whether further commands should be read off the wire.
if ( username == null || username.equals("") ) {
writeLoggedFlushedResponse("Usage: showalias [username]");
return true;
}
User baseuser = users.getUserByName(username);
if (baseuser == null) {
writeLoggedFlushedResponse("No such user " + username);
return true;
} else if (! (baseuser instanceof JamesUser ) ) {
writeLoggedFlushedResponse("Can't show aliases for this user type.");
return true;
}
JamesUser user = (JamesUser)baseuser;
if ( user == null ) {
writeLoggedFlushedResponse("No such user " + username);
return true;
}
if ( !user.getAliasing() ) {
writeLoggedFlushedResponse("User " + username + " does not currently have an alias");
return true;
}
String alias = user.getAlias();
if ( alias == null || alias.equals("") ) { // defensive programming -- neither should occur
String errmsg = "For user " + username + ", the system indicates that aliasing is set but no alias was found";
out.println(errmsg);
getLogger().error(errmsg);
return true;
}
writeLoggedFlushedResponse("Current alias for " + username + " is: " + alias);
return true;
|
private boolean | doSHOWFORWARDING(java.lang.String username)Handler method called upon receipt of an SHOWFORWARDING command.
Returns whether further commands should be read off the wire.
if ( username == null || username.equals("") ) {
writeLoggedFlushedResponse("Usage: showforwarding [username]");
return true;
}
// Verify user exists
User baseuser = users.getUserByName(username);
if (baseuser == null) {
writeLoggedFlushedResponse("No such user " + username);
return true;
} else if (! (baseuser instanceof JamesUser ) ) {
writeLoggedFlushedResponse("Can't set forwarding for this user type.");
return true;
}
JamesUser user = (JamesUser)baseuser;
if ( user == null ) {
writeLoggedFlushedResponse("No such user " + username);
return true;
}
if ( !user.getForwarding() ) {
writeLoggedFlushedResponse("User " + username + " is not currently being forwarded");
return true;
}
MailAddress fwdAddr = user.getForwardingDestination();
if ( fwdAddr == null ) { // defensive programming -- should not occur
String errmsg = "For user " + username + ", the system indicates that forwarding is set but no forwarding destination was found";
out.println(errmsg);
getLogger().error(errmsg);
return true;
}
writeLoggedFlushedResponse("Current forwarding destination for " + username + " is: " + fwdAddr);
return true;
|
private boolean | doSHUTDOWN(java.lang.String argument)Handler method called upon receipt of a SHUTDOWN command.
Returns whether further commands should be read off the wire.
writeLoggedFlushedResponse("Shutting down, bye bye");
System.exit(0);
return false;
|
private boolean | doUNSETALIAS(java.lang.String argument)Handler method called upon receipt of an UNSETALIAS command.
Returns whether further commands should be read off the wire.
if ((argument == null) || (argument.equals(""))) {
writeLoggedFlushedResponse("Usage: unsetalias [username]");
return true;
}
String username = argument;
JamesUser user = (JamesUser) users.getUserByName(username);
if (user == null) {
writeLoggedResponse("No such user " + username);
} else if (user.getAliasing()){
user.setAliasing(false);
users.updateUser(user);
StringBuffer responseBuffer =
new StringBuffer(64)
.append("Alias for ")
.append(username)
.append(" unset");
String response = responseBuffer.toString();
out.println(response);
getLogger().info(response);
} else {
writeLoggedResponse("Aliasing not active for" + username);
}
out.flush();
return true;
|
private boolean | doUNSETFORWARDING(java.lang.String argument)Handler method called upon receipt of an UNSETFORWARDING command.
Returns whether further commands should be read off the wire.
if ((argument == null) || (argument.equals(""))) {
writeLoggedFlushedResponse("Usage: unsetforwarding [username]");
return true;
}
String username = argument;
JamesUser user = (JamesUser) users.getUserByName(username);
if (user == null) {
writeLoggedFlushedResponse("No such user " + username);
} else if (user.getForwarding()){
user.setForwarding(false);
users.updateUser(user);
StringBuffer responseBuffer =
new StringBuffer(64)
.append("Forward for ")
.append(username)
.append(" unset");
String response = responseBuffer.toString();
out.println(response);
out.flush();
getLogger().info(response);
} else {
writeLoggedFlushedResponse("Forwarding not active for" + username);
}
return true;
|
private boolean | doUSER(java.lang.String argument)Handler method called upon receipt of a USER command.
Returns whether further commands should be read off the wire.
if (argument == null || argument.equals("")) {
writeLoggedFlushedResponse("Usage: user [repositoryName]");
return true;
}
String repositoryName = argument.toLowerCase(Locale.US);
UsersRepository repos = theConfigData.getUserStore().getRepository(repositoryName);
if ( repos == null ) {
writeLoggedFlushedResponse("No such repository: " + repositoryName);
} else {
users = repos;
StringBuffer responseBuffer =
new StringBuffer(64)
.append("Changed to repository '")
.append(repositoryName)
.append("'.");
writeLoggedFlushedResponse(responseBuffer.toString());
}
return true;
|
private boolean | doUnknownCommand(java.lang.String argument)Handler method called upon receipt of an unrecognized command.
Returns whether further commands should be read off the wire.
writeLoggedFlushedResponse("Unknown command " + argument);
return true;
|
private boolean | doVERIFY(java.lang.String argument)Handler method called upon receipt of an VERIFY command.
Returns whether further commands should be read off the wire.
String user = argument;
if (user == null || user.equals("")) {
writeLoggedFlushedResponse("Usage: verify [username]");
return true;
}
if (users.contains(user)) {
StringBuffer responseBuffer =
new StringBuffer(64)
.append("User ")
.append(user)
.append(" exists");
String response = responseBuffer.toString();
writeLoggedResponse(response);
} else {
StringBuffer responseBuffer =
new StringBuffer(64)
.append("User ")
.append(user)
.append(" does not exist");
String response = responseBuffer.toString();
writeLoggedResponse(response);
}
out.flush();
return true;
|
org.apache.james.util.watchdog.WatchdogTarget | getWatchdogTarget()Gets the Watchdog Target that should be used by Watchdogs managing
this connection.
return theWatchdogTarget;
|
public void | handleConnection(java.net.Socket connection)
socket = connection;
String remoteIP = socket.getInetAddress().getHostAddress();
String remoteHost = socket.getInetAddress().getHostName();
synchronized (this) {
handlerThread = Thread.currentThread();
}
try {
in = new BufferedReader(new InputStreamReader(socket.getInputStream(), "ASCII"), 512);
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()), 512), false);
if (getLogger().isInfoEnabled()) {
StringBuffer infoBuffer =
new StringBuffer(128)
.append("Access from ")
.append(remoteHost)
.append("(")
.append(remoteIP)
.append(")");
getLogger().info( infoBuffer.toString() );
}
writeLoggedResponse("JAMES Remote Administration Tool " + Constants.SOFTWARE_VERSION );
writeLoggedResponse("Please enter your login and password");
String login = null;
String password = null;
do {
if (login != null) {
final String message = "Login failed for " + login;
writeLoggedFlushedResponse(message);
}
writeLoggedFlushedResponse("Login id:");
login = in.readLine().trim();
writeLoggedFlushedResponse("Password:");
password = in.readLine().trim();
} while (!password.equals(theConfigData.getAdministrativeAccountData().get(login)) || password.length() == 0);
StringBuffer messageBuffer =
new StringBuffer(64)
.append("Welcome ")
.append(login)
.append(". HELP for a list of commands");
out.println( messageBuffer.toString() );
out.flush();
if (getLogger().isInfoEnabled()) {
StringBuffer infoBuffer =
new StringBuffer(128)
.append("Login for ")
.append(login)
.append(" successful");
getLogger().info(infoBuffer.toString());
}
try {
out.print(theConfigData.getPrompt());
out.flush();
theWatchdog.start();
while (parseCommand(in.readLine())) {
theWatchdog.reset();
out.print(theConfigData.getPrompt());
out.flush();
}
theWatchdog.stop();
} catch (IOException ioe) {
//We can cleanly ignore this as it's probably a socket timeout
} catch (Throwable thr) {
System.out.println("Exception: " + thr.getMessage());
getLogger().error("Encountered exception in handling the remote manager connection.", thr);
}
StringBuffer infoBuffer =
new StringBuffer(64)
.append("Logout for ")
.append(login)
.append(".");
getLogger().info(infoBuffer.toString());
} catch ( final IOException e ) {
out.println("Error. Closing connection");
out.flush();
if (getLogger().isErrorEnabled()) {
StringBuffer exceptionBuffer =
new StringBuffer(128)
.append("Exception during connection from ")
.append(remoteHost)
.append(" (")
.append(remoteIP)
.append("): ")
.append(e.getMessage());
getLogger().error(exceptionBuffer.toString());
}
} finally {
resetHandler();
}
|
void | idleClose()Idle out this connection
if (getLogger() != null) {
getLogger().error("Remote Manager Connection has idled out.");
}
try {
if (socket != null) {
socket.close();
}
} catch (Exception e) {
// ignored
} finally {
socket = null;
}
synchronized (this) {
// Interrupt the thread to recover from internal hangs
if (handlerThread != null) {
handlerThread.interrupt();
handlerThread = null;
}
}
|
private final void | logResponseString(java.lang.String responseString)This method logs at a "DEBUG" level the response string that
was sent to the RemoteManager client. The method is provided largely
as syntactic sugar to neaten up the code base. It is declared
private and final to encourage compiler inlining.
if (getLogger().isDebugEnabled()) {
getLogger().debug("Sent: " + responseString);
}
|
private boolean | parseCommand(java.lang.String rawCommand)This method parses and processes RemoteManager commands read off the
wire in handleConnection. It returns true if expecting additional
commands, false otherwise.
if (rawCommand == null) {
return false;
}
String command = rawCommand.trim();
String argument = null;
int breakIndex = command.indexOf(" ");
if (breakIndex > 0) {
argument = command.substring(breakIndex + 1);
command = command.substring(0, breakIndex);
}
command = command.toUpperCase(Locale.US);
if (command.equals(COMMAND_ADDUSER)) {
doADDUSER(argument);
} else if (command.equals(COMMAND_SETPASSWORD)) {
return doSETPASSWORD(argument);
} else if (command.equals(COMMAND_DELUSER)) {
return doDELUSER(argument);
} else if (command.equals(COMMAND_LISTUSERS)) {
return doLISTUSERS(argument);
} else if (command.equals(COMMAND_COUNTUSERS)) {
return doCOUNTUSERS(argument);
} else if (command.equals(COMMAND_VERIFY)) {
return doVERIFY(argument);
} else if (command.equals(COMMAND_HELP)) {
return doHELP(argument);
} else if (command.equals(COMMAND_SETALIAS)) {
return doSETALIAS(argument);
} else if (command.equals(COMMAND_SETFORWARDING)) {
return doSETFORWARDING(argument);
} else if (command.equals(COMMAND_SHOWALIAS)) {
return doSHOWALIAS(argument);
} else if (command.equals(COMMAND_SHOWFORWARDING)) {
return doSHOWFORWARDING(argument);
} else if (command.equals(COMMAND_UNSETALIAS)) {
return doUNSETALIAS(argument);
} else if (command.equals(COMMAND_UNSETFORWARDING)) {
return doUNSETFORWARDING(argument);
} else if (command.equals(COMMAND_USER)) {
return doUSER(argument);
} else if (command.equals(COMMAND_MEMSTAT)) {
return doMEMSTAT(argument);
} else if (command.equals(COMMAND_QUIT)) {
return doQUIT(argument);
} else if (command.equals(COMMAND_SHUTDOWN)) {
return doSHUTDOWN(argument);
} else {
return doUnknownCommand(rawCommand);
}
return true;
|
private void | resetHandler()Resets the handler data to a basic state.
// Clear the Watchdog
if (theWatchdog != null) {
ContainerUtil.dispose(theWatchdog);
theWatchdog = null;
}
in = null;
out = null;
try {
if (socket != null) {
socket.close();
}
} catch (IOException e) {
if (getLogger().isErrorEnabled()) {
getLogger().error("Exception closing socket: "
+ e.getMessage());
}
} finally {
socket = null;
}
synchronized (this) {
handlerThread = null;
}
// Reset user repository
users = theConfigData.getUsersRepository();
// Clear config data
theConfigData = null;
|
void | setConfigurationData(RemoteManagerHandlerConfigurationData theData)Set the configuration data for the handler.
theConfigData = theData;
// Reset the users repository to the default.
users = theConfigData.getUsersRepository();
|
void | setWatchdog(org.apache.james.util.watchdog.Watchdog theWatchdog)Set the Watchdog for use by this handler.
this.theWatchdog = theWatchdog;
|
final void | writeLoggedFlushedResponse(java.lang.String responseString)Write and flush a response string. The response is also logged.
Should be used for the last line of a multi-line response or
for a single line response.
out.println(responseString);
out.flush();
logResponseString(responseString);
|
final void | writeLoggedResponse(java.lang.String responseString)Write a response string. The response is also logged.
Used for multi-line responses.
out.println(responseString);
logResponseString(responseString);
|