-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathpgpmilter.py
executable file
·86 lines (70 loc) · 2.49 KB
/
pgpmilter.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#!/usr/bin/python
"""PGPMilter is a milter using python-milter that rejects all non-GPG mail.
Thrown together in 2011 by Moritz Bartl
> This program is free software: you can redistribute it and/or modify
> it under the terms of the GNU General Public License as published by
> the Free Software Foundation, either version 3 of the License, or
> (at your option) any later version.
> This program is distributed in the hope that it will be useful,
> but WITHOUT ANY WARRANTY; without even the implied warranty of
> MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> GNU General Public License for more details.
> You should have received a copy of the GNU General Public License
> along with this program. If not, see <http://www.gnu.org/licenses/>.
See the pymilter project at http://bmsi.com/python/milter.html
based on Sendmail's milter API http://www.milter.org/milter_api/api.html
"""
import Milter
import StringIO
import time
import email
import sys
import os
from socket import AF_INET, AF_INET6
from Milter.utils import parse_addr
if True:
from multiprocessing import Process as Thread, Queue
else:
from threading import Thread
from Queue import Queue
_PGPHEADER = "-----BEGIN PGP MESSAGE-----"
maxmsglen = 5000
socket = os.getenv("HOME") + "/milter/pgpmilter.sock"
class pgpMilter(Milter.Base):
def __init__(self): # A new instance with each new connection.
self.id = Milter.uniqueID() # Integer incremented with each call.
self.mailbody = None
@Milter.noreply
def connect(self, IPname, family, hostaddr):
self.mailbody = StringIO.StringIO()
return Milter.CONTINUE
def body(self, chunk):
self.mailbody.write(chunk)
currentBody = self.mailbody.getvalue()
if currentBody.find(_PGPHEADER)>-1:
return Milter.ACCEPT
if len(currentBody) > maxmsglen:
self.setreply('550','5.7.1','We only accept PGP encrypted mail. PGP header not found within %s first characters of body' % maxmsglen)
return Milter.REJECT
return Milter.CONTINUE
# end of mail
def eom(self):
self.setreply('550','5.7.1','We only accept PGP encrypted mail')
return Milter.REJECT
## ===
def main():
bt = Thread()
bt.start()
timeout = 60
# Register with Milter factory
Milter.factory = pgpMilter
# we don't modify mails, so no flags
Milter.set_flags(0)
Milter.runmilter("pgpmilter",socket,timeout)
bt.join()
if __name__ == "__main__":
if len(sys.argv) >= 2:
socket = sys.argv[1]
if len(sys.argv) >= 3:
maxmsglen = sys.argv[2]
main()