]> git.wh0rd.org - home.git/blobdiff - .bin/le-renew
test.cc: new C++ test
[home.git] / .bin / le-renew
index f5728d4baaf778ba8b841090ab19884c58524006..58e687b0b7a34ca56356ed60efcbe3fc283515ce 100755 (executable)
@@ -1,6 +1,5 @@
-#!/usr/bin/python2
-# We need to force py2 until M2Crypto is ported:
-# https://gitlab.com/m2crypto/m2crypto/issues/114
+#!/usr/bin/python
+#-*- coding:utf-8 -*-
 # pylint: disable=invalid-name
 
 """Renew Let's Encrypt certs!
@@ -18,6 +17,8 @@ try:
     import configparser
 except ImportError:
     import ConfigParser as configparser
+import cryptography.hazmat.backends
+from cryptography import x509
 try:
     from cStringIO import StringIO
 except ImportError:
@@ -25,9 +26,7 @@ except ImportError:
 import datetime
 import logging
 import logging.handlers
-import M2Crypto
 import os
-import pytz
 import subprocess
 import sys
 
@@ -74,9 +73,10 @@ def setup_logging(debug=False, syslog=None):
 
 def load_cert(path):
     """Load the cert at |path|"""
-    with open(path) as f:
+    with open(path, 'rb') as f:
         data = f.read()
-        return M2Crypto.X509.load_cert_string(data)
+        return x509.load_pem_x509_certificate(
+            data, cryptography.hazmat.backends.default_backend())
 
 
 def load_live_cert(domain):
@@ -107,14 +107,17 @@ def process_domain(domain, dry_run=False):
     logging.info('%s: checking', domain)
 
     conf = load_conf(domain)
-    webroot_path = conf.get('[webroot_map', domain)
+    try:
+        webroot_path = conf.get('[webroot_map', domain)
+    except configparser.NoOptionError:
+        webroot_path = conf.get('renewalparams', 'webroot_path')
+        # The conf writing has a bug here where it appends a comma.
+        webroot_path = webroot_path.rstrip(',')
 
     cert_path = os.path.realpath(conf.get('globals', 'cert'))
 
     cert = load_cert(cert_path)
-    stamp = cert.get_not_after()
-    now = pytz.timezone('UTC').localize(datetime.datetime.now())
-    delta = stamp.get_datetime() - now
+    delta = cert.not_valid_after - datetime.datetime.utcnow()
     logging.info('%s: expires in %2s days', domain, delta.days)
 
     cmd = [
@@ -123,23 +126,35 @@ def process_domain(domain, dry_run=False):
         '--webroot-path', webroot_path,
         '-d', domain,
     ]
-    san = cert.get_ext('subjectAltName').get_value()
-    domains = [x.strip()[4:] for x in san.split(',')]
-    domains.remove(domain)
+    domains = []
+    try:
+        san = cert.extensions.get_extension_for_oid(
+            x509.oid.ExtensionOID.SUBJECT_ALTERNATIVE_NAME)
+        domains = san.value.get_values_for_type(x509.DNSName)
+    except x509.ExtensionNotFound:
+        pass
     for d in domains:
         cmd += ['-d', d]
     if delta.days < 30:
         logging.info('%s: renewing', domain)
-        logging.info('%s: %s', domain, cmd)
+        logging.info('%s: %s', domain, ' '.join(cmd))
         if not dry_run:
-            subprocess.check_call(cmd)
+            try:
+                subprocess.check_call(cmd)
+            except subprocess.CalledProcessError:
+                logging.error('failed', exc_info=True)
+                return 0
             ret = 1
         # Try to revoke the old one.
-        cmd = ['certbot', 'revoke', '--cert-path', cert_path]
+        cmd = ['certbot', 'revoke', '--no-delete-after-revoke', '--cert-path',
+               cert_path]
         logging.info('%s: revoking old cert', domain)
-        logging.info('%s: %s', domain, cmd)
+        logging.info('%s: %s', domain, ' '.join(cmd))
         if not dry_run:
-            subprocess.check_call(cmd)
+            try:
+                subprocess.check_call(cmd, stdin=open('/dev/null', 'r'))
+            except subprocess.CalledProcessError:
+                logging.error('failed', exc_info=True)
     else:
         logging.info('%s: up-to-date!', domain)