Import upstream version 1.19.0
Debian Janitor
1 year, 11 months ago
0 | 0 | Metadata-Version: 2.1 |
1 | 1 | Name: certbot-dns-rfc2136 |
2 | Version: 1.10.1 | |
2 | Version: 1.19.0 | |
3 | 3 | Summary: RFC 2136 DNS Authenticator plugin for Certbot |
4 | 4 | Home-page: https://github.com/certbot/certbot |
5 | 5 | Author: Certbot Project |
6 | Author-email: client-dev@letsencrypt.org | |
6 | Author-email: certbot-dev@eff.org | |
7 | 7 | License: Apache License 2.0 |
8 | Description: UNKNOWN | |
9 | 8 | Platform: UNKNOWN |
10 | 9 | Classifier: Development Status :: 5 - Production/Stable |
11 | 10 | Classifier: Environment :: Plugins |
13 | 12 | Classifier: License :: OSI Approved :: Apache Software License |
14 | 13 | Classifier: Operating System :: POSIX :: Linux |
15 | 14 | Classifier: Programming Language :: Python |
16 | Classifier: Programming Language :: Python :: 2 | |
17 | Classifier: Programming Language :: Python :: 2.7 | |
18 | 15 | Classifier: Programming Language :: Python :: 3 |
19 | 16 | Classifier: Programming Language :: Python :: 3.6 |
20 | 17 | Classifier: Programming Language :: Python :: 3.7 |
26 | 23 | Classifier: Topic :: System :: Networking |
27 | 24 | Classifier: Topic :: System :: Systems Administration |
28 | 25 | Classifier: Topic :: Utilities |
29 | Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.* | |
26 | Requires-Python: >=3.6 | |
30 | 27 | Provides-Extra: docs |
28 | License-File: LICENSE.txt | |
29 | ||
30 | UNKNOWN | |
31 |
2 | 2 | completing a ``dns-01`` challenge (`~acme.challenges.DNS01`) by creating, and |
3 | 3 | subsequently removing, TXT records using RFC 2136 Dynamic Updates. |
4 | 4 | |
5 | .. note:: | |
6 | The plugin is not installed by default. It can be installed by heading to | |
7 | `certbot.eff.org <https://certbot.eff.org/instructions#wildcard>`_, choosing your system and | |
8 | selecting the Wildcard tab. | |
5 | 9 | |
6 | 10 | Named Arguments |
7 | 11 | --------------- |
28 | 32 | :name: credentials.ini |
29 | 33 | :caption: Example credentials file: |
30 | 34 | |
31 | # Target DNS server | |
35 | # Target DNS server (IPv4 or IPv6 address, not a hostname) | |
32 | 36 | dns_rfc2136_server = 192.0.2.1 |
33 | 37 | # Target DNS port |
34 | 38 | dns_rfc2136_port = 53 |
0 | # type: ignore | |
1 | # pylint: disable=no-member | |
2 | # Many attributes of dnspython are now dynamically defined which causes both | |
3 | # mypy and pylint to error about accessing attributes they think do not exist. | |
4 | # This is the case even in up-to-date versions of mypy and pylint which as of | |
5 | # writing this are 0.790 and 2.6.0 respectively. This problem may be fixed in | |
6 | # dnspython 2.1.0. See https://github.com/rthalley/dnspython/issues/598. For | |
7 | # now, let's disable these checks. This is done at the very top of the file | |
8 | # like this because "type: ignore" must be the first line in the file to be | |
9 | # respected by mypy. | |
10 | 0 | """DNS Authenticator using RFC 2136 Dynamic Updates.""" |
11 | 1 | import logging |
2 | from typing import Optional | |
12 | 3 | |
13 | 4 | import dns.flags |
5 | from dns.inet import is_address | |
14 | 6 | import dns.message |
15 | 7 | import dns.name |
16 | 8 | import dns.query |
19 | 11 | import dns.tsig |
20 | 12 | import dns.tsigkeyring |
21 | 13 | import dns.update |
22 | import zope.interface | |
23 | 14 | |
24 | 15 | from certbot import errors |
25 | from certbot import interfaces | |
26 | 16 | from certbot.plugins import dns_common |
17 | from certbot.plugins.dns_common import CredentialsConfiguration | |
27 | 18 | |
28 | 19 | logger = logging.getLogger(__name__) |
29 | 20 | |
30 | 21 | DEFAULT_NETWORK_TIMEOUT = 45 |
31 | 22 | |
32 | @zope.interface.implementer(interfaces.IAuthenticator) | |
33 | @zope.interface.provider(interfaces.IPluginFactory) | |
23 | ||
34 | 24 | class Authenticator(dns_common.DNSAuthenticator): |
35 | 25 | """DNS Authenticator using RFC 2136 Dynamic Updates |
36 | 26 | |
37 | This Authenticator uses RFC 2136 Dynamic Updates to fulfull a dns-01 challenge. | |
27 | This Authenticator uses RFC 2136 Dynamic Updates to fulfill a dns-01 challenge. | |
38 | 28 | """ |
39 | 29 | |
40 | 30 | ALGORITHMS = { |
52 | 42 | ttl = 120 |
53 | 43 | |
54 | 44 | def __init__(self, *args, **kwargs): |
55 | super(Authenticator, self).__init__(*args, **kwargs) | |
56 | self.credentials = None | |
45 | super().__init__(*args, **kwargs) | |
46 | self.credentials: Optional[CredentialsConfiguration] = None | |
57 | 47 | |
58 | 48 | @classmethod |
59 | 49 | def add_parser_arguments(cls, add): # pylint: disable=arguments-differ |
60 | super(Authenticator, cls).add_parser_arguments(add, default_propagation_seconds=60) | |
50 | super().add_parser_arguments(add, default_propagation_seconds=60) | |
61 | 51 | add('credentials', help='RFC 2136 credentials INI file.') |
62 | 52 | |
63 | 53 | def more_info(self): # pylint: disable=missing-function-docstring |
64 | 54 | return 'This plugin configures a DNS TXT record to respond to a dns-01 challenge using ' + \ |
65 | 55 | 'RFC 2136 Dynamic Updates.' |
66 | 56 | |
67 | def _validate_algorithm(self, credentials): | |
57 | def _validate_credentials(self, credentials): | |
58 | server = credentials.conf('server') | |
59 | if not is_address(server): | |
60 | raise errors.PluginError("The configured target DNS server ({0}) is not a valid IPv4 " | |
61 | "or IPv6 address. A hostname is not allowed.".format(server)) | |
68 | 62 | algorithm = credentials.conf('algorithm') |
69 | 63 | if algorithm: |
70 | 64 | if not self.ALGORITHMS.get(algorithm.upper()): |
79 | 73 | 'secret': 'TSIG key secret', |
80 | 74 | 'server': 'The target DNS server' |
81 | 75 | }, |
82 | self._validate_algorithm | |
76 | self._validate_credentials | |
83 | 77 | ) |
84 | 78 | |
85 | 79 | def _perform(self, _domain, validation_name, validation): |
89 | 83 | self._get_rfc2136_client().del_txt_record(validation_name, validation) |
90 | 84 | |
91 | 85 | def _get_rfc2136_client(self): |
86 | if not self.credentials: # pragma: no cover | |
87 | raise errors.Error("Plugin has not been prepared.") | |
92 | 88 | return _RFC2136Client(self.credentials.conf('server'), |
93 | 89 | int(self.credentials.conf('port') or self.PORT), |
94 | 90 | self.credentials.conf('name'), |
97 | 93 | dns.tsig.HMAC_MD5)) |
98 | 94 | |
99 | 95 | |
100 | class _RFC2136Client(object): | |
96 | class _RFC2136Client: | |
101 | 97 | """ |
102 | 98 | Encapsulates all communication with the target DNS server. |
103 | 99 | """ |
0 | 0 | Metadata-Version: 2.1 |
1 | 1 | Name: certbot-dns-rfc2136 |
2 | Version: 1.10.1 | |
2 | Version: 1.19.0 | |
3 | 3 | Summary: RFC 2136 DNS Authenticator plugin for Certbot |
4 | 4 | Home-page: https://github.com/certbot/certbot |
5 | 5 | Author: Certbot Project |
6 | Author-email: client-dev@letsencrypt.org | |
6 | Author-email: certbot-dev@eff.org | |
7 | 7 | License: Apache License 2.0 |
8 | Description: UNKNOWN | |
9 | 8 | Platform: UNKNOWN |
10 | 9 | Classifier: Development Status :: 5 - Production/Stable |
11 | 10 | Classifier: Environment :: Plugins |
13 | 12 | Classifier: License :: OSI Approved :: Apache Software License |
14 | 13 | Classifier: Operating System :: POSIX :: Linux |
15 | 14 | Classifier: Programming Language :: Python |
16 | Classifier: Programming Language :: Python :: 2 | |
17 | Classifier: Programming Language :: Python :: 2.7 | |
18 | 15 | Classifier: Programming Language :: Python :: 3 |
19 | 16 | Classifier: Programming Language :: Python :: 3.6 |
20 | 17 | Classifier: Programming Language :: Python :: 3.7 |
26 | 23 | Classifier: Topic :: System :: Networking |
27 | 24 | Classifier: Topic :: System :: Systems Administration |
28 | 25 | Classifier: Topic :: Utilities |
29 | Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.* | |
26 | Requires-Python: >=3.6 | |
30 | 27 | Provides-Extra: docs |
28 | License-File: LICENSE.txt | |
29 | ||
30 | UNKNOWN | |
31 |
0 | 0 | dnspython |
1 | setuptools | |
2 | zope.interface | |
3 | acme>=0.29.0 | |
4 | certbot>=1.1.0 | |
5 | ||
6 | [:python_version < "3.3"] | |
7 | mock | |
1 | setuptools>=39.0.1 | |
2 | acme>=1.19.0 | |
3 | certbot>=1.19.0 | |
8 | 4 | |
9 | 5 | [docs] |
10 | 6 | Sphinx>=1.0 |
110 | 110 | # Add any paths that contain custom static files (such as style sheets) here, |
111 | 111 | # relative to this directory. They are copied after the builtin static files, |
112 | 112 | # so a file named "default.css" will overwrite the builtin "default.css". |
113 | html_static_path = ['_static'] | |
113 | #html_static_path = ['_static'] | |
114 | 114 | |
115 | 115 | |
116 | 116 | # -- Options for HTMLHelp output ------------------------------------------ |
0 | from distutils.version import LooseVersion | |
1 | 0 | import os |
2 | 1 | import sys |
3 | 2 | |
4 | from setuptools import __version__ as setuptools_version | |
5 | 3 | from setuptools import find_packages |
6 | 4 | from setuptools import setup |
7 | 5 | |
8 | version = '1.10.1' | |
6 | version = '1.19.0' | |
9 | 7 | |
10 | # Remember to update local-oldest-requirements.txt when changing the minimum | |
11 | # acme/certbot version. | |
12 | 8 | install_requires = [ |
13 | 9 | 'dnspython', |
14 | 'setuptools', | |
15 | 'zope.interface', | |
10 | 'setuptools>=39.0.1', | |
16 | 11 | ] |
17 | 12 | |
18 | 13 | if not os.environ.get('SNAP_BUILD'): |
19 | 14 | install_requires.extend([ |
20 | 'acme>=0.29.0', | |
21 | 'certbot>=1.1.0', | |
15 | # We specify the minimum acme and certbot version as the current plugin | |
16 | # version for simplicity. See | |
17 | # https://github.com/certbot/certbot/issues/8761 for more info. | |
18 | f'acme>={version}', | |
19 | f'certbot>={version}', | |
22 | 20 | ]) |
23 | 21 | elif 'bdist_wheel' in sys.argv[1:]: |
24 | 22 | raise RuntimeError('Unset SNAP_BUILD when building wheels ' |
25 | 23 | 'to include certbot dependencies.') |
26 | 24 | if os.environ.get('SNAP_BUILD'): |
27 | 25 | install_requires.append('packaging') |
28 | ||
29 | setuptools_known_environment_markers = (LooseVersion(setuptools_version) >= LooseVersion('36.2')) | |
30 | if setuptools_known_environment_markers: | |
31 | install_requires.append('mock ; python_version < "3.3"') | |
32 | elif 'bdist_wheel' in sys.argv[1:]: | |
33 | raise RuntimeError('Error, you are trying to build certbot wheels using an old version ' | |
34 | 'of setuptools. Version 36.2+ of setuptools is required.') | |
35 | elif sys.version_info < (3,3): | |
36 | install_requires.append('mock') | |
37 | 26 | |
38 | 27 | docs_extras = [ |
39 | 28 | 'Sphinx>=1.0', # autodoc_member_order = 'bysource', autodoc_default_flags |
46 | 35 | description="RFC 2136 DNS Authenticator plugin for Certbot", |
47 | 36 | url='https://github.com/certbot/certbot', |
48 | 37 | author="Certbot Project", |
49 | author_email='client-dev@letsencrypt.org', | |
38 | author_email='certbot-dev@eff.org', | |
50 | 39 | license='Apache License 2.0', |
51 | python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*', | |
40 | python_requires='>=3.6', | |
52 | 41 | classifiers=[ |
53 | 42 | 'Development Status :: 5 - Production/Stable', |
54 | 43 | 'Environment :: Plugins', |
56 | 45 | 'License :: OSI Approved :: Apache Software License', |
57 | 46 | 'Operating System :: POSIX :: Linux', |
58 | 47 | 'Programming Language :: Python', |
59 | 'Programming Language :: Python :: 2', | |
60 | 'Programming Language :: Python :: 2.7', | |
61 | 48 | 'Programming Language :: Python :: 3', |
62 | 49 | 'Programming Language :: Python :: 3.6', |
63 | 50 | 'Programming Language :: Python :: 3.7', |
27 | 27 | def setUp(self): |
28 | 28 | from certbot_dns_rfc2136._internal.dns_rfc2136 import Authenticator |
29 | 29 | |
30 | super(AuthenticatorTest, self).setUp() | |
30 | super().setUp() | |
31 | 31 | |
32 | 32 | path = os.path.join(self.tempdir, 'file.ini') |
33 | 33 | dns_test_common.write(VALID_CONFIG, path) |
41 | 41 | # _get_rfc2136_client | pylint: disable=protected-access |
42 | 42 | self.auth._get_rfc2136_client = mock.MagicMock(return_value=self.mock_client) |
43 | 43 | |
44 | def test_perform(self): | |
44 | @test_util.patch_display_util() | |
45 | def test_perform(self, unused_mock_get_utility): | |
45 | 46 | self.auth.perform([self.achall]) |
46 | 47 | |
47 | 48 | expected = [mock.call.add_txt_record('_acme-challenge.'+DOMAIN, mock.ANY, mock.ANY)] |
64 | 65 | self.auth.perform, |
65 | 66 | [self.achall]) |
66 | 67 | |
67 | def test_valid_algorithm_passes(self): | |
68 | @test_util.patch_display_util() | |
69 | def test_valid_algorithm_passes(self, unused_mock_get_utility): | |
68 | 70 | config = VALID_CONFIG.copy() |
69 | 71 | config["rfc2136_algorithm"] = "HMAC-sha512" |
72 | dns_test_common.write(config, self.config.rfc2136_credentials) | |
73 | ||
74 | self.auth.perform([self.achall]) | |
75 | ||
76 | def test_invalid_server_raises(self): | |
77 | config = VALID_CONFIG.copy() | |
78 | config["rfc2136_server"] = "example.com" | |
79 | dns_test_common.write(config, self.config.rfc2136_credentials) | |
80 | ||
81 | self.assertRaises(errors.PluginError, | |
82 | self.auth.perform, | |
83 | [self.achall]) | |
84 | ||
85 | @test_util.patch_display_util() | |
86 | def test_valid_server_passes(self, unused_mock_get_utility): | |
87 | config = VALID_CONFIG.copy() | |
88 | dns_test_common.write(config, self.config.rfc2136_credentials) | |
89 | ||
90 | self.auth.perform([self.achall]) | |
91 | ||
92 | config["rfc2136_server"] = "2001:db8:3333:4444:cccc:dddd:eeee:ffff" | |
70 | 93 | dns_test_common.write(config, self.config.rfc2136_credentials) |
71 | 94 | |
72 | 95 | self.auth.perform([self.achall]) |