Skip to content

Commit 2f20f90

Browse files
committed
Script to replace expired CAs in LDAP
1 parent ae6e2ed commit 2f20f90

File tree

2 files changed

+77
-2
lines changed

2 files changed

+77
-2
lines changed

replace_ca.py

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#!/usr/bin/env python
2+
3+
from __future__ import print_function
4+
5+
from datetime import datetime, timedelta
6+
import ldap
7+
from OpenSSL import crypto
8+
from scripts import cert, log, auth
9+
from scriptspony import vhosts
10+
import os
11+
import sys
12+
import logging
13+
14+
15+
def pkey_to_pem(pk):
16+
return crypto.dump_publickey(crypto.FILETYPE_PEM, pk)
17+
18+
19+
@log.exceptions
20+
def main():
21+
pem = sys.stdin.read()
22+
replacement_certs = cert.pem_to_certs(pem)
23+
replacements = {pkey_to_pem(c.get_pubkey()): c for c in replacement_certs}
24+
25+
logging.info("Replacement certificates: %s", replacements)
26+
27+
vhosts.connect()
28+
res = vhosts.conn.search_s(
29+
"ou=VirtualHosts,dc=scripts,dc=mit,dc=edu",
30+
ldap.SCOPE_ONELEVEL,
31+
"(&(objectClass=scriptsVhost)(scriptsVhostCertificate=*))",
32+
["scriptsVhostName", "scriptsVhostCertificate"],
33+
)
34+
35+
for dn, attrs in res:
36+
replace = 0
37+
vhost, = attrs["scriptsVhostName"]
38+
logging.info("Examining %s", vhost)
39+
scripts, = attrs["scriptsVhostCertificate"]
40+
chain = cert.scripts_to_chain(scripts)
41+
for i, c in enumerate(chain):
42+
new = replacements.get(pkey_to_pem(c.get_pubkey()))
43+
if new:
44+
chain[i] = new
45+
replace += 1
46+
if replace:
47+
logging.info(
48+
"Replacing %d certificates for %s"
49+
% (replace, vhost)
50+
)
51+
try:
52+
vhosts.conn.modify_s(
53+
dn,
54+
[
55+
(
56+
ldap.MOD_REPLACE,
57+
"scriptsVhostCertificate",
58+
cert.chain_to_scripts(chain),
59+
),
60+
],
61+
)
62+
except ldap.INSUFFICIENT_ACCESS as e:
63+
logging.exception(e)
64+
65+
66+
if __name__ == "__main__":
67+
auth.set_user_from_parent_process()
68+
from paste.deploy import loadapp
69+
70+
loadapp("config:development.ini", relative_to=os.path.dirname(__file__))
71+
logging.basicConfig(level=logging.DEBUG)
72+
main()

scripts/cert.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121
)
2222

2323

24-
def pem_to_chain(data):
25-
certs = [
24+
def pem_to_certs(data):
25+
return [
2626
crypto.load_certificate(crypto.FILETYPE_PEM, m.group(0))
2727
for m in re.finditer(
2828
b"-----BEGIN CERTIFICATE-----\r?\n.+?\r?\n-----END CERTIFICATE-----",
@@ -31,6 +31,9 @@ def pem_to_chain(data):
3131
)
3232
]
3333

34+
35+
def pem_to_chain(data):
36+
certs = pem_to_certs(data)
3437
# Find the leaf certificate
3538
leaf, = [
3639
c for c in certs if not any(c1.get_issuer() == c.get_subject() for c1 in certs)

0 commit comments

Comments
 (0)