From 9953cb45277b6208f03fca707f310e89b77c37e6 Mon Sep 17 00:00:00 2001 From: Kishi85 Date: Tue, 23 Mar 2021 09:22:03 +0100 Subject: [PATCH] standalone: Fix multiple challange handlers on same port If you define challenge handlers on a per-domain basis multiple will be created. This would cause the standalone handler to potientially try to bind the same port (when configured) multiple times, which would only work on the first try. Subsequent tries would fail with "Address already in use". To fix this only bind the server between start and stop of the challenge and cleanup afterwards. --- acertmgr/modes/standalone.py | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/acertmgr/modes/standalone.py b/acertmgr/modes/standalone.py index 464eaa7..bdb83da 100644 --- a/acertmgr/modes/standalone.py +++ b/acertmgr/modes/standalone.py @@ -28,10 +28,20 @@ class HTTPServer6(HTTPServer): class ChallengeHandler(HTTPChallengeHandler): def __init__(self, config): HTTPChallengeHandler.__init__(self, config) - bind_address = config.get("bind_address", "") - port = int(config.get("port", 80)) + self.bind_address = config.get("bind_address", "") + self.port = int(config.get("port", 80)) self.challenges = {} # Initialize the challenge data dict + self.server_thread = None + self.server = None + + def create_challenge(self, domain, thumbprint, token): + self.challenges[token] = "{0}.{1}".format(token, thumbprint) + + def destroy_challenge(self, domain, thumbprint, token): + del self.challenges[token] + + def start_challenge(self, domain, thumbprint, token): _self = self # Custom HTTP request handler @@ -54,19 +64,11 @@ class ChallengeHandler(HTTPChallengeHandler): self.end_headers() self.wfile.write(value) - self.server_thread = None try: - self.server = HTTPServer6((bind_address, port), _HTTPRequestHandler) + self.server = HTTPServer6((self.bind_address, self.port), _HTTPRequestHandler) except socket.gaierror: - self.server = HTTPServer((bind_address, port), _HTTPRequestHandler) + self.server = HTTPServer((self.bind_address, self.port), _HTTPRequestHandler) - def create_challenge(self, domain, thumbprint, token): - self.challenges[token] = "{0}.{1}".format(token, thumbprint) - - def destroy_challenge(self, domain, thumbprint, token): - del self.challenges[token] - - def start_challenge(self, domain, thumbprint, token): def _serve(): self.server.serve_forever() @@ -78,3 +80,6 @@ class ChallengeHandler(HTTPChallengeHandler): if self.server_thread.is_alive(): self.server.shutdown() self.server_thread.join() + self.server.server_close() + self.server = None + self.server_thread = None