001 /****************************************************************
002 * Licensed to the Apache Software Foundation (ASF) under one *
003 * or more contributor license agreements. See the NOTICE file *
004 * distributed with this work for additional information *
005 * regarding copyright ownership. The ASF licenses this file *
006 * to you under the Apache License, Version 2.0 (the *
007 * "License"); you may not use this file except in compliance *
008 * with the License. You may obtain a copy of the License at *
009 * *
010 * http://www.apache.org/licenses/LICENSE-2.0 *
011 * *
012 * Unless required by applicable law or agreed to in writing, *
013 * software distributed under the License is distributed on an *
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
015 * KIND, either express or implied. See the License for the *
016 * specific language governing permissions and limitations *
017 * under the License. *
018 ****************************************************************/
019
020 package org.apache.james.protocols.smtp.core.esmtp;
021
022 import java.util.ArrayList;
023 import java.util.Collection;
024 import java.util.List;
025
026 import org.apache.james.protocols.api.handler.WiringException;
027 import org.apache.james.protocols.smtp.SMTPResponse;
028 import org.apache.james.protocols.smtp.SMTPRetCode;
029 import org.apache.james.protocols.smtp.SMTPSession;
030 import org.apache.james.protocols.smtp.core.AbstractHookableCmdHandler;
031 import org.apache.james.protocols.smtp.dsn.DSNStatus;
032 import org.apache.james.protocols.smtp.hook.HeloHook;
033 import org.apache.james.protocols.smtp.hook.HookResult;
034
035 /**
036 * Handles EHLO command
037 */
038 public class EhloCmdHandler extends AbstractHookableCmdHandler<HeloHook> implements EhloExtension{
039
040 /**
041 * The name of the command handled by the command handler
042 */
043 private final static String COMMAND_NAME = "EHLO";
044
045 private List<EhloExtension> ehloExtensions;
046
047 /**
048 * Handler method called upon receipt of a EHLO command. Responds with a
049 * greeting and informs the client whether client authentication is
050 * required.
051 *
052 * @param session
053 * SMTP session object
054 * @param argument
055 * the argument passed in with the command by the SMTP client
056 */
057 private SMTPResponse doEHLO(SMTPSession session, String argument) {
058 SMTPResponse resp = new SMTPResponse(SMTPRetCode.MAIL_OK, new StringBuilder(session.getHelloName()).append(" Hello ").append(argument)
059 .append(" (").append(session.getRemoteHost()).append(" [")
060 .append(session.getRemoteIPAddress()).append("])"));
061
062 session.getConnectionState().put(SMTPSession.CURRENT_HELO_MODE,
063 COMMAND_NAME);
064
065 processExtensions(session, resp);
066
067
068
069 return resp;
070
071 }
072
073 /**
074 * @see org.apache.james.protocols.api.handler.CommandHandler#getImplCommands()
075 */
076 public Collection<String> getImplCommands() {
077 Collection<String> implCommands = new ArrayList<String>();
078 implCommands.add(COMMAND_NAME);
079
080 return implCommands;
081 }
082
083 /**
084 * @see org.apache.james.protocols.api.handler.ExtensibleHandler#getMarkerInterfaces()
085 */
086 public List<Class<?>> getMarkerInterfaces() {
087 List<Class<?>> classes = super.getMarkerInterfaces();
088 classes.add(EhloExtension.class);
089 return classes;
090 }
091
092 /**
093 * @see org.apache.james.protocols.api.handler.ExtensibleHandler#wireExtensions(java.lang.Class,
094 * java.util.List)
095 */
096 public void wireExtensions(Class interfaceName, List extension) {
097 super.wireExtensions(interfaceName, extension);
098 if (EhloExtension.class.equals(interfaceName)) {
099 this.ehloExtensions = extension;
100 }
101 }
102
103 /**
104 * Process the ehloExtensions
105 *
106 * @param session SMTPSession
107 * @param resp SMTPResponse
108 */
109 private void processExtensions(SMTPSession session, SMTPResponse resp) {
110 if (ehloExtensions != null) {
111 int count = ehloExtensions.size();
112 for (int i = 0; i < count; i++) {
113 List<String> lines = ((EhloExtension) ehloExtensions.get(i))
114 .getImplementedEsmtpFeatures(session);
115 if (lines != null) {
116 for (int j = 0; j < lines.size(); j++) {
117 resp.appendLine(lines.get(j));
118 }
119 }
120 }
121 }
122 }
123
124 /**
125 * @see org.apache.james.protocols.smtp.core.AbstractHookableCmdHandler#doCoreCmd(org.apache.james.protocols.smtp.SMTPSession,
126 * java.lang.String, java.lang.String)
127 */
128 protected SMTPResponse doCoreCmd(SMTPSession session, String command,
129 String parameters) {
130 return doEHLO(session, parameters);
131 }
132
133 /**
134 * @see org.apache.james.protocols.smtp.core.AbstractHookableCmdHandler#doFilterChecks(org.apache.james.protocols.smtp.SMTPSession,
135 * java.lang.String, java.lang.String)
136 */
137 protected SMTPResponse doFilterChecks(SMTPSession session, String command,
138 String parameters) {
139 session.resetState();
140
141 if (parameters == null) {
142 return new SMTPResponse(SMTPRetCode.SYNTAX_ERROR_ARGUMENTS,
143 DSNStatus.getStatus(DSNStatus.PERMANENT,
144 DSNStatus.DELIVERY_INVALID_ARG)
145 + " Domain address required: " + COMMAND_NAME);
146 } else {
147 // store provided name
148 session.getState().put(SMTPSession.CURRENT_HELO_NAME, parameters);
149 return null;
150 }
151 }
152
153 /**
154 * @see org.apache.james.protocols.smtp.core.AbstractHookableCmdHandler#getHookInterface()
155 */
156 protected Class<HeloHook> getHookInterface() {
157 return HeloHook.class;
158 }
159
160 /**
161 * {@inheritDoc}
162 */
163 protected HookResult callHook(HeloHook rawHook, SMTPSession session, String parameters) {
164 return rawHook.doHelo(session, parameters);
165 }
166
167
168
169 /**
170 * @see org.apache.james.protocols.smtp.core.esmtp.EhloExtension#getImplementedEsmtpFeatures(org.apache.james.protocols.smtp.SMTPSession)
171 */
172 public List<String> getImplementedEsmtpFeatures(SMTPSession session) {
173 List<String> extensions = new ArrayList<String>();
174 extensions.add("PIPELINING");
175 extensions.add("ENHANCEDSTATUSCODES");
176 // see http://issues.apache.org/jira/browse/JAMES-419
177 extensions.add("8BITMIME");
178 return extensions;
179 }
180
181 }