mirror of
https://github.com/certbot/certbot.git
synced 2026-08-01 19:14:54 +02:00
fix up acme & certbot standalone code (#10293)
certbot's standalone code contains confusing references to things like `SSLSocket` which we were hoping to deprecate in https://github.com/certbot/certbot/issues/10284. are they relevant? they're sure not! certbot's standalone plugin only supports HTTP-01 so comments about things like `ACMETLSServer` and the completely unused `certs` variable can be deleted furthermore, the type of the different variables named things like `http_01_resources` were wrong in multiple places. as can be seen in certbot's standalone code, the type is `Set[acme_standalone.HTTP01RequestHandler.HTTP01Resource]`. this is also [the type used in acme.standalone's tests](https://github.com/certbot/certbot/blob/723fe64d4dbc778f1e8fd0b93320c1a30dc6fa95/acme/src/acme/_internal/tests/standalone_test.py#L78-L81) despite the file's type annotations saying it takes a different type. i think the incorrect type annotations were never caught because mypy can't fully make sense of our overly complex server classes here finally, `from __future__ import annotations` was added to make [forward references in type annotations](https://mypy.readthedocs.io/en/stable/cheat_sheet_py3.html#forward-references) easier
This commit is contained in:
@@ -1,4 +1,6 @@
|
|||||||
"""Support for standalone client challenge solvers. """
|
"""Support for standalone client challenge solvers. """
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import collections
|
import collections
|
||||||
import functools
|
import functools
|
||||||
import http.client as http_client
|
import http.client as http_client
|
||||||
@@ -219,7 +221,8 @@ class HTTPServer(BaseHTTPServer.HTTPServer):
|
|||||||
class HTTP01Server(HTTPServer, ACMEServerMixin):
|
class HTTP01Server(HTTPServer, ACMEServerMixin):
|
||||||
"""HTTP01 Server."""
|
"""HTTP01 Server."""
|
||||||
|
|
||||||
def __init__(self, server_address: Tuple[str, int], resources: Set[challenges.HTTP01],
|
def __init__(self, server_address: Tuple[str, int],
|
||||||
|
resources: Set[HTTP01RequestHandler.HTTP01Resource],
|
||||||
ipv6: bool = False, timeout: int = 30) -> None:
|
ipv6: bool = False, timeout: int = 30) -> None:
|
||||||
super().__init__(
|
super().__init__(
|
||||||
server_address, HTTP01RequestHandler.partial_init(
|
server_address, HTTP01RequestHandler.partial_init(
|
||||||
@@ -314,8 +317,8 @@ class HTTP01RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
|
|||||||
self.path)
|
self.path)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def partial_init(cls, simple_http_resources: Set[challenges.HTTP01],
|
def partial_init(cls, simple_http_resources: Set[HTTP01RequestHandler.HTTP01Resource],
|
||||||
timeout: int) -> 'functools.partial[HTTP01RequestHandler]':
|
timeout: int) -> functools.partial[HTTP01RequestHandler]:
|
||||||
"""Partially initialize this handler.
|
"""Partially initialize this handler.
|
||||||
|
|
||||||
This is useful because `socketserver.BaseServer` takes
|
This is useful because `socketserver.BaseServer` takes
|
||||||
|
|||||||
@@ -8,11 +8,9 @@ from typing import DefaultDict
|
|||||||
from typing import Dict
|
from typing import Dict
|
||||||
from typing import Iterable
|
from typing import Iterable
|
||||||
from typing import List
|
from typing import List
|
||||||
from typing import Mapping
|
|
||||||
from typing import Set
|
from typing import Set
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
from typing import Type
|
from typing import Type
|
||||||
from typing import Union
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from acme import challenges
|
from acme import challenges
|
||||||
@@ -23,10 +21,6 @@ from certbot import interfaces
|
|||||||
from certbot.display import util as display_util
|
from certbot.display import util as display_util
|
||||||
from certbot.plugins import common
|
from certbot.plugins import common
|
||||||
|
|
||||||
from cryptography import x509
|
|
||||||
from cryptography.hazmat.primitives.asymmetric import types
|
|
||||||
from OpenSSL import crypto
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
@@ -35,30 +29,14 @@ if TYPE_CHECKING:
|
|||||||
Set[achallenges.AnnotatedChallenge]
|
Set[achallenges.AnnotatedChallenge]
|
||||||
]
|
]
|
||||||
|
|
||||||
_KeyAndCert = Union[
|
|
||||||
Tuple[crypto.PKey, crypto.X509],
|
|
||||||
Tuple[types.CertificateIssuerPrivateKeyTypes, x509.Certificate],
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
class ServerManager:
|
class ServerManager:
|
||||||
"""Standalone servers manager.
|
"""Manager for HTTP-01 standalone server instances."""
|
||||||
|
|
||||||
Manager for `ACMEServer` and `ACMETLSServer` instances.
|
def __init__(self,
|
||||||
|
|
||||||
`certs` and `http_01_resources` correspond to
|
|
||||||
`acme.crypto_util.SSLSocket.certs` and
|
|
||||||
`acme.crypto_util.SSLSocket.http_01_resources` respectively. All
|
|
||||||
created servers share the same certificates and resources, so if
|
|
||||||
you're running both TLS and non-TLS instances, HTTP01 handlers
|
|
||||||
will serve the same URLs!
|
|
||||||
|
|
||||||
"""
|
|
||||||
def __init__(self, certs: Mapping[bytes, _KeyAndCert],
|
|
||||||
http_01_resources: Set[acme_standalone.HTTP01RequestHandler.HTTP01Resource]
|
http_01_resources: Set[acme_standalone.HTTP01RequestHandler.HTTP01Resource]
|
||||||
) -> None:
|
) -> None:
|
||||||
self._instances: Dict[int, acme_standalone.HTTP01DualNetworkedServers] = {}
|
self._instances: Dict[int, acme_standalone.HTTP01DualNetworkedServers] = {}
|
||||||
self.certs = certs
|
|
||||||
self.http_01_resources = http_01_resources
|
self.http_01_resources = http_01_resources
|
||||||
|
|
||||||
def run(self, port: int, challenge_type: Type[challenges.Challenge],
|
def run(self, port: int, challenge_type: Type[challenges.Challenge],
|
||||||
@@ -144,10 +122,9 @@ running. HTTP challenge only (wildcards not supported)."""
|
|||||||
# values, main thread writes). Due to the nature of CPython's
|
# values, main thread writes). Due to the nature of CPython's
|
||||||
# GIL, the operations are safe, c.f.
|
# GIL, the operations are safe, c.f.
|
||||||
# https://docs.python.org/2/faq/library.html#what-kinds-of-global-value-mutation-are-thread-safe
|
# https://docs.python.org/2/faq/library.html#what-kinds-of-global-value-mutation-are-thread-safe
|
||||||
self.certs: Mapping[bytes, _KeyAndCert] = {}
|
|
||||||
self.http_01_resources: Set[acme_standalone.HTTP01RequestHandler.HTTP01Resource] = set()
|
self.http_01_resources: Set[acme_standalone.HTTP01RequestHandler.HTTP01Resource] = set()
|
||||||
|
|
||||||
self.servers = ServerManager(self.certs, self.http_01_resources)
|
self.servers = ServerManager(self.http_01_resources)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def add_parser_arguments(cls, add: Callable[..., None]) -> None:
|
def add_parser_arguments(cls, add: Callable[..., None]) -> None:
|
||||||
|
|||||||
@@ -23,13 +23,11 @@ class ServerManagerTest(unittest.TestCase):
|
|||||||
"""Tests for certbot._internal.plugins.standalone.ServerManager."""
|
"""Tests for certbot._internal.plugins.standalone.ServerManager."""
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
from certbot._internal.plugins.standalone import ServerManager, _KeyAndCert
|
from certbot._internal.plugins.standalone import ServerManager
|
||||||
self.certs: Dict[bytes, _KeyAndCert] = {}
|
|
||||||
self.http_01_resources: Set[acme_standalone.HTTP01RequestHandler.HTTP01Resource] = {}
|
self.http_01_resources: Set[acme_standalone.HTTP01RequestHandler.HTTP01Resource] = {}
|
||||||
self.mgr = ServerManager(self.certs, self.http_01_resources)
|
self.mgr = ServerManager(self.http_01_resources)
|
||||||
|
|
||||||
def test_init(self):
|
def test_init(self):
|
||||||
assert self.mgr.certs is self.certs
|
|
||||||
assert self.mgr.http_01_resources is self.http_01_resources
|
assert self.mgr.http_01_resources is self.http_01_resources
|
||||||
|
|
||||||
def _test_run_stop(self, challenge_type):
|
def _test_run_stop(self, challenge_type):
|
||||||
|
|||||||
Reference in New Issue
Block a user