Repository: james-project Updated Branches: refs/heads/master 62466172d -> ae70e0a5c
JAMES-1543 Finish implementing incomplete SIZE extended SMTP behaviour Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/2097ee9e Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/2097ee9e Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/2097ee9e Branch: refs/heads/master Commit: 2097ee9eabbe87428ef3308abf18578ef4fb2de1 Parents: 6246617 Author: benwa <btell...@linagora.com> Authored: Mon Apr 17 16:56:16 2017 +0700 Committer: benwa <btell...@linagora.com> Committed: Wed Apr 19 13:02:24 2017 +0700 ---------------------------------------------------------------------- .../smtp/core/esmtp/MailSizeEsmtpExtension.java | 38 +++++++---- .../apache/james/smtpserver/SMTPServerTest.java | 68 ++++++++++++++++++++ 2 files changed, 92 insertions(+), 14 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/2097ee9e/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/esmtp/MailSizeEsmtpExtension.java ---------------------------------------------------------------------- diff --git a/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/esmtp/MailSizeEsmtpExtension.java b/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/esmtp/MailSizeEsmtpExtension.java index d178847..2079403 100644 --- a/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/esmtp/MailSizeEsmtpExtension.java +++ b/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/esmtp/MailSizeEsmtpExtension.java @@ -30,6 +30,7 @@ import org.apache.james.protocols.api.Response; import org.apache.james.protocols.api.ProtocolSession.State; import org.apache.james.protocols.api.handler.LineHandler; import org.apache.james.protocols.smtp.MailEnvelope; +import org.apache.james.protocols.smtp.SMTPResponse; import org.apache.james.protocols.smtp.SMTPRetCode; import org.apache.james.protocols.smtp.SMTPSession; import org.apache.james.protocols.smtp.core.DataLineFilter; @@ -50,6 +51,8 @@ public class MailSizeEsmtpExtension implements MailParametersHook, EhloExtension private static final HookResult SYNTAX_ERROR = new HookResult(HookReturnCode.DENY, SMTPRetCode.SYNTAX_ERROR_ARGUMENTS, DSNStatus.getStatus(DSNStatus.PERMANENT, DSNStatus.DELIVERY_INVALID_ARG) + " Syntactically incorrect value for SIZE parameter"); private static final HookResult QUOTA_EXCEEDED = new HookResult(HookReturnCode.DENY, SMTPRetCode.QUOTA_EXCEEDED, DSNStatus.getStatus(DSNStatus.PERMANENT, DSNStatus.SYSTEM_MSG_TOO_BIG) + " Message size exceeds fixed maximum message size"); + public static final int SINGLE_CHARACTER_LINE = 3; + public static final int DOT_BYTE = 46; @Override public void init(Configuration config) throws ConfigurationException { @@ -148,16 +151,21 @@ public class MailSizeEsmtpExtension implements MailParametersHook, EhloExtension * @see org.apache.james.protocols.smtp.core.DataLineFilter#onLine(SMTPSession, byte[], LineHandler) */ public Response onLine(SMTPSession session, ByteBuffer line, LineHandler<SMTPSession> next) { - Response response = null; - Boolean failed = (Boolean) session.getAttachment(MESG_FAILED, State.Transaction); + Boolean failed = (Boolean) session.getAttachment(MESG_FAILED, State.Transaction); // If we already defined we failed and sent a reply we should simply // wait for a CRLF.CRLF to be sent by the client. - if (failed != null && failed.booleanValue()) { - // TODO + if (failed != null && failed) { + if (isDataTerminated(line)) { + line.rewind(); + next.onLine(session, ByteBuffer.wrap(".\r\n".getBytes())); + return new SMTPResponse(SMTPRetCode.QUOTA_EXCEEDED, "Quota exceeded"); + } else { + return null; + } } else { - if (line.remaining() == 3 && line.get() == 46) { + if (isDataTerminated(line)) { line.rewind(); - response = next.onLine(session, line); + return next.onLine(session, line); } else { line.rewind(); Long currentSize = (Long) session.getAttachment("CURRENT_SIZE", State.Transaction); @@ -167,25 +175,27 @@ public class MailSizeEsmtpExtension implements MailParametersHook, EhloExtension } else { newSize = Long.valueOf(currentSize.intValue()+line.remaining()); } - + + session.setAttachment("CURRENT_SIZE", newSize, State.Transaction); + if (session.getConfiguration().getMaxMessageSize() > 0 && newSize.intValue() > session.getConfiguration().getMaxMessageSize()) { // Add an item to the state to suppress // logging of extra lines of data // that are sent after the size limit has // been hit. session.setAttachment(MESG_FAILED, Boolean.TRUE, State.Transaction); - // then let the client know that the size - // limit has been hit. - response = next.onLine(session, ByteBuffer.wrap(".\r\n".getBytes())); + + return null; } else { line.rewind(); - response = next.onLine(session, line); + return next.onLine(session, line); } - - session.setAttachment("CURRENT_SIZE", newSize, State.Transaction); } } - return response; + } + + private boolean isDataTerminated(ByteBuffer line) { + return line.remaining() == SINGLE_CHARACTER_LINE && line.get() == DOT_BYTE; } /** http://git-wip-us.apache.org/repos/asf/james-project/blob/2097ee9e/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPServerTest.java ---------------------------------------------------------------------- diff --git a/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPServerTest.java b/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPServerTest.java index 8faca0f..387db29 100644 --- a/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPServerTest.java +++ b/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPServerTest.java @@ -479,6 +479,74 @@ public class SMTPServerTest { } @Test + public void messageExceedingMessageSizeShouldBeDiscarded() throws Exception { + // Given + init(smtpConfiguration); + int maxSize = 1024; + smtpServer.setMaximalMessageSize(maxSize); + + // When + SMTPClient smtpProtocol = new SMTPClient(); + InetSocketAddress bindedAddress = new ProtocolServerUtils(smtpServer).retrieveBindedAddress(); + smtpProtocol.connect(bindedAddress.getAddress().getHostAddress(), bindedAddress.getPort()); + smtpProtocol.sendCommand("EHLO " + InetAddress.getLocalHost()); + smtpProtocol.setSender("mail@localhost"); + smtpProtocol.addRecipient("mail@localhost"); + // Create a 1K+ message + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("Subject: test\r\n\r\n"); + String repeatedString = "This is the repeated body...\r\n"; + int repeatCount = (maxSize / repeatedString.length()) + 1; + for (int i = 0; i < repeatCount; i++) { + stringBuilder.append(repeatedString); + } + stringBuilder.append("\r\n\r\n.\r\n"); + smtpProtocol.sendShortMessageData(stringBuilder.toString()); + + // Then + assertThat(queue.getLastMail()) + .as("mail received by mail server") + .isNull(); + + // finally + smtpProtocol.quit(); + smtpProtocol.disconnect(); + } + + @Test + public void messageExceedingMessageSizeShouldBeRespondedAsOverQuota() throws Exception { + // Given + init(smtpConfiguration); + int maxSize = 1024; + smtpServer.setMaximalMessageSize(maxSize); + + //When + SMTPClient smtpProtocol = new SMTPClient(); + InetSocketAddress bindedAddress = new ProtocolServerUtils(smtpServer).retrieveBindedAddress(); + smtpProtocol.connect(bindedAddress.getAddress().getHostAddress(), bindedAddress.getPort()); + smtpProtocol.sendCommand("EHLO " + InetAddress.getLocalHost()); + smtpProtocol.setSender("mail@localhost"); + smtpProtocol.addRecipient("mail@localhost"); + // Create a 1K+ message + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("Subject: test\r\n\r\n"); + String repeatedString = "This is the repeated body...\r\n"; + int repeatCount = (maxSize / repeatedString.length()) + 1; + for (int i = 0; i < repeatCount; i++) { + stringBuilder.append(repeatedString); + } + stringBuilder.append("\r\n\r\n.\r\n"); + smtpProtocol.sendShortMessageData(stringBuilder.toString()); + + // Then + assertThat(smtpProtocol.getReplyString()).isEqualTo("552 Quota exceeded\r\n"); + + // Finally + smtpProtocol.quit(); + smtpProtocol.disconnect(); + } + + @Test public void testStartTLSInEHLO() throws Exception { smtpConfiguration.setStartTLS(); init(smtpConfiguration); --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org