Browse Source

Enabled POP3S for old-timeys who dig that

added dovecot-pop3d
allowed in the firewall
monitored with monit
added relevant tests
Joost Baaij 11 years ago
parent
commit
335cef5c9f

+ 1
- 0
README.textile View File

28
 What do you get if you point this thing at a VPS? All kinds of good stuff!
28
 What do you get if you point this thing at a VPS? All kinds of good stuff!
29
 
29
 
30
 * "IMAP":https://en.wikipedia.org/wiki/Internet_Message_Access_Protocol over SSL via "Dovecot":http://dovecot.org/, complete with full text search provided by "Solr":https://lucene.apache.org/solr/.
30
 * "IMAP":https://en.wikipedia.org/wiki/Internet_Message_Access_Protocol over SSL via "Dovecot":http://dovecot.org/, complete with full text search provided by "Solr":https://lucene.apache.org/solr/.
31
+* "POP3":https://en.wikipedia.org/wiki/Post_Office_Protocol over SSL, also via Dovecot
31
 * "SMTP":https://en.wikipedia.org/wiki/Simple_Mail_Transfer_Protocol over SSL via Postfix, including a nice set of "DNSBLs":https://en.wikipedia.org/wiki/DNSBL to discard spam before it ever hits your filters.
32
 * "SMTP":https://en.wikipedia.org/wiki/Simple_Mail_Transfer_Protocol over SSL via Postfix, including a nice set of "DNSBLs":https://en.wikipedia.org/wiki/DNSBL to discard spam before it ever hits your filters.
32
 * Webmail via "Roundcube":http://www.roundcube.net/.
33
 * Webmail via "Roundcube":http://www.roundcube.net/.
33
 * Mobile push notifications via "Z-Push":http://z-push.sourceforge.net/soswp/index.php?pages_id=1&t=home.
34
 * Mobile push notifications via "Z-Push":http://z-push.sourceforge.net/soswp/index.php?pages_id=1&t=home.

+ 1
- 0
roles/common/tasks/ufw.yml View File

16
     - https/tcp
16
     - https/tcp
17
     - ssh/tcp
17
     - ssh/tcp
18
     - ssmtp/tcp
18
     - ssmtp/tcp
19
+    - pop3s/tcp
19
     - imaps/tcp
20
     - imaps/tcp
20
     - 5222/tcp  # xmpp c2s
21
     - 5222/tcp  # xmpp c2s
21
     - 5269/tcp  # xmpp s2s
22
     - 5269/tcp  # xmpp s2s

+ 1
- 1
roles/mailserver/files/etc_dovecot_dovecot.conf View File

96
 # A config file can also tried to be included without giving an error if
96
 # A config file can also tried to be included without giving an error if
97
 # it's not found:
97
 # it's not found:
