Initial checkin.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Fri, 20 Nov 2015 23:09:50 +0000 (00:09 +0100)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Fri, 20 Nov 2015 23:09:50 +0000 (00:09 +0100)
README [new file with mode: 0644]
hitch.py [new file with mode: 0644]
setup.py [new file with mode: 0644]

diff --git a/README b/README
new file mode 100644 (file)
index 0000000..35d9a67
--- /dev/null
+++ b/README
@@ -0,0 +1,27 @@
+This is a Let's Encrypt installer module for hitch. It is currently
+(very) alpha quality. See also my Varnish plugin for authentication, at
+
+  https://git.sesse.net/?p=letsencrypt-varnish-plugin;a=summary
+
+To use, assuming you've installed the Varnish authentication plugin:
+
+ 1. Install letsencrypt as usual, with letsencrypt-auto.
+
+ 2. Activate the venv:
+
+    . ~/.local/share/letsencrypt/bin/activate
+
+ 3. Install the module:
+
+    pip install -e path/to/this/letsencrypt-hitch
+
+ 4. Ask for and install a certificate:
+
+    sudo ~/.local/share/letsencrypt/bin/letsencrypt --agree-dev-preview --server https://acme-v01.api.letsencrypt.org/directory -a letsencrypt-varnish-plugin:varnish -i letsencrypt-hitch-plugin:hitch -d <domain>
+
+
+The Hitch installer plugin is licensed under the same terms as the Let's
+Encrypt client itself.
+
+  - Steinar H. Gunderson <steinar+letsencrypt@gunderson.no>
+
diff --git a/hitch.py b/hitch.py
new file mode 100644 (file)
index 0000000..89d682e
--- /dev/null
+++ b/hitch.py
@@ -0,0 +1,112 @@
+"""Hitch plugin."""
+import logging
+import os
+import re
+import subprocess
+
+import zope.component
+import zope.interface
+
+from letsencrypt import errors
+from letsencrypt import interfaces
+from letsencrypt.plugins import common
+
+
+logger = logging.getLogger(__name__)
+
+
+class Installer(common.Plugin):
+    """Hitch installer."""
+    zope.interface.implements(interfaces.IInstaller)
+    zope.interface.classProvides(interfaces.IPluginFactory)
+
+    description = "Hitch Installer"
+    hidden = True
+
+    def prepare(self):
+        with open("/etc/hitch/hitch.conf") as config_file:
+            self.config = config_file.readlines()
+
+    def more_info(self):
+        return "Installer for Hitch TLS wrapper."
+
+    def get_all_names(self):
+        raise errors.PluginError("not implemented")
+
+    def deploy_cert(self, domain, cert_path, key_path,
+                    chain_path=None, fullchain_path=None):
+        # Concatenate private key and certificate together into one file.
+        with open(key_path) as key_file:
+            pem = key_file.read()
+
+        # Add the full chain if we have it; else just the certificate.
+        if fullchain_path is not None:
+            with open(fullchain_path) as cert_file:
+                pem += cert_file.read()
+        else:
+            with open(cert_path) as cert_file:
+                pem += cert_file.read()
+
+        # Add DH params if we have them (needed for PFS).
+        try:
+            with open("/etc/hitch/dh-param.pem") as dh_param_file:
+                pem += dh_param_file.read()
+        except:
+            pass
+
+        # Actually write the full file.
+        filename = os.path.join(os.path.dirname(cert_path), "all.pem")
+        fd = os.open(filename, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0600)
+        with os.fdopen(fd, 'w') as pem_file:
+            pem_file.write(pem)
+
+        # Now go check the config file to see if this file is already there.
+        found = False
+        last_pem_line = None
+        for line_num in xrange(len(self.config)):
+            m = re.match("^\s*pem-file\s*=\s*\"([^\"]+)\"", self.config[line_num])
+            if m:
+                last_pem_line = line_num
+                if m.groups()[0] == filename:
+                    found = True
+
+        # If it's not already there, add it after the last line.
+        if not found:
+            if last_pem_line is None:
+                last_pem_line = len(self.config) - 1
+            config_line = "pem-file = \"%s\"  # Added by Let's Encrypt installer.\n" % filename
+            self.config.insert(last_pem_line + 1, config_line)
+
+        pass  # pragma: no cover
+
+    def enhance(self, domain, enhancement, options=None):
+        raise errors.PluginError("not implemented")
+
+    def supported_enhancements(self):
+        return []
+
+    def get_all_certs_keys(self):
+        raise errors.PluginError("not implemented")
+        return []
+
+    def save(self, title=None, temporary=False):
+        if temporary:
+            raise errors.PluginError("temporary is not implemented")
+
+       with open("/etc/hitch/hitch.conf", "w") as config_file:
+            config_file.writelines(self.config)
+
+    def rollback_checkpoints(self, rollback=1):
+        raise errors.PluginError("not implemented")
+
+    def recovery_routine(self):
+        raise errors.PluginError("not implemented")
+
+    def view_config_changes(self):
+        raise errors.PluginError("not implemented")
+
+    def config_test(self):
+        raise errors.PluginError("not implemented")
+
+    def restart(self):
+        subprocess.call(["systemctl", "reload", "hitch.service"])
diff --git a/setup.py b/setup.py
new file mode 100644 (file)
index 0000000..bbe3859
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,16 @@
+from setuptools import setup
+
+
+setup(
+    name='letsencrypt-hitch-plugin',
+    package='hitch.py',
+    install_requires=[
+        'letsencrypt',
+        'zope.interface',
+    ],
+    entry_points={
+        'letsencrypt.plugins': [
+            'hitch = hitch:Installer',
+        ],
+    },
+)