Hello community, here is the log from the commit of package python-certbot for openSUSE:Factory checked in at 2020-10-07 14:18:47 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-certbot (Old) and /work/SRC/openSUSE:Factory/.python-certbot.new.4249 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-certbot" Wed Oct 7 14:18:47 2020 rev:30 rq:839981 version:1.9.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-certbot/python-certbot.changes 2020-08-21 19:13:15.760680074 +0200 +++ /work/SRC/openSUSE:Factory/.python-certbot.new.4249/python-certbot.changes 2020-10-07 14:19:02.301512020 +0200 @@ -1,0 +2,36 @@ +Wed Oct 7 08:15:42 UTC 2020 - Marketa Calabkova <[email protected]> + +- Update to version 1.9.0 + * certbot-auto was deprecated on all systems except for those based on Debian or RHEL. + * Update the packaging instructions to promote usage of python -m pytest to test Certbot + instead of the deprecated python setup.py test setuptools approach. + * Reduced CLI logging when handling some kinds of errors. + * The minimum version of the acme library required by Certbot was corrected. + In the previous release, Certbot said it required acme>=1.6.0 when it + actually required acme>=1.8.0 to properly support removing contact + information from an ACME account. + +------------------------------------------------------------------- +Mon Sep 28 13:57:39 UTC 2020 - Hans-Peter Jansen <[email protected]> + +- Update to version 1.8.0 + + Added + * Added the ability to remove email and phone contact + information from an account + * using update_account --register-unsafely-without-email + + Changed + * Support for Python 3.5 has been removed. + + Fixed + * The problem causing the Apache plugin in the Certbot snap on + ARM systems to + * fail to load the Augeas library it depends on has been fixed. + * The acme library can now tell the ACME server to clear + contact information by passing an empty + * tuple to the contact field of a Registration message. + * Fixed the *** stack smashing detected *** error in the + Certbot snap on some systems. + * More details about these changes can be found on our GitHub + repo. +- Add certbot keyring and hash file + +------------------------------------------------------------------- Old: ---- certbot-1.7.0.tar.gz New: ---- certbot-1.9.0.tar.gz certbot-1.9.0.tar.gz.asc python-certbot.keyring ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-certbot.spec ++++++ --- /var/tmp/diff_new_pack.O41QVt/_old 2020-10-07 14:19:03.157512701 +0200 +++ /var/tmp/diff_new_pack.O41QVt/_new 2020-10-07 14:19:03.157512701 +0200 @@ -19,13 +19,15 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} %bcond_without python2 Name: python-certbot -Version: 1.7.0 +Version: 1.9.0 Release: 0 Summary: ACME client License: Apache-2.0 URL: https://github.com/certbot/certbot -Source: https://files.pythonhosted.org/packages/source/c/certbot/certbot-%{version}.tar.gz -BuildRequires: %{python_module acme >= 1.6.0} +Source0: https://files.pythonhosted.org/packages/source/c/certbot/certbot-%{version}.tar.gz +Source1: https://files.pythonhosted.org/packages/source/c/certbot/certbot-%{version}.tar.gz.asc +Source2: %{name}.keyring +BuildRequires: %{python_module acme >= 1.8.0} BuildRequires: %{python_module configargparse >= 0.9.3} BuildRequires: %{python_module configobj} BuildRequires: %{python_module cryptography >= 1.2.3} ++++++ certbot-1.7.0.tar.gz -> certbot-1.9.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/CHANGELOG.md new/certbot-1.9.0/CHANGELOG.md --- old/certbot-1.7.0/CHANGELOG.md 2020-08-04 20:20:15.000000000 +0200 +++ new/certbot-1.9.0/CHANGELOG.md 2020-10-06 20:39:49.000000000 +0200 @@ -2,6 +2,55 @@ Certbot adheres to [Semantic Versioning](https://semver.org/). +## 1.9.0 - 2020-10-06 + +### Added + +* `--preconfigured-renewal` flag, for packager use only. + See the [packaging guide](https://certbot.eff.org/docs/packaging.html). + +### Changed + +* certbot-auto was deprecated on all systems except for those based on Debian or RHEL. +* Update the packaging instructions to promote usage of `python -m pytest` to test Certbot + instead of the deprecated `python setup.py test` setuptools approach. +* Reduced CLI logging when reloading nginx, if it is not running. +* Reduced CLI logging when handling some kinds of errors. + +### Fixed + +* Fixed `server_name` case-sensitivity in the nginx plugin. +* The minimum version of the `acme` library required by Certbot was corrected. + In the previous release, Certbot said it required `acme>=1.6.0` when it + actually required `acme>=1.8.0` to properly support removing contact + information from an ACME account. +* Upgraded the version of httplib2 used in our snaps and Docker images to add + support for proxy environment variables and fix the plugin for Google Cloud + DNS. + +More details about these changes can be found on our GitHub repo. + +## 1.8.0 - 2020-09-08 + +### Added + +* Added the ability to remove email and phone contact information from an account + using `update_account --register-unsafely-without-email` + +### Changed + +* Support for Python 3.5 has been removed. + +### Fixed + +* The problem causing the Apache plugin in the Certbot snap on ARM systems to + fail to load the Augeas library it depends on has been fixed. +* The `acme` library can now tell the ACME server to clear contact information by passing an empty + `tuple` to the `contact` field of a `Registration` message. +* Fixed the `*** stack smashing detected ***` error in the Certbot snap on some systems. + +More details about these changes can be found on our GitHub repo. + ## 1.7.0 - 2020-08-04 ### Added @@ -20,7 +69,6 @@ ### Fixed -* More details about these changes can be found on our GitHub repo. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/PKG-INFO new/certbot-1.9.0/PKG-INFO --- old/certbot-1.7.0/PKG-INFO 2020-08-04 20:20:16.638172000 +0200 +++ new/certbot-1.9.0/PKG-INFO 2020-10-06 20:39:50.532854600 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: certbot -Version: 1.7.0 +Version: 1.9.0 Summary: ACME client Home-page: https://github.com/letsencrypt/letsencrypt Author: Certbot Project @@ -75,9 +75,9 @@ Community: https://community.letsencrypt.org - ACME spec: http://ietf-wg-acme.github.io/acme/ + ACME spec: `RFC 8555 <https://tools.ietf.org/html/rfc8555>`_ - ACME working area in github: https://github.com/ietf-wg-acme/acme + ACME working area in github (archived): https://github.com/ietf-wg-acme/acme |build-status| @@ -137,7 +137,6 @@ Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 @@ -147,7 +146,7 @@ Classifier: Topic :: System :: Networking Classifier: Topic :: System :: Systems Administration Classifier: Topic :: Utilities -Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.* +Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.* Provides-Extra: dev Provides-Extra: dev3 Provides-Extra: docs diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/README.rst new/certbot-1.9.0/README.rst --- old/certbot-1.7.0/README.rst 2020-08-04 20:20:15.000000000 +0200 +++ new/certbot-1.9.0/README.rst 2020-10-06 20:39:49.000000000 +0200 @@ -67,9 +67,9 @@ Community: https://community.letsencrypt.org -ACME spec: http://ietf-wg-acme.github.io/acme/ +ACME spec: `RFC 8555 <https://tools.ietf.org/html/rfc8555>`_ -ACME working area in github: https://github.com/ietf-wg-acme/acme +ACME working area in github (archived): https://github.com/ietf-wg-acme/acme |build-status| diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/certbot/__init__.py new/certbot-1.9.0/certbot/__init__.py --- old/certbot-1.7.0/certbot/__init__.py 2020-08-04 20:20:16.000000000 +0200 +++ new/certbot-1.9.0/certbot/__init__.py 2020-10-06 20:39:50.000000000 +0200 @@ -1,13 +1,4 @@ """Certbot client.""" -import warnings -import sys # version number like 1.2.3a0, must have at least 2 parts, like 1.2 -__version__ = '1.7.0' - -if sys.version_info[:2] == (3, 5): - warnings.warn( - "Python 3.5 support will be dropped in the next release of " - "certbot. Please upgrade your Python version.", - PendingDeprecationWarning, - ) # pragma: no cover +__version__ = '1.9.0' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/certbot/_internal/cli/__init__.py new/certbot-1.9.0/certbot/_internal/cli/__init__.py --- old/certbot-1.7.0/certbot/_internal/cli/__init__.py 2020-08-04 20:20:15.000000000 +0200 +++ new/certbot-1.9.0/certbot/_internal/cli/__init__.py 2020-10-06 20:39:49.000000000 +0200 @@ -101,6 +101,11 @@ "flag to 0 disables log rotation entirely, causing " "Certbot to always append to the same log file.") helpful.add( + None, "--preconfigured-renewal", dest="preconfigured_renewal", + action="store_true", default=flag_default("preconfigured_renewal"), + help=argparse.SUPPRESS + ) + helpful.add( [None, "automation", "run", "certonly", "enhance"], "-n", "--non-interactive", "--noninteractive", dest="noninteractive_mode", action="store_true", @@ -171,13 +176,10 @@ ["register", "automation"], "--register-unsafely-without-email", action="store_true", default=flag_default("register_unsafely_without_email"), help="Specifying this flag enables registering an account with no " - "email address. This is strongly discouraged, because in the " - "event of key loss or account compromise you will irrevocably " - "lose access to your account. You will also be unable to receive " - "notice about impending expiration or revocation of your " - "certificates. Updates to the Subscriber Agreement will still " - "affect you, and will be effective 14 days after posting an " - "update to the web site.") + "email address. This is strongly discouraged, because you will be " + "unable to receive notice about impending expiration or " + "revocation of your certificates or problems with your Certbot " + "installation that will lead to failure to renew.") helpful.add( ["register", "update_account", "unregister", "automation"], "-m", "--email", default=flag_default("email"), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/certbot/_internal/cli/helpful.py new/certbot-1.9.0/certbot/_internal/cli/helpful.py --- old/certbot-1.7.0/certbot/_internal/cli/helpful.py 2020-08-04 20:20:15.000000000 +0200 +++ new/certbot-1.9.0/certbot/_internal/cli/helpful.py 2020-10-06 20:39:49.000000000 +0200 @@ -192,8 +192,8 @@ if self.detect_defaults: return parsed_args - self.defaults = dict((key, copy.deepcopy(self.parser.get_default(key))) - for key in vars(parsed_args)) + self.defaults = {key: copy.deepcopy(self.parser.get_default(key)) + for key in vars(parsed_args)} # Do any post-parsing homework here diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/certbot/_internal/constants.py new/certbot-1.9.0/certbot/_internal/constants.py --- old/certbot-1.7.0/certbot/_internal/constants.py 2020-08-04 20:20:15.000000000 +0200 +++ new/certbot-1.9.0/certbot/_internal/constants.py 2020-10-06 20:39:49.000000000 +0200 @@ -16,7 +16,7 @@ CLI_DEFAULTS = dict( config_files=[ os.path.join(misc.get_default_folder('config'), 'cli.ini'), - # http://freedesktop.org/wiki/Software/xdg-user-dirs/ + # https://freedesktop.org/wiki/Software/xdg-user-dirs/ os.path.join(os.environ.get("XDG_CONFIG_HOME", "~/.config"), "letsencrypt", "cli.ini"), ], @@ -25,6 +25,7 @@ verbose_count=-int(logging.INFO / 10), text_mode=False, max_log_backups=1000, + preconfigured_renewal=False, noninteractive_mode=False, force_interactive=False, domains=[], diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/certbot/_internal/error_handler.py new/certbot-1.9.0/certbot/_internal/error_handler.py --- old/certbot-1.7.0/certbot/_internal/error_handler.py 2020-08-04 20:20:15.000000000 +0200 +++ new/certbot-1.9.0/certbot/_internal/error_handler.py 2020-10-06 20:39:49.000000000 +0200 @@ -123,8 +123,10 @@ while self.funcs: try: self.funcs[-1]() - except Exception: # pylint: disable=broad-except - logger.error("Encountered exception during recovery: ", exc_info=True) + except Exception as exc: # pylint: disable=broad-except + output = traceback.format_exception_only(type(exc), exc) + logger.error("Encountered exception during recovery: %s", + ''.join(output).rstrip()) self.funcs.pop() def _set_signal_handlers(self): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/certbot/_internal/log.py new/certbot-1.9.0/certbot/_internal/log.py --- old/certbot-1.7.0/certbot/_internal/log.py 2020-08-04 20:20:15.000000000 +0200 +++ new/certbot-1.9.0/certbot/_internal/log.py 2020-10-06 20:39:49.000000000 +0200 @@ -319,6 +319,9 @@ # logger.DEBUG should be used if debug or not issubclass(exc_type, Exception): assert constants.QUIET_LOGGING_LEVEL <= logging.ERROR + if exc_type is KeyboardInterrupt: + logger.error('Exiting due to user request.') + sys.exit(1) logger.error('Exiting abnormally:', exc_info=exc_info) else: logger.debug('Exiting abnormally:', exc_info=exc_info) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/certbot/_internal/main.py new/certbot-1.9.0/certbot/_internal/main.py --- old/certbot-1.7.0/certbot/_internal/main.py 2020-08-04 20:20:15.000000000 +0200 +++ new/certbot-1.9.0/certbot/_internal/main.py 2020-10-06 20:39:49.000000000 +0200 @@ -11,7 +11,7 @@ import zope.component from acme import errors as acme_errors -from acme.magic_typing import Union +from acme.magic_typing import Union, Iterable, Optional # pylint: disable=unused-import import certbot from certbot import crypto_util from certbot import errors @@ -28,6 +28,7 @@ from certbot._internal import log from certbot._internal import renewal from certbot._internal import reporter +from certbot._internal import snap_config from certbot._internal import storage from certbot._internal import updater from certbot._internal.plugins import disco as plugins_disco @@ -590,7 +591,7 @@ :type config: interfaces.IConfig :param authenticator: Acme authentication handler - :type authenticator: interfaces.IAuthenticator + :type authenticator: Optional[interfaces.IAuthenticator] :param installer: Installer object :type installer: interfaces.IInstaller @@ -703,17 +704,17 @@ if not accounts: return "Could not find an existing account to update." - if config.email is None: - if config.register_unsafely_without_email: - return ("--register-unsafely-without-email provided, however, a " - "new e-mail address must\ncurrently be provided when " - "updating a registration.") + if config.email is None and not config.register_unsafely_without_email: config.email = display_ops.get_email(optional=False) acc, acme = _determine_account(config) cb_client = client.Client(config, acc, None, None, acme=acme) + # Empty list of contacts in case the user is removing all emails + + acc_contacts = () # type: Iterable[str] + if config.email: + acc_contacts = ['mailto:' + email for email in config.email.split(',')] # We rely on an exception to interrupt this process if it didn't work. - acc_contacts = ['mailto:' + email for email in config.email.split(',')] prev_regr_uri = acc.regr.uri acc.regr = cb_client.acme.update_registration(acc.regr.update( body=acc.regr.body.update(contact=acc_contacts))) @@ -722,8 +723,13 @@ # so that we can also continue to use the account object with acmev1. acc.regr = acc.regr.update(uri=prev_regr_uri) account_storage.update_regr(acc, cb_client.acme) - eff.prepare_subscription(config, acc) - add_msg("Your e-mail address was updated to {0}.".format(config.email)) + + if config.email is None: + add_msg("Any contact information associated with this account has been removed.") + else: + eff.prepare_subscription(config, acc) + add_msg("Your e-mail address was updated to {0}.".format(config.email)) + return None @@ -1320,6 +1326,9 @@ log.pre_arg_parse_setup() + if os.environ.get('CERTBOT_SNAPPED') == 'True': + cli_args = snap_config.prepare_env(cli_args) + plugins = plugins_disco.PluginsRegistry.find_all() logger.debug("certbot version: %s", certbot.__version__) # do not log `config`, as it contains sensitive data (e.g. revoke --key)! @@ -1343,10 +1352,6 @@ if config.func != plugins_cmd: # pylint: disable=comparison-with-callable raise - if sys.version_info[:2] == (3, 5): - logger.warning("Python 3.5 support will be dropped in the next release " - "of Certbot - please upgrade your Python version.") - set_displayer(config) # Reporter diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/certbot/_internal/plugins/disco.py new/certbot-1.9.0/certbot/_internal/plugins/disco.py --- old/certbot-1.7.0/certbot/_internal/plugins/disco.py 2020-08-04 20:20:15.000000000 +0200 +++ new/certbot-1.9.0/certbot/_internal/plugins/disco.py 2020-10-06 20:39:49.000000000 +0200 @@ -277,8 +277,8 @@ def filter(self, pred): """Filter plugins based on predicate.""" - return type(self)(dict((name, plugin_ep) for name, plugin_ep - in six.iteritems(self._plugins) if pred(plugin_ep))) + return type(self)({name: plugin_ep for name, plugin_ep + in six.iteritems(self._plugins) if pred(plugin_ep)}) def visible(self): """Filter plugins based on visibility.""" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/certbot/_internal/renewal.py new/certbot-1.9.0/certbot/_internal/renewal.py --- old/certbot-1.7.0/certbot/_internal/renewal.py 2020-08-04 20:20:15.000000000 +0200 +++ new/certbot-1.9.0/certbot/_internal/renewal.py 2020-10-06 20:39:49.000000000 +0200 @@ -9,16 +9,21 @@ import time import traceback +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives.asymmetric import rsa +from cryptography.hazmat.primitives.serialization import load_pem_private_key import OpenSSL import six import zope.component from acme.magic_typing import List +from acme.magic_typing import Optional # pylint: disable=unused-import from certbot import crypto_util from certbot import errors from certbot import interfaces from certbot import util from certbot._internal import cli +from certbot._internal import client # pylint: disable=unused-import from certbot._internal import constants from certbot._internal import hooks from certbot._internal import storage @@ -308,7 +313,8 @@ def renew_cert(config, domains, le_client, lineage): - "Renew a certificate lineage." + # type: (interfaces.IConfig, Optional[List[str]], client.Client, storage.RenewableCert) -> None + """Renew a certificate lineage.""" renewal_params = lineage.configuration["renewalparams"] original_server = renewal_params.get("server", cli.flag_default("server")) _avoid_invalidating_lineage(config, lineage, original_server) @@ -316,11 +322,14 @@ domains = lineage.names() # The private key is the existing lineage private key if reuse_key is set. # Otherwise, generate a fresh private key by passing None. - new_key = os.path.normpath(lineage.privkey) if config.reuse_key else None + if config.reuse_key: + new_key = os.path.normpath(lineage.privkey) + _update_renewal_params_from_key(new_key, config) + else: + new_key = None new_cert, new_chain, new_key, _ = le_client.obtain_certificate(domains, new_key) if config.dry_run: - logger.debug("Dry run: skipping updating lineage at %s", - os.path.dirname(lineage.cert)) + logger.debug("Dry run: skipping updating lineage at %s", os.path.dirname(lineage.cert)) else: prior_version = lineage.latest_common_version() # TODO: Check return value of save_successor @@ -335,6 +344,7 @@ lines = ("%s (%s)" % (m, category) for m in msgs) return " " + "\n ".join(lines) + def _renew_describe_results(config, renew_successes, renew_failures, renew_skipped, parse_failures): @@ -489,3 +499,13 @@ # Windows installer integration tests rely on handle_renewal_request behavior here. # If the text below changes, these tests will need to be updated accordingly. logger.debug("no renewal failures") + + +def _update_renewal_params_from_key(key_path, config): + # type: (str, interfaces.IConfig) -> None + with open(key_path, 'rb') as file_h: + key = load_pem_private_key(file_h.read(), password=None, backend=default_backend()) + if isinstance(key, rsa.RSAPrivateKey): + config.rsa_key_size = key.key_size + else: + raise errors.Error('Key at {0} is of an unsupported type: {1}.'.format(key_path, type(key))) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/certbot/_internal/snap_config.py new/certbot-1.9.0/certbot/_internal/snap_config.py --- old/certbot-1.7.0/certbot/_internal/snap_config.py 1970-01-01 01:00:00.000000000 +0100 +++ new/certbot-1.9.0/certbot/_internal/snap_config.py 2020-10-06 20:39:49.000000000 +0200 @@ -0,0 +1,102 @@ +"""Module configuring Certbot in a snap environment""" +import logging +import socket + +from requests import Session +from requests.adapters import HTTPAdapter +from requests.exceptions import HTTPError +from requests.exceptions import RequestException + +from acme.magic_typing import List +from certbot.compat import os +from certbot.errors import Error + +try: + from urllib3.connection import HTTPConnection + from urllib3.connectionpool import HTTPConnectionPool +except ImportError: + # Stub imports for oldest requirements, that will never be used in snaps. + HTTPConnection = object + HTTPConnectionPool = object + + +_ARCH_TRIPLET_MAP = { + 'arm64': 'aarch64-linux-gnu', + 'armhf': 'arm-linux-gnueabihf', + 'i386': 'i386-linux-gnu', + 'ppc64el': 'powerpc64le-linux-gnu', + 'powerpc': 'powerpc-linux-gnu', + 'amd64': 'x86_64-linux-gnu', + 's390x': 's390x-linux-gnu', +} + +LOGGER = logging.getLogger(__name__) + + +def prepare_env(cli_args): + # type: (List[str]) -> List[str] + """ + Prepare runtime environment for a certbot execution in snap. + :param list cli_args: List of command line arguments + :return: Update list of command line arguments + :rtype: list + """ + snap_arch = os.environ.get('SNAP_ARCH') + + if snap_arch not in _ARCH_TRIPLET_MAP: + raise Error('Unrecognized value of SNAP_ARCH: {0}'.format(snap_arch)) + + os.environ['CERTBOT_AUGEAS_PATH'] = '{0}/usr/lib/{1}/libaugeas.so.0'.format( + os.environ.get('SNAP'), _ARCH_TRIPLET_MAP[snap_arch]) + + session = Session() + session.mount('http://snapd/', _SnapdAdapter()) + + try: + response = session.get('http://snapd/v2/connections?snap=certbot&interface=content') + response.raise_for_status() + except RequestException as e: + if isinstance(e, HTTPError) and e.response.status_code == 404: + LOGGER.error('An error occurred while fetching Certbot snap plugins: ' + 'your version of snapd is outdated.') + LOGGER.error('Please run "sudo snap install core; sudo snap refresh core" ' + 'in your terminal and try again.') + else: + LOGGER.error('An error occurred while fetching Certbot snap plugins: ' + 'make sure the snapd service is running.') + raise e + + data = response.json() + connections = ['/snap/{0}/current/lib/python3.8/site-packages/'.format(item['slot']['snap']) + for item in data.get('result', {}).get('established', []) + if item.get('plug', {}).get('plug') == 'plugin' + and item.get('plug-attrs', {}).get('content') == 'certbot-1'] + + os.environ['CERTBOT_PLUGIN_PATH'] = ':'.join(connections) + + cli_args.append('--preconfigured-renewal') + + return cli_args + + +class _SnapdConnection(HTTPConnection): + def __init__(self): + super(_SnapdConnection, self).__init__("localhost") + self.sock = None + + def connect(self): + self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + self.sock.connect("/run/snapd.socket") + + +class _SnapdConnectionPool(HTTPConnectionPool): + def __init__(self): + super(_SnapdConnectionPool, self).__init__("localhost") + + def _new_conn(self): + return _SnapdConnection() + + +class _SnapdAdapter(HTTPAdapter): + def get_connection(self, url, proxies=None): + return _SnapdConnectionPool() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/certbot/_internal/storage.py new/certbot-1.9.0/certbot/_internal/storage.py --- old/certbot-1.7.0/certbot/_internal/storage.py 2020-08-04 20:20:15.000000000 +0200 +++ new/certbot-1.9.0/certbot/_internal/storage.py 2020-10-06 20:39:49.000000000 +0200 @@ -127,7 +127,7 @@ config["renewalparams"].update(relevant_data) - for k in config["renewalparams"].keys(): + for k in config["renewalparams"]: if k not in relevant_data: del config["renewalparams"][k] @@ -1126,7 +1126,7 @@ logger.debug("Writing full chain to %s.", target["fullchain"]) f.write(new_cert + new_chain) - symlinks = dict((kind, self.configuration[kind]) for kind in ALL_FOUR) + symlinks = {kind: self.configuration[kind] for kind in ALL_FOUR} # Update renewal config file self.configfile = update_configuration( self.lineagename, self.archive_dir, symlinks, cli_config) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/certbot/compat/filesystem.py new/certbot-1.9.0/certbot/compat/filesystem.py --- old/certbot-1.7.0/certbot/compat/filesystem.py 2020-08-04 20:20:15.000000000 +0200 +++ new/certbot-1.9.0/certbot/compat/filesystem.py 2020-10-06 20:39:49.000000000 +0200 @@ -340,8 +340,9 @@ :param str dst: The new file path. """ if hasattr(os, 'replace'): - # Use replace if possible. On Windows, only Python >= 3.5 is supported - # so we can assume that os.replace() is always available for this platform. + # Use replace if possible. Since we don't support Python 2 on Windows + # and os.replace() was added in Python 3.3, we can assume that + # os.replace() is always available on Windows. getattr(os, 'replace')(src, dst) else: # Otherwise, use os.rename() that behaves like os.replace() on Linux. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/certbot/compat/os.py new/certbot-1.9.0/certbot/compat/os.py --- old/certbot-1.7.0/certbot/compat/os.py 2020-08-04 20:20:15.000000000 +0200 +++ new/certbot-1.9.0/certbot/compat/os.py 2020-10-06 20:39:49.000000000 +0200 @@ -3,8 +3,11 @@ (e.g. chown, chmod, getuid) that would be harmful to the Windows file security model of Certbot. This module is intended to replace standard os module throughout certbot projects (except acme). -isort:skip_file +This module has the same API as the os module in the Python standard library +except for the functions defined below. + """ +# isort:skip_file # pylint: disable=function-redefined from __future__ import absolute_import @@ -21,12 +24,15 @@ import sys as std_sys ourselves = std_sys.modules[__name__] -for attribute in dir(std_os): - # Check if the attribute does not already exist in our module. It could be internal attributes - # of the module (__name__, __doc__), or attributes from standard os already imported with - # `from os import *`. - if not hasattr(ourselves, attribute): - setattr(ourselves, attribute, getattr(std_os, attribute)) +# Adding all of stdlib os to this module confuses Sphinx so we skip this when +# building the documentation. +if not std_os.environ.get("CERTBOT_DOCS") == "1": + for attribute in dir(std_os): + # Check if the attribute does not already exist in our module. It could + # be internal attributes of the module (__name__, __doc__), or + # attributes from standard os already imported with `from os import *`. + if not hasattr(ourselves, attribute): + setattr(ourselves, attribute, getattr(std_os, attribute)) # Import our internal path module, then allow certbot.compat.os.path # to behave as a module (similarly to os.path). diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/certbot/display/ops.py new/certbot-1.9.0/certbot/display/ops.py --- old/certbot-1.7.0/certbot/display/ops.py 2020-08-04 20:20:15.000000000 +0200 +++ new/certbot-1.9.0/certbot/display/ops.py 2020-10-06 20:39:49.000000000 +0200 @@ -6,7 +6,6 @@ from certbot import errors from certbot import interfaces from certbot import util -from certbot.compat import misc from certbot.compat import os from certbot.display import util as display_util @@ -33,9 +32,10 @@ msg = "Enter email address (used for urgent renewal and security notices)\n" unsafe_suggestion = ("\n\nIf you really want to skip this, you can run " "the client with --register-unsafely-without-email " - "but make sure you then backup your account key from " - "{0}\n\n".format(os.path.join( - misc.get_default_folder('config'), 'accounts'))) + "but you will then be unable to receive notice about " + "impending expiration or revocation of your " + "certificates or problems with your Certbot " + "installation that will lead to failure to renew.\n\n") if optional: if invalid: msg += unsafe_suggestion @@ -275,15 +275,6 @@ pause=False) -def _gen_ssl_lab_urls(domains): - """Returns a list of urls. - - :param list domains: Each domain is a 'str' - - """ - return ["https://www.ssllabs.com/ssltest/analyze.html?d=%s" % dom for dom in domains] - - def _gen_https_names(domains): """Returns a string of the https domains. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/certbot/plugins/storage.py new/certbot-1.9.0/certbot/plugins/storage.py --- old/certbot-1.7.0/certbot/plugins/storage.py 2020-08-04 20:20:15.000000000 +0200 +++ new/certbot-1.9.0/certbot/plugins/storage.py 2020-10-06 20:39:49.000000000 +0200 @@ -106,7 +106,7 @@ if not self._initialized: self._initialize_storage() - if not self._classkey in self._data.keys(): + if self._classkey not in self._data: self._data[self._classkey] = {} self._data[self._classkey][key] = value diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/certbot/reverter.py new/certbot-1.9.0/certbot/reverter.py --- old/certbot-1.7.0/certbot/reverter.py 2020-08-04 20:20:15.000000000 +0200 +++ new/certbot-1.9.0/certbot/reverter.py 2020-10-06 20:39:49.000000000 +0200 @@ -180,7 +180,7 @@ shutil.copy2(filename, os.path.join( cp_dir, os.path.basename(filename) + "_" + str(idx))) op_fd.write('{0}\n'.format(filename)) - # http://stackoverflow.com/questions/4726260/effective-use-of-python-shutil-copy2 + # https://stackoverflow.com/questions/4726260/effective-use-of-python-shutil-copy2 except IOError: op_fd.close() logger.error( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/certbot.egg-info/PKG-INFO new/certbot-1.9.0/certbot.egg-info/PKG-INFO --- old/certbot-1.7.0/certbot.egg-info/PKG-INFO 2020-08-04 20:20:16.000000000 +0200 +++ new/certbot-1.9.0/certbot.egg-info/PKG-INFO 2020-10-06 20:39:50.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: certbot -Version: 1.7.0 +Version: 1.9.0 Summary: ACME client Home-page: https://github.com/letsencrypt/letsencrypt Author: Certbot Project @@ -75,9 +75,9 @@ Community: https://community.letsencrypt.org - ACME spec: http://ietf-wg-acme.github.io/acme/ + ACME spec: `RFC 8555 <https://tools.ietf.org/html/rfc8555>`_ - ACME working area in github: https://github.com/ietf-wg-acme/acme + ACME working area in github (archived): https://github.com/ietf-wg-acme/acme |build-status| @@ -137,7 +137,6 @@ Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 @@ -147,7 +146,7 @@ Classifier: Topic :: System :: Networking Classifier: Topic :: System :: Systems Administration Classifier: Topic :: Utilities -Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.* +Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.* Provides-Extra: dev Provides-Extra: dev3 Provides-Extra: docs diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/certbot.egg-info/SOURCES.txt new/certbot-1.9.0/certbot.egg-info/SOURCES.txt --- old/certbot-1.7.0/certbot.egg-info/SOURCES.txt 2020-08-04 20:20:16.000000000 +0200 +++ new/certbot-1.9.0/certbot.egg-info/SOURCES.txt 2020-10-06 20:39:50.000000000 +0200 @@ -35,6 +35,7 @@ certbot/_internal/main.py certbot/_internal/renewal.py certbot/_internal/reporter.py +certbot/_internal/snap_config.py certbot/_internal/storage.py certbot/_internal/updater.py certbot/_internal/cli/__init__.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/certbot.egg-info/requires.txt new/certbot-1.9.0/certbot.egg-info/requires.txt --- old/certbot-1.7.0/certbot.egg-info/requires.txt 2020-08-04 20:20:16.000000000 +0200 +++ new/certbot-1.9.0/certbot.egg-info/requires.txt 2020-10-06 20:39:50.000000000 +0200 @@ -1,4 +1,4 @@ -acme>=1.6.0 +acme>=1.8.0 ConfigArgParse>=0.9.3 configobj cryptography>=1.2.3 @@ -28,8 +28,10 @@ [dev3] astroid +azure-devops ipdb mypy +PyGithub pylint [docs] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/docs/Makefile new/certbot-1.9.0/docs/Makefile --- old/certbot-1.7.0/docs/Makefile 2020-08-04 20:20:15.000000000 +0200 +++ new/certbot-1.9.0/docs/Makefile 2020-10-06 20:39:49.000000000 +0200 @@ -9,7 +9,7 @@ # User-friendly check for sphinx-build ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) -$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) +$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from https://www.sphinx-doc.org/) endif # Internal variables. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/docs/_templates/footer.html new/certbot-1.9.0/docs/_templates/footer.html --- old/certbot-1.7.0/docs/_templates/footer.html 2020-08-04 20:20:15.000000000 +0200 +++ new/certbot-1.9.0/docs/_templates/footer.html 2020-10-06 20:39:49.000000000 +0200 @@ -44,7 +44,7 @@ </div> {%- if show_sphinx %} - {% trans %}Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>{% endtrans %}. + {% trans %}Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>{% endtrans %}. {%- endif %} {%- block extrafooter %} {% endblock %} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/docs/ciphers.rst new/certbot-1.9.0/docs/ciphers.rst --- old/certbot-1.7.0/docs/ciphers.rst 2020-08-04 20:20:15.000000000 +0200 +++ new/certbot-1.9.0/docs/ciphers.rst 2020-10-06 20:39:49.000000000 +0200 @@ -208,17 +208,17 @@ Damien Giry collects recommendations by academic researchers and standards organizations about keylengths for particular cryptoperiods, years, or security levels. The keylength recommendations of the various sources are summarized in a chart. This site has been updated over time and includes expert guidance from eight sources published between 2000 and 2017. -http://www.keylength.com/ +https://www.keylength.com/ NIST ~~~~ -NISA published its "NIST Special Publication 800-52 Revision 1: Guidelines for the Selection, Configuration, and Use of Transport Layer Security (TLS) Implementations" +NIST published its "NIST Special Publication 800-52 Revision 2: Guidelines for the Selection, Configuration, and Use of Transport Layer Security (TLS) Implementations" -http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-52r1.pdf +https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-52r2.pdf -and its "NIST Special Publication 800-57: Recommendation for Key Management – Part 1: General (Revision 3)" +and its "NIST Special Publication 800-57: Recommendation for Key Management – Part 1: General (Revision 5)" -http://csrc.nist.gov/publications/nistpubs/800-57/sp800-57_part1_rev3_general.pdf +https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57pt1r5.pdf ENISA ~~~~~ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/docs/cli-help.txt new/certbot-1.9.0/docs/cli-help.txt --- old/certbot-1.7.0/docs/cli-help.txt 2020-08-04 20:20:15.000000000 +0200 +++ new/certbot-1.9.0/docs/cli-help.txt 2020-10-06 20:39:49.000000000 +0200 @@ -118,7 +118,7 @@ case, and to know when to deprecate support for past Python versions and flags. If you wish to hide this information from the Let's Encrypt server, set this to - "". (default: CertbotACMEClient/1.6.0 (certbot(-auto); + "". (default: CertbotACMEClient/1.8.0 (certbot(-auto); OS_NAME OS_VERSION) Authenticator/XXX Installer/YYY (SUBCOMMAND; flags: FLAGS) Py/major.minor.patchlevel). The flags encoded in the user agent are: --duplicate, @@ -373,13 +373,11 @@ --register-unsafely-without-email Specifying this flag enables registering an account with no email address. This is strongly discouraged, - because in the event of key loss or account compromise - you will irrevocably lose access to your account. You - will also be unable to receive notice about impending - expiration or revocation of your certificates. Updates - to the Subscriber Agreement will still affect you, and - will be effective 14 days after posting an update to - the web site. (default: False) + because you will be unable to receive notice about + impending expiration or revocation of your + certificates or problems with your Certbot + installation that will lead to failure to renew. + (default: False) -m EMAIL, --email EMAIL Email used for registration and recovery contact. Use comma to register multiple emails, ex: @@ -602,7 +600,7 @@ --dns-linode-propagation-seconds DNS_LINODE_PROPAGATION_SECONDS The number of seconds to wait for DNS to propagate before asking the ACME server to verify the DNS - record. (default: 1200) + record. (default: 120) --dns-linode-credentials DNS_LINODE_CREDENTIALS Linode credentials INI file. (default: None) @@ -702,6 +700,9 @@ --nginx-ctl NGINX_CTL Path to the 'nginx' binary, used for 'configtest' and retrieving nginx version number. (default: nginx) + --nginx-sleep-seconds NGINX_SLEEP_SECONDS + Number of seconds to wait for nginx configuration + changes to apply when reloading. (default: 1) null: Null Installer diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/docs/conf.py new/certbot-1.9.0/docs/conf.py --- old/certbot-1.7.0/docs/conf.py 2020-08-04 20:20:15.000000000 +0200 +++ new/certbot-1.9.0/docs/conf.py 2020-10-06 20:39:49.000000000 +0200 @@ -131,7 +131,7 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -# http://docs.readthedocs.org/en/latest/theme.html#how-do-i-use-this-locally-and-on-read-the-docs +# https://docs.readthedocs.io/en/stable/faq.html#i-want-to-use-the-read-the-docs-theme-locally # on_rtd is whether we are on readthedocs.org on_rtd = os.environ.get('READTHEDOCS', None) == 'True' if not on_rtd: # only import and set the theme if we're building docs locally diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/docs/contributing.rst new/certbot-1.9.0/docs/contributing.rst --- old/certbot-1.7.0/docs/contributing.rst 2020-08-04 20:20:15.000000000 +0200 +++ new/certbot-1.9.0/docs/contributing.rst 2020-10-06 20:39:49.000000000 +0200 @@ -18,6 +18,7 @@ and continue with these instructions on that UNIX-like OS. .. _local copy: +.. _prerequisites: Running a local copy of the client ---------------------------------- @@ -346,7 +347,7 @@ starting reference for how to do this. .. _`setuptools entry points`: - http://setuptools.readthedocs.io/en/latest/pkg_resources.html#entry-points + https://setuptools.readthedocs.io/en/latest/pkg_resources.html#entry-points .. _coding-style: @@ -377,7 +378,7 @@ .. _Google Python Style Guide: https://google.github.io/styleguide/pyguide.html -.. _Sphinx-style: http://sphinx-doc.org/ +.. _Sphinx-style: https://www.sphinx-doc.org/ .. _PEP 8 - Style Guide for Python Code: https://www.python.org/dev/peps/pep-0008 @@ -578,33 +579,3 @@ Now running the check for linting errors described above is as easy as:: tox -e lint - -.. _prerequisites: - -Notes on OS dependencies -======================== - -OS-level dependencies can be installed like so: - -.. code-block:: shell - - ./certbot-auto --debug --os-packages-only - -In general... - -* ``sudo`` is required as a suggested way of running privileged process -* `Python`_ 2.7 or 3.5+ is required -* `Augeas`_ is required for the Python bindings -* ``virtualenv`` is used for managing other Python library dependencies - -.. _Python: https://wiki.python.org/moin/BeginnersGuide/Download -.. _Augeas: http://augeas.net/ -.. _Virtualenv: https://virtualenv.pypa.io - - -FreeBSD -------- - -FreeBSD by default uses ``tcsh``. In order to activate virtualenv (see -above), you will need a compatible shell, e.g. ``pkg install bash && -bash``. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/docs/install.rst new/certbot-1.9.0/docs/install.rst --- old/certbot-1.7.0/docs/install.rst 2020-08-04 20:20:15.000000000 +0200 +++ new/certbot-1.9.0/docs/install.rst 2020-10-06 20:39:49.000000000 +0200 @@ -18,7 +18,7 @@ certbot.eff.org_, where you will also find the correct installation instructions for your system. -.. Note:: Unless you have very specific requirements, we kindly suggest that you use the Certbot packages provided by your package manager (see certbot.eff.org_). If such packages are not available, we recommend using ``certbot-auto``, which automates the process of installing Certbot on your system. +.. Note:: Unless you have very specific requirements, we kindly suggest that you use the installation instructions for your system found at certbot.eff.org_. .. _certbot.eff.org: https://certbot.eff.org @@ -28,7 +28,7 @@ System Requirements =================== -Certbot currently requires Python 2.7 or 3.5+ running on a UNIX-like operating +Certbot currently requires Python 2.7 or 3.6+ running on a UNIX-like operating system. By default, it requires root access in order to write to ``/etc/letsencrypt``, ``/var/log/letsencrypt``, ``/var/lib/letsencrypt``; to bind to port 80 (if you use the ``standalone`` plugin) and to read and @@ -156,18 +156,17 @@ certificates or configure your webserver, because our installer plugins cannot reach your webserver from inside the Docker container. -Most users should use the operating system packages (see instructions at -certbot.eff.org_) or, as a fallback, ``certbot-auto``. You should only -use Docker if you are sure you know what you are doing and have a -good reason to do so. +Most users should use the instructions at certbot.eff.org_. You should only use +Docker if you are sure you know what you are doing and have a good reason to do +so. You should definitely read the :ref:`where-certs` section, in order to know how to manage the certs manually. `Our ciphersuites page <ciphers.html>`__ provides some information about recommended ciphersuites. If none of -these make much sense to you, you should definitely use the -certbot-auto_ method, which enables you to use installer plugins -that cover both of those hard topics. +these make much sense to you, you should definitely use the installation method +recommended for your system at certbot.eff.org_, which enables you to use +installer plugins that cover both of those hard topics. If you're still not convinced and have decided to use this method, from the server that the domain you're requesting a certficate for resolves @@ -197,10 +196,7 @@ you'd use ``certbot/dns-route53``. You may also need to add flags to Certbot and/or mount additional directories to provide access to your DNS API credentials as specified in the :ref:`DNS plugin documentation -<dns_plugins>`. If you would like to obtain a wildcard certificate from -Let's Encrypt's ACMEv2 server, you'll need to include ``--server -https://acme-v02.api.letsencrypt.org/directory`` on the command line as -well. +<dns_plugins>`. For more information about the layout of the ``/etc/letsencrypt`` directory, see :ref:`where-certs`. @@ -250,9 +246,6 @@ They can be installed by running the same installation command above but replacing ``certbot`` with the name of the desired package. -There are no Certbot packages available for Debian Jessie and Jessie users -should instead use certbot-auto_. - **Ubuntu** If you run Ubuntu Trusty, Xenial, or Bionic, certbot is available through the official PPA, @@ -291,39 +284,19 @@ **Gentoo** -The official Certbot client is available in Gentoo Portage. If you -want to use the Apache plugin, it has to be installed separately: +The official Certbot client is available in Gentoo Portage. From the +official Certbot plugins, three of them are also available in Portage. +They need to be installed separately if you require their functionality. .. code-block:: shell emerge -av app-crypt/certbot emerge -av app-crypt/certbot-apache + emerge -av app-crypt/certbot-nginx + emerge -av app-crypt/certbot-dns-nsone -When using the Apache plugin, you will run into a "cannot find an -SSLCertificateFile directive" or "cannot find an SSLCertificateKeyFile -directive for certificate" error if you're sporting the default Gentoo -``httpd.conf``. You can fix this by commenting out two lines in -``/etc/apache2/httpd.conf`` as follows: - -Change - -.. code-block:: shell - - <IfDefine SSL> - LoadModule ssl_module modules/mod_ssl.so - </IfDefine> - -to - -.. code-block:: shell - - #<IfDefine SSL> - LoadModule ssl_module modules/mod_ssl.so - #</IfDefine> - -For the time being, this is the only way for the Apache plugin to recognise -the appropriate directives when installing the certificate. -Note: this change is not required for the other plugins. +.. Note:: The ``app-crypt/certbot-dns-nsone`` package has a different + maintainer than the other packages and can lag behind in version. **NetBSD** diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/docs/make.bat new/certbot-1.9.0/docs/make.bat --- old/certbot-1.7.0/docs/make.bat 2020-08-04 20:20:15.000000000 +0200 +++ new/certbot-1.9.0/docs/make.bat 2020-10-06 20:39:49.000000000 +0200 @@ -65,7 +65,7 @@ echo.may add the Sphinx directory to PATH. echo. echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ + echo.https://www.sphinx-doc.org/ exit /b 1 ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/docs/packaging.rst new/certbot-1.9.0/docs/packaging.rst --- old/certbot-1.7.0/docs/packaging.rst 2020-08-04 20:20:15.000000000 +0200 +++ new/certbot-1.9.0/docs/packaging.rst 2020-10-06 20:39:49.000000000 +0200 @@ -31,7 +31,7 @@ We use git tags to identify releases, using `Semantic Versioning`_. For example: `v0.11.1`. -.. _`Semantic Versioning`: http://semver.org/ +.. _`Semantic Versioning`: https://semver.org/ Our packages are cryptographically signed and their signature can be verified using the PGP key ``A2CFB51FA275A7286234E7B24D17C995CD9775F2``. This key can be @@ -44,9 +44,13 @@ 1. Do not package ``certbot-compatibility-test`` as it's only used internally. -2. To run tests on our packages, you should use ``python setup.py test``. Doing things like running ``pytest`` directly on our package files may not work because Certbot relies on setuptools to register and find its plugins. +2. To run tests on our packages, you should use pytest by running the command ``python -m pytest``. Running ``pytest`` directly may not work because PYTHONPATH is not handled the same way and local modules may not be found by the test runner. -3. If you'd like to include automated renewal in your package ``certbot renew -q`` should be added to crontab or systemd timer. Additionally you should include a random per-machine time offset to avoid having a large number of your clients hit Let's Encrypt's servers simultaneously. +3. If you'd like to include automated renewal in your package: + + - ``certbot renew -q`` should be added to crontab or systemd timer. + - A random per-machine time offset should be included to avoid having a large number of your clients hit Let's Encrypt's servers simultaneously. + - ``--preconfigured-renewal`` should be included on the CLI or in ``cli.ini`` for all invocations of Certbot, so that it can adjust its interactive output regarding automated renewal (Certbot >= 1.9.0). 4. ``jws`` is an internal script for ``acme`` module and it doesn't have to be packaged - it's mostly for debugging: you can use it as ``echo foo | jws sign | jws verify``. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/docs/using.rst new/certbot-1.9.0/docs/using.rst --- old/certbot-1.7.0/docs/using.rst 2020-08-04 20:20:15.000000000 +0200 +++ new/certbot-1.9.0/docs/using.rst 2020-10-06 20:39:49.000000000 +0200 @@ -287,7 +287,7 @@ .. _haproxy: https://github.com/greenhost/certbot-haproxy .. _s3front: https://github.com/dlapiduz/letsencrypt-s3front .. _gandi: https://github.com/obynio/certbot-plugin-gandi -.. _varnish: http://git.sesse.net/?p=letsencrypt-varnish-plugin +.. _varnish: https://git.sesse.net/?p=letsencrypt-varnish-plugin .. _pritunl: https://github.com/kharkevich/letsencrypt-pritunl .. _proxmox: https://github.com/kharkevich/letsencrypt-proxmox .. _external-auth: https://github.com/EnigmaBridge/certbot-external-auth @@ -392,7 +392,7 @@ .. _changing: Changing a Certificate's Domains -================================ +-------------------------------- The ``--cert-name`` flag can also be used to modify the domains a certificate contains, by specifying new domains using the ``-d`` or ``--domains`` flag. If certificate ``example.com`` @@ -631,7 +631,6 @@ :header: "Distribution Name", "Distribution Version", "Automation Method" "CentOS", "EPEL 7", "systemd" - "Debian", "jessie", "cron, systemd" "Debian", "stretch", "cron, systemd" "Debian", "testing/sid", "cron, systemd" "Fedora", "26", "systemd" @@ -685,7 +684,7 @@ This is what Apache needs for `SSLCertificateKeyFile <https://httpd.apache.org/docs/2.4/mod/mod_ssl.html#sslcertificatekeyfile>`_, and Nginx for `ssl_certificate_key - <http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate_key>`_. + <https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate_key>`_. ``fullchain.pem`` All certificates, **including** server certificate (aka leaf certificate or @@ -695,7 +694,7 @@ This is what Apache >= 2.4.8 needs for `SSLCertificateFile <https://httpd.apache.org/docs/2.4/mod/mod_ssl.html#sslcertificatefile>`_, and what Nginx needs for `ssl_certificate - <http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate>`_. + <https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate>`_. ``cert.pem`` and ``chain.pem`` (less common) ``cert.pem`` contains the server certificate by itself, and @@ -714,7 +713,7 @@ If you're using OCSP stapling with Nginx >= 1.3.7, ``chain.pem`` should be provided as the `ssl_trusted_certificate - <http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_trusted_certificate>`_ + <https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_trusted_certificate>`_ to validate OCSP responses. .. note:: All files are PEM-encoded. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/setup.py new/certbot-1.9.0/setup.py --- old/certbot-1.7.0/setup.py 2020-08-04 20:20:15.000000000 +0200 +++ new/certbot-1.9.0/setup.py 2020-10-06 20:39:49.000000000 +0200 @@ -7,10 +7,9 @@ from setuptools import __version__ as setuptools_version from setuptools import find_packages from setuptools import setup -from setuptools.command.test import test as TestCommand -# Workaround for http://bugs.python.org/issue8876, see -# http://bugs.python.org/issue8876#msg208792 +# Workaround for https://bugs.python.org/issue8876, see +# https://bugs.python.org/issue8876#msg208792 # This can be removed when using Python 2.7.9 or later: # https://hg.python.org/cpython/raw-file/v2.7.9/Misc/NEWS if os.path.abspath(__file__).split(os.path.sep)[1] == 'vagrant': @@ -36,7 +35,7 @@ # specified here to avoid masking the more specific request requirements in # acme. See https://github.com/pypa/pip/issues/988 for more info. install_requires = [ - 'acme>=1.6.0', + 'acme>=1.8.0', # We technically need ConfigArgParse 0.10.0 for Python 2.6 support, but # saying so here causes a runtime error against our temporary fork of 0.9.3 # in which we added 2.6 support (see #2243), so we relax the requirement. @@ -93,8 +92,10 @@ dev3_extras = [ 'astroid', + 'azure-devops', 'ipdb', 'mypy', + 'PyGithub', 'pylint', ] @@ -106,22 +107,6 @@ 'sphinx_rtd_theme', ] - -class PyTest(TestCommand): - user_options = [] - - def initialize_options(self): - TestCommand.initialize_options(self) - self.pytest_args = '' - - def run_tests(self): - import shlex - # import here, cause outside the eggs aren't loaded - import pytest - errno = pytest.main(shlex.split(self.pytest_args)) - sys.exit(errno) - - setup( name='certbot', version=version, @@ -131,7 +116,7 @@ author="Certbot Project", author_email='[email protected]', license='Apache License 2.0', - python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*', + python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*', classifiers=[ 'Development Status :: 5 - Production/Stable', 'Environment :: Console', @@ -143,7 +128,6 @@ 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', @@ -165,10 +149,6 @@ 'docs': docs_extras, }, - test_suite='certbot', - tests_require=["pytest"], - cmdclass={"test": PyTest}, - entry_points={ 'console_scripts': [ 'certbot = certbot.main:main', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/tests/cert_manager_test.py new/certbot-1.9.0/tests/cert_manager_test.py --- old/certbot-1.7.0/tests/cert_manager_test.py 2020-08-04 20:20:15.000000000 +0200 +++ new/certbot-1.9.0/tests/cert_manager_test.py 2020-10-06 20:39:49.000000000 +0200 @@ -35,8 +35,8 @@ "example.org": None, "other.com": os.path.join(self.config.config_dir, "specialarchive") } - self.config_files = dict((domain, self._set_up_config(domain, self.domains[domain])) - for domain in self.domains) + self.config_files = {domain: self._set_up_config(domain, self.domains[domain]) + for domain in self.domains} # We also create a file that isn't a renewal config in the same # location to test that logic that reads in all-and-only renewal @@ -80,8 +80,8 @@ archive_dir_path = custom_archive else: archive_dir_path = os.path.join(self.config.default_archive_dir, domain) - archive_paths[domain] = dict((kind, - os.path.join(archive_dir_path, kind + "1.pem")) for kind in ALL_FOUR) + archive_paths[domain] = {kind: + os.path.join(archive_dir_path, kind + "1.pem") for kind in ALL_FOUR} for kind in ALL_FOUR: live_path = self.config_files[domain][kind] archive_path = archive_paths[domain][kind] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/tests/client_test.py new/certbot-1.9.0/tests/client_test.py --- old/certbot-1.7.0/tests/client_test.py 2020-08-04 20:20:15.000000000 +0200 +++ new/certbot-1.9.0/tests/client_test.py 2020-10-06 20:39:49.000000000 +0200 @@ -483,7 +483,6 @@ def test_save_certificate(self, mock_parser): certs = ["cert_512.pem", "cert-san_512.pem"] tmp_path = tempfile.mkdtemp() - filesystem.chmod(tmp_path, 0o755) # TODO: really?? cert_pem = test_util.load_vector(certs[0]) chain_pem = (test_util.load_vector(certs[0]) + test_util.load_vector(certs[1])) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/tests/crypto_util_test.py new/certbot-1.9.0/tests/crypto_util_test.py --- old/certbot-1.7.0/tests/crypto_util_test.py 2020-08-04 20:20:15.000000000 +0200 +++ new/certbot-1.9.0/tests/crypto_util_test.py 2020-10-06 20:39:49.000000000 +0200 @@ -185,8 +185,6 @@ """Refactoring for verification tests.""" def setUp(self): - super(VerifyCertSetup, self).setUp() - self.renewable_cert = mock.MagicMock() self.renewable_cert.cert_path = SS_CERT_PATH self.renewable_cert.chain_path = SS_CERT_PATH diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/tests/display/ops_test.py new/certbot-1.9.0/tests/display/ops_test.py --- old/certbot-1.7.0/tests/display/ops_test.py 2020-08-04 20:20:15.000000000 +0200 +++ new/certbot-1.9.0/tests/display/ops_test.py 2020-10-06 20:39:49.000000000 +0200 @@ -131,26 +131,6 @@ self.assertTrue(self._call([self.acc1, self.acc2]) is None) -class GenSSLLabURLs(unittest.TestCase): - """Loose test of _gen_ssl_lab_urls. URL can change easily in the future.""" - def setUp(self): - zope.component.provideUtility(display_util.FileDisplay(sys.stdout, - False)) - - @classmethod - def _call(cls, domains): - from certbot.display.ops import _gen_ssl_lab_urls - return _gen_ssl_lab_urls(domains) - - def test_zero(self): - self.assertEqual(self._call([]), []) - - def test_two(self): - urls = self._call(["eff.org", "umich.edu"]) - self.assertTrue("eff.org" in urls[0]) - self.assertTrue("umich.edu" in urls[1]) - - class GenHttpsNamesTest(unittest.TestCase): """Test _gen_https_names.""" def setUp(self): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/tests/display/util_test.py new/certbot-1.9.0/tests/display/util_test.py --- old/certbot-1.7.0/tests/display/util_test.py 2020-08-04 20:20:15.000000000 +0200 +++ new/certbot-1.9.0/tests/display/util_test.py 2020-10-06 20:39:49.000000000 +0200 @@ -326,7 +326,6 @@ class NoninteractiveDisplayTest(unittest.TestCase): """Test non-interactive display. These tests are pretty easy!""" def setUp(self): - super(NoninteractiveDisplayTest, self).setUp() self.mock_stdout = mock.MagicMock() self.displayer = display_util.NoninteractiveDisplay(self.mock_stdout) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/tests/error_handler_test.py new/certbot-1.9.0/tests/error_handler_test.py --- old/certbot-1.7.0/tests/error_handler_test.py 2020-08-04 20:20:15.000000000 +0200 +++ new/certbot-1.9.0/tests/error_handler_test.py 2020-10-06 20:39:49.000000000 +0200 @@ -14,7 +14,7 @@ def get_signals(signums): """Get the handlers for an iterable of signums.""" - return dict((s, signal.getsignal(s)) for s in signums) + return {s: signal.getsignal(s) for s in signums} def set_signals(sig_handler_dict): @@ -28,7 +28,7 @@ """Context manager to catch signals""" signals = [] prev_handlers = get_signals(signums) # type: Dict[int, Union[int, None, Callable]] - set_signals(dict((s, lambda s, _: signals.append(s)) for s in signums)) + set_signals({s: lambda s, _: signals.append(s) for s in signums}) yield signals set_signals(prev_handlers) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/tests/log_test.py new/certbot-1.9.0/tests/log_test.py --- old/certbot-1.7.0/tests/log_test.py 2020-08-04 20:20:15.000000000 +0200 +++ new/certbot-1.9.0/tests/log_test.py 2020-10-06 20:39:49.000000000 +0200 @@ -306,7 +306,7 @@ self.log_path = 'foo.log' def test_base_exception(self): - exc_type = KeyboardInterrupt + exc_type = BaseException mock_logger, output = self._test_common(exc_type, debug=False) self._assert_exception_logged(mock_logger.error, exc_type) self._assert_logfile_output(output) @@ -342,6 +342,11 @@ self._assert_exception_logged(mock_logger.debug, exc_type) self._assert_quiet_output(mock_logger, output) + def test_keyboardinterrupt(self): + exc_type = KeyboardInterrupt + mock_logger, output = self._test_common(exc_type, debug=False) + mock_logger.error.assert_called_once_with('Exiting due to user request.') + def _test_common(self, error_type, debug): """Returns the mocked logger and stderr output.""" mock_err = six.StringIO() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/tests/main_test.py new/certbot-1.9.0/tests/main_test.py --- old/certbot-1.7.0/tests/main_test.py 2020-08-04 20:20:15.000000000 +0200 +++ new/certbot-1.9.0/tests/main_test.py 2020-10-06 20:39:49.000000000 +0200 @@ -1404,6 +1404,43 @@ "[email protected]"]) self.assertTrue("Could not find an existing account" in x[0]) + @mock.patch('certbot._internal.main._determine_account') + @mock.patch('certbot._internal.eff.prepare_subscription') + @mock.patch('certbot._internal.main.account') + def test_update_account_remove_email(self, mocked_account_module, mock_prepare, mock_det_acc): + # Mock account storage and the account object returned + mocked_storage = mock.MagicMock() + mocked_account = mock.MagicMock() + + mocked_account_module.AccountFileStorage.return_value = mocked_storage + mocked_storage.find_all.return_value = [mocked_account] + mock_det_acc.return_value = (mocked_account, "foo") + + # Mock registration body to verify calls are made + mock_regr_body = mock.MagicMock() + + # mocked_account.regr is overwritten in update, requiring an odd mock setup + mocked_account.regr.body = mock_regr_body + + x = self._call( + ["update_account", "--register-unsafely-without-email"]) + + + # When update succeeds, the return value of update_account() is None + self.assertTrue(x[0] is None) + # and we got supposedly did update the registration from + # the server + client_mock = x[3] + self.assertTrue(client_mock.Client().acme.update_registration.called) + + self.assertTrue(mock_regr_body.update.called) + self.assertTrue('contact' in mock_regr_body.update.call_args[1]) + self.assertEqual(mock_regr_body.update.call_args[1]['contact'], ()) + # and we saved the updated registration on disk + self.assertTrue(mocked_storage.update_regr.called) + # ensure we didn't try to subscribe (no email to subscribe with) + self.assertFalse(mock_prepare.called) + @mock.patch('certbot._internal.main.display_ops.get_email') @test_util.patch_get_utility() def test_update_account_with_email(self, mock_utility, mock_email): @@ -1455,7 +1492,7 @@ 'account': mock.patch('certbot._internal.main.account'), 'client': mock.patch('certbot._internal.main.client'), 'get_utility': test_util.patch_get_utility()} - self.mocks = dict((k, v.start()) for k, v in self.patchers.items()) + self.mocks = {k: v.start() for k, v in self.patchers.items()} def tearDown(self): for patch in self.patchers.values(): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/certbot-1.7.0/tests/renewal_test.py new/certbot-1.9.0/tests/renewal_test.py --- old/certbot-1.7.0/tests/renewal_test.py 2020-08-04 20:20:15.000000000 +0200 +++ new/certbot-1.9.0/tests/renewal_test.py 2020-10-06 20:39:49.000000000 +0200 @@ -3,7 +3,7 @@ try: import mock -except ImportError: # pragma: no cover +except ImportError: # pragma: no cover from unittest import mock from acme import challenges @@ -54,6 +54,26 @@ self.assertEqual(self.config.webroot_map, {}) self.assertEqual(self.config.webroot_path, ['/var/www/test']) + def test_reuse_key_renewal_params(self): + self.config.rsa_key_size = 'INVALID_VALUE' + self.config.reuse_key = True + self.config.dry_run = True + config = configuration.NamespaceConfig(self.config) + + rc_path = test_util.make_lineage( + self.config.config_dir, 'sample-renewal.conf') + lineage = storage.RenewableCert(rc_path, config) + + le_client = mock.MagicMock() + le_client.obtain_certificate.return_value = (None, None, None, None) + + from certbot._internal import renewal + + with mock.patch('certbot._internal.renewal.hooks.renew_hook'): + renewal.renew_cert(self.config, None, le_client, lineage) + + assert self.config.rsa_key_size == 2048 + class RestoreRequiredConfigElementsTest(test_util.ConfigTestCase): """Tests for certbot._internal.renewal.restore_required_config_elements."""