98
 !include_try /usr/share/dovecot/protocols.d/*.protocol
98
 !include_try /usr/share/dovecot/protocols.d/*.protocol
99
-protocols = imap lmtp sieve
99
+protocols = imap lmtp sieve pop3

+ 1
- 0
roles/mailserver/tasks/dovecot.yml View File

3
   with_items:
3
   with_items:
4
     - dovecot-core
4
     - dovecot-core
5
     - dovecot-imapd
5
     - dovecot-imapd
6
+    - dovecot-pop3d
6
     - dovecot-lmtpd
7
     - dovecot-lmtpd
7
     - dovecot-managesieved
8
     - dovecot-managesieved
8
     - postgresql-9.1
9
     - postgresql-9.1

+ 2
- 1
roles/monitoring/files/etc_monit_conf.d_dovecot View File

3
   start program = "/etc/init.d/dovecot start"
3
   start program = "/etc/init.d/dovecot start"
4
   stop program = "/etc/init.d/dovecot stop"
4
   stop program = "/etc/init.d/dovecot stop"
5
   if failed port 993 type tcpssl sslauto protocol imap for 5 cycles then restart
5
   if failed port 993 type tcpssl sslauto protocol imap for 5 cycles then restart
6
-  if 3 restarts within 5 cycles then timeout
6
+  if failed port 995 type tcpssl sslauto protocol pop for 5 cycles then restart
7
+  if 3 restarts within 5 cycles then timeout

+ 44
- 7
tests.py View File

161
 
161
 
162
 
162
 
163
 class MailTests(unittest.TestCase):
163
 class MailTests(unittest.TestCase):
164
-    def assertEmailReceived(self, subject):
165
-        """Connects with IMAP and asserts the existance of an email, then deletes it"""
164
+    def assertIMAPReceived(self, subject):
165
+        """Connects with IMAP and asserts the existence of an email, then deletes it"""
166
         import imaplib
166
         import imaplib
167
 
167
 
168
         sleep(1)
168
         sleep(1)
172
         m.login(TEST_ADDRESS, TEST_PASSWORD)
172
         m.login(TEST_ADDRESS, TEST_PASSWORD)
173
         m.select()
173
         m.select()
174
 
174
 
175
-        # Assert the message exist
175
+        # Assert the message exists
176
         typ, data = m.search(None, '(SUBJECT \"{}\")'.format(subject))
176
         typ, data = m.search(None, '(SUBJECT \"{}\")'.format(subject))
177
         self.assertTrue(len(data[0].split()), 1)
177
         self.assertTrue(len(data[0].split()), 1)
178
 
178
 
182
         m.close()
182
         m.close()
183
         m.logout()
183
         m.logout()
184
 
184
 
185
+    def assertPOP3Received(self, subject):
186
+        """Connects with POP3S and asserts the existence of an email, then deletes it"""
187
+        import poplib
188
+
189
+        sleep(1)
190
+
191
+        # Login to POP3
192
+        mail = poplib.POP3_SSL(TEST_SERVER, 995)
193
+        mail.user(TEST_ADDRESS)
194
+        mail.pass_(TEST_PASSWORD)
195
+
196
+        # Assert the message exists
197
+        num = len(mail.list()[1])
198
+        resp, text, octets = mail.retr(num)
199
+        self.assertTrue("Subject: " + subject in text)
200
+
201
+        # Delete it and log out
202
+        mail.dele(num)
203
+        mail.quit()
204
+
185
     def test_imap_requires_ssl(self):
205
     def test_imap_requires_ssl(self):
186
         """IMAP without SSL is NOT available"""
206
         """IMAP without SSL is NOT available"""
187
         import imaplib
207
         import imaplib
189
         with self.assertRaisesRegexp(socket.timeout, 'timed out'):
209
         with self.assertRaisesRegexp(socket.timeout, 'timed out'):
190
             imaplib.IMAP4(TEST_SERVER, 143)
210
             imaplib.IMAP4(TEST_SERVER, 143)
191
 
211
 
212
+    def test_pop3_requires_ssl(self):
213
+        """POP3 without SSL is NOT available"""
214
+        import poplib
215
+
216
+        with self.assertRaisesRegexp(socket.timeout, 'timed out'):
217
+            poplib.POP3(TEST_SERVER, 110)
218
+
192
     def test_smtps(self):
219
     def test_smtps(self):
193
         """Email sent from an MUA via SMTPS is delivered"""
220
         """Email sent from an MUA via SMTPS is delivered"""
194
         import smtplib
221
         import smtplib
197
         s.login(TEST_ADDRESS, TEST_PASSWORD)
224
         s.login(TEST_ADDRESS, TEST_PASSWORD)
198
         s.sendmail(TEST_ADDRESS, ['root@sovereign.local'], msg)
225
         s.sendmail(TEST_ADDRESS, ['root@sovereign.local'], msg)
199
         s.quit()
226
         s.quit()
200
-        self.assertEmailReceived(subject)
227
+        self.assertIMAPReceived(subject)
201
 
228
 
202
     def test_smtps_delimiter_to(self):
229
     def test_smtps_delimiter_to(self):
203
         """Email sent to address with delimiter is delivered"""
230
         """Email sent to address with delimiter is delivered"""
207
         s.login(TEST_ADDRESS, TEST_PASSWORD)
234
         s.login(TEST_ADDRESS, TEST_PASSWORD)
208
         s.sendmail(TEST_ADDRESS, ['root+foo@sovereign.local'], msg)
235
         s.sendmail(TEST_ADDRESS, ['root+foo@sovereign.local'], msg)
209
         s.quit()
236
         s.quit()
210
-        self.assertEmailReceived(subject)
237
+        self.assertIMAPReceived(subject)
211
 
238
 
212
     def test_smtps_requires_auth(self):
239
     def test_smtps_requires_auth(self):
213
         """SMTPS with no authentication is rejected"""
240
         """SMTPS with no authentication is rejected"""
226
         s = smtplib.SMTP(TEST_SERVER, 25)
253
         s = smtplib.SMTP(TEST_SERVER, 25)
227
         s.sendmail('someone@example.com', [TEST_ADDRESS], msg)
254
         s.sendmail('someone@example.com', [TEST_ADDRESS], msg)
228
         s.quit()
255
         s.quit()
229
-        self.assertEmailReceived(subject)
256
+        self.assertIMAPReceived(subject)
230
 
257
 
231
     def test_smtp_tls(self):
258
     def test_smtp_tls(self):
232
         """Email sent from an MTA via SMTP+TLS is delivered"""
259
         """Email sent from an MTA via SMTP+TLS is delivered"""
236
         s.starttls()
263
         s.starttls()
237
         s.sendmail('someone@example.com', [TEST_ADDRESS], msg)
264
         s.sendmail('someone@example.com', [TEST_ADDRESS], msg)
238
         s.quit()
265
         s.quit()
239
-        self.assertEmailReceived(subject)
266
+        self.assertIMAPReceived(subject)
240
 
267
 
241
     def test_smtps_headers(self):
268
     def test_smtps_headers(self):
242
         """Email sent from an MUA has DKIM and TLS headers"""
269
         """Email sent from an MUA has DKIM and TLS headers"""
312
         m.close()
339
         m.close()
313
         m.logout()
340
         m.logout()
314
 
341
 
342
+    def test_pop3s(self):
343
+        """Connects with POP3S and asserts the existance of an email, then deletes it"""
344
+        import smtplib
345
+        msg, subject = new_message(TEST_ADDRESS, 'root@sovereign.local')
346
+        s = smtplib.SMTP_SSL(TEST_SERVER, 465)
347
+        s.login(TEST_ADDRESS, TEST_PASSWORD)
348
+        s.sendmail(TEST_ADDRESS, ['root@sovereign.local'], msg)
349
+        s.quit()
350
+        self.assertPOP3Received(subject)
351
+
315
 
352
 
316
 class XMPPTests(unittest.TestCase):
353
 class XMPPTests(unittest.TestCase):
317
     def test_xmpp_c2s(self):
354
     def test_xmpp_c2s(self):

Loading…
Cancel
Save