1   /*****************************************************************
2    * Licensed to the Apache Software Foundation (ASF) under one   *
3    * or more contributor license agreements.  See the NOTICE file *
4    * distributed with this work for additional information        *
5    * regarding copyright ownership.  The ASF licenses this file   *
6    * to you under the Apache License, Version 2.0 (the            *
7    * "License"); you may not use this file except in compliance   *
8    * with the License.  You may obtain a copy of the License at   *
9    *                                                              *
10   *   http://www.apache.org/licenses/LICENSE-2.0                 *
11   *                                                              *
12   * Unless required by applicable law or agreed to in writing,   *
13   * software distributed under the License is distributed on an  *
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
15   * KIND, either express or implied.  See the License for the    *
16   * specific language governing permissions and limitations      *
17   * under the License.                                           *
18   ****************************************************************/
19  package org.apache.james.smtpserver;
20  
21  import org.apache.avalon.cornerstone.services.sockets.SocketManager;
22  import org.apache.avalon.cornerstone.services.store.Store;
23  import org.apache.avalon.cornerstone.services.threads.ThreadManager;
24  import org.apache.avalon.framework.container.ContainerUtil;
25  import org.apache.commons.net.smtp.SMTPClient;
26  import org.apache.commons.net.smtp.SMTPReply;
27  import org.apache.james.Constants;
28  import org.apache.james.core.MailImpl;
29  import org.apache.james.services.DNSServer;
30  import org.apache.james.services.JamesConnectionManager;
31  import org.apache.james.services.MailServer;
32  import org.apache.james.services.UsersRepository;
33  import org.apache.james.test.mock.avalon.MockLogger;
34  import org.apache.james.test.mock.avalon.MockServiceManager;
35  import org.apache.james.test.mock.avalon.MockSocketManager;
36  import org.apache.james.test.mock.avalon.MockStore;
37  import org.apache.james.test.mock.avalon.MockThreadManager;
38  import org.apache.james.test.mock.james.InMemorySpoolRepository;
39  import org.apache.james.test.mock.james.MockMailServer;
40  import org.apache.james.test.mock.mailet.MockMailContext;
41  import org.apache.james.test.mock.mailet.MockMailetConfig;
42  import org.apache.james.test.util.Util;
43  import org.apache.james.transport.mailets.RemoteDelivery;
44  import org.apache.james.userrepository.MockUsersRepository;
45  import org.apache.james.util.Base64;
46  import org.apache.james.util.connection.SimpleConnectionManager;
47  import org.apache.mailet.MailAddress;
48  
49  import javax.mail.MessagingException;
50  import javax.mail.Session;
51  import javax.mail.internet.MimeMessage;
52  
53  import java.io.ByteArrayInputStream;
54  import java.io.ByteArrayOutputStream;
55  import java.io.IOException;
56  import java.io.Writer;
57  import java.net.InetAddress;
58  import java.net.Socket;
59  import java.net.UnknownHostException;
60  import java.util.ArrayList;
61  import java.util.Arrays;
62  import java.util.Collection;
63  import java.util.Iterator;
64  import java.util.List;
65  import java.util.Properties;
66  
67  import junit.framework.TestCase;
68  
69  /***
70   * Tests the org.apache.james.smtpserver.SMTPServer unit 
71   */
72  public class SMTPServerTest extends TestCase {
73      private int m_smtpListenerPort = Util.getNonPrivilegedPort();
74      private MockMailServer m_mailServer;
75      private SMTPTestConfiguration m_testConfiguration;
76      private SMTPServer m_smtpServer;
77      private MockUsersRepository m_usersRepository = new MockUsersRepository();
78  
79      public SMTPServerTest() {
80          super("SMTPServerTest");
81      }
82  
83      public void verifyLastMail(String sender, String recipient, MimeMessage msg) throws IOException, MessagingException {
84          Object[] mailData = m_mailServer.getLastMail();
85          assertNotNull("mail received by mail server", mailData);
86  
87          if (sender == null && recipient == null && msg == null) fail("no verification can be done with all arguments null");
88  
89          if (sender != null) assertEquals("sender verfication", sender, ((MailAddress)mailData[0]).toString());
90          if (recipient != null) assertTrue("recipient verfication", ((Collection) mailData[1]).contains(new MailAddress(recipient)));
91          if (msg != null) {
92              ByteArrayOutputStream bo1 = new ByteArrayOutputStream();
93              msg.writeTo(bo1);
94              ByteArrayOutputStream bo2 = new ByteArrayOutputStream();
95              ((MimeMessage) mailData[2]).writeTo(bo2);
96              assertEquals(bo1.toString(),bo2.toString());
97              assertEquals("message verification", msg, ((MimeMessage) mailData[2]));
98          }
99      }
100     
101     protected void setUp() throws Exception {
102         m_smtpServer = new SMTPServer();
103         ContainerUtil.enableLogging(m_smtpServer,new MockLogger());
104         m_serviceManager = setUpServiceManager();
105         ContainerUtil.service(m_smtpServer, m_serviceManager);
106         m_testConfiguration = new SMTPTestConfiguration(m_smtpListenerPort);
107     }
108 
109     private void finishSetUp(SMTPTestConfiguration testConfiguration) throws Exception {
110         testConfiguration.init();
111         ContainerUtil.configure(m_smtpServer, testConfiguration);
112         ContainerUtil.initialize(m_smtpServer);
113         m_mailServer.setMaxMessageSizeBytes(m_testConfiguration.getMaxMessageSize()*1024);
114     }
115 
116     private MockServiceManager setUpServiceManager() throws Exception {
117         m_serviceManager = new MockServiceManager();
118         SimpleConnectionManager connectionManager = new SimpleConnectionManager();
119         ContainerUtil.enableLogging(connectionManager, new MockLogger());
120         m_serviceManager.put(JamesConnectionManager.ROLE, connectionManager);
121         m_serviceManager.put("org.apache.mailet.MailetContext", new MockMailContext());
122         m_mailServer = new MockMailServer();
123         m_serviceManager.put(MailServer.ROLE, m_mailServer);
124         m_serviceManager.put(UsersRepository.ROLE, m_usersRepository);
125         m_serviceManager.put(SocketManager.ROLE, new MockSocketManager(m_smtpListenerPort));
126         m_serviceManager.put(ThreadManager.ROLE, new MockThreadManager());
127         
128         DNSServer dns = new DNSServer() {
129 
130             public Collection findMXRecords(String hostname) {
131                 List res = new ArrayList();
132                 if (hostname == null) {
133                     return res;
134                 };
135                 if ("james.apache.org".equals(hostname)) {
136                     res.add("nagoya.apache.org");
137                 }
138                 return res;
139             }
140 
141             public Iterator getSMTPHostAddresses(String domainName) {
142                 throw new UnsupportedOperationException("Unimplemented mock service");
143             }
144             
145 
146             public InetAddress[] getAllByName(String host) throws UnknownHostException
147             {
148                 return new InetAddress[] {getByName(host)};
149 
150             }
151 
152 
153             public InetAddress getByName(String host) throws UnknownHostException
154             {
155                 return InetAddress.getByName(host);
156 
157             }
158             
159             public Collection findTXTRecords(String hostname) {
160                 List res = new ArrayList();
161                 if (hostname == null) {
162                     return res;
163                 };
164                 if ("2.0.0.127.bl.spamcop.net".equals(hostname)) {
165                     res.add("Blocked - see http://www.spamcop.net/bl.shtml?127.0.0.2");
166                 }
167                 return res;
168             }
169             
170         };
171         m_serviceManager.put(DNSServer.ROLE, dns);
172         m_serviceManager.put(Store.ROLE, new MockStore());
173         return m_serviceManager;
174     }
175 
176     public void testSimpleMailSendWithEHLO() throws Exception {
177         finishSetUp(m_testConfiguration);
178         
179         SMTPClient smtpProtocol = new SMTPClient();
180         smtpProtocol.connect("127.0.0.1", m_smtpListenerPort);
181 
182         
183         assertNull("no mail received by mail server", m_mailServer.getLastMail());
184 
185         smtpProtocol.sendCommand("EHLO "+InetAddress.getLocalHost());
186         String[] capabilityRes = smtpProtocol.getReplyStrings();
187         
188         List capabilitieslist = new ArrayList();
189         for (int i = 1; i < capabilityRes.length; i++) {
190             capabilitieslist.add(capabilityRes[i].substring(4));
191         }
192         
193         assertEquals("capabilities", 2, capabilitieslist.size());
194         assertTrue("capabilities present PIPELINING", capabilitieslist.contains("PIPELINING"));
195         assertTrue("capabilities present ENHANCEDSTATUSCODES", capabilitieslist.contains("ENHANCEDSTATUSCODES"));
196         
197 
198         smtpProtocol.setSender("mail@localhost");
199         smtpProtocol.addRecipient("mail@localhost");
200 
201         smtpProtocol.sendShortMessageData("Subject: test\r\n\r\nBody\r\n\r\n.\r\n");
202         smtpProtocol.quit();
203         smtpProtocol.disconnect();
204 
205         
206         assertNotNull("mail received by mail server", m_mailServer.getLastMail());
207     }
208 
209     public void testEmptyMessage() throws Exception {
210         finishSetUp(m_testConfiguration);
211 
212         SMTPClient smtp = new SMTPClient();
213         smtp.connect("127.0.0.1", m_smtpListenerPort);
214 
215         
216         assertNull("no mail received by mail server", m_mailServer.getLastMail());
217 
218         smtp.helo(InetAddress.getLocalHost().toString());
219         
220         smtp.setSender("mail@localhost");
221         
222         smtp.addRecipient("mail@localhost");
223 
224         smtp.sendShortMessageData("");
225 
226         smtp.quit();
227         
228         smtp.disconnect();
229 
230         
231         assertNotNull("mail received by mail server", m_mailServer.getLastMail());
232 
233         
234         
235         System.gc();
236 
237         int size = ((MimeMessage) m_mailServer.getLastMail()[2]).getSize();
238 
239         assertEquals(size, 2);
240     }
241 
242     public void testSimpleMailSendWithHELO() throws Exception {
243         finishSetUp(m_testConfiguration);
244 
245         SMTPClient smtpProtocol = new SMTPClient();
246         smtpProtocol.connect("127.0.0.1", m_smtpListenerPort);
247 
248         
249         assertNull("no mail received by mail server", m_mailServer.getLastMail());
250 
251         smtpProtocol.helo(InetAddress.getLocalHost().toString());
252         
253         smtpProtocol.setSender("mail@localhost");
254         
255         smtpProtocol.addRecipient("mail@localhost");
256 
257         smtpProtocol.sendShortMessageData("Subject: test mail\r\n\r\nTest body\r\n.\r\n");
258 
259         smtpProtocol.quit();
260         smtpProtocol.disconnect();
261 
262         
263         assertNotNull("mail received by mail server", m_mailServer.getLastMail());
264     }
265 
266     public void testTwoSimultaneousMails() throws Exception {
267         finishSetUp(m_testConfiguration);
268 
269         SMTPClient smtpProtocol1 = new SMTPClient();
270         smtpProtocol1.connect("127.0.0.1", m_smtpListenerPort);
271         SMTPClient smtpProtocol2 = new SMTPClient();
272         smtpProtocol2.connect("127.0.0.1", m_smtpListenerPort);
273 
274         assertTrue("first connection taken",smtpProtocol1.isConnected());
275         assertTrue("second connection taken",smtpProtocol2.isConnected());
276 
277         
278         assertNull("no mail received by mail server", m_mailServer.getLastMail());
279 
280         smtpProtocol1.helo(InetAddress.getLocalHost().toString());
281         smtpProtocol2.helo(InetAddress.getLocalHost().toString());
282 
283         String sender1 = "mail_sender1@localhost";
284         String recipient1 = "mail_recipient1@localhost";
285         smtpProtocol1.setSender(sender1);
286         smtpProtocol1.addRecipient(recipient1);
287 
288         String sender2 = "mail_sender2@localhost";
289         String recipient2 = "mail_recipient2@localhost";
290         smtpProtocol2.setSender(sender2);
291         smtpProtocol2.addRecipient(recipient2);
292 
293         smtpProtocol1.sendShortMessageData("Subject: test\r\n\r\nTest body\r\n.\r\n");
294         verifyLastMail(sender1, recipient1, null);
295             
296         smtpProtocol2.sendShortMessageData("Subject: test\r\n\r\nTest body\r\n.\r\n");
297         verifyLastMail(sender2, recipient2, null);
298 
299         smtpProtocol1.quit();
300         smtpProtocol2.quit();
301         
302         smtpProtocol1.disconnect();
303         smtpProtocol2.disconnect();
304     }
305 
306     public void testTwoMailsInSequence() throws Exception {
307         finishSetUp(m_testConfiguration);
308 
309         SMTPClient smtpProtocol1 = new SMTPClient();
310         smtpProtocol1.connect("127.0.0.1", m_smtpListenerPort);
311 
312         assertTrue("first connection taken", smtpProtocol1.isConnected());
313 
314         
315         assertNull("no mail received by mail server", m_mailServer.getLastMail());
316 
317         smtpProtocol1.helo(InetAddress.getLocalHost().toString());
318 
319         String sender1 = "mail_sender1@localhost";
320         String recipient1 = "mail_recipient1@localhost";
321         smtpProtocol1.setSender(sender1);
322         smtpProtocol1.addRecipient(recipient1);
323 
324         smtpProtocol1.sendShortMessageData("Subject: test\r\n\r\nTest body\r\n");
325         verifyLastMail(sender1, recipient1, null);
326             
327         String sender2 = "mail_sender2@localhost";
328         String recipient2 = "mail_recipient2@localhost";
329         smtpProtocol1.setSender(sender2);
330         smtpProtocol1.addRecipient(recipient2);
331 
332         smtpProtocol1.sendShortMessageData("Subject: test2\r\n\r\nTest body2\r\n");
333         verifyLastMail(sender2, recipient2, null);
334 
335         smtpProtocol1.quit();
336         smtpProtocol1.disconnect();
337     }
338     
339     public void testHeloResolv() throws Exception {
340         m_testConfiguration.setHeloResolv();
341         m_testConfiguration.setAuthorizedAddresses("192.168.0.1");
342         finishSetUp(m_testConfiguration);
343 
344 
345         SMTPClient smtpProtocol1 = new SMTPClient();
346         smtpProtocol1.connect("127.0.0.1", m_smtpListenerPort);
347 
348         assertTrue("first connection taken", smtpProtocol1.isConnected());
349 
350         
351         assertNull("no mail received by mail server", m_mailServer.getLastMail());
352 
353         String helo1 = "abgsfe3rsf.de";
354         String helo2 = "james.apache.org";
355         
356         smtpProtocol1.sendCommand("helo",helo1);
357         
358         assertEquals("expected error: helo could not resolved", 501, smtpProtocol1.getReplyCode());
359             
360         smtpProtocol1.sendCommand("helo", helo2);
361         
362         assertEquals("Helo accepted", 250, smtpProtocol1.getReplyCode());
363 
364         smtpProtocol1.quit();
365     }
366     
367     public void testHeloResolvDefault() throws Exception {
368         finishSetUp(m_testConfiguration);
369 
370         SMTPClient smtpProtocol1 = new SMTPClient();
371         smtpProtocol1.connect("127.0.0.1", m_smtpListenerPort);
372         
373         smtpProtocol1.helo("abgsfe3rsf.de");
374         
375         assertEquals("Helo accepted", 250, smtpProtocol1.getReplyCode());
376 
377         smtpProtocol1.quit();
378     }
379     
380     public void testSenderDomainResolv() throws Exception {
381         m_testConfiguration.setSenderDomainResolv();
382         m_testConfiguration.setAuthorizedAddresses("192.168.0.1/32");
383         finishSetUp(m_testConfiguration);
384 
385         SMTPClient smtpProtocol1 = new SMTPClient();
386         smtpProtocol1.connect("127.0.0.1", m_smtpListenerPort);
387 
388         
389         assertTrue("first connection taken", smtpProtocol1.isConnected());
390 
391         
392         assertNull("no mail received by mail server", m_mailServer.getLastMail());
393 
394         smtpProtocol1.helo(InetAddress.getLocalHost().toString());
395 
396         String sender1 = "mail_sender1@xfwrqqfgfe.de";
397         String sender2 = "mail_sender2@james.apache.org";
398         
399         smtpProtocol1.setSender(sender1);
400         assertEquals("expected 501 error", 501, smtpProtocol1.getReplyCode());
401     
402         smtpProtocol1.setSender(sender2);
403 
404         smtpProtocol1.quit();
405         
406     }
407  
408     public void testSenderDomainResolvDefault() throws Exception {
409         finishSetUp(m_testConfiguration);
410 
411         SMTPClient smtpProtocol1 = new SMTPClient();
412         smtpProtocol1.connect("127.0.0.1", m_smtpListenerPort);
413         
414         smtpProtocol1.helo(InetAddress.getLocalHost().toString());
415         
416         String sender1 = "mail_sender1@xfwrqqfgfe.de";
417         
418         smtpProtocol1.setSender(sender1);
419 
420         smtpProtocol1.quit();
421     }
422     
423     public void testSenderDomainResolvRelayClientDefault() throws Exception {
424         m_testConfiguration.setSenderDomainResolv();
425         finishSetUp(m_testConfiguration);
426 
427         SMTPClient smtpProtocol1 = new SMTPClient();
428         smtpProtocol1.connect("127.0.0.1", m_smtpListenerPort);
429 
430         
431         assertTrue("first connection taken", smtpProtocol1.isConnected());
432 
433         
434         assertNull("no mail received by mail server", m_mailServer.getLastMail());
435 
436         smtpProtocol1.helo(InetAddress.getLocalHost().toString());
437 
438         String sender1 = "mail_sender1@xfwrqqfgfe.de";
439         
440         
441         smtpProtocol1.setSender(sender1);
442 
443         smtpProtocol1.quit();
444         
445     }
446     
447     public void testSenderDomainResolvRelayClient() throws Exception {
448         m_testConfiguration.setSenderDomainResolv();
449         m_testConfiguration.setCheckAuthClients(true);
450         finishSetUp(m_testConfiguration);
451 
452         SMTPClient smtpProtocol1 = new SMTPClient();
453         smtpProtocol1.connect("127.0.0.1", m_smtpListenerPort);
454 
455         
456         assertTrue("first connection taken", smtpProtocol1.isConnected());
457 
458         
459         assertNull("no mail received by mail server", m_mailServer.getLastMail());
460 
461         smtpProtocol1.helo(InetAddress.getLocalHost().toString());
462 
463         String sender1 = "mail_sender1@xfwrqqfgfe.de";
464         String sender2 = "mail_sender2@james.apache.org";
465         
466         smtpProtocol1.setSender(sender1);
467         assertEquals("expected 501 error", 501, smtpProtocol1.getReplyCode());
468     
469         smtpProtocol1.setSender(sender2);
470 
471         smtpProtocol1.quit();
472         
473     }
474     
475     public void testMaxRcpt() throws Exception {
476         m_testConfiguration.setMaxRcpt(1);
477         finishSetUp(m_testConfiguration);
478 
479 
480         SMTPClient smtpProtocol1 = new SMTPClient();
481         smtpProtocol1.connect("127.0.0.1", m_smtpListenerPort);
482 
483         assertTrue("first connection taken", smtpProtocol1.isConnected());
484 
485         
486         assertNull("no mail received by mail server", m_mailServer.getLastMail());
487 
488         smtpProtocol1.helo(InetAddress.getLocalHost().toString());
489 
490         String sender1 = "mail_sender1@james.apache.org";
491         String rcpt1 = "test@localhost";
492         String rcpt2 = "test2@localhost";
493     
494         smtpProtocol1.setSender(sender1);
495         smtpProtocol1.addRecipient(rcpt1);
496 
497         smtpProtocol1.addRecipient(rcpt2);
498         assertEquals("expected 452 error", 452, smtpProtocol1.getReplyCode());
499         
500         smtpProtocol1.sendShortMessageData("Subject: test\r\n\r\nTest body\r\n");
501         
502         
503         
504         smtpProtocol1.setSender(sender1);
505  
506         smtpProtocol1.addRecipient(rcpt1);
507         
508         smtpProtocol1.sendShortMessageData("Subject: test\r\n\r\nTest body\r\n");
509         
510         smtpProtocol1.quit();
511         
512     }
513 
514     public void testMaxRcptDefault() throws Exception {
515         finishSetUp(m_testConfiguration);
516 
517         SMTPClient smtpProtocol1 = new SMTPClient();
518         smtpProtocol1.connect("127.0.0.1", m_smtpListenerPort);
519         
520         smtpProtocol1.helo(InetAddress.getLocalHost().toString());
521         
522         String sender1 = "mail_sender1@james.apache.org";
523         String rcpt1 = "test@localhost";
524         
525         smtpProtocol1.setSender(sender1);
526         
527         smtpProtocol1.addRecipient(rcpt1);
528         
529         smtpProtocol1.sendShortMessageData("Subject: test\r\n\r\nTest body\r\n");
530         
531         smtpProtocol1.quit();
532     }
533   
534     public void testEhloResolv() throws Exception {
535         m_testConfiguration.setEhloResolv();
536         m_testConfiguration.setAuthorizedAddresses("192.168.0.1");
537         finishSetUp(m_testConfiguration);
538 
539 
540         SMTPClient smtpProtocol1 = new SMTPClient();
541         smtpProtocol1.connect("127.0.0.1", m_smtpListenerPort);
542 
543         assertTrue("first connection taken", smtpProtocol1.isConnected());
544 
545         
546         assertNull("no mail received by mail server", m_mailServer.getLastMail());
547 
548         String ehlo1 = "abgsfe3rsf.de";
549         String ehlo2 = "james.apache.org";
550         
551         smtpProtocol1.sendCommand("ehlo", ehlo1);
552         
553         assertEquals("expected error: ehlo could not resolved", 501, smtpProtocol1.getReplyCode());
554             
555         smtpProtocol1.sendCommand("ehlo", ehlo2);
556         
557         assertEquals("ehlo accepted", 250, smtpProtocol1.getReplyCode());
558 
559         smtpProtocol1.quit();
560     }
561     
562     public void testEhloResolvDefault() throws Exception {
563         finishSetUp(m_testConfiguration);
564 
565         SMTPClient smtpProtocol1 = new SMTPClient();
566         smtpProtocol1.connect("127.0.0.1", m_smtpListenerPort);
567         
568         smtpProtocol1.sendCommand("ehlo","abgsfe3rsf.de");
569         
570         assertEquals("ehlo accepted", 250, smtpProtocol1.getReplyCode());
571 
572         smtpProtocol1.quit();
573     }
574     
575     public void testEhloResolvIgnoreClientDisabled() throws Exception {
576         m_testConfiguration.setEhloResolv();
577         m_testConfiguration.setCheckAuthNetworks(true);
578         finishSetUp(m_testConfiguration);
579 
580 
581         SMTPClient smtpProtocol1 = new SMTPClient();
582         smtpProtocol1.connect("127.0.0.1", m_smtpListenerPort);
583 
584         assertTrue("first connection taken", smtpProtocol1.isConnected());
585 
586         
587         assertNull("no mail received by mail server", m_mailServer.getLastMail());
588 
589         String ehlo1 = "abgsfe3rsf.de";
590         String ehlo2 = "james.apache.org";
591         
592         smtpProtocol1.sendCommand("ehlo", ehlo1);
593         
594         assertEquals("expected error: ehlo could not resolved", 501, smtpProtocol1.getReplyCode());
595             
596         smtpProtocol1.sendCommand("ehlo", ehlo2);
597         
598         assertEquals("ehlo accepted", 250, smtpProtocol1.getReplyCode());
599 
600         smtpProtocol1.quit();
601     }
602     
603     public void testHeloEnforcement() throws Exception {
604         finishSetUp(m_testConfiguration);
605 
606         SMTPClient smtpProtocol1 = new SMTPClient();
607         smtpProtocol1.connect("127.0.0.1", m_smtpListenerPort);
608 
609         assertTrue("first connection taken", smtpProtocol1.isConnected());
610 
611         
612         assertNull("no mail received by mail server", m_mailServer.getLastMail());
613 
614         String sender1 = "mail_sender1@localhost";
615         smtpProtocol1.setSender(sender1);
616         assertEquals("expected 503 error", 503, smtpProtocol1.getReplyCode());
617         
618         smtpProtocol1.helo(InetAddress.getLocalHost().toString());
619         
620         smtpProtocol1.setSender(sender1);
621         
622         smtpProtocol1.quit();
623     }
624     
625     public void testHeloEnforcementDisabled() throws Exception {
626         m_testConfiguration.setHeloEhloEnforcement(false);
627         finishSetUp(m_testConfiguration);
628 
629         SMTPClient smtpProtocol1 = new SMTPClient();
630         smtpProtocol1.connect("127.0.0.1", m_smtpListenerPort);
631 
632         assertTrue("first connection taken", smtpProtocol1.isConnected());
633 
634         
635         assertNull("no mail received by mail server", m_mailServer.getLastMail());
636 
637         String sender1 = "mail_sender1@localhost";
638         
639         smtpProtocol1.setSender(sender1);
640         
641         smtpProtocol1.quit();
642     }
643 
644     public void testAuth() throws Exception {
645         m_testConfiguration.setAuthorizedAddresses("128.0.0.1/8");
646         m_testConfiguration.setAuthorizingAnnounce();
647         finishSetUp(m_testConfiguration);
648 
649         SMTPClient smtpProtocol = new SMTPClient();
650         smtpProtocol.connect("127.0.0.1", m_smtpListenerPort);
651 
652         smtpProtocol.sendCommand("ehlo", InetAddress.getLocalHost().toString());
653         String[] capabilityRes = smtpProtocol.getReplyStrings();
654         
655         List capabilitieslist = new ArrayList();
656         for (int i = 1; i < capabilityRes.length; i++) {
657             capabilitieslist.add(capabilityRes[i].substring(4));
658         }
659             
660         assertTrue("anouncing auth required", capabilitieslist.contains("AUTH LOGIN PLAIN"));
661         
662 
663         String userName = "test_user_smtp";
664         String noexistUserName = "noexist_test_user_smtp";
665         String sender ="test_user_smtp@localhost";
666         smtpProtocol.sendCommand("AUTH FOO", null);
667         assertEquals("expected error: unrecognized authentication type", 504, smtpProtocol.getReplyCode());
668 
669         smtpProtocol.setSender(sender);
670 
671         smtpProtocol.addRecipient("mail@sample.com");
672         assertEquals("expected 530 error", 530, smtpProtocol.getReplyCode());
673 
674         assertFalse("user not existing", m_usersRepository.contains(noexistUserName));
675 
676         smtpProtocol.sendCommand("AUTH PLAIN");
677         smtpProtocol.sendCommand(Base64.encodeAsString("\0"+noexistUserName+"\0pwd\0"));
678 
679         assertEquals("expected error", 535, smtpProtocol.getReplyCode());
680 
681         m_usersRepository.addUser(userName, "pwd");
682 
683         smtpProtocol.sendCommand("AUTH PLAIN");
684         smtpProtocol.sendCommand(Base64.encodeAsString("\0"+userName+"\0wrongpwd\0"));
685         assertEquals("expected error", 535, smtpProtocol.getReplyCode());
686 
687         smtpProtocol.sendCommand("AUTH PLAIN");
688         smtpProtocol.sendCommand(Base64.encodeAsString("\0"+userName+"\0pwd\0"));
689         assertEquals("authenticated", 235, smtpProtocol.getReplyCode());
690 
691         smtpProtocol.sendCommand("AUTH PLAIN");
692         assertEquals("expected error: User has previously authenticated.", 503, smtpProtocol.getReplyCode());
693 
694         smtpProtocol.addRecipient("mail@sample.com");
695         smtpProtocol.sendShortMessageData("Subject: test\r\n\r\nTest body\r\n");
696 
697         smtpProtocol.quit();
698 
699         
700         assertNotNull("mail received by mail server", m_mailServer.getLastMail());
701     }
702 
703     public void testAuthWithEmptySender() throws Exception {
704         m_testConfiguration.setAuthorizedAddresses("128.0.0.1/8");
705         m_testConfiguration.setAuthorizingAnnounce();
706         finishSetUp(m_testConfiguration);
707 
708         SMTPClient smtpProtocol = new SMTPClient();
709         smtpProtocol.connect("127.0.0.1", m_smtpListenerPort);
710 
711         smtpProtocol.sendCommand("ehlo "+InetAddress.getLocalHost());
712 
713         String userName = "test_user_smtp";
714         m_usersRepository.addUser(userName, "pwd");
715 
716         smtpProtocol.setSender("");
717 
718         smtpProtocol.sendCommand("AUTH PLAIN");
719         smtpProtocol.sendCommand(Base64.encodeAsString("\0"+userName+"\0pwd\0"));
720         assertEquals("authenticated", 235, smtpProtocol.getReplyCode());
721 
722         smtpProtocol.addRecipient("mail@sample.com");
723         assertEquals("expected error", 503, smtpProtocol.getReplyCode());
724         
725         smtpProtocol.quit();
726     }
727 
728     public void testNoRecepientSpecified() throws Exception {
729         finishSetUp(m_testConfiguration);
730 
731         SMTPClient smtpProtocol = new SMTPClient();
732         smtpProtocol.connect("127.0.0.1", m_smtpListenerPort);
733 
734         smtpProtocol.sendCommand("ehlo "+InetAddress.getLocalHost());
735 
736         smtpProtocol.setSender("mail@sample.com");
737 
738         
739 
740         smtpProtocol.sendShortMessageData("Subject: test\r\n\r\nTest body\r\n");
741         assertTrue("sending succeeded without recepient", SMTPReply.isNegativePermanent(smtpProtocol.getReplyCode()));
742 
743         smtpProtocol.quit();
744 
745         
746         assertNull("no mail received by mail server", m_mailServer.getLastMail());
747     }
748 
749     public void testMultipleMailsAndRset() throws Exception {
750         finishSetUp(m_testConfiguration);
751 
752         SMTPClient smtpProtocol = new SMTPClient();
753         smtpProtocol.connect("127.0.0.1", m_smtpListenerPort);
754 
755         smtpProtocol.sendCommand("ehlo "+InetAddress.getLocalHost());
756 
757         smtpProtocol.setSender("mail@sample.com");
758         
759         smtpProtocol.reset();
760         
761         smtpProtocol.setSender("mail@sample.com");
762 
763         smtpProtocol.quit();
764 
765         
766         assertNull("no mail received by mail server", m_mailServer.getLastMail());
767     }
768 
769     public void testRelayingDenied() throws Exception {
770         m_testConfiguration.setAuthorizedAddresses("128.0.0.1/8");
771         finishSetUp(m_testConfiguration);
772 
773         SMTPClient smtpProtocol = new SMTPClient();
774         smtpProtocol.connect("127.0.0.1", m_smtpListenerPort);
775 
776         smtpProtocol.sendCommand("ehlo "+InetAddress.getLocalHost());
777 
778         smtpProtocol.setSender("mail@sample.com");
779 
780         smtpProtocol.addRecipient("maila@sample.com");
781         assertEquals("expected 550 error", 550, smtpProtocol.getReplyCode());
782     }
783 
784     public void testHandleAnnouncedMessageSizeLimitExceeded() throws Exception {
785         m_testConfiguration.setMaxMessageSize(1); 
786         finishSetUp(m_testConfiguration);
787 
788         SMTPClient smtpProtocol = new SMTPClient();
789         smtpProtocol.connect("127.0.0.1", m_smtpListenerPort);
790 
791         smtpProtocol.sendCommand("ehlo "+InetAddress.getLocalHost());
792 
793         smtpProtocol.sendCommand("MAIL FROM:<mail@localhost> SIZE=1025", null);
794         assertEquals("expected error: max msg size exceeded", 552, smtpProtocol.getReplyCode());
795 
796         smtpProtocol.addRecipient("mail@localhost");
797         assertEquals("expected error", 503, smtpProtocol.getReplyCode());
798     }
799 
800     public void testHandleMessageSizeLimitExceeded() throws Exception {
801         m_testConfiguration.setMaxMessageSize(1); 
802         finishSetUp(m_testConfiguration);
803 
804         SMTPClient smtpProtocol = new SMTPClient();
805         smtpProtocol.connect("127.0.0.1", m_smtpListenerPort);
806 
807         smtpProtocol.sendCommand("ehlo "+InetAddress.getLocalHost());
808 
809         smtpProtocol.setSender("mail@localhost");
810         smtpProtocol.addRecipient("mail@localhost");
811 
812         Writer wr = smtpProtocol.sendMessageData();
813         
814         wr.write("1234567810123456782012345678301234567840123456785012345678601234567870123456788012345678901234567100");
815         wr.write("1234567810123456782012345678301234567840123456785012345678601234567870123456788012345678901234567100");
816         wr.write("1234567810123456782012345678301234567840123456785012345678601234567870123456788012345678901234567100");
817         wr.write("1234567810123456782012345678301234567840123456785012345678601234567870123456788012345678901234567100");
818         wr.write("1234567810123456782012345678301234567840123456785012345678601234567870123456788012345678901234567100\r\n");
819         
820         wr.write("1234567810123456782012345678301234567840123456785012345678601234567870123456788012345678901234567100");
821         wr.write("1234567810123456782012345678301234567840123456785012345678601234567870123456788012345678901234567100");
822         wr.write("1234567810123456782012345678301234567840123456785012345678601234567870123456788012345678901234567100");
823         wr.write("1234567810123456782012345678301234567840123456785012345678601234567870123456788012345678901234567100");
824         wr.write("1234567810123456782012345678301234567840123456785012345678601234567870123456788012345678901234567100");
825         wr.write("123456781012345678201\r\n"); 
826         wr.close();
827         
828         assertFalse(smtpProtocol.completePendingCommand());
829 
830         assertEquals("expected 552 error", 552, smtpProtocol.getReplyCode());
831 
832     }
833 
834     public void testHandleMessageSizeLimitRespected() throws Exception {
835         m_testConfiguration.setMaxMessageSize(1); 
836         finishSetUp(m_testConfiguration);
837 
838         SMTPClient smtpProtocol = new SMTPClient();
839         smtpProtocol.connect("127.0.0.1", m_smtpListenerPort);
840 
841         smtpProtocol.sendCommand("ehlo "+InetAddress.getLocalHost());
842 
843         smtpProtocol.setSender("mail@localhost");
844         smtpProtocol.addRecipient("mail@localhost");
845 
846         Writer wr = smtpProtocol.sendMessageData();
847         
848         wr.write("1234567810123456782012345678301234567840123456785012345678601234567870123456788012345678901234567100");
849         wr.write("1234567810123456782012345678301234567840123456785012345678601234567870123456788012345678901234567100");
850         wr.write("1234567810123456782012345678301234567840123456785012345678601234567870123456788012345678901234567100");
851         wr.write("1234567810123456782012345678301234567840123456785012345678601234567870123456788012345678901234567100");
852         wr.write("1234567810123456782012345678301234567840123456785012345678601234567870123456788012345678901234567100");
853         wr.write("1234567810123456782012345678301234567840123456785012345678601234567870123456788012345678901234567100");
854         wr.write("1234567810123456782012345678301234567840123456785012345678601234567870123456788012345678901234567100");
855         wr.write("1234567810123456782012345678301234567840123456785012345678601234567870123456788012345678901234567100");
856         wr.write("1234567810123456782012345678301234567840123456785012345678601234567870123456788012345678901234567100");
857         wr.write("1234567810123456782012345678301234567840123456785012345678601234567870123456788012345678901234567100");
858         wr.write("1234567810123456782012\r\n"); 
859         wr.close();
860         
861         assertTrue(smtpProtocol.completePendingCommand());
862 
863         assertEquals("expected 250 ok", 250, smtpProtocol.getReplyCode());
864 
865     }
866 
867     
868 
869 
870 
871 
872 
873 
874 
875 
876 
877 
878 
879 
880 
881 
882 
883 
884     public void testConnectionLimitExceeded() throws Exception {
885         final int acceptLimit = 1;
886         final int backlog = 1;
887 
888         m_testConfiguration.setConnectionLimit(acceptLimit);   
889         m_testConfiguration.setConnectionBacklog(backlog);     
890         finishSetUp(m_testConfiguration);
891 
892         final SMTPClient[] client = new SMTPClient[acceptLimit];
893         for (int i = 0; i < client.length; i++) {
894              client[i] = new SMTPClient(); 
895              try {
896                 client[i].connect("127.0.0.1", m_smtpListenerPort);
897             } catch (Exception _) {
898             }
899             assertTrue("client #" + (i+1) + " established", client[i].isConnected());
900         }
901 
902         
903         
904         
905         
906         
907         
908         
909         
910         
911         
912         
913         final Socket connection[] = new Socket[Math.max(((backlog * 3) / 2) + 1, backlog + 3)];
914 
915         final java.net.SocketAddress server = new java.net.InetSocketAddress("localhost", m_smtpListenerPort);
916 
917         for (int i = 0; i < connection.length; i++) {
918             connection[i] = new Socket();
919             try {
920                 connection[i].connect(server, 1000);
921             } catch (Exception _) {
922                 assertTrue("Accepted connections " + i + " did not meet or exceed backlog of " + backlog + ".", i >= backlog);
923                 connection[i] = null; 
924                 break; 
925             }
926             assertTrue("connection #" + (i+1) + " established", connection[i].isConnected());
927         }
928         
929         try {
930             final Socket shouldFail = new Socket();
931             shouldFail.connect(server, 1000);
932             fail("connection # " + (client.length + connection.length + 1) + " did not fail.");            
933         } catch (Exception _) {      
934         }
935         
936         client[0].quit();
937         client[0].disconnect();  
938         
939         Thread.sleep(100);
940 
941         
942         try {
943             final Socket shouldWork = new Socket();
944             shouldWork.connect(server, 1000);
945             assertTrue("Additional connection established after close.", shouldWork.isConnected());
946             shouldWork.close();
947         } catch (Exception e) {
948             fail("Could not establish additional connection after close." + e.getMessage());
949         }
950         
951         
952         for (int i = 0; i < connection.length; i++) if (connection[i] != null) connection[i].close();
953         
954         
955         for (int i = 1; i < client.length; i++) {
956             client[i].quit();
957             client[i].disconnect();
958         }
959     }
960 
961     
962     
963     
964     InMemorySpoolRepository outgoingSpool;
965     private MockServiceManager m_serviceManager;
966     
967     private Properties getStandardParameters() {
968         Properties parameters = new Properties();
969         parameters.put("delayTime", "500 msec, 500 msec, 500 msec"); 
970         parameters.put("maxRetries", "3");
971         parameters.put("deliveryThreads", "1");
972         parameters.put("debug", "true");
973         parameters.put("sendpartial", "false");
974         parameters.put("bounceProcessor", "bounce");
975         parameters.put("outgoing", "mocked://outgoing/");
976         return parameters;
977     }
978     
979 
980     /***
981      * This has been created to test javamail 1.4 introduced bug.
982      * http://issues.apache.org/jira/browse/JAMES-490
983      */
984     public void testDeliveryToSelfWithGatewayAndBind() throws Exception {
985         finishSetUp(m_testConfiguration);
986         outgoingSpool = new InMemorySpoolRepository();
987         ((MockStore) m_serviceManager.lookup(Store.ROLE)).add("outgoing", outgoingSpool);
988         
989         RemoteDelivery rd = new RemoteDelivery();
990         
991         MockMailContext mmc = new MockMailContext();
992         mmc.setAttribute(Constants.AVALON_COMPONENT_MANAGER,m_serviceManager);
993         mmc.setAttribute(Constants.HELLO_NAME,"localhost");
994         MockMailetConfig mci = new MockMailetConfig("Test",mmc,getStandardParameters());
995         mci.setProperty("bind", "127.0.0.1");
996         mci.setProperty("gateway","127.0.0.1");
997         mci.setProperty("gatewayPort",""+m_smtpListenerPort);
998         rd.init(mci);
999         String sources = "Content-Type: text/plain;\r\nSubject: test\r\n\r\nBody";
1000         String sender = "test@localhost";
1001         String recipient = "test@localhost";
1002         MimeMessage mm = new MimeMessage(Session.getDefaultInstance(new Properties()),new ByteArrayInputStream(sources.getBytes()));
1003         MailImpl mail = new MailImpl("name",new MailAddress(sender),Arrays.asList(new MailAddress[] {new MailAddress(recipient)}),mm);
1004         
1005         rd.service(mail);
1006         
1007         while (outgoingSpool.size() > 0) {
1008             Thread.sleep(1000);
1009         }
1010 
1011         verifyLastMail(sender, recipient, null);
1012         
1013         assertEquals(((String) mm.getContent()).trim(),((String) ((MimeMessage) m_mailServer.getLastMail()[2]).getContent()).trim());
1014         
1015         mail.dispose();
1016     }
1017 
1018     
1019     /***
1020      * This is useful code to run tests on javamail bugs 
1021      * http://issues.apache.org/jira/browse/JAMES-52
1022      * 
1023      * This 
1024      * @throws Exception
1025      */
1026     public void test8bitmimeFromStream() throws Exception {
1027         finishSetUp(m_testConfiguration);
1028         outgoingSpool = new InMemorySpoolRepository();
1029         ((MockStore) m_serviceManager.lookup(Store.ROLE)).add("outgoing", outgoingSpool);
1030         
1031         RemoteDelivery rd = new RemoteDelivery();
1032         
1033         MockMailContext mmc = new MockMailContext();
1034         mmc.setAttribute(Constants.AVALON_COMPONENT_MANAGER,m_serviceManager);
1035         mmc.setAttribute(Constants.HELLO_NAME,"localhost");
1036         MockMailetConfig mci = new MockMailetConfig("Test",mmc,getStandardParameters());
1037         mci.setProperty("gateway","127.0.0.1");
1038         mci.setProperty("gatewayPort",""+m_smtpListenerPort);
1039         rd.init(mci);
1040         
1041         String sources = "Content-Type: text/plain;\r\nContent-Transfer-Encoding: quoted-printable\r\nSubject: test\r\n\r\nBody=80\r\n";
1042         
1043         
1044         String sender = "test@localhost";
1045         String recipient = "test@localhost";
1046         MimeMessage mm = new MimeMessage(Session.getDefaultInstance(new Properties()),new ByteArrayInputStream(sources.getBytes()));
1047         MailImpl mail = new MailImpl("name",new MailAddress(sender),Arrays.asList(new MailAddress[] {new MailAddress(recipient)}),mm);
1048         
1049         rd.service(mail);
1050         
1051         while (outgoingSpool.size() > 0) {
1052             Thread.sleep(1000);
1053         }
1054 
1055         
1056         verifyLastMail(sender, recipient, null);
1057         
1058         
1059         
1060         
1061         mail.dispose();
1062     }
1063     
1064     
1065 }