-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
85 lines (67 loc) · 2.29 KB
/
main.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
import config
import utils
import Milter
import email
class PGPMilter(Milter.Base):
def __init__(self):
self.recipients = []
self.headers = []
self.content = bytes()
@Milter.noreply
def connect(_self, _ip_name, _family, _hostaddr):
return Milter.CONTINUE
@Milter.noreply
def envfrom(self, name, *esmtp_params):
self.__init__()
return Milter.CONTINUE
@Milter.noreply
def envrcpt(self, name, *strings):
self.recipients.append(name)
return Milter.CONTINUE
@Milter.noreply
def header(self, k: str, v: str):
self.headers.append((k.encode(), v.encode()))
return Milter.CONTINUE
def eoh(self):
return Milter.CONTINUE
def body(self, chunk):
self.content += chunk
return Milter.CONTINUE
def eom(self):
print('Encrypting message to recipients: [%s]' % ', '.join(self.recipients))
raw_headers = b'\n'.join(map(lambda header : b'%s: %s' % header, self.headers))
msg = email.message_from_bytes(raw_headers + b'\n\n' + self.content,\
policy=email.policy.default)
if b'-----BEGIN PGP MESSAGE-----' in self.content or utils.already_encrypted(msg):
print('Already encrypted, passing through.')
return Milter.ACCEPT
enc_msg, encrypted = utils.encrypt(msg, self.recipients)
if not encrypted:
print('No keys found, passing through.')
return Milter.ACCEPT
# `Content-Transfer-Encoding: quoted-printable`
# can prevent the message from being decrypted by clients
self.set_header(msg, 'Content-Transfer-Encoding', '')
for (k, v) in enc_msg.items():
self.set_header(msg, k, v)
enc_bytes = enc_msg.as_bytes()
enc_body = enc_bytes[enc_bytes.find(b'\n\n')+2:]
self.replacebody(enc_body)
return Milter.ACCEPT
def close(self):
self.__init__()
return Milter.CONTINUE
def set_header(self, old_msg, k, v):
old_headers = old_msg.get_all(k)
if old_headers != None:
for i in range(len(old_headers)-1, -1, -1):
self.chgheader(k, i, '')
if v != None and len(v) > 0:
self.addheader(k, v)
def main():
Milter.factory = PGPMilter
Milter.set_flags(Milter.ADDHDRS + Milter.CHGHDRS + Milter.CHGBODY)
Milter.runmilter('cmail-pgp-milter', config.socket)
if __name__ == '__main__':
print('Starting CMail PGP Milter')
main()