You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by ch...@apache.org on 2001/06/19 18:00:48 UTC
cvs commit: jakarta-james/src/java/org/apache/james/smtpserver SMTPHandler.java
charlesb 01/06/19 09:00:48
Modified: src/conf james-config.xml
src/java/org/apache/james/services MailServer.java
src/java/org/apache/james/smtpserver SMTPHandler.java
Removed: proposals/v1.3/conf james-config.xml
proposals/v1.3/java/org/apache/james/services
MailServer.java
proposals/v1.3/java/org/apache/james/smtpserver
SMTPHandler.java
proposals/v1.3/java/org/apache/james/util Base64.java
Log:
Moved size-limiting SMTP handler to main tree
Revision Changes Path
1.4 +4 -4 jakarta-james/src/conf/james-config.xml
Index: james-config.xml
===================================================================
RCS file: /home/cvs/jakarta-james/src/conf/james-config.xml,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- james-config.xml 2001/06/14 13:05:02 1.3
+++ james-config.xml 2001/06/19 16:00:38 1.4
@@ -13,8 +13,8 @@
CONFIRM? comment in the left
margin.
- This is $Revision: 1.3 $
- Committed on $Date: 2001/06/14 13:05:02 $ by: $Author: charlesb $
+ This is $Revision: 1.4 $
+ Committed on $Date: 2001/06/19 16:00:38 $ by: $Author: charlesb $
-->
<config>
@@ -396,9 +396,9 @@
as somebody else -->
<!-- This sets the maximum allowed message size for the smtphandler
- in KBytes. The value defaults to 0, which means no limit.
+ in KBytes. The value defaults to 0, which means no limit. -->
<maxmessagesize>0</maxmessagesize>
- -->
+
</handler>
</smtpserver>
1.2 +57 -0 jakarta-james/src/java/org/apache/james/services/MailServer.java
Index: MailServer.java
===================================================================
RCS file: /home/cvs/jakarta-james/src/java/org/apache/james/services/MailServer.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- MailServer.java 2001/05/11 09:39:34 1.1
+++ MailServer.java 2001/06/19 16:00:42 1.2
@@ -20,6 +20,9 @@
*
* @author Federico Barbieri <sc...@pop.systemy.it>
* @author <a href="mailto:charles@benett1.demon.co.uk">Charles Benett</a>
+ *
+ * This is $Revision: 1.2 $
+ * Committed on $Date: 2001/06/19 16:00:42 $ by: $Author: charlesb $
*/
public interface MailServer
extends Service {
@@ -34,18 +37,72 @@
*/
String ALL = "AllMailUsers";
+ /**
+ * Pass a MimeMessage to this MailServer for processing
+ *
+ * @param sender - the sender of the message
+ * @param recipients - a Collection of String objects of recipients
+ * @param msg - the MimeMessage of the headers and body content of
+ * the outgoing message
+ * @throws MessagingException - if the message fails to parse
+ */
void sendMail(MailAddress sender, Collection recipients, MimeMessage msg)
throws MessagingException;
+ /**
+ * Pass a MimeMessage to this MailServer for processing
+ *
+ * @param sender - the sender of the message
+ * @param recipients - a Collection of String objects of recipients
+ * @param msg - an InputStream containing the headers and body content of
+ * the outgoing message
+ * @throws MessagingException - if the message fails to parse
+ */
void sendMail(MailAddress sender, Collection recipients, InputStream msg)
throws MessagingException;
+ /**
+ * Pass a Mail to this MailServer for processing
+ *
+ * @param sender - the sender of the message
+ * @param recipients - a Collection of String objects of recipients
+ * @param msg - an InputStream containing the headers and body content of
+ * the outgoing message
+ * @throws MessagingException - if the message fails to parse
+ */
void sendMail(Mail mail)
throws MessagingException;
+ /**
+ * Retrieve the primary mailbox for userName. For POP3 style stores this
+ * is their (sole) mailbox. For IMAP style stores this is the INBOX
+ * mailbox.
+ *
+ * @param sender - the name of the user
+ * @returns a reference to an initialised mailbox
+ */
MailRepository getUserInbox(String userName);
String getId();
+ /**
+ * Adds a new user to the mail system with userName. For POP3 style stores
+ * this may only involve adding the user to the UsersStore.
+ * For IMAP style stores this involves creating malboxes with appropriate
+ * ACLs. Additional considerations apply if there has been a previous user
+ * with the same name in an IMAP system.
+ * mailbox.
+ *
+ * @param sender - the name of the user
+ * @returns a reference to an initialised mailbox
+ */
boolean addUser(String userName, String password);
+
+ /**
+ * Checks if a server is serviced by mail context
+ *
+ * @param serverName - name of server.
+ * @return true if server is local, i.e. serviced by this mail context
+ */
+ boolean isLocalServer(String serverName);
}
1.3 +89 -20 jakarta-james/src/java/org/apache/james/smtpserver/SMTPHandler.java
Index: SMTPHandler.java
===================================================================
RCS file: /home/cvs/jakarta-james/src/java/org/apache/james/smtpserver/SMTPHandler.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- SMTPHandler.java 2001/06/14 13:05:03 1.2
+++ SMTPHandler.java 2001/06/19 16:00:45 1.3
@@ -41,9 +41,10 @@
* @author Serge Knystautas <se...@lokitech.com>
* @author Federico Barbieri <sc...@systemy.it>
* @author Jason Borden <jb...@javasense.com>
+ * @author Matthew Pangaro <ma...@lokitech.com>
*
- * This is $Revision: 1.2 $
- * Committed on $Date: 2001/06/14 13:05:03 $ by: $Author: charlesb $
+ * This is $Revision: 1.3 $
+ * Committed on $Date: 2001/06/19 16:00:45 $ by: $Author: charlesb $
*/
public class SMTPHandler
extends BaseConnectionHandler
@@ -56,10 +57,12 @@
public final static String NAME_GIVEN = "NAME_GIVEN";
public final static String CURRENT_HELO_MODE = "CURRENT_HELO_MODE";
public final static String SENDER = "SENDER_ADDRESS";
+ public final static String MESG_FAILED = "MESG_FAILED";
public final static String RCPT_VECTOR = "RCPT_VECTOR";
public final static String SMTP_ID = "SMTP_ID";
public final static String AUTH = "AUTHENTICATED";
public final static char[] SMTPTerminator = {'\r','\n','.','\r','\n'};
+ private final static boolean DEEP_DEBUG = true;
private Socket socket;
private DataInputStream in;
@@ -74,17 +77,17 @@
private boolean authRequired = false;
private boolean verifyIdentity = false;
- private Configuration conf;
+ // private Configuration conf;
private TimeScheduler scheduler;
private UsersRepository users;
private MailServer mailServer;
- private James parentJames;
private String softwaretype = "JAMES SMTP Server "
+ Constants.SOFTWARE_VERSION;
private static long count;
private Hashtable state = new Hashtable();
private Random random = new Random();
+ private long maxmessagesize = 0;
public void configure ( Configuration configuration )
throws ConfigurationException {
@@ -93,14 +96,19 @@
= configuration.getChild("authRequired").getValueAsBoolean(false);
verifyIdentity
= configuration.getChild("verifyIdentity").getValueAsBoolean(false);
+ // get the message size limit from the conf file and multiply
+ // by 1024, to put it in bytes
+ maxmessagesize =
+ configuration.getChild( "maxmessagesize" ).getValueAsLong( 0 ) * 1024;
+ if (DEEP_DEBUG) {
+ getLogger().debug("Max message size is: " + maxmessagesize);
+ }
}
public void compose( final ComponentManager componentManager )
throws ComponentException {
mailServer = (MailServer)componentManager.lookup(
"org.apache.james.services.MailServer");
- parentJames = (James)componentManager.lookup(
- "org.apache.james.services.MailServer");
scheduler = (TimeScheduler)componentManager.lookup(
"org.apache.avalon.cornerstone.services.scheduler.TimeScheduler");
UsersStore usersStore = (UsersStore)componentManager.lookup(
@@ -203,7 +211,9 @@
throws Exception {
if (command == null) return false;
- getLogger().info("Command received: " + command);
+ if (state.get(MESG_FAILED) == null) {
+ getLogger().info("Command received: " + command);
+ }
StringTokenizer commandLine
= new StringTokenizer(command.trim(), " :");
int arguments = commandLine.countTokens();
@@ -247,20 +257,38 @@
private void doHELO(String command,String argument,String argument1) {
if (state.containsKey(CURRENT_HELO_MODE)) {
out.println("250 " + state.get(SERVER_NAME)
- + " Duplicate HELO/EHLO");
+ + " Duplicate HELO");
} else if (argument == null) {
out.println("501 domain address required: " + command);
} else {
state.put(CURRENT_HELO_MODE, command);
state.put(NAME_GIVEN, argument);
- out.println(((authRequired) ? "250-AUTH LOGIN PLAIN\r\n" : "")
- + "250 " + state.get(SERVER_NAME) + " Hello "
+ out.println( "250 " + state.get(SERVER_NAME) + " Hello "
+ argument + " (" + state.get(REMOTE_NAME)
+ " [" + state.get(REMOTE_IP) + "])");
}
}
private void doEHLO(String command,String argument,String argument1) {
- doHELO(command,argument,argument1);
+ if (state.containsKey(CURRENT_HELO_MODE)) {
+ out.println("250 " + state.get(SERVER_NAME)
+ + " Duplicate EHLO");
+ } else if (argument == null) {
+ out.println("501 domain address required: " + command);
+ } else {
+ state.put(CURRENT_HELO_MODE, command);
+ state.put(NAME_GIVEN, argument);
+ out.println( "250 " + state.get(SERVER_NAME) + " Hello "
+ + argument + " (" + state.get(REMOTE_NAME)
+ + " [" + state.get(REMOTE_IP) + "])");
+ if (maxmessagesize > 0) {
+ // out.println("250 SIZE " + maxmessagesize);
+ }
+ if (authRequired) {
+ out.println("250 AUTH LOGIN PLAIN");
+ }
+ }
+
+
}
private void doAUTH(String command,String argument,String argument1)
@@ -390,7 +418,7 @@
String toDomain
= recipient.substring(recipient.indexOf('@') + 1);
- if (!parentJames.isLocalServer(toDomain)) {
+ if (!mailServer.isLocalServer(toDomain)) {
out.println("530 Authentication Required");
getLogger().error(
"Authentication is required for mail request");
@@ -412,7 +440,7 @@
+ senderAddress);
return;
}
- if (!parentJames.isLocalServer(
+ if (!mailServer.isLocalServer(
senderAddress.getHost())) {
out.println("503 Incorrect Authentication for Specified Email Address");
getLogger().error("User " + authUser
@@ -447,6 +475,16 @@
// parse headers
InputStream msgIn
= new CharTerminatedInputStream(in, SMTPTerminator);
+ // if the message size limit has been set, we'll
+ // wrap msgIn with a SizeLimitedInputStream
+ if (maxmessagesize > 0) {
+ if (DEEP_DEBUG) {
+ getLogger().debug("Using SizeLimitedInputStream "
+ + " with max message size: "
+ + maxmessagesize);
+ }
+ msgIn = new SizeLimitedInputStream(msgIn, maxmessagesize);
+ }
MailHeaders headers = new MailHeaders(msgIn);
// if headers do not contains minimum REQUIRED headers fields
// add them
@@ -481,14 +519,41 @@
(MailAddress)state.get(SENDER),
(Vector)state.get(RCPT_VECTOR),
new SequenceInputStream(headersIn, msgIn));
+ // if the message size limit has been set, we'll
+ // call mail.getSize() to force the message to be
+ // loaded. Need to do this to limit the size
+ if (maxmessagesize > 0) {
+ mail.getSize();
+ }
mail.setRemoteHost((String)state.get(REMOTE_NAME));
mail.setRemoteAddr((String)state.get(REMOTE_IP));
mailServer.sendMail(mail);
} catch (MessagingException me) {
- out.println("451 Error processing message: "
- + me.getMessage());
- getLogger().error("Error processing message: "
- + me.getMessage());
+ //Grab any exception attached to this one.
+ Exception e = me.getNextException();
+
+ //If there was an attached exception, and it's a
+ //MessageSizeException
+ if (e != null && e instanceof MessageSizeException) {
+ getLogger().error("552 Error processing message: "
+ + e.getMessage());
+ // Add an item to the state to suppress
+ // logging of extra lines of data
+ // that are sent after the size limit has
+ // been hit.
+ state.put(MESG_FAILED, Boolean.TRUE);
+
+ //then let the client know that the size
+ //limit has been hit.
+ out.println("552 Error processing message: "
+ + e.getMessage());
+ } else {
+ out.println("451 Error processing message: "
+ + me.getMessage());
+ getLogger().error("Error processing message: "
+ + me.getMessage());
+ me.printStackTrace();
+ }
return;
}
getLogger().info("Mail sent to Mail Server");
@@ -501,8 +566,12 @@
+ " Service closing transmission channel");
}
- private void doUnknownCmd(String command,String argument,String argument1) {
- out.println("500 " + state.get(SERVER_NAME) + " Syntax error, command unrecognized: " +
- command);
+ private void doUnknownCmd(String command,String argument,
+ String argument1) {
+ if (state.get(MESG_FAILED) == null) {
+ out.println("500 " + state.get(SERVER_NAME)
+ + " Syntax error, command unrecognized: " + command);
+ }
}
+
}
---------------------------------------------------------------------
To unsubscribe, e-mail: james-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: james-dev-help@jakarta.apache.org