-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathhandle_cert_mail.py
executable file
·89 lines (80 loc) · 2.77 KB
/
handle_cert_mail.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
87
88
89
#!/usr/bin/env python
import email
import os.path
import sys
import ldap
import ldap.filter
from scripts import cert, log, auth
from scriptspony import vhosts
BLACKLIST = ["scripts.mit.edu", "notfound.example.com"]
@log.exceptions
def main():
if hasattr(sys.stdin, "buffer"):
msg = email.message_from_binary_file(sys.stdin.buffer)
else:
msg = email.message_from_file(sys.stdin)
pem = cert.msg_to_pem(msg)
if pem is None:
log.info("handle_cert_mail.py: No certificate")
return
chain = cert.pem_to_chain(pem)
names = cert.chain_subject_names(chain)
filter = ldap.filter.filter_format(
"(&(objectClass=scriptsVhost)(|"
+ "".join("(scriptsVhostName=%s)" for name in names)
+ "".join("(scriptsVhostAlias=%s)" for name in names)
+ ")"
+ "".join("(!(scriptsVhostName=%s))" for name in BLACKLIST)
+ ")",
list(names) + list(names) + BLACKLIST,
)
vhosts.connect()
res = vhosts.conn.search_s(
"ou=VirtualHosts,dc=scripts,dc=mit,dc=edu",
ldap.SCOPE_ONELEVEL,
filter,
["scriptsVhostName", "scriptsVhostAccount", "scriptsVhostCertificate"],
)
if res:
for dn, attrs in res:
vhost, = attrs["scriptsVhostName"]
account, = attrs["scriptsVhostAccount"]
if "scriptsVhostCertificate" in attrs:
old_scripts, = attrs["scriptsVhostCertificate"]
old_chain = cert.scripts_to_chain(old_scripts)
else:
old_chain = None
if cert.chain_should_install(chain, old_chain):
log.info(
"handle_cert_mail.py: Installing certificate for %s on %s"
% (vhost, account)
)
vhosts.conn.modify_s(
dn,
[
(
ldap.MOD_REPLACE,
"scriptsVhostCertificate",
cert.chain_to_scripts(chain),
),
(
ldap.MOD_REPLACE,
"scriptsVhostCertificateKeyFile",
"scripts-2048.key",
),
],
)
else:
log.info(
"handle_cert_mail.py: IGNORING certificate for %s on %s"
% (vhost, account)
)
else:
log.error(
"handle_cert_mail.py: Certificate for %s matches no vhost" % list(names)
)
if __name__ == "__main__":
auth.set_user_from_parent_process()
from paste.deploy import loadapp
loadapp("config:development.ini", relative_to=os.path.dirname(__file__))
main()