/*
* $Id: ConsoleCommand.html,v 1.2 2004/09/24 13:07:22 suhrin Exp $
*
* Copyright (c) 1999-2004 Gnome Ltd. All Rights Reserved.
*
* This software is the confidential and proprietary information of
* Gnome Ltd. You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms
* of the license agreement you entered into with Gnome Ltd.
*/
package SK.gnome.dwarf.mail.sample;
import java.io.*;
import java.util.Collection;
import java.util.Iterator;
import java.security.AccessControlException;
import javax.security.auth.Subject;
import javax.security.auth.login.LoginException;
import SK.gnome.dwarf.auth.AuthId;
import SK.gnome.dwarf.auth.login.BasicCallbackHandler;
import SK.gnome.dwarf.main.Main;
import SK.gnome.dwarf.main.Console;
import SK.gnome.dwarf.mail.MailException;
import SK.gnome.dwarf.mail.mime.MimePart;
import SK.gnome.dwarf.mail.mime.MimeMessageBuilder;
import SK.gnome.dwarf.mail.smtp.Recipient;
import SK.gnome.dwarf.mail.smtp.SMTPParameters;
import SK.gnome.dwarf.mail.smtp.proc.MailAgent;
import SK.gnome.dwarf.mail.smtp.proc.MailAgentMessage;
import SK.gnome.dwarf.mail.smtp.proc.Preprocessing;
/**
* Provides agent for remote execution of console commands.
*
* <p>The agent is activated by a message to postmaster's address with subject equal to
* the <tt>"console command"</tt> string. The message body must consist of two lines with the
* authentication information (username and password) and one or more lines with the console
* commands to be executed. The output from executed commands is sent back to the sender
* address in a new mail message.
*
* <p>Please note that this agent is only for testing purposes since it may open a security
* hole, therefore do not use it in a production server!
*/
public class ConsoleCommand extends MailAgent implements Preprocessing
{
/**
* Creates a new <tt>ConsoleCommand</tt> agent.
*
* @param name the service name
*/
public ConsoleCommand(String name)
{ super(name);
}
protected void preprocess(MailAgentMessage message, Collection recipients)
throws IOException, MailException
{
// first of all, mark the passed recipients as finished
// (if you omit this step, the message will be normally delivered
// to the given recipients later)
for (Iterator it = recipients.iterator(); it.hasNext(); )
{ Recipient rcpt = (Recipient)it.next();
if (!rcpt.isFinished())
rcpt.finish(Recipient.DELIVERED, "2.1.5", "Delivered to mail agent");
}
// this output stream will hold responses from the console commands
ByteArrayOutputStream out = new ByteArrayOutputStream();
Writer writer = new OutputStreamWriter(out);
// get the MIME view of the message data
MimePart part = message.getMimePart();
InputStream in = null;
try
{ // get the decoded message content as an input stream
in = part.getDecodedInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
// get the username from the first line
String username = reader.readLine();
if (username == null)
throw new MailException("No username");
// get the password from the second line
String password = reader.readLine();
if (password == null)
throw new MailException("No password");
try
{ // authenticate the subject with the given username and password, because
// the console command must be executed on behalf of a concrete subject
Subject subject = new Subject();
Console console = Main.getMainServer().getConsole();
AuthId authId = console.login(subject, new BasicCallbackHandler(username, password.toCharArray()));
// take the rest of message lines as console commands and execute them; skip empty lines
String command;
while ((command = reader.readLine()) != null)
{ command = command.trim();
if (command.length() > 0)
{ writer.write("\r\n#command=" + command + "\r\n");
console.execute(subject, command, writer);
}
}
// logout the subject since we don't need it any more
console.logout(authId, subject);
}
catch (LoginException le)
{ String msg = "Failed login [user=" + username + ", cause=\"" + le.getMessage() + "\"]";
log(LOG_INFO, msg);
writer.write(msg);
}
catch (AccessControlException ace)
{ log(LOG_ERROR, "Error while user authorization", ace);
writer.write("Unauthorized access [user=" + username + ", cause=\"" + ace.getMessage() + "\"]");
}
}
finally
{ try
{ in.close();
}
catch (Exception e)
{
}
}
// flush out the output stream
writer.flush();
// create and send a response message with the output of executed commands as the message body
MimeMessageBuilder msg = new MimeMessageBuilder();
String postmaster = ((SMTPParameters)getParameters()).getPostmasterAddress();
msg.setFrom("Mail Delivery Subsystem <" + postmaster + ">");
msg.setTo(part.getHeader("From", null));
msg.setSubject("Output of console command");
msg.setHeader("In-Reply-To", part.getHeader("Message-Id", null));
ByteArrayInputStream buf = new ByteArrayInputStream(out.toByteArray());
msg.setContent(buf, "text/plain", "quoted-printable");
context.sendMessage(msg);
}
}
|