Initial checkin.
[letsencrypt-hitch-plugin] / hitch.py
1 """Hitch plugin."""
2 import logging
3 import os
4 import re
5 import subprocess
6
7 import zope.component
8 import zope.interface
9
10 from letsencrypt import errors
11 from letsencrypt import interfaces
12 from letsencrypt.plugins import common
13
14
15 logger = logging.getLogger(__name__)
16
17
18 class Installer(common.Plugin):
19     """Hitch installer."""
20     zope.interface.implements(interfaces.IInstaller)
21     zope.interface.classProvides(interfaces.IPluginFactory)
22
23     description = "Hitch Installer"
24     hidden = True
25
26     def prepare(self):
27         with open("/etc/hitch/hitch.conf") as config_file:
28             self.config = config_file.readlines()
29
30     def more_info(self):
31         return "Installer for Hitch TLS wrapper."
32
33     def get_all_names(self):
34         raise errors.PluginError("not implemented")
35
36     def deploy_cert(self, domain, cert_path, key_path,
37                     chain_path=None, fullchain_path=None):
38         # Concatenate private key and certificate together into one file.
39         with open(key_path) as key_file:
40             pem = key_file.read()
41
42         # Add the full chain if we have it; else just the certificate.
43         if fullchain_path is not None:
44             with open(fullchain_path) as cert_file:
45                 pem += cert_file.read()
46         else:
47             with open(cert_path) as cert_file:
48                 pem += cert_file.read()
49
50         # Add DH params if we have them (needed for PFS).
51         try:
52             with open("/etc/hitch/dh-param.pem") as dh_param_file:
53                 pem += dh_param_file.read()
54         except:
55             pass
56
57         # Actually write the full file.
58         filename = os.path.join(os.path.dirname(cert_path), "all.pem")
59         fd = os.open(filename, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0600)
60         with os.fdopen(fd, 'w') as pem_file:
61             pem_file.write(pem)
62
63         # Now go check the config file to see if this file is already there.
64         found = False
65         last_pem_line = None
66         for line_num in xrange(len(self.config)):
67             m = re.match("^\s*pem-file\s*=\s*\"([^\"]+)\"", self.config[line_num])
68             if m:
69                 last_pem_line = line_num
70                 if m.groups()[0] == filename:
71                     found = True
72
73         # If it's not already there, add it after the last line.
74         if not found:
75             if last_pem_line is None:
76                 last_pem_line = len(self.config) - 1
77             config_line = "pem-file = \"%s\"  # Added by Let's Encrypt installer.\n" % filename
78             self.config.insert(last_pem_line + 1, config_line)
79
80         pass  # pragma: no cover
81
82     def enhance(self, domain, enhancement, options=None):
83         raise errors.PluginError("not implemented")
84
85     def supported_enhancements(self):
86         return []
87
88     def get_all_certs_keys(self):
89         raise errors.PluginError("not implemented")
90         return []
91
92     def save(self, title=None, temporary=False):
93         if temporary:
94             raise errors.PluginError("temporary is not implemented")
95
96         with open("/etc/hitch/hitch.conf", "w") as config_file:
97             config_file.writelines(self.config)
98
99     def rollback_checkpoints(self, rollback=1):
100         raise errors.PluginError("not implemented")
101
102     def recovery_routine(self):
103         raise errors.PluginError("not implemented")
104
105     def view_config_changes(self):
106         raise errors.PluginError("not implemented")
107
108     def config_test(self):
109         raise errors.PluginError("not implemented")
110
111     def restart(self):
112         subprocess.call(["systemctl", "reload", "hitch.service"])