1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.apache.james.smtpserver;
23
24 import org.apache.avalon.framework.configuration.Configuration;
25 import org.apache.avalon.framework.configuration.ConfigurationException;
26 import org.apache.avalon.framework.container.ContainerUtil;
27 import org.apache.avalon.framework.service.ServiceException;
28 import org.apache.avalon.framework.service.ServiceManager;
29 import org.apache.james.Constants;
30 import org.apache.james.api.dnsservice.DNSService;
31 import org.apache.james.api.dnsservice.util.NetMatcher;
32 import org.apache.james.api.user.UsersRepository;
33 import org.apache.james.services.MailServer;
34 import org.apache.james.socket.AbstractJamesService;
35 import org.apache.james.socket.ProtocolHandler;
36 import org.apache.mailet.MailetContext;
37
38
39
40
41
42
43
44
45
46
47
48
49 public class SMTPServer extends AbstractJamesService implements SMTPServerMBean {
50
51
52
53
54
55
56 SMTPHandlerChain handlerChain = new SMTPHandlerChain();
57
58
59
60
61 MailetContext mailetcontext;
62
63
64
65
66
67 private UsersRepository users;
68
69
70
71
72 private MailServer mailServer;
73
74
75
76
77 private DNSService dnsServer;
78
79
80
81
82
83 private final static int AUTH_DISABLED = 0;
84 private final static int AUTH_REQUIRED = 1;
85 private final static int AUTH_ANNOUNCE = 2;
86 private int authRequired = AUTH_DISABLED;
87
88
89
90
91
92
93
94 private boolean verifyIdentity = false;
95
96
97
98
99 private boolean heloEhloEnforcement = false;
100
101
102
103
104 private String smtpGreeting = null;
105
106
107
108
109
110 private NetMatcher authorizedNetworks = null;
111
112
113
114
115
116 private long maxMessageSize = 0;
117
118
119
120
121
122
123 private int lengthReset = 20 * 1024;
124
125
126
127
128 private SMTPHandlerConfigurationData theConfigData
129 = new SMTPHandlerConfigurationDataImpl();
130
131 private ServiceManager serviceManager;
132
133 private boolean addressBracketsEnforcement = true;
134
135
136
137
138 public void service( final ServiceManager manager ) throws ServiceException {
139 super.service( manager );
140 serviceManager = manager;
141 mailetcontext = (MailetContext) manager.lookup(MailetContext.class.getName());
142 mailServer = (MailServer) manager.lookup(MailServer.ROLE);
143 users = (UsersRepository) manager.lookup(UsersRepository.ROLE);
144 dnsServer = (DNSService) manager.lookup(DNSService.ROLE);
145 }
146
147
148
149
150 public void configure(final Configuration configuration) throws ConfigurationException {
151 super.configure(configuration);
152 String hello = (String) mailetcontext.getAttribute(Constants.HELLO_NAME);
153
154 if (isEnabled()) {
155
156 if (hello == null) mailetcontext.setAttribute(Constants.HELLO_NAME, helloName);
157
158 Configuration handlerConfiguration = configuration.getChild("handler");
159 String authRequiredString = handlerConfiguration.getChild("authRequired").getValue("false").trim().toLowerCase();
160 if (authRequiredString.equals("true")) authRequired = AUTH_REQUIRED;
161 else if (authRequiredString.equals("announce")) authRequired = AUTH_ANNOUNCE;
162 else authRequired = AUTH_DISABLED;
163 verifyIdentity = handlerConfiguration.getChild("verifyIdentity").getValueAsBoolean(false);
164 if (authRequired != AUTH_DISABLED) {
165 if (verifyIdentity) {
166 getLogger().info("This SMTP server requires authentication and verifies that the authentication credentials match the sender address.");
167 } else {
168 getLogger().info("This SMTP server requires authentication, but doesn't verify that the authentication credentials match the sender address.");
169 }
170 } else {
171 getLogger().info("This SMTP server does not require authentication.");
172 }
173
174 String authorizedAddresses = handlerConfiguration.getChild("authorizedAddresses").getValue(null);
175 if (authRequired == AUTH_DISABLED && authorizedAddresses == null) {
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190 authorizedAddresses = "0.0.0.0/0.0.0.0";
191 }
192
193 if (authorizedAddresses != null) {
194 java.util.StringTokenizer st = new java.util.StringTokenizer(authorizedAddresses, ", ", false);
195 java.util.Collection networks = new java.util.ArrayList();
196 while (st.hasMoreTokens()) {
197 String addr = st.nextToken();
198 networks.add(addr);
199 }
200 authorizedNetworks = new NetMatcher(networks,dnsServer);
201 }
202
203 if (authorizedNetworks != null) {
204 getLogger().info("Authorized addresses: " + authorizedNetworks.toString());
205 }
206
207
208
209 maxMessageSize = handlerConfiguration.getChild( "maxmessagesize" ).getValueAsLong( maxMessageSize ) * 1024;
210 if (maxMessageSize > 0) {
211 getLogger().info("The maximum allowed message size is " + maxMessageSize + " bytes.");
212 } else {
213 getLogger().info("No maximum message size is enforced for this server.");
214 }
215
216 lengthReset = configuration.getChild("lengthReset").getValueAsInteger(lengthReset);
217 if (lengthReset <= 0) {
218 throw new ConfigurationException("The configured value for the idle timeout reset, " + lengthReset + ", is not valid.");
219 }
220 if (getLogger().isInfoEnabled()) {
221 getLogger().info("The idle timeout will be reset every " + lengthReset + " bytes.");
222 }
223
224 heloEhloEnforcement = handlerConfiguration.getChild("heloEhloEnforcement").getValueAsBoolean(true);
225
226 if (authRequiredString.equals("true")) authRequired = AUTH_REQUIRED;
227
228
229 smtpGreeting = handlerConfiguration.getChild("smtpGreeting").getValue(null);
230
231 addressBracketsEnforcement = handlerConfiguration.getChild("addressBracketsEnforcement").getValueAsBoolean(true);
232
233
234 ContainerUtil.enableLogging(handlerChain,getLogger());
235
236 try {
237 ContainerUtil.service(handlerChain,serviceManager);
238 } catch (ServiceException e) {
239 if (getLogger().isErrorEnabled()) {
240 getLogger().error("Failed to service handlerChain",e);
241 }
242 throw new ConfigurationException("Failed to service handlerChain");
243 }
244
245
246 ContainerUtil.configure(handlerChain,handlerConfiguration.getChild("handlerchain"));
247
248 } else {
249
250 if (hello == null) mailetcontext.setAttribute(Constants.HELLO_NAME, "localhost");
251 }
252 }
253
254
255
256
257 public void initialize() throws Exception {
258 super.initialize();
259 ContainerUtil.initialize(handlerChain);
260 }
261
262
263
264
265 protected int getDefaultPort() {
266 return 25;
267 }
268
269
270
271
272 public String getServiceType() {
273 return "SMTP Service";
274 }
275
276
277
278
279 public ProtocolHandler newProtocolHandlerInstance() {
280 SMTPHandler theHandler = new SMTPHandler();
281
282 theHandler.setHandlerChain(handlerChain);
283 return theHandler;
284 }
285
286
287
288
289 private class SMTPHandlerConfigurationDataImpl
290 implements SMTPHandlerConfigurationData {
291
292
293
294
295 public String getHelloName() {
296 if (SMTPServer.this.helloName == null) {
297 return SMTPServer.this.mailServer.getHelloName();
298 } else {
299 return SMTPServer.this.helloName;
300 }
301 }
302
303
304
305
306 public int getResetLength() {
307 return SMTPServer.this.lengthReset;
308 }
309
310
311
312
313 public long getMaxMessageSize() {
314 return SMTPServer.this.maxMessageSize;
315 }
316
317
318
319
320 public boolean isRelayingAllowed(String remoteIP) {
321 boolean relayingAllowed = false;
322 if (authorizedNetworks != null) {
323 relayingAllowed = SMTPServer.this.authorizedNetworks.matchInetNetwork(remoteIP);
324 }
325 return relayingAllowed;
326 }
327
328
329
330
331 public boolean isAuthRequired(String remoteIP) {
332 if (SMTPServer.this.authRequired == AUTH_ANNOUNCE) return true;
333 boolean authRequired = SMTPServer.this.authRequired != AUTH_DISABLED;
334 if (authorizedNetworks != null) {
335 authRequired = authRequired && !SMTPServer.this.authorizedNetworks.matchInetNetwork(remoteIP);
336 }
337 return authRequired;
338 }
339
340
341
342
343 public boolean isAuthRequired() {
344 return SMTPServer.this.authRequired != AUTH_DISABLED;
345 }
346
347
348
349
350 public boolean isVerifyIdentity() {
351 return SMTPServer.this.verifyIdentity;
352 }
353
354
355
356
357 public MailServer getMailServer() {
358 return SMTPServer.this.mailServer;
359 }
360
361
362
363
364 public UsersRepository getUsersRepository() {
365 return SMTPServer.this.users;
366 }
367
368
369
370
371 public boolean useHeloEhloEnforcement() {
372 return SMTPServer.this.heloEhloEnforcement;
373 }
374
375
376
377
378
379 public String getSMTPGreeting() {
380 return SMTPServer.this.smtpGreeting;
381 }
382
383
384
385
386 public boolean useAddressBracketsEnforcement() {
387
388 return SMTPServer.this.addressBracketsEnforcement;
389 }
390
391
392
393
394 }
395
396
397
398
399 protected Object getConfigurationData() {
400 return theConfigData;
401 }
402 }