diff --git a/built-in-lexicon.patch b/built-in-lexicon.patch new file mode 100644 index 0000000..8f771ba --- /dev/null +++ b/built-in-lexicon.patch @@ -0,0 +1,91 @@ +From cabce363b1831a6bec1aa947a94eefcfab92d873 Mon Sep 17 00:00:00 2001 +From: Adrien Ferrand +Date: Thu, 9 Nov 2023 00:21:36 +0100 +Subject: [PATCH] Remove client authentication attemps in favor of built-in + lexicon zone name resolution + +--- + certbot/certbot/plugins/dns_common_lexicon.py | 51 ++----------------- + 1 file changed, 3 insertions(+), 48 deletions(-) + +diff --git a/certbot/certbot/plugins/dns_common_lexicon.py b/certbot/certbot/plugins/dns_common_lexicon.py +index be94e191ba..231342f89c 100644 +--- a/certbot/certbot/plugins/dns_common_lexicon.py ++++ b/certbot/certbot/plugins/dns_common_lexicon.py +@@ -198,10 +198,7 @@ def _build_lexicon_config(self, domain: str) -> ConfigResolver: + + dict_config = { + 'domain': domain, +- # We bypass Lexicon subdomain resolution by setting the 'delegated' field in the config +- # to the value of the 'domain' field itself. Here we consider that the domain passed to +- # _build_lexicon_config() is already the exact subdomain of the actual DNS zone to use. +- 'delegated': domain, ++ 'resolve_zone_name': 'true', + 'provider_name': self._provider_name, + 'ttl': self._ttl, + self._provider_name: {item[2]: self._credentials.conf(item[0]) +@@ -217,10 +214,8 @@ def _setup_credentials(self) -> None: + ) + + def _perform(self, domain: str, validation_name: str, validation: str) -> None: +- resolved_domain = self._resolve_domain(domain) +- + try: +- with Client(self._build_lexicon_config(resolved_domain)) as operations: ++ with Client(self._build_lexicon_config(domain)) as operations: + operations.create_record(rtype='TXT', name=validation_name, content=validation) + except RequestException as e: + logger.debug('Encountered error adding TXT record: %s', e, exc_info=True) +@@ -228,51 +223,11 @@ def _perform(self, domain: str, validation_name: str, validation: str) -> None: + + def _cleanup(self, domain: str, validation_name: str, validation: str) -> None: + try: +- resolved_domain = self._resolve_domain(domain) +- except errors.PluginError as e: +- logger.debug('Encountered error finding domain_id during deletion: %s', e, +- exc_info=True) +- return +- +- try: +- with Client(self._build_lexicon_config(resolved_domain)) as operations: ++ with Client(self._build_lexicon_config(domain)) as operations: + operations.delete_record(rtype='TXT', name=validation_name, content=validation) + except RequestException as e: + logger.debug('Encountered error deleting TXT record: %s', e, exc_info=True) + +- def _resolve_domain(self, domain: str) -> str: +- domain_name_guesses = dns_common.base_domain_name_guesses(domain) +- +- for domain_name in domain_name_guesses: +- try: +- # Using client as a context manager requires `dns-lexicon>=3.14` and we may want to +- # provide better checks and error handling around this in the future. +- with Client(self._build_lexicon_config(domain_name)): +- return domain_name +- except HTTPError as e: +- result1 = self._handle_http_error(e, domain_name) +- +- if result1: +- raise result1 +- except Exception as e: # pylint: disable=broad-except +- result2 = self._handle_general_error(e, domain_name) +- +- if result2: +- raise result2 # pylint: disable=raising-bad-type +- +- raise errors.PluginError('Unable to determine zone identifier for {0} using zone names: {1}' +- .format(domain, domain_name_guesses)) +- +- def _handle_http_error(self, e: HTTPError, domain_name: str) -> Optional[errors.PluginError]: +- return errors.PluginError('Error determining zone identifier for {0}: {1}.' +- .format(domain_name, e)) +- +- def _handle_general_error(self, e: Exception, domain_name: str) -> Optional[errors.PluginError]: +- if not str(e).startswith('No domain found'): +- return errors.PluginError('Unexpected error determining zone identifier for {0}: {1}' +- .format(domain_name, e)) +- return None +- + + # This class takes a similar approach to the cryptography project to deprecate attributes + # in public modules. See the _ModuleWithDeprecation class here: diff --git a/python-certbot.changes b/python-certbot.changes index 5c0733f..4cf79ac 100644 --- a/python-certbot.changes +++ b/python-certbot.changes @@ -4,6 +4,7 @@ Thu Nov 16 12:56:34 UTC 2023 - Markéta Machová - Update to 2.7.4 * Fixed a bug introduced in version 2.7.0 that caused interactively entered webroot plugin values to not be saved for renewal. +- Add built-in-lexicon.patch to fix failures with dns-lexicon. ------------------------------------------------------------------- Mon Oct 30 15:37:44 UTC 2023 - Markéta Machová diff --git a/python-certbot.spec b/python-certbot.spec index 9891da5..9c996a8 100644 --- a/python-certbot.spec +++ b/python-certbot.spec @@ -25,6 +25,7 @@ Summary: ACME client License: Apache-2.0 URL: https://github.com/certbot/certbot Source0: https://files.pythonhosted.org/packages/source/c/certbot/certbot-%{version}.tar.gz +Patch: built-in-lexicon.patch BuildRequires: %{python_module acme >= %{version}} BuildRequires: %{python_module configargparse >= 1.5.3} BuildRequires: %{python_module configobj >= 5.0.6} @@ -69,6 +70,7 @@ to lower the barriers to entry for encrypting all HTTP traffic on the internet. %prep %setup -q -n certbot-%{version} +%autopatch -p1 %build %python_build