From d5de24d9fcab7d0c60174478bcfab8418f8ce94b Mon Sep 17 00:00:00 2001 From: Adrien Ferrand Date: Fri, 12 Apr 2019 22:32:52 +0200 Subject: [PATCH] [Windows] Security model for files permissions - STEP 2 (#6895) This PR is the second part of #6497 to ease the integration, following the new plan propose by @bmw here: #6497 (comment) This PR creates the module certbot.compat.os, that delegates everything to os, and that will be the safeguard against problematic methods of the standard module. On top of that, a quality check wrapper is called in the lint tox environment. This wrapper calls pylint and ensures that standard os module is no used directly in the certbot codebase. Finally local oldest requirements are updated to ensure that tests will take the new logic when running. * Add executable permissions * Add the delegate certbot.compat.os module, add check coding style to enforce usage of certbot.compat.os instead of standard os * Load certbot.compat.os instead of os * Move existing compat test * Update local oldest requirements * Import sys * Update account_test.py * Update os.py * Update os.py * Update local oldest requirements * Implement the new linter_plugin * Fix local oldest for nginx * Remove check coding style * Update linter_plugin.py * Add several comments * Update the setup.py * Add documentation * Update acme dependencies * Update certbot/compat/os.py * Update docs/contributing.rst * Update linter_plugin.py * Handle os.path. Simplify checker. * Add a comment to a reference implementation * Update changelog * Fix module registering * Update docs/contributing.rst * Update config and changelog --- .pylintrc | 2 +- CHANGELOG.md | 18 ++++++ certbot-apache/certbot_apache/apache_util.py | 3 +- certbot-apache/certbot_apache/configurator.py | 4 +- certbot-apache/certbot_apache/display_ops.py | 6 +- certbot-apache/certbot_apache/http_01.py | 5 +- .../certbot_apache/override_debian.py | 5 +- certbot-apache/certbot_apache/parser.py | 3 +- .../tests/augeas_configurator_test.py | 2 +- .../certbot_apache/tests/centos6_test.py | 6 +- .../certbot_apache/tests/centos_test.py | 3 +- .../tests/complex_parsing_test.py | 2 +- .../certbot_apache/tests/configurator_test.py | 6 +- .../certbot_apache/tests/debian_test.py | 2 +- .../certbot_apache/tests/gentoo_test.py | 5 +- .../certbot_apache/tests/http_01_test.py | 4 +- .../certbot_apache/tests/parser_test.py | 2 +- certbot-apache/certbot_apache/tests/util.py | 4 +- certbot-apache/docs/conf.py | 2 +- certbot-apache/local-oldest-requirements.txt | 4 +- certbot-apache/setup.py | 4 +- .../dns_cloudflare_test.py | 2 +- .../local-oldest-requirements.txt | 4 +- certbot-dns-cloudflare/setup.py | 4 +- .../certbot_dns_cloudxns/dns_cloudxns_test.py | 2 +- .../local-oldest-requirements.txt | 2 +- certbot-dns-cloudxns/setup.py | 2 +- .../dns_digitalocean_test.py | 2 +- .../local-oldest-requirements.txt | 4 +- certbot-dns-digitalocean/setup.py | 4 +- .../certbot_dns_dnsimple/dns_dnsimple_test.py | 2 +- .../local-oldest-requirements.txt | 2 +- certbot-dns-dnsimple/setup.py | 2 +- .../dns_dnsmadeeasy_test.py | 2 +- .../local-oldest-requirements.txt | 2 +- certbot-dns-dnsmadeeasy/setup.py | 2 +- .../certbot_dns_gehirn/dns_gehirn_test.py | 2 +- .../local-oldest-requirements.txt | 2 +- certbot-dns-gehirn/setup.py | 2 +- .../certbot_dns_google/dns_google_test.py | 2 +- .../local-oldest-requirements.txt | 4 +- certbot-dns-google/setup.py | 4 +- .../certbot_dns_linode/dns_linode_test.py | 2 +- .../local-oldest-requirements.txt | 2 +- certbot-dns-linode/setup.py | 2 +- .../certbot_dns_luadns/dns_luadns_test.py | 2 +- .../local-oldest-requirements.txt | 2 +- certbot-dns-luadns/setup.py | 2 +- .../certbot_dns_nsone/dns_nsone_test.py | 2 +- .../local-oldest-requirements.txt | 2 +- certbot-dns-nsone/setup.py | 2 +- .../certbot_dns_ovh/dns_ovh_test.py | 2 +- certbot-dns-ovh/local-oldest-requirements.txt | 2 +- certbot-dns-ovh/setup.py | 2 +- .../certbot_dns_rfc2136/dns_rfc2136_test.py | 2 +- .../local-oldest-requirements.txt | 4 +- certbot-dns-rfc2136/setup.py | 4 +- .../certbot_dns_route53/dns_route53_test.py | 2 +- .../local-oldest-requirements.txt | 4 +- certbot-dns-route53/setup.py | 4 +- .../dns_sakuracloud_test.py | 2 +- .../local-oldest-requirements.txt | 2 +- certbot-dns-sakuracloud/setup.py | 2 +- certbot-nginx/certbot_nginx/configurator.py | 2 +- certbot-nginx/certbot_nginx/http_01.py | 2 +- certbot-nginx/certbot_nginx/parser.py | 2 +- .../certbot_nginx/tests/configurator_test.py | 5 +- .../certbot_nginx/tests/parser_test.py | 5 +- certbot-nginx/certbot_nginx/tests/util.py | 2 +- certbot-nginx/docs/conf.py | 2 +- certbot-nginx/local-oldest-requirements.txt | 2 +- certbot-nginx/setup.py | 2 +- certbot-postfix/certbot_postfix/installer.py | 14 ++--- .../certbot_postfix/tests/installer_test.py | 4 +- certbot-postfix/docs/conf.py | 2 +- certbot-postfix/local-oldest-requirements.txt | 4 +- certbot-postfix/setup.py | 4 +- certbot/account.py | 2 +- certbot/cert_manager.py | 2 +- certbot/cli.py | 11 ++-- certbot/client.py | 2 +- certbot/compat/misc.py | 8 +-- certbot/compat/os.py | 31 ++++++++++ certbot/configuration.py | 2 +- certbot/constants.py | 2 +- certbot/crypto_util.py | 2 +- certbot/display/ops.py | 2 +- certbot/display/util.py | 2 +- certbot/error_handler.py | 2 +- certbot/hooks.py | 7 +-- certbot/lock.py | 5 +- certbot/log.py | 2 +- certbot/main.py | 2 +- certbot/plugins/common.py | 4 +- certbot/plugins/common_test.py | 5 +- certbot/plugins/dns_common.py | 3 +- certbot/plugins/dns_common_test.py | 2 +- certbot/plugins/dns_test_common.py | 4 +- certbot/plugins/manual.py | 5 +- certbot/plugins/manual_test.py | 7 +-- certbot/plugins/selection.py | 3 +- certbot/plugins/selection_test.py | 2 +- certbot/plugins/storage.py | 3 +- certbot/plugins/storage_test.py | 5 +- certbot/plugins/util.py | 2 +- certbot/plugins/util_test.py | 4 +- certbot/plugins/webroot.py | 5 +- certbot/plugins/webroot_test.py | 4 +- certbot/renewal.py | 17 +++--- certbot/reverter.py | 4 +- certbot/storage.py | 2 +- certbot/tests/account_test.py | 4 +- certbot/tests/cert_manager_test.py | 4 +- certbot/tests/cli_test.py | 10 ++-- certbot/tests/client_test.py | 4 +- certbot/tests/compat/__init__.py | 0 certbot/tests/{ => compat}/compat_test.py | 3 +- certbot/tests/configuration_test.py | 2 +- certbot/tests/crypto_util_test.py | 5 +- certbot/tests/display/completer_test.py | 5 +- certbot/tests/display/ops_test.py | 9 +-- certbot/tests/error_handler_test.py | 4 +- certbot/tests/hook_test.py | 4 +- certbot/tests/lock_test.py | 2 +- certbot/tests/log_test.py | 3 +- certbot/tests/main_test.py | 2 +- certbot/tests/reverter_test.py | 2 +- certbot/tests/storage_test.py | 2 +- certbot/tests/util.py | 2 +- certbot/tests/util_test.py | 2 +- certbot/util.py | 2 +- docs/contributing.rst | 17 ++++++ linter_plugin.py | 60 ++++++++++++------- 133 files changed, 321 insertions(+), 240 deletions(-) create mode 100644 certbot/compat/os.py create mode 100644 certbot/tests/compat/__init__.py rename certbot/tests/{ => compat}/compat_test.py (96%) diff --git a/.pylintrc b/.pylintrc index 0284c68a0..bd4eab11a 100644 --- a/.pylintrc +++ b/.pylintrc @@ -22,7 +22,7 @@ persistent=yes # List of plugins (as comma separated values of python modules names) to load, # usually to register additional checkers. -load-plugins= +load-plugins=linter_plugin [MESSAGES CONTROL] diff --git a/CHANGELOG.md b/CHANGELOG.md index e05808edc..89da42c80 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ Certbot adheres to [Semantic Versioning](https://semver.org/). configuration test error is detected. This has to be done due to the way Fedora now generates the self signed certificate files upon first restart. +* Updated Certbot and its plugins to improve the handling of file system permissions + on Windows as a step towards adding proper Windows support to Certbot. ### Fixed @@ -23,7 +25,23 @@ Despite us having broken lockstep, we are continuing to release new versions of all Certbot components during releases for the time being, however, the only package with changes other than its version number was: +* certbot * certbot-apache +* certbot-dns-cloudflare +* certbot-dns-cloudxns +* certbot-dns-digitalocean +* certbot-dns-dnsimple +* certbot-dns-dnsmadeeasy +* certbot-dns-gehirn +* certbot-dns-google +* certbot-dns-linode +* certbot-dns-luadns +* certbot-dns-nsone +* certbot-dns-ovh +* certbot-dns-rfc2136 +* certbot-dns-route53 +* certbot-dns-sakuracloud +* certbot-nginx More details about these changes can be found on our GitHub repo. diff --git a/certbot-apache/certbot_apache/apache_util.py b/certbot-apache/certbot_apache/apache_util.py index 62342004f..7a2ecf49b 100644 --- a/certbot-apache/certbot_apache/apache_util.py +++ b/certbot-apache/certbot_apache/apache_util.py @@ -1,8 +1,9 @@ """ Utility functions for certbot-apache plugin """ import binascii -import os from certbot import util +from certbot.compat import os + def get_mod_deps(mod_name): """Get known module dependencies. diff --git a/certbot-apache/certbot_apache/configurator.py b/certbot-apache/certbot_apache/configurator.py index b59bc0460..9174143a4 100644 --- a/certbot-apache/certbot_apache/configurator.py +++ b/certbot-apache/certbot_apache/configurator.py @@ -3,7 +3,6 @@ import copy import fnmatch import logging -import os import re import socket import time @@ -17,13 +16,14 @@ import zope.component import zope.interface from acme import challenges -from acme.magic_typing import Any, DefaultDict, Dict, List, Set, Union # pylint: disable=unused-import, no-name-in-module +from acme.magic_typing import DefaultDict, Dict, List, Set, Union # pylint: disable=unused-import, no-name-in-module from certbot import errors from certbot import interfaces from certbot import util from certbot.achallenges import KeyAuthorizationAnnotatedChallenge # pylint: disable=unused-import +from certbot.compat import os from certbot.plugins import common from certbot.plugins.util import path_surgery from certbot.plugins.enhancements import AutoHSTSEnhancement diff --git a/certbot-apache/certbot_apache/display_ops.py b/certbot-apache/certbot_apache/display_ops.py index 9e036bbcd..2639eabd1 100644 --- a/certbot-apache/certbot_apache/display_ops.py +++ b/certbot-apache/certbot_apache/display_ops.py @@ -1,14 +1,12 @@ """Contains UI methods for Apache operations.""" import logging -import os import zope.component +import certbot.display.util as display_util from certbot import errors from certbot import interfaces - -import certbot.display.util as display_util - +from certbot.compat import os logger = logging.getLogger(__name__) diff --git a/certbot-apache/certbot_apache/http_01.py b/certbot-apache/certbot_apache/http_01.py index 962433415..1d1f99919 100644 --- a/certbot-apache/certbot_apache/http_01.py +++ b/certbot-apache/certbot_apache/http_01.py @@ -1,15 +1,18 @@ """A class that performs HTTP-01 challenges for Apache""" import logging -import os from acme.magic_typing import List, Set # pylint: disable=unused-import, no-name-in-module + from certbot import errors +from certbot.compat import os from certbot.plugins import common + from certbot_apache.obj import VirtualHost # pylint: disable=unused-import from certbot_apache.parser import get_aug_path logger = logging.getLogger(__name__) + class ApacheHttp01(common.TLSSNI01): """Class that performs HTTP-01 challenges within the Apache configurator.""" diff --git a/certbot-apache/certbot_apache/override_debian.py b/certbot-apache/certbot_apache/override_debian.py index f4bdd2bc9..5706ce760 100644 --- a/certbot-apache/certbot_apache/override_debian.py +++ b/certbot-apache/certbot_apache/override_debian.py @@ -1,19 +1,20 @@ """ Distribution specific override class for Debian family (Ubuntu/Debian) """ import logging -import os -import pkg_resources +import pkg_resources import zope.interface from certbot import errors from certbot import interfaces from certbot import util +from certbot.compat import os from certbot_apache import apache_util from certbot_apache import configurator logger = logging.getLogger(__name__) + @zope.interface.provider(interfaces.IPluginFactory) class DebianConfigurator(configurator.ApacheConfigurator): """Debian specific ApacheConfigurator override class""" diff --git a/certbot-apache/certbot_apache/parser.py b/certbot-apache/certbot_apache/parser.py index 1e6f956b1..95b0930a0 100644 --- a/certbot-apache/certbot_apache/parser.py +++ b/certbot-apache/certbot_apache/parser.py @@ -2,7 +2,6 @@ import copy import fnmatch import logging -import os import re import subprocess import sys @@ -10,7 +9,9 @@ import sys import six from acme.magic_typing import Dict, List, Set # pylint: disable=unused-import, no-name-in-module + from certbot import errors +from certbot.compat import os logger = logging.getLogger(__name__) diff --git a/certbot-apache/certbot_apache/tests/augeas_configurator_test.py b/certbot-apache/certbot_apache/tests/augeas_configurator_test.py index c121ecdf3..bfe3b7f16 100644 --- a/certbot-apache/certbot_apache/tests/augeas_configurator_test.py +++ b/certbot-apache/certbot_apache/tests/augeas_configurator_test.py @@ -1,11 +1,11 @@ """Test for certbot_apache.augeas_configurator.""" -import os import shutil import unittest import mock from certbot import errors +from certbot.compat import os from certbot_apache.tests import util diff --git a/certbot-apache/certbot_apache/tests/centos6_test.py b/certbot-apache/certbot_apache/tests/centos6_test.py index ea8a85ed7..0d093aca8 100644 --- a/certbot-apache/certbot_apache/tests/centos6_test.py +++ b/certbot-apache/certbot_apache/tests/centos6_test.py @@ -1,12 +1,14 @@ """Test for certbot_apache.configurator for CentOS 6 overrides""" -import os import unittest +from certbot.compat import os +from certbot.errors import MisconfigurationError + from certbot_apache import obj from certbot_apache import override_centos from certbot_apache import parser from certbot_apache.tests import util -from certbot.errors import MisconfigurationError + def get_vh_truth(temp_dir, config_name): """Return the ground truth for the specified directory.""" diff --git a/certbot-apache/certbot_apache/tests/centos_test.py b/certbot-apache/certbot_apache/tests/centos_test.py index c5a51c749..a0c1636b0 100644 --- a/certbot-apache/certbot_apache/tests/centos_test.py +++ b/certbot-apache/certbot_apache/tests/centos_test.py @@ -1,15 +1,16 @@ """Test for certbot_apache.configurator for Centos overrides""" -import os import unittest import mock from certbot import errors +from certbot.compat import os from certbot_apache import obj from certbot_apache import override_centos from certbot_apache.tests import util + def get_vh_truth(temp_dir, config_name): """Return the ground truth for the specified directory.""" prefix = os.path.join( diff --git a/certbot-apache/certbot_apache/tests/complex_parsing_test.py b/certbot-apache/certbot_apache/tests/complex_parsing_test.py index a296fb0eb..8712eb5bf 100644 --- a/certbot-apache/certbot_apache/tests/complex_parsing_test.py +++ b/certbot-apache/certbot_apache/tests/complex_parsing_test.py @@ -1,9 +1,9 @@ """Tests for certbot_apache.parser.""" -import os import shutil import unittest from certbot import errors +from certbot.compat import os from certbot_apache.tests import util diff --git a/certbot-apache/certbot_apache/tests/configurator_test.py b/certbot-apache/certbot_apache/tests/configurator_test.py index 7842eaaac..5b2884eb2 100644 --- a/certbot-apache/certbot_apache/tests/configurator_test.py +++ b/certbot-apache/certbot_apache/tests/configurator_test.py @@ -1,7 +1,6 @@ # pylint: disable=too-many-public-methods,too-many-lines """Test for certbot_apache.configurator.""" import copy -import os import shutil import socket import tempfile @@ -16,15 +15,14 @@ from acme import challenges from certbot import achallenges from certbot import crypto_util from certbot import errors - +from certbot.compat import os from certbot.tests import acme_util from certbot.tests import util as certbot_util from certbot_apache import apache_util from certbot_apache import constants -from certbot_apache import parser from certbot_apache import obj - +from certbot_apache import parser from certbot_apache.tests import util diff --git a/certbot-apache/certbot_apache/tests/debian_test.py b/certbot-apache/certbot_apache/tests/debian_test.py index bb1d64278..f1d5843a5 100644 --- a/certbot-apache/certbot_apache/tests/debian_test.py +++ b/certbot-apache/certbot_apache/tests/debian_test.py @@ -1,11 +1,11 @@ """Test for certbot_apache.configurator for Debian overrides""" -import os import shutil import unittest import mock from certbot import errors +from certbot.compat import os from certbot_apache import apache_util from certbot_apache import obj diff --git a/certbot-apache/certbot_apache/tests/gentoo_test.py b/certbot-apache/certbot_apache/tests/gentoo_test.py index f61165a3d..dd01e9170 100644 --- a/certbot-apache/certbot_apache/tests/gentoo_test.py +++ b/certbot-apache/certbot_apache/tests/gentoo_test.py @@ -1,15 +1,16 @@ """Test for certbot_apache.configurator for Gentoo overrides""" -import os import unittest import mock from certbot import errors +from certbot.compat import os -from certbot_apache import override_gentoo from certbot_apache import obj +from certbot_apache import override_gentoo from certbot_apache.tests import util + def get_vh_truth(temp_dir, config_name): """Return the ground truth for the specified directory.""" prefix = os.path.join( diff --git a/certbot-apache/certbot_apache/tests/http_01_test.py b/certbot-apache/certbot_apache/tests/http_01_test.py index 7a950ad7f..a6af68037 100644 --- a/certbot-apache/certbot_apache/tests/http_01_test.py +++ b/certbot-apache/certbot_apache/tests/http_01_test.py @@ -1,5 +1,4 @@ """Test for certbot_apache.http_01.""" -import os import unittest import mock @@ -8,8 +7,9 @@ from acme.magic_typing import List # pylint: disable=unused-import, no-name-in- from certbot import achallenges from certbot import errors - +from certbot.compat import os from certbot.tests import acme_util + from certbot_apache.parser import get_aug_path from certbot_apache.tests import util diff --git a/certbot-apache/certbot_apache/tests/parser_test.py b/certbot-apache/certbot_apache/tests/parser_test.py index dd12e4a49..ef4412a58 100644 --- a/certbot-apache/certbot_apache/tests/parser_test.py +++ b/certbot-apache/certbot_apache/tests/parser_test.py @@ -1,5 +1,4 @@ """Tests for certbot_apache.parser.""" -import os import shutil import unittest @@ -7,6 +6,7 @@ import augeas import mock from certbot import errors +from certbot.compat import os from certbot_apache.tests import util diff --git a/certbot-apache/certbot_apache/tests/util.py b/certbot-apache/certbot_apache/tests/util.py index 02de6ada4..2ac51540f 100644 --- a/certbot-apache/certbot_apache/tests/util.py +++ b/certbot-apache/certbot_apache/tests/util.py @@ -1,5 +1,4 @@ """Common utilities for certbot_apache.""" -import os import shutil import sys import unittest @@ -9,10 +8,9 @@ import josepy as jose import mock import zope.component +from certbot.compat import os from certbot.display import util as display_util - from certbot.plugins import common - from certbot.tests import util as test_util from certbot_apache import configurator diff --git a/certbot-apache/docs/conf.py b/certbot-apache/docs/conf.py index d2fe15581..5375fd2b8 100644 --- a/certbot-apache/docs/conf.py +++ b/certbot-apache/docs/conf.py @@ -13,7 +13,7 @@ # serve to show the default. import sys -import os +from certbot.compat import os import shlex import mock diff --git a/certbot-apache/local-oldest-requirements.txt b/certbot-apache/local-oldest-requirements.txt index da4df38e1..da509406e 100644 --- a/certbot-apache/local-oldest-requirements.txt +++ b/certbot-apache/local-oldest-requirements.txt @@ -1,3 +1,3 @@ # Remember to update setup.py to match the package versions below. -acme[dev]==0.25.0 -certbot[dev]==0.26.0 +acme[dev]==0.29.0 +-e .[dev] diff --git a/certbot-apache/setup.py b/certbot-apache/setup.py index 978f7752e..deb688fd2 100644 --- a/certbot-apache/setup.py +++ b/certbot-apache/setup.py @@ -9,8 +9,8 @@ version = '0.34.0.dev0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. install_requires = [ - 'acme>=0.25.0', - 'certbot>=0.26.0', + 'acme>=0.29.0', + 'certbot>=0.34.0.dev0', 'mock', 'python-augeas', 'setuptools', diff --git a/certbot-dns-cloudflare/certbot_dns_cloudflare/dns_cloudflare_test.py b/certbot-dns-cloudflare/certbot_dns_cloudflare/dns_cloudflare_test.py index e60d6ff8b..4b9419ca8 100644 --- a/certbot-dns-cloudflare/certbot_dns_cloudflare/dns_cloudflare_test.py +++ b/certbot-dns-cloudflare/certbot_dns_cloudflare/dns_cloudflare_test.py @@ -1,12 +1,12 @@ """Tests for certbot_dns_cloudflare.dns_cloudflare.""" -import os import unittest import CloudFlare import mock from certbot import errors +from certbot.compat import os from certbot.plugins import dns_test_common from certbot.plugins.dns_test_common import DOMAIN from certbot.tests import util as test_util diff --git a/certbot-dns-cloudflare/local-oldest-requirements.txt b/certbot-dns-cloudflare/local-oldest-requirements.txt index ab4ff195f..da509406e 100644 --- a/certbot-dns-cloudflare/local-oldest-requirements.txt +++ b/certbot-dns-cloudflare/local-oldest-requirements.txt @@ -1,3 +1,3 @@ # Remember to update setup.py to match the package versions below. -acme[dev]==0.21.1 -certbot[dev]==0.21.1 +acme[dev]==0.29.0 +-e .[dev] diff --git a/certbot-dns-cloudflare/setup.py b/certbot-dns-cloudflare/setup.py index 878ecd5f9..971ce7be8 100644 --- a/certbot-dns-cloudflare/setup.py +++ b/certbot-dns-cloudflare/setup.py @@ -7,8 +7,8 @@ version = '0.34.0.dev0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. install_requires = [ - 'acme>=0.21.1', - 'certbot>=0.21.1', + 'acme>=0.29.0', + 'certbot>=0.34.0.dev0', 'cloudflare>=1.5.1', 'mock', 'setuptools', diff --git a/certbot-dns-cloudxns/certbot_dns_cloudxns/dns_cloudxns_test.py b/certbot-dns-cloudxns/certbot_dns_cloudxns/dns_cloudxns_test.py index c9bad23ab..6bc1e1f79 100644 --- a/certbot-dns-cloudxns/certbot_dns_cloudxns/dns_cloudxns_test.py +++ b/certbot-dns-cloudxns/certbot_dns_cloudxns/dns_cloudxns_test.py @@ -1,11 +1,11 @@ """Tests for certbot_dns_cloudxns.dns_cloudxns.""" -import os import unittest import mock from requests.exceptions import HTTPError, RequestException +from certbot.compat import os from certbot.plugins import dns_test_common from certbot.plugins import dns_test_common_lexicon from certbot.tests import util as test_util diff --git a/certbot-dns-cloudxns/local-oldest-requirements.txt b/certbot-dns-cloudxns/local-oldest-requirements.txt index 9525206e8..2b3ba9f32 100644 --- a/certbot-dns-cloudxns/local-oldest-requirements.txt +++ b/certbot-dns-cloudxns/local-oldest-requirements.txt @@ -1,3 +1,3 @@ # Remember to update setup.py to match the package versions below. acme[dev]==0.31.0 -certbot[dev]==0.31.0 +-e .[dev] diff --git a/certbot-dns-cloudxns/setup.py b/certbot-dns-cloudxns/setup.py index e2462ac64..6af7bb6e7 100644 --- a/certbot-dns-cloudxns/setup.py +++ b/certbot-dns-cloudxns/setup.py @@ -8,7 +8,7 @@ version = '0.34.0.dev0' # acme/certbot version. install_requires = [ 'acme>=0.31.0', - 'certbot>=0.31.0', + 'certbot>=0.34.0.dev0', 'dns-lexicon>=2.2.1', # Support for >1 TXT record per name 'mock', 'setuptools', diff --git a/certbot-dns-digitalocean/certbot_dns_digitalocean/dns_digitalocean_test.py b/certbot-dns-digitalocean/certbot_dns_digitalocean/dns_digitalocean_test.py index 0e2043f50..3cb49e9fb 100644 --- a/certbot-dns-digitalocean/certbot_dns_digitalocean/dns_digitalocean_test.py +++ b/certbot-dns-digitalocean/certbot_dns_digitalocean/dns_digitalocean_test.py @@ -1,12 +1,12 @@ """Tests for certbot_dns_digitalocean.dns_digitalocean.""" -import os import unittest import digitalocean import mock from certbot import errors +from certbot.compat import os from certbot.plugins import dns_test_common from certbot.plugins.dns_test_common import DOMAIN from certbot.tests import util as test_util diff --git a/certbot-dns-digitalocean/local-oldest-requirements.txt b/certbot-dns-digitalocean/local-oldest-requirements.txt index ab4ff195f..da509406e 100644 --- a/certbot-dns-digitalocean/local-oldest-requirements.txt +++ b/certbot-dns-digitalocean/local-oldest-requirements.txt @@ -1,3 +1,3 @@ # Remember to update setup.py to match the package versions below. -acme[dev]==0.21.1 -certbot[dev]==0.21.1 +acme[dev]==0.29.0 +-e .[dev] diff --git a/certbot-dns-digitalocean/setup.py b/certbot-dns-digitalocean/setup.py index 1cea2f8cc..81803d7da 100644 --- a/certbot-dns-digitalocean/setup.py +++ b/certbot-dns-digitalocean/setup.py @@ -7,8 +7,8 @@ version = '0.34.0.dev0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. install_requires = [ - 'acme>=0.21.1', - 'certbot>=0.21.1', + 'acme>=0.29.0', + 'certbot>=0.34.0.dev0', 'mock', 'python-digitalocean>=1.11', 'setuptools', diff --git a/certbot-dns-dnsimple/certbot_dns_dnsimple/dns_dnsimple_test.py b/certbot-dns-dnsimple/certbot_dns_dnsimple/dns_dnsimple_test.py index d8f3a23ea..d84bf71ed 100644 --- a/certbot-dns-dnsimple/certbot_dns_dnsimple/dns_dnsimple_test.py +++ b/certbot-dns-dnsimple/certbot_dns_dnsimple/dns_dnsimple_test.py @@ -1,11 +1,11 @@ """Tests for certbot_dns_dnsimple.dns_dnsimple.""" -import os import unittest import mock from requests.exceptions import HTTPError +from certbot.compat import os from certbot.plugins import dns_test_common from certbot.plugins import dns_test_common_lexicon from certbot.tests import util as test_util diff --git a/certbot-dns-dnsimple/local-oldest-requirements.txt b/certbot-dns-dnsimple/local-oldest-requirements.txt index 9525206e8..2b3ba9f32 100644 --- a/certbot-dns-dnsimple/local-oldest-requirements.txt +++ b/certbot-dns-dnsimple/local-oldest-requirements.txt @@ -1,3 +1,3 @@ # Remember to update setup.py to match the package versions below. acme[dev]==0.31.0 -certbot[dev]==0.31.0 +-e .[dev] diff --git a/certbot-dns-dnsimple/setup.py b/certbot-dns-dnsimple/setup.py index eac823013..4512f9fc0 100644 --- a/certbot-dns-dnsimple/setup.py +++ b/certbot-dns-dnsimple/setup.py @@ -8,7 +8,7 @@ version = '0.34.0.dev0' # acme/certbot version. install_requires = [ 'acme>=0.31.0', - 'certbot>=0.31.0', + 'certbot>=0.34.0.dev0', 'dns-lexicon>=2.2.1', # Support for >1 TXT record per name 'mock', 'setuptools', diff --git a/certbot-dns-dnsmadeeasy/certbot_dns_dnsmadeeasy/dns_dnsmadeeasy_test.py b/certbot-dns-dnsmadeeasy/certbot_dns_dnsmadeeasy/dns_dnsmadeeasy_test.py index 44a777e1b..f0901664c 100644 --- a/certbot-dns-dnsmadeeasy/certbot_dns_dnsmadeeasy/dns_dnsmadeeasy_test.py +++ b/certbot-dns-dnsmadeeasy/certbot_dns_dnsmadeeasy/dns_dnsmadeeasy_test.py @@ -1,11 +1,11 @@ """Tests for certbot_dns_dnsmadeeasy.dns_dnsmadeeasy.""" -import os import unittest import mock from requests.exceptions import HTTPError +from certbot.compat import os from certbot.plugins import dns_test_common from certbot.plugins import dns_test_common_lexicon from certbot.plugins.dns_test_common import DOMAIN diff --git a/certbot-dns-dnsmadeeasy/local-oldest-requirements.txt b/certbot-dns-dnsmadeeasy/local-oldest-requirements.txt index 9525206e8..2b3ba9f32 100644 --- a/certbot-dns-dnsmadeeasy/local-oldest-requirements.txt +++ b/certbot-dns-dnsmadeeasy/local-oldest-requirements.txt @@ -1,3 +1,3 @@ # Remember to update setup.py to match the package versions below. acme[dev]==0.31.0 -certbot[dev]==0.31.0 +-e .[dev] diff --git a/certbot-dns-dnsmadeeasy/setup.py b/certbot-dns-dnsmadeeasy/setup.py index 9fcc76b7e..51c6637a9 100644 --- a/certbot-dns-dnsmadeeasy/setup.py +++ b/certbot-dns-dnsmadeeasy/setup.py @@ -8,7 +8,7 @@ version = '0.34.0.dev0' # acme/certbot version. install_requires = [ 'acme>=0.31.0', - 'certbot>=0.31.0', + 'certbot>=0.34.0.dev0', 'dns-lexicon>=2.2.1', # Support for >1 TXT record per name 'mock', 'setuptools', diff --git a/certbot-dns-gehirn/certbot_dns_gehirn/dns_gehirn_test.py b/certbot-dns-gehirn/certbot_dns_gehirn/dns_gehirn_test.py index b771c103e..5a591392b 100644 --- a/certbot-dns-gehirn/certbot_dns_gehirn/dns_gehirn_test.py +++ b/certbot-dns-gehirn/certbot_dns_gehirn/dns_gehirn_test.py @@ -1,11 +1,11 @@ """Tests for certbot_dns_gehirn.dns_gehirn.""" -import os import unittest import mock from requests.exceptions import HTTPError +from certbot.compat import os from certbot.plugins import dns_test_common from certbot.plugins import dns_test_common_lexicon from certbot.plugins.dns_test_common import DOMAIN diff --git a/certbot-dns-gehirn/local-oldest-requirements.txt b/certbot-dns-gehirn/local-oldest-requirements.txt index 9525206e8..2b3ba9f32 100644 --- a/certbot-dns-gehirn/local-oldest-requirements.txt +++ b/certbot-dns-gehirn/local-oldest-requirements.txt @@ -1,3 +1,3 @@ # Remember to update setup.py to match the package versions below. acme[dev]==0.31.0 -certbot[dev]==0.31.0 +-e .[dev] diff --git a/certbot-dns-gehirn/setup.py b/certbot-dns-gehirn/setup.py index e21b6bcc4..deb5c442d 100644 --- a/certbot-dns-gehirn/setup.py +++ b/certbot-dns-gehirn/setup.py @@ -7,7 +7,7 @@ version = '0.34.0.dev0' # Please update tox.ini when modifying dependency version requirements install_requires = [ 'acme>=0.31.0', - 'certbot>=0.31.0', + 'certbot>=0.34.0.dev0', 'dns-lexicon>=2.1.22', 'mock', 'setuptools', diff --git a/certbot-dns-google/certbot_dns_google/dns_google_test.py b/certbot-dns-google/certbot_dns_google/dns_google_test.py index 2b081885b..288357bc1 100644 --- a/certbot-dns-google/certbot_dns_google/dns_google_test.py +++ b/certbot-dns-google/certbot_dns_google/dns_google_test.py @@ -1,6 +1,5 @@ """Tests for certbot_dns_google.dns_google.""" -import os import unittest import mock @@ -10,6 +9,7 @@ from googleapiclient.http import HttpMock from httplib2 import ServerNotFoundError from certbot import errors +from certbot.compat import os from certbot.errors import PluginError from certbot.plugins import dns_test_common from certbot.plugins.dns_test_common import DOMAIN diff --git a/certbot-dns-google/local-oldest-requirements.txt b/certbot-dns-google/local-oldest-requirements.txt index ab4ff195f..da509406e 100644 --- a/certbot-dns-google/local-oldest-requirements.txt +++ b/certbot-dns-google/local-oldest-requirements.txt @@ -1,3 +1,3 @@ # Remember to update setup.py to match the package versions below. -acme[dev]==0.21.1 -certbot[dev]==0.21.1 +acme[dev]==0.29.0 +-e .[dev] diff --git a/certbot-dns-google/setup.py b/certbot-dns-google/setup.py index 67f31b924..176c74968 100644 --- a/certbot-dns-google/setup.py +++ b/certbot-dns-google/setup.py @@ -7,8 +7,8 @@ version = '0.34.0.dev0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. install_requires = [ - 'acme>=0.21.1', - 'certbot>=0.21.1', + 'acme>=0.29.0', + 'certbot>=0.34.0.dev0', # 1.5 is the first version that supports oauth2client>=2.0 'google-api-python-client>=1.5', 'mock', diff --git a/certbot-dns-linode/certbot_dns_linode/dns_linode_test.py b/certbot-dns-linode/certbot_dns_linode/dns_linode_test.py index 2a0ee49f7..c1a4e0ec0 100644 --- a/certbot-dns-linode/certbot_dns_linode/dns_linode_test.py +++ b/certbot-dns-linode/certbot_dns_linode/dns_linode_test.py @@ -1,10 +1,10 @@ """Tests for certbot_dns_linode.dns_linode.""" -import os import unittest import mock +from certbot.compat import os from certbot.plugins import dns_test_common from certbot.plugins import dns_test_common_lexicon from certbot.tests import util as test_util diff --git a/certbot-dns-linode/local-oldest-requirements.txt b/certbot-dns-linode/local-oldest-requirements.txt index 9525206e8..2b3ba9f32 100644 --- a/certbot-dns-linode/local-oldest-requirements.txt +++ b/certbot-dns-linode/local-oldest-requirements.txt @@ -1,3 +1,3 @@ # Remember to update setup.py to match the package versions below. acme[dev]==0.31.0 -certbot[dev]==0.31.0 +-e .[dev] diff --git a/certbot-dns-linode/setup.py b/certbot-dns-linode/setup.py index 57305e83a..e43ab8de9 100644 --- a/certbot-dns-linode/setup.py +++ b/certbot-dns-linode/setup.py @@ -6,7 +6,7 @@ version = '0.34.0.dev0' # Please update tox.ini when modifying dependency version requirements install_requires = [ 'acme>=0.31.0', - 'certbot>=0.31.0', + 'certbot>=0.34.0.dev0', 'dns-lexicon>=2.2.1', 'mock', 'setuptools', diff --git a/certbot-dns-luadns/certbot_dns_luadns/dns_luadns_test.py b/certbot-dns-luadns/certbot_dns_luadns/dns_luadns_test.py index bf77e03e4..73cef6521 100644 --- a/certbot-dns-luadns/certbot_dns_luadns/dns_luadns_test.py +++ b/certbot-dns-luadns/certbot_dns_luadns/dns_luadns_test.py @@ -1,11 +1,11 @@ """Tests for certbot_dns_luadns.dns_luadns.""" -import os import unittest import mock from requests.exceptions import HTTPError +from certbot.compat import os from certbot.plugins import dns_test_common from certbot.plugins import dns_test_common_lexicon from certbot.tests import util as test_util diff --git a/certbot-dns-luadns/local-oldest-requirements.txt b/certbot-dns-luadns/local-oldest-requirements.txt index 9525206e8..2b3ba9f32 100644 --- a/certbot-dns-luadns/local-oldest-requirements.txt +++ b/certbot-dns-luadns/local-oldest-requirements.txt @@ -1,3 +1,3 @@ # Remember to update setup.py to match the package versions below. acme[dev]==0.31.0 -certbot[dev]==0.31.0 +-e .[dev] diff --git a/certbot-dns-luadns/setup.py b/certbot-dns-luadns/setup.py index 2d4478dd1..ef77e4143 100644 --- a/certbot-dns-luadns/setup.py +++ b/certbot-dns-luadns/setup.py @@ -8,7 +8,7 @@ version = '0.34.0.dev0' # acme/certbot version. install_requires = [ 'acme>=0.31.0', - 'certbot>=0.31.0', + 'certbot>=0.34.0.dev0', 'dns-lexicon>=2.2.1', # Support for >1 TXT record per name 'mock', 'setuptools', diff --git a/certbot-dns-nsone/certbot_dns_nsone/dns_nsone_test.py b/certbot-dns-nsone/certbot_dns_nsone/dns_nsone_test.py index 56668dd01..b2db2f603 100644 --- a/certbot-dns-nsone/certbot_dns_nsone/dns_nsone_test.py +++ b/certbot-dns-nsone/certbot_dns_nsone/dns_nsone_test.py @@ -1,11 +1,11 @@ """Tests for certbot_dns_nsone.dns_nsone.""" -import os import unittest import mock from requests.exceptions import HTTPError +from certbot.compat import os from certbot.plugins import dns_test_common from certbot.plugins import dns_test_common_lexicon from certbot.plugins.dns_test_common import DOMAIN diff --git a/certbot-dns-nsone/local-oldest-requirements.txt b/certbot-dns-nsone/local-oldest-requirements.txt index 9525206e8..2b3ba9f32 100644 --- a/certbot-dns-nsone/local-oldest-requirements.txt +++ b/certbot-dns-nsone/local-oldest-requirements.txt @@ -1,3 +1,3 @@ # Remember to update setup.py to match the package versions below. acme[dev]==0.31.0 -certbot[dev]==0.31.0 +-e .[dev] diff --git a/certbot-dns-nsone/setup.py b/certbot-dns-nsone/setup.py index 0b66f6f22..7bb7fbbff 100644 --- a/certbot-dns-nsone/setup.py +++ b/certbot-dns-nsone/setup.py @@ -8,7 +8,7 @@ version = '0.34.0.dev0' # acme/certbot version. install_requires = [ 'acme>=0.31.0', - 'certbot>=0.31.0', + 'certbot>=0.34.0.dev0', 'dns-lexicon>=2.2.1', # Support for >1 TXT record per name 'mock', 'setuptools', diff --git a/certbot-dns-ovh/certbot_dns_ovh/dns_ovh_test.py b/certbot-dns-ovh/certbot_dns_ovh/dns_ovh_test.py index f2a10485d..b48a85055 100644 --- a/certbot-dns-ovh/certbot_dns_ovh/dns_ovh_test.py +++ b/certbot-dns-ovh/certbot_dns_ovh/dns_ovh_test.py @@ -1,11 +1,11 @@ """Tests for certbot_dns_ovh.dns_ovh.""" -import os import unittest import mock from requests.exceptions import HTTPError +from certbot.compat import os from certbot.plugins import dns_test_common from certbot.plugins import dns_test_common_lexicon from certbot.tests import util as test_util diff --git a/certbot-dns-ovh/local-oldest-requirements.txt b/certbot-dns-ovh/local-oldest-requirements.txt index 379345762..ed5aa6c87 100644 --- a/certbot-dns-ovh/local-oldest-requirements.txt +++ b/certbot-dns-ovh/local-oldest-requirements.txt @@ -1,4 +1,4 @@ # Remember to update setup.py to match the package versions below. acme[dev]==0.31.0 -certbot[dev]==0.31.0 +-e .[dev] dns-lexicon==2.7.14 diff --git a/certbot-dns-ovh/setup.py b/certbot-dns-ovh/setup.py index 3d6b45017..9a05e69cc 100644 --- a/certbot-dns-ovh/setup.py +++ b/certbot-dns-ovh/setup.py @@ -8,7 +8,7 @@ version = '0.34.0.dev0' # acme/certbot version. install_requires = [ 'acme>=0.31.0', - 'certbot>=0.31.0', + 'certbot>=0.34.0.dev0', 'dns-lexicon>=2.7.14', # Correct proxy use on OVH provider 'mock', 'setuptools', diff --git a/certbot-dns-rfc2136/certbot_dns_rfc2136/dns_rfc2136_test.py b/certbot-dns-rfc2136/certbot_dns_rfc2136/dns_rfc2136_test.py index 30afdbec9..2eb0517f6 100644 --- a/certbot-dns-rfc2136/certbot_dns_rfc2136/dns_rfc2136_test.py +++ b/certbot-dns-rfc2136/certbot_dns_rfc2136/dns_rfc2136_test.py @@ -1,6 +1,5 @@ """Tests for certbot_dns_rfc2136.dns_rfc2136.""" -import os import unittest import dns.flags @@ -9,6 +8,7 @@ import dns.tsig import mock from certbot import errors +from certbot.compat import os from certbot.plugins import dns_test_common from certbot.plugins.dns_test_common import DOMAIN from certbot.tests import util as test_util diff --git a/certbot-dns-rfc2136/local-oldest-requirements.txt b/certbot-dns-rfc2136/local-oldest-requirements.txt index ab4ff195f..da509406e 100644 --- a/certbot-dns-rfc2136/local-oldest-requirements.txt +++ b/certbot-dns-rfc2136/local-oldest-requirements.txt @@ -1,3 +1,3 @@ # Remember to update setup.py to match the package versions below. -acme[dev]==0.21.1 -certbot[dev]==0.21.1 +acme[dev]==0.29.0 +-e .[dev] diff --git a/certbot-dns-rfc2136/setup.py b/certbot-dns-rfc2136/setup.py index 321e3c29a..8e1d37650 100644 --- a/certbot-dns-rfc2136/setup.py +++ b/certbot-dns-rfc2136/setup.py @@ -7,8 +7,8 @@ version = '0.34.0.dev0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. install_requires = [ - 'acme>=0.21.1', - 'certbot>=0.21.1', + 'acme>=0.29.0', + 'certbot>=0.34.0.dev0', 'dnspython', 'mock', 'setuptools', diff --git a/certbot-dns-route53/certbot_dns_route53/dns_route53_test.py b/certbot-dns-route53/certbot_dns_route53/dns_route53_test.py index 71326c2af..36c391690 100644 --- a/certbot-dns-route53/certbot_dns_route53/dns_route53_test.py +++ b/certbot-dns-route53/certbot_dns_route53/dns_route53_test.py @@ -1,12 +1,12 @@ """Tests for certbot_dns_route53.dns_route53.Authenticator""" -import os import unittest import mock from botocore.exceptions import NoCredentialsError, ClientError from certbot import errors +from certbot.compat import os from certbot.plugins import dns_test_common from certbot.plugins.dns_test_common import DOMAIN diff --git a/certbot-dns-route53/local-oldest-requirements.txt b/certbot-dns-route53/local-oldest-requirements.txt index ca12653b0..da509406e 100644 --- a/certbot-dns-route53/local-oldest-requirements.txt +++ b/certbot-dns-route53/local-oldest-requirements.txt @@ -1,3 +1,3 @@ # Remember to update setup.py to match the package versions below. -acme[dev]==0.25.0 -certbot[dev]==0.21.1 +acme[dev]==0.29.0 +-e .[dev] diff --git a/certbot-dns-route53/setup.py b/certbot-dns-route53/setup.py index 196d80b08..787d4a555 100644 --- a/certbot-dns-route53/setup.py +++ b/certbot-dns-route53/setup.py @@ -6,8 +6,8 @@ version = '0.34.0.dev0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. install_requires = [ - 'acme>=0.25.0', - 'certbot>=0.21.1', + 'acme>=0.29.0', + 'certbot>=0.34.0.dev0', 'boto3', 'mock', 'setuptools', diff --git a/certbot-dns-sakuracloud/certbot_dns_sakuracloud/dns_sakuracloud_test.py b/certbot-dns-sakuracloud/certbot_dns_sakuracloud/dns_sakuracloud_test.py index 1d9282f9a..10abc29e2 100644 --- a/certbot-dns-sakuracloud/certbot_dns_sakuracloud/dns_sakuracloud_test.py +++ b/certbot-dns-sakuracloud/certbot_dns_sakuracloud/dns_sakuracloud_test.py @@ -1,11 +1,11 @@ """Tests for certbot_dns_sakuracloud.dns_sakuracloud.""" -import os import unittest import mock from requests.exceptions import HTTPError +from certbot.compat import os from certbot.plugins import dns_test_common from certbot.plugins import dns_test_common_lexicon from certbot.plugins.dns_test_common import DOMAIN diff --git a/certbot-dns-sakuracloud/local-oldest-requirements.txt b/certbot-dns-sakuracloud/local-oldest-requirements.txt index 9525206e8..2b3ba9f32 100644 --- a/certbot-dns-sakuracloud/local-oldest-requirements.txt +++ b/certbot-dns-sakuracloud/local-oldest-requirements.txt @@ -1,3 +1,3 @@ # Remember to update setup.py to match the package versions below. acme[dev]==0.31.0 -certbot[dev]==0.31.0 +-e .[dev] diff --git a/certbot-dns-sakuracloud/setup.py b/certbot-dns-sakuracloud/setup.py index 787e361b1..286b13ee9 100644 --- a/certbot-dns-sakuracloud/setup.py +++ b/certbot-dns-sakuracloud/setup.py @@ -7,7 +7,7 @@ version = '0.34.0.dev0' # Please update tox.ini when modifying dependency version requirements install_requires = [ 'acme>=0.31.0', - 'certbot>=0.31.0', + 'certbot>=0.34.0.dev0', 'dns-lexicon>=2.1.23', 'mock', 'setuptools', diff --git a/certbot-nginx/certbot_nginx/configurator.py b/certbot-nginx/certbot_nginx/configurator.py index 6bf82088b..6da00e513 100644 --- a/certbot-nginx/certbot_nginx/configurator.py +++ b/certbot-nginx/certbot_nginx/configurator.py @@ -1,6 +1,5 @@ """Nginx Configuration""" import logging -import os import re import socket import subprocess @@ -20,6 +19,7 @@ from certbot import errors from certbot import interfaces from certbot import util from certbot.compat import misc +from certbot.compat import os from certbot.plugins import common from certbot_nginx import constants diff --git a/certbot-nginx/certbot_nginx/http_01.py b/certbot-nginx/certbot_nginx/http_01.py index 2e897a8ac..70147a433 100644 --- a/certbot-nginx/certbot_nginx/http_01.py +++ b/certbot-nginx/certbot_nginx/http_01.py @@ -1,12 +1,12 @@ """A class that performs HTTP-01 challenges for Nginx""" import logging -import os from acme import challenges from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module from certbot import errors +from certbot.compat import os from certbot.plugins import common from certbot_nginx import obj diff --git a/certbot-nginx/certbot_nginx/parser.py b/certbot-nginx/certbot_nginx/parser.py index 49f02b741..d50606fc5 100644 --- a/certbot-nginx/certbot_nginx/parser.py +++ b/certbot-nginx/certbot_nginx/parser.py @@ -3,13 +3,13 @@ import copy import functools import glob import logging -import os import re import pyparsing import six from certbot import errors +from certbot.compat import os from certbot_nginx import obj from certbot_nginx import nginxparser diff --git a/certbot-nginx/certbot_nginx/tests/configurator_test.py b/certbot-nginx/certbot_nginx/tests/configurator_test.py index 08e4a56ae..6c3f4f0cf 100644 --- a/certbot-nginx/certbot_nginx/tests/configurator_test.py +++ b/certbot-nginx/certbot_nginx/tests/configurator_test.py @@ -1,17 +1,16 @@ # pylint: disable=too-many-public-methods """Test for certbot_nginx.configurator.""" -import os import unittest -import mock import OpenSSL - +import mock from acme import challenges from acme import messages from certbot import achallenges from certbot import crypto_util from certbot import errors +from certbot.compat import os from certbot.tests import util as certbot_test_util from certbot_nginx import constants diff --git a/certbot-nginx/certbot_nginx/tests/parser_test.py b/certbot-nginx/certbot_nginx/tests/parser_test.py index 126eb2a38..97c542532 100644 --- a/certbot-nginx/certbot_nginx/tests/parser_test.py +++ b/certbot-nginx/certbot_nginx/tests/parser_test.py @@ -1,17 +1,18 @@ """Tests for certbot_nginx.parser.""" import glob -import os import re import shutil import unittest +from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module + from certbot import errors +from certbot.compat import os from certbot_nginx import nginxparser from certbot_nginx import obj from certbot_nginx import parser from certbot_nginx.tests import util -from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module class NginxParserTest(util.NginxTest): #pylint: disable=too-many-public-methods diff --git a/certbot-nginx/certbot_nginx/tests/util.py b/certbot-nginx/certbot_nginx/tests/util.py index 2c5f6f39a..5476333e0 100644 --- a/certbot-nginx/certbot_nginx/tests/util.py +++ b/certbot-nginx/certbot_nginx/tests/util.py @@ -1,6 +1,5 @@ """Common utilities for certbot_nginx.""" import copy -import os import shutil import tempfile import unittest @@ -12,6 +11,7 @@ import pkg_resources import zope.component from certbot import configuration +from certbot.compat import os from certbot.plugins import common from certbot.tests import util as test_util diff --git a/certbot-nginx/docs/conf.py b/certbot-nginx/docs/conf.py index 167abb4fb..d606b6292 100644 --- a/certbot-nginx/docs/conf.py +++ b/certbot-nginx/docs/conf.py @@ -13,7 +13,7 @@ # serve to show the default. import sys -import os +from certbot.compat import os import shlex diff --git a/certbot-nginx/local-oldest-requirements.txt b/certbot-nginx/local-oldest-requirements.txt index 3a59d83ab..da509406e 100644 --- a/certbot-nginx/local-oldest-requirements.txt +++ b/certbot-nginx/local-oldest-requirements.txt @@ -1,3 +1,3 @@ # Remember to update setup.py to match the package versions below. acme[dev]==0.29.0 -certbot[dev]==0.33.0 +-e .[dev] diff --git a/certbot-nginx/setup.py b/certbot-nginx/setup.py index 07c4e5301..a6da1d851 100644 --- a/certbot-nginx/setup.py +++ b/certbot-nginx/setup.py @@ -10,7 +10,7 @@ version = '0.34.0.dev0' # acme/certbot version. install_requires = [ 'acme>=0.29.0', - 'certbot>=0.33.0', + 'certbot>=0.34.0.dev0', 'mock', 'PyOpenSSL', 'pyparsing>=1.5.5', # Python3 support; perhaps unnecessary? diff --git a/certbot-postfix/certbot_postfix/installer.py b/certbot-postfix/certbot_postfix/installer.py index 93afd4de9..b5e4df5ec 100644 --- a/certbot-postfix/certbot_postfix/installer.py +++ b/certbot-postfix/certbot_postfix/installer.py @@ -1,24 +1,24 @@ """certbot installer plugin for postfix.""" import logging -import os -import zope.interface -import zope.component import six +import zope.component +import zope.interface + +# pylint: disable=unused-import, no-name-in-module +from acme.magic_typing import Callable, Dict, List +# pylint: enable=unused-import, no-name-in-module from certbot import errors from certbot import interfaces from certbot import util as certbot_util +from certbot.compat import os from certbot.plugins import common as plugins_common from certbot_postfix import constants from certbot_postfix import postconf from certbot_postfix import util -# pylint: disable=unused-import, no-name-in-module -from acme.magic_typing import Callable, Dict, List -# pylint: enable=unused-import, no-name-in-module - logger = logging.getLogger(__name__) @zope.interface.implementer(interfaces.IInstaller) diff --git a/certbot-postfix/certbot_postfix/tests/installer_test.py b/certbot-postfix/certbot_postfix/tests/installer_test.py index 8222ccb12..a24643379 100644 --- a/certbot-postfix/certbot_postfix/tests/installer_test.py +++ b/certbot-postfix/certbot_postfix/tests/installer_test.py @@ -1,16 +1,16 @@ """Tests for certbot_postfix.installer.""" import copy import functools -import os import unittest from contextlib import contextmanager import mock import pkg_resources import six -from acme.magic_typing import Dict, Tuple # pylint: disable=unused-import, no-name-in-module +from acme.magic_typing import Dict, Tuple # pylint: disable=unused-import,no-name-in-module from certbot import errors +from certbot.compat import os from certbot.tests import util as certbot_test_util diff --git a/certbot-postfix/docs/conf.py b/certbot-postfix/docs/conf.py index 51d99aab5..a2f1a8092 100644 --- a/certbot-postfix/docs/conf.py +++ b/certbot-postfix/docs/conf.py @@ -12,7 +12,7 @@ # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. # -import os +from certbot.compat import os # import sys # sys.path.insert(0, os.path.abspath('.')) diff --git a/certbot-postfix/local-oldest-requirements.txt b/certbot-postfix/local-oldest-requirements.txt index 27652f94e..da509406e 100644 --- a/certbot-postfix/local-oldest-requirements.txt +++ b/certbot-postfix/local-oldest-requirements.txt @@ -1,3 +1,3 @@ # Remember to update setup.py to match the package versions below. -acme[dev]==0.25.0 -certbot[dev]==0.23.0 +acme[dev]==0.29.0 +-e .[dev] diff --git a/certbot-postfix/setup.py b/certbot-postfix/setup.py index 0ff2908df..e708863b2 100644 --- a/certbot-postfix/setup.py +++ b/certbot-postfix/setup.py @@ -5,8 +5,8 @@ from setuptools import find_packages version = '0.26.0.dev0' install_requires = [ - 'acme>=0.25.0', - 'certbot>=0.23.0', + 'acme>=0.29.0', + 'certbot>=0.34.0.dev0', 'setuptools', 'six', 'zope.component', diff --git a/certbot/account.py b/certbot/account.py index 418eb417e..bf5c131db 100644 --- a/certbot/account.py +++ b/certbot/account.py @@ -3,7 +3,6 @@ import datetime import functools import hashlib import logging -import os import shutil import socket @@ -22,6 +21,7 @@ from certbot import errors from certbot import interfaces from certbot import util from certbot.compat import misc +from certbot.compat import os logger = logging.getLogger(__name__) diff --git a/certbot/cert_manager.py b/certbot/cert_manager.py index 5c102beb4..ab929b597 100644 --- a/certbot/cert_manager.py +++ b/certbot/cert_manager.py @@ -1,7 +1,6 @@ """Tools for managing certificates.""" import datetime import logging -import os import re import traceback @@ -17,6 +16,7 @@ from certbot import ocsp from certbot import storage from certbot import util from certbot.compat import misc +from certbot.compat import os from certbot.display import util as display_util logger = logging.getLogger(__name__) diff --git a/certbot/cli.py b/certbot/cli.py index 93c81648b..96f58caf7 100644 --- a/certbot/cli.py +++ b/certbot/cli.py @@ -1,19 +1,17 @@ """Certbot command line argument & config processing.""" # pylint: disable=too-many-lines from __future__ import print_function + import argparse import copy import glob -import logging import logging.handlers -import os import sys import configargparse import six import zope.component import zope.interface - from zope.interface import interfaces as zope_interfaces from acme import challenges @@ -22,18 +20,17 @@ from acme.magic_typing import Any, Dict, Optional # pylint: enable=unused-import, no-name-in-module import certbot - +import certbot.plugins.enhancements as enhancements +import certbot.plugins.selection as plugin_selection from certbot import constants from certbot import crypto_util from certbot import errors from certbot import hooks from certbot import interfaces from certbot import util - +from certbot.compat import os from certbot.display import util as display_util from certbot.plugins import disco as plugins_disco -import certbot.plugins.enhancements as enhancements -import certbot.plugins.selection as plugin_selection logger = logging.getLogger(__name__) diff --git a/certbot/client.py b/certbot/client.py index 3cc073c03..5ec3c4d92 100644 --- a/certbot/client.py +++ b/certbot/client.py @@ -1,7 +1,6 @@ """Certbot client API.""" import datetime import logging -import os import platform import OpenSSL @@ -32,6 +31,7 @@ from certbot import reverter from certbot import storage from certbot import util from certbot.compat import misc +from certbot.compat import os from certbot.display import enhancements from certbot.display import ops as display_ops from certbot.plugins import selection as plugin_selection diff --git a/certbot/compat/misc.py b/certbot/compat/misc.py index 3ea4a7908..2f4ba0c6b 100644 --- a/certbot/compat/misc.py +++ b/certbot/compat/misc.py @@ -2,14 +2,14 @@ This compat module handles various platform specific calls that do not fall into one particular category. """ -import os -import select -import sys -import errno import ctypes +import errno +import select import stat +import sys from certbot import errors +from certbot.compat import os UNPRIVILEGED_SUBCOMMANDS_ALLOWED = [ 'certificates', 'enhance', 'revoke', 'delete', diff --git a/certbot/compat/os.py b/certbot/compat/os.py new file mode 100644 index 000000000..0112fbc73 --- /dev/null +++ b/certbot/compat/os.py @@ -0,0 +1,31 @@ +""" +This compat modules is a wrapper of the core os module that forbids usage of specific operations +(eg. 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). +""" +from __future__ import absolute_import + +# First round of wrapping: we import statically all public attributes exposed by the os module +# This allows in particular to have pylint, mypy, IDEs be aware that most of os members are +# available in certbot.compat.os. +from os import * # type: ignore # pylint: disable=wildcard-import,unused-wildcard-import,redefined-builtin,os-module-forbidden + +# Second round of wrapping: we import dynamically all attributes from the os module that have not +# yet been imported by the first round (static import). This covers in particular the case of +# specific python 3.x versions where not all public attributes are in the special __all__ of os, +# and so not in `from os import *`. +import os as std_os # pylint: disable=os-module-forbidden +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)) + +# Similar to os.path, allow certbot.compat.os.path to behave as a module +std_sys.modules[__name__ + '.path'] = path + +# Clean all remaining importables that are not from the core os module. +del ourselves, std_os, std_sys diff --git a/certbot/configuration.py b/certbot/configuration.py index b5d5bb1e6..cc9cb2d98 100644 --- a/certbot/configuration.py +++ b/certbot/configuration.py @@ -1,6 +1,5 @@ """Certbot user-supplied configuration.""" import copy -import os import zope.interface from six.moves.urllib import parse # pylint: disable=relative-import @@ -10,6 +9,7 @@ from certbot import errors from certbot import interfaces from certbot import util from certbot.compat import misc +from certbot.compat import os @zope.interface.implementer(interfaces.IConfig) diff --git a/certbot/constants.py b/certbot/constants.py index 3b2f7a2d9..c23effe2d 100644 --- a/certbot/constants.py +++ b/certbot/constants.py @@ -1,12 +1,12 @@ """Certbot constants.""" import logging -import os import pkg_resources from acme import challenges from certbot.compat import misc +from certbot.compat import os SETUPTOOLS_PLUGINS_ENTRY_POINT = "certbot.plugins" """Setuptools entry point group name for plugins.""" diff --git a/certbot/crypto_util.py b/certbot/crypto_util.py index f976372c5..281a76668 100644 --- a/certbot/crypto_util.py +++ b/certbot/crypto_util.py @@ -6,7 +6,6 @@ """ import hashlib import logging -import os import warnings import pyrfc3339 @@ -30,6 +29,7 @@ from certbot import errors from certbot import interfaces from certbot import util from certbot.compat import misc +from certbot.compat import os logger = logging.getLogger(__name__) diff --git a/certbot/display/ops.py b/certbot/display/ops.py index 3624a4727..b5f3655fe 100644 --- a/certbot/display/ops.py +++ b/certbot/display/ops.py @@ -1,6 +1,5 @@ """Contains UI methods for LE user operations.""" import logging -import os import zope.component @@ -8,6 +7,7 @@ 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 logger = logging.getLogger(__name__) diff --git a/certbot/display/util.py b/certbot/display/util.py index 6e078137f..91f3bc33c 100644 --- a/certbot/display/util.py +++ b/certbot/display/util.py @@ -1,6 +1,5 @@ """Certbot display.""" import logging -import os import sys import textwrap @@ -10,6 +9,7 @@ from certbot import constants from certbot import errors from certbot import interfaces from certbot.compat import misc +from certbot.compat import os from certbot.display import completer logger = logging.getLogger(__name__) diff --git a/certbot/error_handler.py b/certbot/error_handler.py index 2114fbbed..1a570e48e 100644 --- a/certbot/error_handler.py +++ b/certbot/error_handler.py @@ -1,7 +1,6 @@ """Registers functions to be called if an exception or signal occurs.""" import functools import logging -import os import signal import traceback @@ -10,6 +9,7 @@ from acme.magic_typing import Any, Callable, Dict, List, Union # pylint: enable=unused-import, no-name-in-module from certbot import errors +from certbot.compat import os logger = logging.getLogger(__name__) diff --git a/certbot/hooks.py b/certbot/hooks.py index 7d2e42fcd..7de846ae4 100644 --- a/certbot/hooks.py +++ b/certbot/hooks.py @@ -2,14 +2,13 @@ from __future__ import print_function import logging -import os - from subprocess import Popen, PIPE -from acme.magic_typing import Set, List # pylint: disable=unused-import, no-name-in-module +from acme.magic_typing import Set, List # pylint: disable=unused-import, no-name-in-module + from certbot import errors from certbot import util - +from certbot.compat import os from certbot.plugins import util as plug_util logger = logging.getLogger(__name__) diff --git a/certbot/lock.py b/certbot/lock.py index 760a12b8f..fad8a5175 100644 --- a/certbot/lock.py +++ b/certbot/lock.py @@ -1,7 +1,6 @@ """Implements file locks compatible with Linux and Windows for locking files and directories.""" import errno import logging -import os try: import fcntl # pylint: disable=import-error except ImportError: @@ -10,8 +9,10 @@ except ImportError: else: POSIX_MODE = True +from acme.magic_typing import Optional # pylint: disable=unused-import, no-name-in-module + from certbot import errors -from acme.magic_typing import Optional, Callable # pylint: disable=unused-import, no-name-in-module +from certbot.compat import os logger = logging.getLogger(__name__) diff --git a/certbot/log.py b/certbot/log.py index 84911c1c0..bf444de07 100644 --- a/certbot/log.py +++ b/certbot/log.py @@ -17,7 +17,6 @@ from __future__ import print_function import functools import logging import logging.handlers -import os import sys import tempfile import traceback @@ -28,6 +27,7 @@ from certbot import constants from certbot import errors from certbot import util from certbot.compat import misc +from certbot.compat import os # Logging format CLI_FMT = "%(message)s" diff --git a/certbot/main.py b/certbot/main.py index 570004b2b..5365cd591 100644 --- a/certbot/main.py +++ b/certbot/main.py @@ -4,7 +4,6 @@ from __future__ import print_function import functools import logging.handlers -import os import sys import configobj @@ -33,6 +32,7 @@ from certbot import storage from certbot import updater from certbot import util from certbot.compat import misc +from certbot.compat import os from certbot.display import util as display_util, ops as display_ops from certbot.plugins import disco as plugins_disco from certbot.plugins import enhancements diff --git a/certbot/plugins/common.py b/certbot/plugins/common.py index 78684193b..3dd9534db 100644 --- a/certbot/plugins/common.py +++ b/certbot/plugins/common.py @@ -1,6 +1,5 @@ """Plugin common functions.""" import logging -import os import re import shutil import tempfile @@ -12,6 +11,7 @@ import zope.interface from josepy import util as jose_util from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module + from certbot import achallenges # pylint: disable=unused-import from certbot import constants from certbot import crypto_util @@ -19,7 +19,7 @@ from certbot import errors from certbot import interfaces from certbot import reverter from certbot import util - +from certbot.compat import os from certbot.plugins.storage import PluginStorage logger = logging.getLogger(__name__) diff --git a/certbot/plugins/common_test.py b/certbot/plugins/common_test.py index 103a12499..bce8f833a 100644 --- a/certbot/plugins/common_test.py +++ b/certbot/plugins/common_test.py @@ -1,20 +1,19 @@ """Tests for certbot.plugins.common.""" import functools -import os import shutil import tempfile import unittest +import OpenSSL import josepy as jose import mock -import OpenSSL from acme import challenges from certbot import achallenges from certbot import crypto_util from certbot import errors - +from certbot.compat import os from certbot.tests import acme_util from certbot.tests import util as test_util diff --git a/certbot/plugins/dns_common.py b/certbot/plugins/dns_common.py index 61878a7fd..9be2868b0 100644 --- a/certbot/plugins/dns_common.py +++ b/certbot/plugins/dns_common.py @@ -2,16 +2,17 @@ import abc import logging -import os import stat from time import sleep import configobj import zope.interface + from acme import challenges from certbot import errors from certbot import interfaces +from certbot.compat import os from certbot.display import ops from certbot.display import util as display_util from certbot.plugins import common diff --git a/certbot/plugins/dns_common_test.py b/certbot/plugins/dns_common_test.py index 62c99d579..6741ff8e5 100644 --- a/certbot/plugins/dns_common_test.py +++ b/certbot/plugins/dns_common_test.py @@ -2,12 +2,12 @@ import collections import logging -import os import unittest import mock from certbot import errors +from certbot.compat import os from certbot.display import util as display_util from certbot.plugins import dns_common from certbot.plugins import dns_test_common diff --git a/certbot/plugins/dns_test_common.py b/certbot/plugins/dns_test_common.py index 54b656b20..7f57b9431 100644 --- a/certbot/plugins/dns_test_common.py +++ b/certbot/plugins/dns_test_common.py @@ -1,14 +1,14 @@ """Base test class for DNS authenticators.""" -import os - import configobj import josepy as jose import mock import six + from acme import challenges from certbot import achallenges +from certbot.compat import os from certbot.tests import acme_util from certbot.tests import util as test_util diff --git a/certbot/plugins/manual.py b/certbot/plugins/manual.py index b4d20478a..4bb11de3f 100644 --- a/certbot/plugins/manual.py +++ b/certbot/plugins/manual.py @@ -1,6 +1,4 @@ """Manual authenticator plugin""" -import os - import zope.component import zope.interface @@ -8,10 +6,11 @@ from acme import challenges from acme.magic_typing import Dict # pylint: disable=unused-import, no-name-in-module from certbot import achallenges # pylint: disable=unused-import -from certbot import interfaces from certbot import errors from certbot import hooks +from certbot import interfaces from certbot import reverter +from certbot.compat import os from certbot.plugins import common diff --git a/certbot/plugins/manual_test.py b/certbot/plugins/manual_test.py index 5c869f68e..10dbe73c9 100644 --- a/certbot/plugins/manual_test.py +++ b/certbot/plugins/manual_test.py @@ -1,15 +1,14 @@ """Tests for certbot.plugins.manual""" -import os import unittest import sys -import six import mock +import six from acme import challenges from certbot import errors - +from certbot.compat import os from certbot.tests import acme_util from certbot.tests import util as test_util @@ -73,7 +72,7 @@ class AuthenticatorTest(test_util.TempDirTestCase): self.config.manual_public_ip_logging_ok = True self.config.manual_auth_hook = ( '{0} -c "from __future__ import print_function;' - 'import os; print(os.environ.get(\'CERTBOT_DOMAIN\'));' + 'from certbot.compat import os; print(os.environ.get(\'CERTBOT_DOMAIN\'));' 'print(os.environ.get(\'CERTBOT_TOKEN\', \'notoken\'));' 'print(os.environ.get(\'CERTBOT_VALIDATION\', \'novalidation\'));"' .format(sys.executable)) diff --git a/certbot/plugins/selection.py b/certbot/plugins/selection.py index 0b321d713..39a6b01fc 100644 --- a/certbot/plugins/selection.py +++ b/certbot/plugins/selection.py @@ -1,7 +1,6 @@ """Decide which plugins to use for authentication & installation""" from __future__ import print_function -import os import logging import six @@ -9,7 +8,7 @@ import zope.component from certbot import errors from certbot import interfaces - +from certbot.compat import os from certbot.display import util as display_util logger = logging.getLogger(__name__) diff --git a/certbot/plugins/selection_test.py b/certbot/plugins/selection_test.py index 7ebc2b53b..a2a171c1d 100644 --- a/certbot/plugins/selection_test.py +++ b/certbot/plugins/selection_test.py @@ -1,5 +1,4 @@ """Tests for letsencrypt.plugins.selection""" -import os import sys import unittest @@ -10,6 +9,7 @@ from acme.magic_typing import List # pylint: disable=unused-import, no-name-in- from certbot import errors from certbot import interfaces +from certbot.compat import os from certbot.display import util as display_util from certbot.plugins.disco import PluginsRegistry from certbot.tests import util as test_util diff --git a/certbot/plugins/storage.py b/certbot/plugins/storage.py index ae3ca1889..51350802c 100644 --- a/certbot/plugins/storage.py +++ b/certbot/plugins/storage.py @@ -1,10 +1,11 @@ """Plugin storage class.""" import json import logging -import os from acme.magic_typing import Any, Dict # pylint: disable=unused-import, no-name-in-module + from certbot import errors +from certbot.compat import os logger = logging.getLogger(__name__) diff --git a/certbot/plugins/storage_test.py b/certbot/plugins/storage_test.py index 4b5af5c22..2fa2c0345 100644 --- a/certbot/plugins/storage_test.py +++ b/certbot/plugins/storage_test.py @@ -1,14 +1,15 @@ """Tests for certbot.plugins.storage.PluginStorage""" import json -import os import unittest import mock from certbot import errors +from certbot.compat import os from certbot.plugins import common from certbot.tests import util as test_util + class PluginStorageTest(test_util.ConfigTestCase): """Test for certbot.plugins.storage.PluginStorage""" @@ -71,7 +72,7 @@ class PluginStorageTest(test_util.ConfigTestCase): def test_save_errors_unable_to_write_file(self): mock_open = mock.mock_open() mock_open.side_effect = IOError - with mock.patch("os.open", mock_open): + with mock.patch("certbot.compat.os.open", mock_open): with mock.patch("certbot.plugins.storage.logger.error") as mock_log: self.plugin.storage._data = {"valid": "data"} # pylint: disable=protected-access self.plugin.storage._initialized = True # pylint: disable=protected-access diff --git a/certbot/plugins/util.py b/certbot/plugins/util.py index aac39a579..61f811280 100644 --- a/certbot/plugins/util.py +++ b/certbot/plugins/util.py @@ -1,8 +1,8 @@ """Plugin utilities.""" import logging -import os from certbot import util +from certbot.compat import os logger = logging.getLogger(__name__) diff --git a/certbot/plugins/util_test.py b/certbot/plugins/util_test.py index 8ecd380b8..6ec6f62f4 100644 --- a/certbot/plugins/util_test.py +++ b/certbot/plugins/util_test.py @@ -1,9 +1,11 @@ """Tests for certbot.plugins.util.""" -import os import unittest import mock +from certbot.compat import os + + class GetPrefixTest(unittest.TestCase): """Tests for certbot.plugins.get_prefixes.""" def test_get_prefix(self): diff --git a/certbot/plugins/webroot.py b/certbot/plugins/webroot.py index 205f31fba..1c94b34d3 100644 --- a/certbot/plugins/webroot.py +++ b/certbot/plugins/webroot.py @@ -4,7 +4,6 @@ import collections import errno import json import logging -import os import six import zope.component @@ -19,12 +18,12 @@ from certbot import achallenges # pylint: disable=unused-import from certbot import cli from certbot import errors from certbot import interfaces -from certbot.display import util as display_util +from certbot.compat import os from certbot.display import ops +from certbot.display import util as display_util from certbot.plugins import common from certbot.plugins import util - logger = logging.getLogger(__name__) diff --git a/certbot/plugins/webroot_test.py b/certbot/plugins/webroot_test.py index a67ddbb83..3a902b91f 100644 --- a/certbot/plugins/webroot_test.py +++ b/certbot/plugins/webroot_test.py @@ -5,7 +5,6 @@ from __future__ import print_function import argparse import errno import json -import os import shutil import tempfile import unittest @@ -19,6 +18,7 @@ from acme import challenges from certbot import achallenges from certbot import errors from certbot.compat import misc +from certbot.compat import os from certbot.display import util as display_util from certbot.tests import acme_util from certbot.tests import util as test_util @@ -242,7 +242,7 @@ class AuthenticatorTest(unittest.TestCase): os.rmdir(leftover_path) - @mock.patch('os.rmdir') + @mock.patch('certbot.compat.os.rmdir') def test_cleanup_failure(self, mock_rmdir): self.auth.prepare() self.auth.perform([self.achall]) diff --git a/certbot/renewal.py b/certbot/renewal.py index 9da0ec596..f932269b6 100644 --- a/certbot/renewal.py +++ b/certbot/renewal.py @@ -1,30 +1,29 @@ """Functionality for autorenewal and associated juggling of configurations""" from __future__ import print_function + import copy import itertools import logging -import os -import traceback +import random import sys import time -import random - -import six -import zope.component +import traceback import OpenSSL +import six +import zope.component from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module from certbot import cli from certbot import crypto_util from certbot import errors -from certbot import interfaces -from certbot import util from certbot import hooks +from certbot import interfaces from certbot import storage from certbot import updater - +from certbot import util +from certbot.compat import os from certbot.plugins import disco as plugins_disco logger = logging.getLogger(__name__) diff --git a/certbot/reverter.py b/certbot/reverter.py index 764cdf2c0..c7992e73c 100644 --- a/certbot/reverter.py +++ b/certbot/reverter.py @@ -2,7 +2,6 @@ import csv import glob import logging -import os import shutil import sys import time @@ -11,11 +10,12 @@ import traceback import six import zope.component -from certbot.compat import misc from certbot import constants from certbot import errors from certbot import interfaces from certbot import util +from certbot.compat import misc +from certbot.compat import os logger = logging.getLogger(__name__) diff --git a/certbot/storage.py b/certbot/storage.py index 05faf81cb..01e012920 100644 --- a/certbot/storage.py +++ b/certbot/storage.py @@ -2,7 +2,6 @@ import datetime import glob import logging -import os import re import shutil import stat @@ -20,6 +19,7 @@ from certbot import error_handler from certbot import errors from certbot import util from certbot.compat import misc +from certbot.compat import os from certbot.plugins import common as plugins_common from certbot.plugins import disco as plugins_disco diff --git a/certbot/tests/account_test.py b/certbot/tests/account_test.py index fb0205f9c..24a092cc8 100644 --- a/certbot/tests/account_test.py +++ b/certbot/tests/account_test.py @@ -1,7 +1,6 @@ """Tests for certbot.account.""" import datetime import json -import os import shutil import stat import unittest @@ -15,6 +14,7 @@ from acme import messages import certbot.tests.util as test_util from certbot import errors from certbot.compat import misc +from certbot.compat import os KEY = jose.JWKRSA.load(test_util.load_vector("rsa512_key.pem")) @@ -233,7 +233,7 @@ class AccountFileStorageTest(test_util.ConfigTestCase): self._set_server('https://acme-v02.api.letsencrypt.org/directory') self.assertEqual([self.acc], self.storage.find_all()) - @mock.patch('os.rmdir') + @mock.patch('certbot.compat.os.rmdir') def test_corrupted_account(self, mock_rmdir): # pylint: disable=protected-access self._set_server('https://acme-staging.api.letsencrypt.org/directory') diff --git a/certbot/tests/cert_manager_test.py b/certbot/tests/cert_manager_test.py index 3c212ebe1..08d7282a7 100644 --- a/certbot/tests/cert_manager_test.py +++ b/certbot/tests/cert_manager_test.py @@ -1,7 +1,6 @@ """Tests for certbot.cert_manager.""" # pylint: disable=protected-access -import os import re import shutil import tempfile @@ -12,10 +11,9 @@ import mock from certbot import configuration from certbot import errors - +from certbot.compat import os from certbot.display import util as display_util from certbot.storage import ALL_FOUR - from certbot.tests import storage_test from certbot.tests import util as test_util diff --git a/certbot/tests/cli_test.py b/certbot/tests/cli_test.py index ebba0b0c0..592bd1be7 100644 --- a/certbot/tests/cli_test.py +++ b/certbot/tests/cli_test.py @@ -1,10 +1,9 @@ """Tests for certbot.cli.""" import argparse -import unittest -import os -import tempfile import copy import sys +import tempfile +import unittest import mock import six @@ -12,13 +11,12 @@ from six.moves import reload_module # pylint: disable=import-error from acme import challenges +import certbot.tests.util as test_util from certbot import cli from certbot import constants from certbot import errors +from certbot.compat import os from certbot.plugins import disco - -import certbot.tests.util as test_util - from certbot.tests.util import TempDirTestCase PLUGINS = disco.PluginsRegistry.find_all() diff --git a/certbot/tests/client_test.py b/certbot/tests/client_test.py index e338905d2..711346dbb 100644 --- a/certbot/tests/client_test.py +++ b/certbot/tests/client_test.py @@ -1,5 +1,4 @@ """Tests for certbot.client.""" -import os import platform import shutil import tempfile @@ -12,6 +11,7 @@ from josepy import interfaces import certbot.tests.util as test_util from certbot import account from certbot import errors +from certbot.compat import os from certbot import util KEY = test_util.load_vector("rsa512_key.pem") @@ -323,7 +323,7 @@ class ClientTest(ClientTestCommon): self.eg_order.fullchain_pem) @mock.patch("certbot.client.crypto_util") - @mock.patch("os.remove") + @mock.patch("certbot.compat.os.remove") def test_obtain_certificate_partial_success(self, mock_remove, mock_crypto_util): csr = util.CSR(form="pem", file=mock.sentinel.csr_file, data=CSR_SAN) key = util.CSR(form="pem", file=mock.sentinel.key_file, data=CSR_SAN) diff --git a/certbot/tests/compat/__init__.py b/certbot/tests/compat/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/certbot/tests/compat_test.py b/certbot/tests/compat/compat_test.py similarity index 96% rename from certbot/tests/compat_test.py rename to certbot/tests/compat/compat_test.py index ffbba24fd..832c557f6 100644 --- a/certbot/tests/compat_test.py +++ b/certbot/tests/compat/compat_test.py @@ -1,8 +1,7 @@ """Tests for certbot.compat.""" -import os - import certbot.tests.util as test_util from certbot.compat import misc +from certbot.compat import os class OsReplaceTest(test_util.TempDirTestCase): diff --git a/certbot/tests/configuration_test.py b/certbot/tests/configuration_test.py index a4d32a57f..aa07a580f 100644 --- a/certbot/tests/configuration_test.py +++ b/certbot/tests/configuration_test.py @@ -1,5 +1,4 @@ """Tests for certbot.configuration.""" -import os import unittest import mock @@ -7,6 +6,7 @@ import mock from certbot import constants from certbot import errors from certbot.compat import misc +from certbot.compat import os from certbot.tests import util as test_util diff --git a/certbot/tests/crypto_util_test.py b/certbot/tests/crypto_util_test.py index c2f5fa25d..5c1a07f8d 100644 --- a/certbot/tests/crypto_util_test.py +++ b/certbot/tests/crypto_util_test.py @@ -1,17 +1,16 @@ """Tests for certbot.crypto_util.""" import logging -import os import unittest import OpenSSL import mock import zope.component +import certbot.tests.util as test_util from certbot import errors from certbot import interfaces from certbot import util -import certbot.tests.util as test_util - +from certbot.compat import os RSA256_KEY = test_util.load_vector('rsa256_key.pem') RSA256_KEY_PATH = test_util.vector_path('rsa256_key.pem') diff --git a/certbot/tests/display/completer_test.py b/certbot/tests/display/completer_test.py index 34ed11e69..bbbc50c49 100644 --- a/certbot/tests/display/completer_test.py +++ b/certbot/tests/display/completer_test.py @@ -1,5 +1,4 @@ """Test certbot.display.completer.""" -import os try: import readline # pylint: disable=import-error except ImportError: @@ -11,7 +10,9 @@ import unittest import mock from six.moves import reload_module # pylint: disable=import-error -from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module +from acme.magic_typing import List # pylint: disable=unused-import,no-name-in-module + +from certbot.compat import os # pylint: disable=ungrouped-imports import certbot.tests.util as test_util # pylint: disable=ungrouped-imports diff --git a/certbot/tests/display/ops_test.py b/certbot/tests/display/ops_test.py index d499c026b..95334a9d3 100644 --- a/certbot/tests/display/ops_test.py +++ b/certbot/tests/display/ops_test.py @@ -1,6 +1,5 @@ # coding=utf-8 """Test certbot.display.ops.""" -import os import sys import unittest @@ -10,14 +9,12 @@ import zope.component from acme import messages +import certbot.tests.util as test_util from certbot import account from certbot import errors - -from certbot.display import util as display_util +from certbot.compat import os from certbot.display import ops - -import certbot.tests.util as test_util - +from certbot.display import util as display_util KEY = jose.JWKRSA.load(test_util.load_vector("rsa512_key.pem")) diff --git a/certbot/tests/error_handler_test.py b/certbot/tests/error_handler_test.py index 1626580fc..cc805a9e6 100644 --- a/certbot/tests/error_handler_test.py +++ b/certbot/tests/error_handler_test.py @@ -1,15 +1,17 @@ """Tests for certbot.error_handler.""" import contextlib -import os import signal import sys import unittest import mock + # pylint: disable=unused-import, no-name-in-module from acme.magic_typing import Callable, Dict, Union # pylint: enable=unused-import, no-name-in-module +from certbot.compat import os + def get_signals(signums): """Get the handlers for an iterable of signums.""" diff --git a/certbot/tests/hook_test.py b/certbot/tests/hook_test.py index 90f639958..2a3742aa2 100644 --- a/certbot/tests/hook_test.py +++ b/certbot/tests/hook_test.py @@ -1,12 +1,12 @@ """Tests for certbot.hooks.""" -import os import stat import unittest import mock - from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module + from certbot import errors +from certbot.compat import os from certbot.tests import util diff --git a/certbot/tests/lock_test.py b/certbot/tests/lock_test.py index d2e61e386..fb3a8fedf 100644 --- a/certbot/tests/lock_test.py +++ b/certbot/tests/lock_test.py @@ -1,7 +1,6 @@ """Tests for certbot.lock.""" import functools import multiprocessing -import os import unittest try: import fcntl # pylint: disable=import-error,unused-import @@ -13,6 +12,7 @@ else: import mock from certbot import errors +from certbot.compat import os from certbot.tests import util as test_util diff --git a/certbot/tests/log_test.py b/certbot/tests/log_test.py index f55affcfc..d203635a2 100644 --- a/certbot/tests/log_test.py +++ b/certbot/tests/log_test.py @@ -1,13 +1,13 @@ """Tests for certbot.log.""" import logging import logging.handlers -import os import sys import time import unittest import mock import six + from acme import messages from acme.magic_typing import Optional # pylint: disable=unused-import, no-name-in-module @@ -15,6 +15,7 @@ from certbot import constants from certbot import errors from certbot import util from certbot.compat import misc +from certbot.compat import os from certbot.tests import util as test_util diff --git a/certbot/tests/main_test.py b/certbot/tests/main_test.py index 7ff8b7452..bdc42a62f 100644 --- a/certbot/tests/main_test.py +++ b/certbot/tests/main_test.py @@ -6,7 +6,6 @@ from __future__ import print_function import datetime import itertools import json -import os import shutil import sys import tempfile @@ -33,6 +32,7 @@ from certbot import main from certbot import updater from certbot import util from certbot.compat import misc +from certbot.compat import os from certbot.plugins import disco from certbot.plugins import enhancements from certbot.plugins import manual diff --git a/certbot/tests/reverter_test.py b/certbot/tests/reverter_test.py index 18e698444..f90708a69 100644 --- a/certbot/tests/reverter_test.py +++ b/certbot/tests/reverter_test.py @@ -1,7 +1,6 @@ """Test certbot.reverter.""" import csv import logging -import os import shutil import tempfile import unittest @@ -10,6 +9,7 @@ import mock import six from certbot import errors +from certbot.compat import os from certbot.tests import util as test_util diff --git a/certbot/tests/storage_test.py b/certbot/tests/storage_test.py index a6577deb3..13c09395d 100644 --- a/certbot/tests/storage_test.py +++ b/certbot/tests/storage_test.py @@ -1,7 +1,6 @@ """Tests for certbot.storage.""" # pylint disable=protected-access import datetime -import os import shutil import stat import unittest @@ -15,6 +14,7 @@ import certbot import certbot.tests.util as test_util from certbot import errors from certbot.compat import misc +from certbot.compat import os from certbot.storage import ALL_FOUR CERT = test_util.load_cert('cert_512.pem') diff --git a/certbot/tests/util.py b/certbot/tests/util.py index 29d108d20..49ff6731b 100644 --- a/certbot/tests/util.py +++ b/certbot/tests/util.py @@ -4,7 +4,6 @@ """ import logging -import os import shutil import stat import sys @@ -27,6 +26,7 @@ from certbot import interfaces from certbot import lock from certbot import storage from certbot import util +from certbot.compat import os from certbot.display import util as display_util diff --git a/certbot/tests/util_test.py b/certbot/tests/util_test.py index 853c78499..6e231b74d 100644 --- a/certbot/tests/util_test.py +++ b/certbot/tests/util_test.py @@ -1,7 +1,6 @@ """Tests for certbot.util.""" import argparse import errno -import os import unittest import mock @@ -11,6 +10,7 @@ from six.moves import reload_module # pylint: disable=import-error import certbot.tests.util as test_util from certbot import errors from certbot.compat import misc +from certbot.compat import os class RunScriptTest(unittest.TestCase): diff --git a/certbot/util.py b/certbot/util.py index ec8be3150..e15d02779 100644 --- a/certbot/util.py +++ b/certbot/util.py @@ -8,7 +8,6 @@ from collections import OrderedDict import distutils.version # pylint: disable=import-error,no-name-in-module import errno import logging -import os import platform import re import socket @@ -23,6 +22,7 @@ from certbot import constants from certbot import errors from certbot import lock from certbot.compat import misc +from certbot.compat import os logger = logging.getLogger(__name__) diff --git a/docs/contributing.rst b/docs/contributing.rst index 0319160e6..582f14599 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -312,6 +312,23 @@ Please: .. _PEP 8 - Style Guide for Python Code: https://www.python.org/dev/peps/pep-0008 +Use ``certbot.compat.os`` instead of ``os`` +=========================================== + + +Python's standard library ``os`` module lacks full support for several Windows +security features about file permissions (eg. DACLs). However several files +handled by Certbot (eg. private keys) need strongly restricted access +on both Linux and Windows. + +To help with this, the ``certbot.compat.os`` module wraps the standard +``os`` module, and forbids usage of methods that lack support for these Windows +security features. + +As a developer, when working on Certbot or its plugins, you must use ``certbot.compat.os`` +in every place you would need ``os`` (eg. ``from certbot.compat import os`` instead of +``import os``). Otherwise the tests will fail when your PR is submitted. + Mypy type annotations ===================== diff --git a/linter_plugin.py b/linter_plugin.py index 85896a36b..e870fda3a 100644 --- a/linter_plugin.py +++ b/linter_plugin.py @@ -1,31 +1,51 @@ -"""Certbot ACME PyLint plugin. - +"""Certbot PyLint plugin. http://docs.pylint.org/plugins.html - """ -from astroid import MANAGER -from astroid import nodes +# The built-in ImportChecker of Pylint does a similar job to ForbidStandardOsModule to detect +# deprecated modules. You can check its behavior as a reference to what is coded here. +# See https://github.com/PyCQA/pylint/blob/b20a2984c94e2946669d727dbda78735882bf50a/pylint/checkers/imports.py#L287 +from pylint.checkers import BaseChecker +from pylint.interfaces import IAstroidChecker -def register(unused_linter): - """Register this module as PyLint plugin.""" - pass +# Modules in theses packages can import the os module. +WHITELIST_PACKAGES = ['acme', 'certbot_compatibility_test', 'letshelp_certbot', 'lock_test'] -def _transform(cls): - # fix the "no-member" error on instances of - # letsencrypt.acme.util.ImmutableMap subclasses (instance - # attributes are initialized dynamically based on __slots__) +class ForbidStandardOsModule(BaseChecker): + """ + This checker ensures that standard os module (and submodules) is not imported by certbot + modules. Otherwise a 'os-module-forbidden' error will be registered for the faulty lines. + """ + __implements__ = IAstroidChecker - # TODO: this is too broad and applies to any tested class... + name = 'forbid-os-module' + msgs = { + 'E5001': ( + 'Forbidden use of os module, certbot.compat.os must be used instead', + 'os-module-forbidden', + 'Some methods from the standard os module cannot be used for security reasons on Windows: ' + 'the safe wrapper certbot.compat.os must be used instead in Certbot.' + ) + } + priority = -1 - #if cls.slots() is not None: - # for slot in cls.slots(): - # cls.locals[slot.value] = [nodes.EmptyNode()] + def visit_import(self, node): + os_used = any(name for name in node.names if name[0] == 'os' or name[0].startswith('os.')) + if os_used and not _check_disabled(node): + self.add_message('os-module-forbidden', node=node) - if cls.name == 'JSONObjectWithFields': - # _fields is magically introduced by JSONObjectWithFieldsMeta - cls.locals['_fields'] = [nodes.EmptyNode()] + def visit_importfrom(self, node): + if node.modname == 'os' or node.modname.startswith('os.') and not _check_disabled(node): + self.add_message('os-module-forbidden', node=node) -MANAGER.register_transform(nodes.Class, _transform) +def register(linter): + """Pylint hook to auto-register this linter""" + linter.register_checker(ForbidStandardOsModule(linter)) + + +def _check_disabled(node): + module = node.root() + return any(package for package in WHITELIST_PACKAGES + if module.name.startswith(package + '.') or module.name == package)