1
0
mirror of https://github.com/moepman/acertmgr.git synced 2024-11-14 23:15:27 +01:00
acertmgr/modes/standalone.py

85 lines
2.9 KiB
Python
Raw Normal View History

2016-04-04 01:04:20 +02:00
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# standalone - standalone ACME challenge webserver
2016-04-04 01:04:20 +02:00
# Copyright (c) Markus Hauschild & David Klaftenegger, 2016.
# Copyright (c) Rudolf Mayerhofer, 2019.
2016-04-04 01:04:20 +02:00
# available under the ISC license, see LICENSE
try:
2019-01-08 08:12:20 +01:00
from SimpleHTTPServer import SimpleHTTPRequestHandler
2016-04-04 01:04:20 +02:00
except ImportError:
2019-01-08 08:12:20 +01:00
from http.server import SimpleHTTPRequestHandler
2016-04-04 01:04:20 +02:00
try:
2019-01-08 08:12:20 +01:00
from SocketServer import TCPServer as HTTPServer
2016-04-04 01:04:20 +02:00
except ImportError:
2019-01-08 08:12:20 +01:00
from http.server import HTTPServer
2016-04-04 01:04:20 +02:00
import os
2016-04-04 01:04:20 +02:00
import threading
from modes.webdir import ChallengeHandler as WebChallengeHandler
import datetime
2019-01-08 08:12:20 +01:00
2016-04-04 01:04:20 +02:00
# @brief custom request handler for ACME challenges
# @note current working directory is temporarily changed by the script before
# the webserver starts, which allows using SimpleHTTPRequestHandler
class ACMERequestHandler(SimpleHTTPRequestHandler):
2019-01-08 08:12:20 +01:00
# @brief remove directories from GET URL
# @details the current working directory contains the challenge files,
# there is no need for creating subdirectories for the path
# that ACME expects.
# Additionally, this allows redirecting the ACME path to this
# webserver without having to know which subdirectory is
# redirected, which simplifies integration with existing
# webservers.
def translate_path(self, path):
spath = path.split('/')
assert (spath[0] == '')
spath = spath[1:]
if spath[0] == '.well-known':
spath = spath[1:]
if spath[0] == 'acme-challenge':
spath = spath[1:]
assert (len(spath) == 1)
spath.insert(0, '')
path = '/'.join(spath)
return SimpleHTTPRequestHandler.translate_path(self, path)
2016-04-04 01:04:20 +02:00
# @brief start the standalone webserver
# @param server the HTTPServer object
# @note this function is used to be passed to threading.Thread
def start_standalone(server):
2019-01-08 08:12:20 +01:00
server.serve_forever()
2016-04-04 01:04:20 +02:00
HTTPServer.allow_reuse_address = True
class ChallengeHandler(WebChallengeHandler):
def __init__(self, config):
WebChallengeHandler.__init__(self, config)
self.current_directory = os.getcwd()
if "port" in config:
port = int(config["port"])
else:
port = 80
self.server_thread = None
2019-01-08 08:12:20 +01:00
self.server = HTTPServer(("", port), ACMERequestHandler)
def create_challenge(self, domain, thumbprint, token):
WebChallengeHandler.create_challenge(self, domain, thumbprint, token)
2019-01-08 08:12:20 +01:00
self.server_thread = threading.Thread(target=start_standalone, args=(self.server,))
os.chdir(self.challenge_directory)
2019-01-08 08:12:20 +01:00
self.server_thread.start()
return datetime.datetime.now()
2016-04-04 01:04:20 +02:00
def destroy_challenge(self, domain, thumbprint, token):
2019-01-08 08:12:20 +01:00
self.server.shutdown()
self.server_thread.join()
os.chdir(self.current_directory)
WebChallengeHandler.destroy_challenge(self, domain, thumbprint, token)