1 /************************************************************************
2 * Copyright (c) 1999-2006 The Apache Software Foundation. *
3 * All rights reserved. *
4 * ------------------------------------------------------------------- *
5 * Licensed under the Apache License, Version 2.0 (the "License"); you *
6 * may not use this file except in compliance with the License. You *
7 * may obtain a copy of the License at: *
8 * *
9 * http://www.apache.org/licenses/LICENSE-2.0 *
10 * *
11 * Unless required by applicable law or agreed to in writing, software *
12 * distributed under the License is distributed on an "AS IS" BASIS, *
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or *
14 * implied. See the License for the specific language governing *
15 * permissions and limitations under the License. *
16 ***********************************************************************/
17
18 package org.apache.james.smtpserver;
19
20 import org.apache.avalon.framework.configuration.Configurable;
21 import org.apache.avalon.framework.configuration.Configuration;
22 import org.apache.avalon.framework.configuration.ConfigurationException;
23 import org.apache.avalon.framework.logger.AbstractLogEnabled;
24 import org.apache.james.util.mail.dsn.DSNStatus;
25
26 import java.net.UnknownHostException;
27 import java.util.ArrayList;
28
29 /***
30 * Handles EHLO command
31 */
32 public class EhloCmdHandler extends AbstractLogEnabled implements CommandHandler,Configurable {
33
34 /***
35 * The name of the command handled by the command handler
36 */
37 private final static String COMMAND_NAME = "EHLO";
38
39 /***
40 * set checkResolvableEhlo to false as default value
41 */
42 private boolean checkResolvableEhlo = false;
43
44 private boolean checkAuthNetworks = false;
45
46 /***
47 * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
48 */
49 public void configure(Configuration handlerConfiguration) throws ConfigurationException {
50 Configuration configuration = handlerConfiguration.getChild("checkResolvableEhlo",false);
51 if(configuration != null) {
52 checkResolvableEhlo = configuration.getValueAsBoolean();
53 }
54
55 Configuration configRelay = handlerConfiguration.getChild("checkAuthNetworks",false);
56 if(configRelay != null) {
57 checkAuthNetworks = configRelay.getValueAsBoolean();
58 }
59 }
60
61
62
63
64
65
66 public void onCommand(SMTPSession session) {
67 doEHLO(session, session.getCommandArgument());
68 }
69
70 /***
71 * Handler method called upon receipt of a EHLO command.
72 * Responds with a greeting and informs the client whether
73 * client authentication is required.
74 *
75 * @param session SMTP session object
76 * @param argument the argument passed in with the command by the SMTP client
77 */
78 private void doEHLO(SMTPSession session, String argument) {
79 String responseString = null;
80 StringBuffer responseBuffer = session.getResponseBuffer();
81 boolean badEhlo = false;
82
83
84 if (checkResolvableEhlo) {
85
86 /***
87 * don't check if the ip address is allowed to relay. Only check if it is set in the config. ed.
88 */
89 if (!session.isRelayingAllowed() || checkAuthNetworks) {
90
91
92
93 try {
94 org.apache.james.dnsserver.DNSServer.getByName(argument);
95 } catch (UnknownHostException e) {
96 badEhlo = true;
97 responseString = "501 "+DSNStatus.getStatus(DSNStatus.PERMANENT,DSNStatus.DELIVERY_INVALID_ARG)+" Provided EHLO " + argument + " can not resolved";
98 session.writeResponse(responseString);
99 getLogger().info(responseString);
100 }
101 }
102 }
103
104 if (argument == null) {
105 responseString = "501 "+DSNStatus.getStatus(DSNStatus.PERMANENT,DSNStatus.DELIVERY_INVALID_ARG)+" Domain address required: " + COMMAND_NAME;
106 session.writeResponse(responseString);
107 } else if (!badEhlo){
108 session.resetState();
109 session.getState().put(SMTPSession.CURRENT_HELO_MODE, COMMAND_NAME);
110
111 ArrayList esmtpextensions = new ArrayList();
112
113 esmtpextensions.add(new StringBuffer(session.getConfigurationData().getHelloName())
114 .append(" Hello ")
115 .append(argument)
116 .append(" (")
117 .append(session.getRemoteHost())
118 .append(" [")
119 .append(session.getRemoteIPAddress())
120 .append("])").toString());
121
122
123 long maxMessageSize = session.getConfigurationData().getMaxMessageSize();
124 if (maxMessageSize > 0) {
125 esmtpextensions.add("SIZE " + maxMessageSize);
126 }
127
128 if (session.isAuthRequired()) {
129 esmtpextensions.add("AUTH LOGIN PLAIN");
130 esmtpextensions.add("AUTH=LOGIN PLAIN");
131 }
132
133 esmtpextensions.add("PIPELINING");
134 esmtpextensions.add("ENHANCEDSTATUSCODES");
135
136
137
138
139
140 for (int i = 0; i < esmtpextensions.size(); i++) {
141 if (i == esmtpextensions.size() - 1) {
142 responseBuffer.append("250 ");
143 responseBuffer.append((String) esmtpextensions.get(i));
144 session.writeResponse(session.clearResponseBuffer());
145 } else {
146 responseBuffer.append("250-");
147 responseBuffer.append((String) esmtpextensions.get(i));
148 session.writeResponse(session.clearResponseBuffer());
149 }
150 }
151 }
152 }
153
154 }