def test_idempotent(self): """ Loading the key twice loads the same key the second time as was created the first time. """ tempdir = self.useFixture(TempDir()).path temp_path = FilePath(tempdir) key_path = temp_path.child('client.key') self.assertThat(key_path.isfile(), Equals(False)) key = load_or_create_client_key(temp_path) self.assertThat(load_or_create_client_key(temp_path), Equals(key))
def __init__( self, acme_key=None, staging=True, pem_path=pem_path, clock=reactor, responder=None, ): if responder is None: responder = HTTP01ResponderWithProxy() # Keep an easy reference to this responder self._responder = responder if acme_key is None: _ensure_dirs(pem_path) acme_key = load_or_create_client_key(pem_path) if staging: acme_url = txacme.urls.LETSENCRYPT_STAGING_DIRECTORY else: acme_url = txacme.urls.LETSENCRYPT_DIRECTORY # Keep track of factories used with this AcmeService self._factories = set() super(AcmeService, self).__init__( clock=clock, client_creator=partial( Client.from_url, reactor=clock, url=acme_url, key=acme_key ), cert_store=DirectoryStore(pem_path), responders=[responder], )
def test_create_key(self): """ `~txacme.endpoint.load_or_create_client_key` creates a new key if one does not exist. """ tempdir = self.useFixture(TempDir()).path temp_path = FilePath(tempdir) key_path = temp_path.child('client.key') self.assertThat(key_path.isfile(), Equals(False)) self.assertThat( load_or_create_client_key(temp_path), Equals(JWKRSA(key=load_pem_private_key( key_path.getContent(), password=None, backend=default_backend()))))
def makeService(config): ini = ConfigParser.RawConfigParser() ini.read(config['config']) configPath = FilePath(config['config']).parent() rproxyConf = dict(ini.items("rproxy")) hostsConf = dict(ini.items("hosts")) hosts = {} for k, v in hostsConf.items(): k = k.lower() hostname, part = k.rsplit("_", 1) if hostname not in hosts: hosts[hostname] = {} hosts[hostname][part] = v if not hosts: raise ValueError("No hosts configured.") for i in hosts: if "port" not in hosts[i]: raise ValueError("All hosts need a port.") if "host" not in hosts[i]: print("%s does not have a host, making localhost" % (i,)) hosts[i]["host"] = "localhost" if "wwwtoo" not in hosts[i]: print("%s does not have an wwwtoo setting, making True" % (i,)) hosts[i]["wwwtoo"] = "True" if "proxysecure" not in hosts[i]: print("%s does not have an proxysecure setting, making False" % (i,)) hosts[i]["proxysecure"] = False hosts[i]["wwwtoo"] = True if hosts[i]["wwwtoo"]=="True" else False hosts[i]["proxysecure"] = True if hosts[i]["proxysecure"]=="True" else False hosts[i]["sendhsts"] = True if hosts[i].get("sendhsts")=="True" else False from twisted.internet import reactor pool = HTTPConnectionPool(reactor) resource = EncodingResourceWrapper( RProxyResource(hosts, rproxyConf.get("clacks"), pool, reactor, {}, False), [server.GzipEncoderFactory()]) responder = HTTP01Responder() site = server.Site(EnsureHTTPS(resource, responder.resource),) multiService = service.MultiService() certificates = rproxyConf.get("certificates", None) if certificates: try: configPath.child(certificates).makedirs() except: pass certificates = configPath.child(certificates).path for i in rproxyConf.get("https_ports").split(","): print("Starting HTTPS on port " + i) multiService.addService(strports.service('txsni:' + certificates + ':tcp:' + i, site)) for host in hosts.keys(): with open(FilePath(certificates).child(host + ".pem").path, 'r+'): # Open it so that txacme can find it pass if hosts[host]["wwwtoo"]: with open(FilePath(certificates).child("www." + host + ".pem").path, 'r+'): # Open it so that txacme can find it pass for i in rproxyConf.get("http_ports", "").split(","): print("Starting HTTP on port " + i) multiService.addService(strports.service('tcp:' + i, site)) issuingService = AcmeIssuingService( cert_store=DirectoryStore(FilePath(certificates)), client_creator=(lambda: Client.from_url( reactor=reactor, url=LETSENCRYPT_DIRECTORY, key=load_or_create_client_key(FilePath(certificates)), alg=RS256, )), clock=reactor, responders=[responder], ) issuingService.setServiceParent(multiService) return multiService
def start_listening(self): # Configure logging for txacme, if you need to debug # from eliot import add_destinations # from eliot.twisted import TwistedDestination # # add_destinations(TwistedDestination()) from txacme.challenges import HTTP01Responder from txacme.service import AcmeIssuingService from txacme.endpoint import load_or_create_client_key from txacme.client import Client from josepy.jwa import RS256 self._store = ErsatzStore() responder = HTTP01Responder() self._issuer = AcmeIssuingService( cert_store=self._store, client_creator=(lambda: Client.from_url( reactor=self.reactor, url=URL.from_text(self.hs.config.acme_url), key=load_or_create_client_key( FilePath(self.hs.config.config_dir_path)), alg=RS256, )), clock=self.reactor, responders=[responder], ) well_known = Resource() well_known.putChild(b'acme-challenge', responder.resource) responder_resource = Resource() responder_resource.putChild(b'.well-known', well_known) responder_resource.putChild(b'check', static.Data(b'OK', b'text/plain')) srv = server.Site(responder_resource) bind_addresses = self.hs.config.acme_bind_addresses for host in bind_addresses: logger.info( "Listening for ACME requests on %s:%i", host, self.hs.config.acme_port, ) try: self.reactor.listenTCP( self.hs.config.acme_port, srv, interface=host, ) except twisted.internet.error.CannotListenError as e: check_bind_error(e, host, bind_addresses) # Make sure we are registered to the ACME server. There's no public API # for this, it is usually triggered by startService, but since we don't # want it to control where we save the certificates, we have to reach in # and trigger the registration machinery ourselves. self._issuer._registered = False yield self._issuer._ensure_registered()
def makeService(config): ini = ConfigParser.RawConfigParser() ini.read(config['config']) configPath = FilePath(config['config']).parent() rproxyConf = dict(ini.items("rproxy")) hostsConf = dict(ini.items("hosts")) hosts = {} for k, v in hostsConf.items(): k = k.lower() hostname, part = k.rsplit("_", 1) if hostname not in hosts: hosts[hostname] = {} hosts[hostname][part] = v if not hosts: raise ValueError("No hosts configured.") for i in hosts: if "port" not in hosts[i]: raise ValueError("All hosts need a port.") if "host" not in hosts[i]: print("%s does not have a host, making localhost" % (i, )) hosts[i]["host"] = "localhost" if "wwwtoo" not in hosts[i]: print("%s does not have an wwwtoo setting, making True" % (i, )) hosts[i]["wwwtoo"] = "True" if "proxysecure" not in hosts[i]: print("%s does not have an proxysecure setting, making False" % (i, )) hosts[i]["proxysecure"] = False hosts[i]["wwwtoo"] = True if hosts[i]["wwwtoo"] == "True" else False hosts[i]["proxysecure"] = True if hosts[i][ "proxysecure"] == "True" else False hosts[i]["sendhsts"] = True if hosts[i].get( "sendhsts") == "True" else False from twisted.internet import reactor pool = HTTPConnectionPool(reactor) resource = EncodingResourceWrapper( RProxyResource(hosts, rproxyConf.get("clacks"), pool, reactor, {}, False), [server.GzipEncoderFactory()]) responder = HTTP01Responder() site = server.Site(EnsureHTTPS(resource, responder.resource), ) multiService = service.MultiService() certificates = rproxyConf.get("certificates", None) if certificates: try: configPath.child(certificates).makedirs() except: pass certificates = configPath.child(certificates).path for i in rproxyConf.get("https_ports").split(","): print("Starting HTTPS on port " + i) multiService.addService( strports.service('txsni:' + certificates + ':tcp:' + i, site)) for host in hosts.keys(): with open(FilePath(certificates).child(host + ".pem").path, 'w'): # Open it so that txacme can find it pass if hosts[host]["wwwtoo"]: with open( FilePath(certificates).child("www." + host + ".pem").path, 'w'): # Open it so that txacme can find it pass for i in rproxyConf.get("http_ports", "").split(","): print("Starting HTTP on port " + i) multiService.addService(strports.service('tcp:' + i, site)) issuingService = AcmeIssuingService( cert_store=DirectoryStore(FilePath(certificates)), client_creator=(lambda: Client.from_url( reactor=reactor, url=LETSENCRYPT_DIRECTORY, key=load_or_create_client_key(FilePath(certificates)), alg=RS256, )), clock=reactor, responders=[responder], ) issuingService.setServiceParent(multiService) return multiService