1
0
mirror of https://github.com/certbot/certbot.git synced 2025-08-09 15:02:48 +03:00

Merge remote-tracking branch 'origin/master' into ap2_to_master

This commit is contained in:
Joona Hoikkala
2020-01-30 17:08:16 +02:00
132 changed files with 1924 additions and 922 deletions

View File

@@ -69,12 +69,12 @@ Access can be defined for all or only selected repositories, which is nice.
``` ```
- Redirected to Azure DevOps, select the account created in _Having an Azure DevOps account_ section. - Redirected to Azure DevOps, select the account created in _Having an Azure DevOps account_ section.
- Select the organization, and click "Create a new project" (let's name it the same than the targetted github repo) - Select the organization, and click "Create a new project" (let's name it the same than the targeted github repo)
- The Visibility is public, to profit from 10 parallel jobs - The Visibility is public, to profit from 10 parallel jobs
``` ```
!!! ACCESS !!! !!! ACCESS !!!
Azure Pipelines needs access to the GitHub account (in term of beeing able to check it is valid), and the Resources shared between the GitHub account and Azure Pipelines. Azure Pipelines needs access to the GitHub account (in term of being able to check it is valid), and the Resources shared between the GitHub account and Azure Pipelines.
``` ```
_Done. We can move to pipelines configuration._ _Done. We can move to pipelines configuration._

View File

@@ -40,7 +40,7 @@ jobs:
displayName: Retrieve Windows installer displayName: Retrieve Windows installer
- script: $(Build.SourcesDirectory)\bin\certbot-beta-installer-win32.exe /S - script: $(Build.SourcesDirectory)\bin\certbot-beta-installer-win32.exe /S
displayName: Install Certbot displayName: Install Certbot
- powershell: Invoke-WebRequest https://www.python.org/ftp/python/3.8.0/python-3.8.0-amd64-webinstall.exe -OutFile C:\py3-setup.exe - powershell: Invoke-WebRequest https://www.python.org/ftp/python/3.8.1/python-3.8.1-amd64-webinstall.exe -OutFile C:\py3-setup.exe
displayName: Get Python displayName: Get Python
- script: C:\py3-setup.exe /quiet PrependPath=1 InstallAllUsers=1 Include_launcher=1 InstallLauncherAllUsers=1 Include_test=0 Include_doc=0 Include_dev=1 Include_debug=0 Include_tcltk=0 TargetDir=C:\py3 - script: C:\py3-setup.exe /quiet PrependPath=1 InstallAllUsers=1 Include_launcher=1 InstallLauncherAllUsers=1 Include_test=0 Include_doc=0 Include_dev=1 Include_debug=0 Include_tcltk=0 TargetDir=C:\py3
displayName: Install Python displayName: Install Python

1
.gitignore vendored
View File

@@ -26,6 +26,7 @@ tags
\#*# \#*#
.idea .idea
.ropeproject .ropeproject
.vscode
# auth --cert-path --chain-path # auth --cert-path --chain-path
/*.pem /*.pem

View File

@@ -59,11 +59,8 @@ matrix:
dist: trusty dist: trusty
env: TOXENV='py27-{acme,apache,apache-v2,certbot,dns,nginx}-oldest' env: TOXENV='py27-{acme,apache,apache-v2,certbot,dns,nginx}-oldest'
<<: *not-on-master <<: *not-on-master
- python: "3.4" - python: "3.5"
env: TOXENV=py34 env: TOXENV=py35
<<: *not-on-master
- python: "3.7"
env: TOXENV=py37
<<: *not-on-master <<: *not-on-master
- python: "3.8" - python: "3.8"
env: TOXENV=py38 env: TOXENV=py38
@@ -163,31 +160,12 @@ matrix:
sudo: required sudo: required
services: docker services: docker
<<: *extended-test-suite <<: *extended-test-suite
- python: "3.4"
env: TOXENV=py34
<<: *extended-test-suite
- python: "3.5"
env: TOXENV=py35
<<: *extended-test-suite
- python: "3.6" - python: "3.6"
env: TOXENV=py36 env: TOXENV=py36
<<: *extended-test-suite <<: *extended-test-suite
- python: "3.7" - python: "3.7"
env: TOXENV=py37 env: TOXENV=py37
<<: *extended-test-suite <<: *extended-test-suite
- python: "3.8"
env: TOXENV=py38
<<: *extended-test-suite
- python: "3.4"
env: ACME_SERVER=boulder-v1 TOXENV=integration
sudo: required
services: docker
<<: *extended-test-suite
- python: "3.4"
env: ACME_SERVER=boulder-v2 TOXENV=integration
sudo: required
services: docker
<<: *extended-test-suite
- python: "3.5" - python: "3.5"
env: ACME_SERVER=boulder-v1 TOXENV=integration env: ACME_SERVER=boulder-v1 TOXENV=integration
sudo: required sudo: required
@@ -232,6 +210,10 @@ matrix:
env: TOXENV=le_auto_centos6 env: TOXENV=le_auto_centos6
services: docker services: docker
<<: *extended-test-suite <<: *extended-test-suite
- sudo: required
env: TOXENV=le_auto_oraclelinux6
services: docker
<<: *extended-test-suite
- sudo: required - sudo: required
env: TOXENV=docker_dev env: TOXENV=docker_dev
services: docker services: docker
@@ -243,9 +225,6 @@ matrix:
- language: generic - language: generic
env: TOXENV=py27 env: TOXENV=py27
os: osx os: osx
# Using this osx_image is a workaround for
# https://travis-ci.community/t/xcode-8-3-homebrew-outdated-error/3798.
osx_image: xcode10.2
addons: addons:
homebrew: homebrew:
packages: packages:
@@ -255,9 +234,6 @@ matrix:
- language: generic - language: generic
env: TOXENV=py3 env: TOXENV=py3
os: osx os: osx
# Using this osx_image is a workaround for
# https://travis-ci.community/t/xcode-8-3-homebrew-outdated-error/3798.
osx_image: xcode10.2
addons: addons:
homebrew: homebrew:
packages: packages:

View File

@@ -36,6 +36,7 @@ Authors
* [Brad Warren](https://github.com/bmw) * [Brad Warren](https://github.com/bmw)
* [Brandon Kraft](https://github.com/kraftbj) * [Brandon Kraft](https://github.com/kraftbj)
* [Brandon Kreisel](https://github.com/kraftbj) * [Brandon Kreisel](https://github.com/kraftbj)
* [Cameron Steel](https://github.com/Tugzrida)
* [Ceesjan Luiten](https://github.com/quinox) * [Ceesjan Luiten](https://github.com/quinox)
* [Chad Whitacre](https://github.com/whit537) * [Chad Whitacre](https://github.com/whit537)
* [Chhatoi Pritam Baral](https://github.com/pritambaral) * [Chhatoi Pritam Baral](https://github.com/pritambaral)
@@ -100,6 +101,7 @@ Authors
* [Harlan Lieberman-Berg](https://github.com/hlieberman) * [Harlan Lieberman-Berg](https://github.com/hlieberman)
* [Henri Salo](https://github.com/fgeek) * [Henri Salo](https://github.com/fgeek)
* [Henry Chen](https://github.com/henrychen95) * [Henry Chen](https://github.com/henrychen95)
* [Hugo van Kemenade](https://github.com/hugovk)
* [Ingolf Becker](https://github.com/watercrossing) * [Ingolf Becker](https://github.com/watercrossing)
* [Jaap Eldering](https://github.com/eldering) * [Jaap Eldering](https://github.com/eldering)
* [Jacob Hoffman-Andrews](https://github.com/jsha) * [Jacob Hoffman-Andrews](https://github.com/jsha)
@@ -124,6 +126,7 @@ Authors
* [Jonathan Herlin](https://github.com/Jonher937) * [Jonathan Herlin](https://github.com/Jonher937)
* [Jon Walsh](https://github.com/code-tree) * [Jon Walsh](https://github.com/code-tree)
* [Joona Hoikkala](https://github.com/joohoi) * [Joona Hoikkala](https://github.com/joohoi)
* [Josh McCullough](https://github.com/JoshMcCullough)
* [Josh Soref](https://github.com/jsoref) * [Josh Soref](https://github.com/jsoref)
* [Joubin Jabbari](https://github.com/joubin) * [Joubin Jabbari](https://github.com/joubin)
* [Juho Juopperi](https://github.com/jkjuopperi) * [Juho Juopperi](https://github.com/jkjuopperi)

View File

@@ -942,7 +942,7 @@ class ClientNetwork(object):
:param messages.RegistrationResource account: Account object. Required if you are :param messages.RegistrationResource account: Account object. Required if you are
planning to use .post() with acme_version=2 for anything other than planning to use .post() with acme_version=2 for anything other than
creating a new account; may be set later after registering. creating a new account; may be set later after registering.
:param josepy.JWASignature alg: Algoritm to use in signing JWS. :param josepy.JWASignature alg: Algorithm to use in signing JWS.
:param bool verify_ssl: Whether to verify certificates on SSL connections. :param bool verify_ssl: Whether to verify certificates on SSL connections.
:param str user_agent: String to send as User-Agent header. :param str user_agent: String to send as User-Agent header.
:param float timeout: Timeout for requests. :param float timeout: Timeout for requests.

View File

@@ -36,7 +36,7 @@ ERROR_CODES = {
' domain'), ' domain'),
'dns': 'There was a problem with a DNS query during identifier validation', 'dns': 'There was a problem with a DNS query during identifier validation',
'dnssec': 'The server could not validate a DNSSEC signed domain', 'dnssec': 'The server could not validate a DNSSEC signed domain',
'incorrectResponse': 'Response recieved didn\'t match the challenge\'s requirements', 'incorrectResponse': 'Response received didn\'t match the challenge\'s requirements',
# deprecate invalidEmail # deprecate invalidEmail
'invalidEmail': 'The provided email for a registration was invalid', 'invalidEmail': 'The provided email for a registration was invalid',
'invalidContact': 'The provided contact URI was invalid', 'invalidContact': 'The provided contact URI was invalid',
@@ -245,13 +245,13 @@ class Directory(jose.JSONDeSerializable):
try: try:
return self[name.replace('_', '-')] return self[name.replace('_', '-')]
except KeyError as error: except KeyError as error:
raise AttributeError(str(error) + ': ' + name) raise AttributeError(str(error))
def __getitem__(self, name): def __getitem__(self, name):
try: try:
return self._jobj[self._canon_key(name)] return self._jobj[self._canon_key(name)]
except KeyError: except KeyError:
raise KeyError('Directory field not found') raise KeyError('Directory field "' + self._canon_key(name) + '" not found')
def to_partial_json(self): def to_partial_json(self):
return self._jobj return self._jobj

View File

@@ -41,7 +41,7 @@ extensions = [
] ]
autodoc_member_order = 'bysource' autodoc_member_order = 'bysource'
autodoc_default_flags = ['show-inheritance', 'private-members'] autodoc_default_flags = ['show-inheritance']
# Add any paths that contain templates here, relative to this directory. # Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates'] templates_path = ['_templates']

View File

@@ -4,7 +4,7 @@ from setuptools import find_packages
from setuptools import setup from setuptools import setup
from setuptools.command.test import test as TestCommand from setuptools.command.test import test as TestCommand
version = '1.1.0.dev0' version = '1.2.0.dev0'
# Please update tox.ini when modifying dependency version requirements # Please update tox.ini when modifying dependency version requirements
install_requires = [ install_requires = [
@@ -61,7 +61,7 @@ setup(
author="Certbot Project", author="Certbot Project",
author_email='client-dev@letsencrypt.org', author_email='client-dev@letsencrypt.org',
license='Apache License 2.0', license='Apache License 2.0',
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
classifiers=[ classifiers=[
'Development Status :: 5 - Production/Stable', 'Development Status :: 5 - Production/Stable',
'Intended Audience :: Developers', 'Intended Audience :: Developers',
@@ -70,7 +70,6 @@ setup(
'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.7',

View File

@@ -1,7 +1,6 @@
include LICENSE.txt include LICENSE.txt
include README.rst include README.rst
recursive-include tests * recursive-include tests *
include certbot_apache/_internal/centos-options-ssl-apache.conf
include certbot_apache/_internal/options-ssl-apache.conf include certbot_apache/_internal/options-ssl-apache.conf
recursive-include certbot_apache/_internal/augeas_lens *.aug recursive-include certbot_apache/_internal/augeas_lens *.aug
global-exclude __pycache__ global-exclude __pycache__

View File

@@ -1,25 +0,0 @@
# This file contains important security parameters. If you modify this file
# manually, Certbot will be unable to automatically provide future security
# updates. Instead, Certbot will print and log an error message with a path to
# the up-to-date file that you will need to refer to when manually updating
# this file.
SSLEngine on
# Intermediate configuration, tweak to your needs
SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS
SSLHonorCipherOrder on
SSLOptions +StrictRequire
# Add vhost name to log entries:
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" vhost_combined
LogFormat "%v %h %l %u %t \"%r\" %>s %b" vhost_common
#CustomLog /var/log/apache2/access.log vhost_combined
#LogLevel warn
#ErrorLog /var/log/apache2/error.log
# Always ensure Cookies have "Secure" set (JAH 2012/1)
#Header edit Set-Cookie (?i)^(.*)(;\s*secure)??((\s*;)?(.*)) "$1; Secure$3$4"

View File

@@ -1946,7 +1946,7 @@ class ApacheConfigurator(common.Installer):
ssl_vhost.filep) ssl_vhost.filep)
def _verify_no_matching_http_header(self, ssl_vhost, header_substring): def _verify_no_matching_http_header(self, ssl_vhost, header_substring):
"""Checks to see if an there is an existing Header directive that """Checks to see if there is an existing Header directive that
contains the string header_substring. contains the string header_substring.
:param ssl_vhost: vhost to check :param ssl_vhost: vhost to check

View File

@@ -24,6 +24,8 @@ ALL_SSL_OPTIONS_HASHES = [
'0fcdc81280cd179a07ec4d29d3595068b9326b455c488de4b09f585d5dafc137', '0fcdc81280cd179a07ec4d29d3595068b9326b455c488de4b09f585d5dafc137',
'86cc09ad5415cd6d5f09a947fe2501a9344328b1e8a8b458107ea903e80baa6c', '86cc09ad5415cd6d5f09a947fe2501a9344328b1e8a8b458107ea903e80baa6c',
'06675349e457eae856120cdebb564efe546f0b87399f2264baeb41e442c724c7', '06675349e457eae856120cdebb564efe546f0b87399f2264baeb41e442c724c7',
'5cc003edd93fb9cd03d40c7686495f8f058f485f75b5e764b789245a386e6daf',
'007cd497a56a3bb8b6a2c1aeb4997789e7e38992f74e44cc5d13a625a738ac73',
] ]
"""SHA256 hashes of the contents of previous versions of all versions of MOD_SSL_CONF_SRC""" """SHA256 hashes of the contents of previous versions of all versions of MOD_SSL_CONF_SRC"""

View File

@@ -7,20 +7,12 @@
SSLEngine on SSLEngine on
# Intermediate configuration, tweak to your needs # Intermediate configuration, tweak to your needs
SSLProtocol all -SSLv2 -SSLv3 SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
SSLHonorCipherOrder on SSLHonorCipherOrder off
SSLCompression off
SSLOptions +StrictRequire SSLOptions +StrictRequire
# Add vhost name to log entries: # Add vhost name to log entries:
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" vhost_combined LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" vhost_combined
LogFormat "%v %h %l %u %t \"%r\" %>s %b" vhost_common LogFormat "%v %h %l %u %t \"%r\" %>s %b" vhost_common
#CustomLog /var/log/apache2/access.log vhost_combined
#LogLevel warn
#ErrorLog /var/log/apache2/error.log
# Always ensure Cookies have "Secure" set (JAH 2012/1)
#Header edit Set-Cookie (?i)^(.*)(;\s*secure)??((\s*;)?(.*)) "$1; Secure$3$4"

View File

@@ -38,7 +38,7 @@ class CentOSConfigurator(configurator.ApacheConfigurator):
handle_sites=False, handle_sites=False,
challenge_location="/etc/httpd/conf.d", challenge_location="/etc/httpd/conf.d",
MOD_SSL_CONF_SRC=pkg_resources.resource_filename( MOD_SSL_CONF_SRC=pkg_resources.resource_filename(
"certbot_apache", os.path.join("_internal", "centos-options-ssl-apache.conf")) "certbot_apache", os.path.join("_internal", "options-ssl-apache.conf"))
) )
def config_test(self): def config_test(self):

View File

@@ -33,7 +33,7 @@ class FedoraConfigurator(configurator.ApacheConfigurator):
challenge_location="/etc/httpd/conf.d", challenge_location="/etc/httpd/conf.d",
MOD_SSL_CONF_SRC=pkg_resources.resource_filename( MOD_SSL_CONF_SRC=pkg_resources.resource_filename(
# TODO: eventually newest version of Fedora will need their own config # TODO: eventually newest version of Fedora will need their own config
"certbot_apache", os.path.join("_internal", "centos-options-ssl-apache.conf")) "certbot_apache", os.path.join("_internal", "options-ssl-apache.conf"))
) )
def config_test(self): def config_test(self):

View File

@@ -705,7 +705,7 @@ class ApacheParser(object):
split_arg = arg.split("/") split_arg = arg.split("/")
for idx, split in enumerate(split_arg): for idx, split in enumerate(split_arg):
if any(char in ApacheParser.fnmatch_chars for char in split): if any(char in ApacheParser.fnmatch_chars for char in split):
# Turn it into a augeas regex # Turn it into an augeas regex
# TODO: Can this instead be an augeas glob instead of regex # TODO: Can this instead be an augeas glob instead of regex
split_arg[idx] = ("* [label()=~regexp('%s')]" % split_arg[idx] = ("* [label()=~regexp('%s')]" %
self.fnmatch_to_re(split)) self.fnmatch_to_re(split))

View File

@@ -1,3 +1,3 @@
# Remember to update setup.py to match the package versions below. # Remember to update setup.py to match the package versions below.
acme[dev]==0.29.0 acme[dev]==0.29.0
-e certbot[dev] certbot[dev]==1.1.0

View File

@@ -4,13 +4,13 @@ from setuptools import find_packages
from setuptools import setup from setuptools import setup
from setuptools.command.test import test as TestCommand from setuptools.command.test import test as TestCommand
version = '1.1.0.dev0' version = '1.2.0.dev0'
# Remember to update local-oldest-requirements.txt when changing the minimum # Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version. # acme/certbot version.
install_requires = [ install_requires = [
'acme>=0.29.0', 'acme>=0.29.0',
'certbot>=1.0.0.dev0', 'certbot>=1.1.0',
'mock', 'mock',
'python-augeas', 'python-augeas',
'setuptools', 'setuptools',
@@ -45,7 +45,7 @@ setup(
author="Certbot Project", author="Certbot Project",
author_email='client-dev@letsencrypt.org', author_email='client-dev@letsencrypt.org',
license='Apache License 2.0', license='Apache License 2.0',
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
classifiers=[ classifiers=[
'Development Status :: 5 - Production/Stable', 'Development Status :: 5 - Production/Stable',
'Environment :: Plugins', 'Environment :: Plugins',
@@ -56,7 +56,6 @@ setup(
'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.7',

View File

@@ -26,7 +26,7 @@ Listen 443
# Pass Phrase Dialog: # Pass Phrase Dialog:
# Configure the pass phrase gathering process. # Configure the pass phrase gathering process.
# The filtering dialog program (`builtin' is a internal # The filtering dialog program (`builtin' is an internal
# terminal dialog) has to provide the pass phrase on stdout. # terminal dialog) has to provide the pass phrase on stdout.
SSLPassPhraseDialog builtin SSLPassPhraseDialog builtin

View File

@@ -702,7 +702,7 @@ IndexIgnore .??* *~ *# HEADER* README* RCS CVS *,v *,t
# English (en) - Esperanto (eo) - Estonian (et) - French (fr) - German (de) # English (en) - Esperanto (eo) - Estonian (et) - French (fr) - German (de)
# Greek-Modern (el) - Hebrew (he) - Italian (it) - Japanese (ja) # Greek-Modern (el) - Hebrew (he) - Italian (it) - Japanese (ja)
# Korean (ko) - Luxembourgeois* (ltz) - Norwegian Nynorsk (nn) # Korean (ko) - Luxembourgeois* (ltz) - Norwegian Nynorsk (nn)
# Norwegian (no) - Polish (pl) - Portugese (pt) # Norwegian (no) - Polish (pl) - Portuguese (pt)
# Brazilian Portuguese (pt-BR) - Russian (ru) - Swedish (sv) # Brazilian Portuguese (pt-BR) - Russian (ru) - Swedish (sv)
# Simplified Chinese (zh-CN) - Spanish (es) - Traditional Chinese (zh-TW) # Simplified Chinese (zh-CN) - Spanish (es) - Traditional Chinese (zh-TW)
# #

View File

@@ -13,7 +13,7 @@ Listen 443 https
# Pass Phrase Dialog: # Pass Phrase Dialog:
# Configure the pass phrase gathering process. # Configure the pass phrase gathering process.
# The filtering dialog program (`builtin' is a internal # The filtering dialog program (`builtin' is an internal
# terminal dialog) has to provide the pass phrase on stdout. # terminal dialog) has to provide the pass phrase on stdout.
SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog

View File

@@ -31,7 +31,7 @@
# Pass Phrase Dialog: # Pass Phrase Dialog:
# Configure the pass phrase gathering process. # Configure the pass phrase gathering process.
# The filtering dialog program (`builtin' is a internal # The filtering dialog program (`builtin' is an internal
# terminal dialog) has to provide the pass phrase on stdout. # terminal dialog) has to provide the pass phrase on stdout.
SSLPassPhraseDialog exec:/usr/share/apache2/ask-for-passphrase SSLPassPhraseDialog exec:/usr/share/apache2/ask-for-passphrase

View File

@@ -31,7 +31,7 @@
# Pass Phrase Dialog: # Pass Phrase Dialog:
# Configure the pass phrase gathering process. # Configure the pass phrase gathering process.
# The filtering dialog program (`builtin' is a internal # The filtering dialog program (`builtin' is an internal
# terminal dialog) has to provide the pass phrase on stdout. # terminal dialog) has to provide the pass phrase on stdout.
SSLPassPhraseDialog exec:/usr/share/apache2/ask-for-passphrase SSLPassPhraseDialog exec:/usr/share/apache2/ask-for-passphrase

View File

@@ -31,7 +31,7 @@
# Pass Phrase Dialog: # Pass Phrase Dialog:
# Configure the pass phrase gathering process. # Configure the pass phrase gathering process.
# The filtering dialog program (`builtin' is a internal # The filtering dialog program (`builtin' is an internal
# terminal dialog) has to provide the pass phrase on stdout. # terminal dialog) has to provide the pass phrase on stdout.
SSLPassPhraseDialog exec:/usr/share/apache2/ask-for-passphrase SSLPassPhraseDialog exec:/usr/share/apache2/ask-for-passphrase

View File

@@ -33,7 +33,7 @@
# English (en) - Esperanto (eo) - Estonian (et) - French (fr) - German (de) # English (en) - Esperanto (eo) - Estonian (et) - French (fr) - German (de)
# Greek-Modern (el) - Hebrew (he) - Italian (it) - Japanese (ja) # Greek-Modern (el) - Hebrew (he) - Italian (it) - Japanese (ja)
# Korean (ko) - Luxembourgeois* (ltz) - Norwegian Nynorsk (nn) # Korean (ko) - Luxembourgeois* (ltz) - Norwegian Nynorsk (nn)
# Norwegian (no) - Polish (pl) - Portugese (pt) # Norwegian (no) - Polish (pl) - Portuguese (pt)
# Brazilian Portuguese (pt-BR) - Russian (ru) - Swedish (sv) # Brazilian Portuguese (pt-BR) - Russian (ru) - Swedish (sv)
# Simplified Chinese (zh-CN) - Spanish (es) - Traditional Chinese (zh-TW) # Simplified Chinese (zh-CN) - Spanish (es) - Traditional Chinese (zh-TW)
AddLanguage ca .ca AddLanguage ca .ca

View File

@@ -43,7 +43,7 @@ SSLRandomSeed connect builtin
## Pass Phrase Dialog: ## Pass Phrase Dialog:
# Configure the pass phrase gathering process. The filtering dialog program # Configure the pass phrase gathering process. The filtering dialog program
# (`builtin' is a internal terminal dialog) has to provide the pass phrase on # (`builtin' is an internal terminal dialog) has to provide the pass phrase on
# stdout. # stdout.
SSLPassPhraseDialog builtin SSLPassPhraseDialog builtin

View File

@@ -31,7 +31,7 @@ if [ -z "$VENV_PATH" ]; then
fi fi
VENV_BIN="$VENV_PATH/bin" VENV_BIN="$VENV_PATH/bin"
BOOTSTRAP_VERSION_PATH="$VENV_PATH/certbot-auto-bootstrap-version.txt" BOOTSTRAP_VERSION_PATH="$VENV_PATH/certbot-auto-bootstrap-version.txt"
LE_AUTO_VERSION="1.0.0" LE_AUTO_VERSION="1.1.0"
BASENAME=$(basename $0) BASENAME=$(basename $0)
USAGE="Usage: $BASENAME [OPTIONS] USAGE="Usage: $BASENAME [OPTIONS]
A self-updating wrapper script for the Certbot ACME client. When run, updates A self-updating wrapper script for the Certbot ACME client. When run, updates
@@ -256,20 +256,28 @@ DeprecationBootstrap() {
fi fi
} }
MIN_PYTHON_VERSION="2.7" MIN_PYTHON_2_VERSION="2.7"
MIN_PYVER=$(echo "$MIN_PYTHON_VERSION" | sed 's/\.//') MIN_PYVER2=$(echo "$MIN_PYTHON_2_VERSION" | sed 's/\.//')
MIN_PYTHON_3_VERSION="3.5"
MIN_PYVER3=$(echo "$MIN_PYTHON_3_VERSION" | sed 's/\.//')
# Sets LE_PYTHON to Python version string and PYVER to the first two # Sets LE_PYTHON to Python version string and PYVER to the first two
# digits of the python version # digits of the python version.
# MIN_PYVER and MIN_PYTHON_VERSION are also set by this function, and their
# values depend on if we try to use Python 3 or Python 2.
DeterminePythonVersion() { DeterminePythonVersion() {
# Arguments: "NOCRASH" if we shouldn't crash if we don't find a good python # Arguments: "NOCRASH" if we shouldn't crash if we don't find a good python
# #
# If no Python is found, PYVER is set to 0. # If no Python is found, PYVER is set to 0.
if [ "$USE_PYTHON_3" = 1 ]; then if [ "$USE_PYTHON_3" = 1 ]; then
MIN_PYVER=$MIN_PYVER3
MIN_PYTHON_VERSION=$MIN_PYTHON_3_VERSION
for LE_PYTHON in "$LE_PYTHON" python3; do for LE_PYTHON in "$LE_PYTHON" python3; do
# Break (while keeping the LE_PYTHON value) if found. # Break (while keeping the LE_PYTHON value) if found.
$EXISTS "$LE_PYTHON" > /dev/null && break $EXISTS "$LE_PYTHON" > /dev/null && break
done done
else else
MIN_PYVER=$MIN_PYVER2
MIN_PYTHON_VERSION=$MIN_PYTHON_2_VERSION
for LE_PYTHON in "$LE_PYTHON" python2.7 python27 python2 python; do for LE_PYTHON in "$LE_PYTHON" python2.7 python27 python2 python; do
# Break (while keeping the LE_PYTHON value) if found. # Break (while keeping the LE_PYTHON value) if found.
$EXISTS "$LE_PYTHON" > /dev/null && break $EXISTS "$LE_PYTHON" > /dev/null && break
@@ -285,7 +293,7 @@ DeterminePythonVersion() {
fi fi
fi fi
PYVER=`"$LE_PYTHON" -V 2>&1 | cut -d" " -f 2 | cut -d. -f1,2 | sed 's/\.//'` PYVER=$("$LE_PYTHON" -V 2>&1 | cut -d" " -f 2 | cut -d. -f1,2 | sed 's/\.//')
if [ "$PYVER" -lt "$MIN_PYVER" ]; then if [ "$PYVER" -lt "$MIN_PYVER" ]; then
if [ "$1" != "NOCRASH" ]; then if [ "$1" != "NOCRASH" ]; then
error "You have an ancient version of Python entombed in your operating system..." error "You have an ancient version of Python entombed in your operating system..."
@@ -368,7 +376,9 @@ BootstrapDebCommon() {
# Sets TOOL to the name of the package manager # Sets TOOL to the name of the package manager
# Sets appropriate values for YES_FLAG and QUIET_FLAG based on $ASSUME_YES and $QUIET_FLAG. # Sets appropriate values for YES_FLAG and QUIET_FLAG based on $ASSUME_YES and $QUIET_FLAG.
# Enables EPEL if applicable and possible. # Note: this function is called both while selecting the bootstrap scripts and
# during the actual bootstrap. Some things like prompting to user can be done in the latter
# case, but not in the former one.
InitializeRPMCommonBase() { InitializeRPMCommonBase() {
if type dnf 2>/dev/null if type dnf 2>/dev/null
then then
@@ -388,26 +398,6 @@ InitializeRPMCommonBase() {
if [ "$QUIET" = 1 ]; then if [ "$QUIET" = 1 ]; then
QUIET_FLAG='--quiet' QUIET_FLAG='--quiet'
fi fi
if ! $TOOL list *virtualenv >/dev/null 2>&1; then
echo "To use Certbot, packages from the EPEL repository need to be installed."
if ! $TOOL list epel-release >/dev/null 2>&1; then
error "Enable the EPEL repository and try running Certbot again."
exit 1
fi
if [ "$ASSUME_YES" = 1 ]; then
/bin/echo -n "Enabling the EPEL repository in 3 seconds..."
sleep 1s
/bin/echo -ne "\e[0K\rEnabling the EPEL repository in 2 seconds..."
sleep 1s
/bin/echo -e "\e[0K\rEnabling the EPEL repository in 1 second..."
sleep 1s
fi
if ! $TOOL install $YES_FLAG $QUIET_FLAG epel-release; then
error "Could not enable EPEL. Aborting bootstrap!"
exit 1
fi
fi
} }
BootstrapRpmCommonBase() { BootstrapRpmCommonBase() {
@@ -488,13 +478,91 @@ BootstrapRpmCommon() {
BootstrapRpmCommonBase "$python_pkgs" BootstrapRpmCommonBase "$python_pkgs"
} }
# If new packages are installed by BootstrapRpmPython3 below, this version
# number must be increased.
BOOTSTRAP_RPM_PYTHON3_LEGACY_VERSION=1
# Checks if rh-python36 can be installed.
Python36SclIsAvailable() {
InitializeRPMCommonBase >/dev/null 2>&1;
if "${TOOL}" list rh-python36 >/dev/null 2>&1; then
return 0
fi
if "${TOOL}" list centos-release-scl >/dev/null 2>&1; then
return 0
fi
return 1
}
# Try to enable rh-python36 from SCL if it is necessary and possible.
EnablePython36SCL() {
if "$EXISTS" python3.6 > /dev/null 2> /dev/null; then
return 0
fi
if [ ! -f /opt/rh/rh-python36/enable ]; then
return 0
fi
set +e
if ! . /opt/rh/rh-python36/enable; then
error 'Unable to enable rh-python36!'
exit 1
fi
set -e
}
# This bootstrap concerns old RedHat-based distributions that do not ship by default
# with Python 2.7, but only Python 2.6. We bootstrap them by enabling SCL and installing
# Python 3.6. Some of these distributions are: CentOS/RHEL/OL/SL 6.
BootstrapRpmPython3Legacy() {
# Tested with:
# - CentOS 6
InitializeRPMCommonBase
if ! "${TOOL}" list rh-python36 >/dev/null 2>&1; then
echo "To use Certbot on this operating system, packages from the SCL repository need to be installed."
if ! "${TOOL}" list centos-release-scl >/dev/null 2>&1; then
error "Enable the SCL repository and try running Certbot again."
exit 1
fi
if [ "${ASSUME_YES}" = 1 ]; then
/bin/echo -n "Enabling the SCL repository in 3 seconds... (Press Ctrl-C to cancel)"
sleep 1s
/bin/echo -ne "\e[0K\rEnabling the SCL repository in 2 seconds... (Press Ctrl-C to cancel)"
sleep 1s
/bin/echo -e "\e[0K\rEnabling the SCL repository in 1 second... (Press Ctrl-C to cancel)"
sleep 1s
fi
if ! "${TOOL}" install "${YES_FLAG}" "${QUIET_FLAG}" centos-release-scl; then
error "Could not enable SCL. Aborting bootstrap!"
exit 1
fi
fi
# CentOS 6 must use rh-python36 from SCL
if "${TOOL}" list rh-python36 >/dev/null 2>&1; then
python_pkgs="rh-python36-python
rh-python36-python-virtualenv
rh-python36-python-devel
"
else
error "No supported Python package available to install. Aborting bootstrap!"
exit 1
fi
BootstrapRpmCommonBase "${python_pkgs}"
# Enable SCL rh-python36 after bootstrapping.
EnablePython36SCL
}
# If new packages are installed by BootstrapRpmPython3 below, this version # If new packages are installed by BootstrapRpmPython3 below, this version
# number must be increased. # number must be increased.
BOOTSTRAP_RPM_PYTHON3_VERSION=1 BOOTSTRAP_RPM_PYTHON3_VERSION=1
BootstrapRpmPython3() { BootstrapRpmPython3() {
# Tested with: # Tested with:
# - CentOS 6
# - Fedora 29 # - Fedora 29
InitializeRPMCommonBase InitializeRPMCommonBase
@@ -505,12 +573,6 @@ BootstrapRpmPython3() {
python3-virtualenv python3-virtualenv
python3-devel python3-devel
" "
# EPEL uses python34
elif $TOOL list python34 >/dev/null 2>&1; then
python_pkgs="python34
python34-devel
python34-tools
"
else else
error "No supported Python package available to install. Aborting bootstrap!" error "No supported Python package available to install. Aborting bootstrap!"
exit 1 exit 1
@@ -758,6 +820,11 @@ elif [ -f /etc/redhat-release ]; then
RPM_DIST_NAME=`(. /etc/os-release 2> /dev/null && echo $ID) || echo "unknown"` RPM_DIST_NAME=`(. /etc/os-release 2> /dev/null && echo $ID) || echo "unknown"`
if [ "$PYVER" -eq 26 -a $(uname -m) != 'x86_64' ]; then
# 32 bits CentOS 6 and affiliates are not supported anymore by certbot-auto.
DEPRECATED_OS=1
fi
# Set RPM_DIST_VERSION to VERSION_ID from /etc/os-release after splitting on # Set RPM_DIST_VERSION to VERSION_ID from /etc/os-release after splitting on
# '.' characters (e.g. "8.0" becomes "8"). If the command exits with an # '.' characters (e.g. "8.0" becomes "8"). If the command exits with an
# error, RPM_DIST_VERSION is set to "unknown". # error, RPM_DIST_VERSION is set to "unknown".
@@ -769,31 +836,50 @@ elif [ -f /etc/redhat-release ]; then
RPM_DIST_VERSION=0 RPM_DIST_VERSION=0
fi fi
# Starting to Fedora 29, python2 is on a deprecation path. Let's move to python3 then. # Handle legacy RPM distributions
# RHEL 8 also uses python3 by default. if [ "$PYVER" -eq 26 ]; then
if [ "$RPM_DIST_NAME" = "fedora" -a "$RPM_DIST_VERSION" -ge 29 -o "$PYVER" -eq 26 ]; then # Check if an automated bootstrap can be achieved on this system.
RPM_USE_PYTHON_3=1 if ! Python36SclIsAvailable; then
elif [ "$RPM_DIST_NAME" = "rhel" -a "$RPM_DIST_VERSION" -ge 8 ]; then INTERACTIVE_BOOTSTRAP=1
RPM_USE_PYTHON_3=1 fi
elif [ "$RPM_DIST_NAME" = "centos" -a "$RPM_DIST_VERSION" -ge 8 ]; then
RPM_USE_PYTHON_3=1
else
RPM_USE_PYTHON_3=0
fi
if [ "$RPM_USE_PYTHON_3" = 1 ]; then
Bootstrap() { Bootstrap() {
BootstrapMessage "RedHat-based OSes that will use Python3" BootstrapMessage "Legacy RedHat-based OSes that will use Python3"
BootstrapRpmPython3 BootstrapRpmPython3Legacy
} }
USE_PYTHON_3=1 USE_PYTHON_3=1
BOOTSTRAP_VERSION="BootstrapRpmPython3 $BOOTSTRAP_RPM_PYTHON3_VERSION" BOOTSTRAP_VERSION="BootstrapRpmPython3Legacy $BOOTSTRAP_RPM_PYTHON3_LEGACY_VERSION"
# Try now to enable SCL rh-python36 for systems already bootstrapped
# NB: EnablePython36SCL has been defined along with BootstrapRpmPython3Legacy in certbot-auto
EnablePython36SCL
else else
Bootstrap() { # Starting to Fedora 29, python2 is on a deprecation path. Let's move to python3 then.
BootstrapMessage "RedHat-based OSes" # RHEL 8 also uses python3 by default.
BootstrapRpmCommon if [ "$RPM_DIST_NAME" = "fedora" -a "$RPM_DIST_VERSION" -ge 29 ]; then
} RPM_USE_PYTHON_3=1
BOOTSTRAP_VERSION="BootstrapRpmCommon $BOOTSTRAP_RPM_COMMON_VERSION" elif [ "$RPM_DIST_NAME" = "rhel" -a "$RPM_DIST_VERSION" -ge 8 ]; then
RPM_USE_PYTHON_3=1
elif [ "$RPM_DIST_NAME" = "centos" -a "$RPM_DIST_VERSION" -ge 8 ]; then
RPM_USE_PYTHON_3=1
else
RPM_USE_PYTHON_3=0
fi
if [ "$RPM_USE_PYTHON_3" = 1 ]; then
Bootstrap() {
BootstrapMessage "RedHat-based OSes that will use Python3"
BootstrapRpmPython3
}
USE_PYTHON_3=1
BOOTSTRAP_VERSION="BootstrapRpmPython3 $BOOTSTRAP_RPM_PYTHON3_VERSION"
else
Bootstrap() {
BootstrapMessage "RedHat-based OSes"
BootstrapRpmCommon
}
BOOTSTRAP_VERSION="BootstrapRpmCommon $BOOTSTRAP_RPM_COMMON_VERSION"
fi
fi fi
LE_PYTHON="$prev_le_python" LE_PYTHON="$prev_le_python"
@@ -870,6 +956,13 @@ if [ "$NO_BOOTSTRAP" = 1 ]; then
unset BOOTSTRAP_VERSION unset BOOTSTRAP_VERSION
fi fi
if [ "$DEPRECATED_OS" = 1 ]; then
Bootstrap() {
error "Skipping bootstrap because certbot-auto is deprecated on this system."
}
unset BOOTSTRAP_VERSION
fi
# Sets PREV_BOOTSTRAP_VERSION to the identifier for the bootstrap script used # Sets PREV_BOOTSTRAP_VERSION to the identifier for the bootstrap script used
# to install OS dependencies on this system. PREV_BOOTSTRAP_VERSION isn't set # to install OS dependencies on this system. PREV_BOOTSTRAP_VERSION isn't set
# if it is unknown how OS dependencies were installed on this system. # if it is unknown how OS dependencies were installed on this system.
@@ -1067,6 +1160,28 @@ if [ "$1" = "--le-auto-phase2" ]; then
# Phase 2: Create venv, install LE, and run. # Phase 2: Create venv, install LE, and run.
shift 1 # the --le-auto-phase2 arg shift 1 # the --le-auto-phase2 arg
if [ "$DEPRECATED_OS" = 1 ]; then
# Phase 2 damage control mode for deprecated OSes.
# In this situation, we bypass any bootstrap or certbot venv setup.
error "Your system is not supported by certbot-auto anymore."
if [ ! -d "$VENV_PATH" ] && OldVenvExists; then
VENV_BIN="$OLD_VENV_PATH/bin"
fi
if [ -f "$VENV_BIN/letsencrypt" -a "$INSTALL_ONLY" != 1 ]; then
error "Certbot will no longer receive updates."
error "Please visit https://certbot.eff.org/ to check for other alternatives."
"$VENV_BIN/letsencrypt" "$@"
exit 0
else
error "Certbot cannot be installed."
error "Please visit https://certbot.eff.org/ to check for other alternatives."
exit 1
fi
fi
SetPrevBootstrapVersion SetPrevBootstrapVersion
if [ -z "$PHASE_1_VERSION" -a "$USE_PYTHON_3" = 1 ]; then if [ -z "$PHASE_1_VERSION" -a "$USE_PYTHON_3" = 1 ]; then
@@ -1078,8 +1193,15 @@ if [ "$1" = "--le-auto-phase2" ]; then
# If the selected Bootstrap function isn't a noop and it differs from the # If the selected Bootstrap function isn't a noop and it differs from the
# previously used version # previously used version
if [ -n "$BOOTSTRAP_VERSION" -a "$BOOTSTRAP_VERSION" != "$PREV_BOOTSTRAP_VERSION" ]; then if [ -n "$BOOTSTRAP_VERSION" -a "$BOOTSTRAP_VERSION" != "$PREV_BOOTSTRAP_VERSION" ]; then
# if non-interactive mode or stdin and stdout are connected to a terminal # Check if we can rebootstrap without manual user intervention: this requires that
if [ \( "$NONINTERACTIVE" = 1 \) -o \( \( -t 0 \) -a \( -t 1 \) \) ]; then # certbot-auto is in non-interactive mode AND selected bootstrap does not claim to
# require a manual user intervention.
if [ "$NONINTERACTIVE" = 1 -a "$INTERACTIVE_BOOTSTRAP" != 1 ]; then
CAN_REBOOTSTRAP=1
fi
# Check if rebootstrap can be done non-interactively and current shell is non-interactive
# (true if stdin and stdout are not attached to a terminal).
if [ \( "$CAN_REBOOTSTRAP" = 1 \) -o \( \( -t 0 \) -a \( -t 1 \) \) ]; then
if [ -d "$VENV_PATH" ]; then if [ -d "$VENV_PATH" ]; then
rm -rf "$VENV_PATH" rm -rf "$VENV_PATH"
fi fi
@@ -1090,12 +1212,21 @@ if [ "$1" = "--le-auto-phase2" ]; then
ln -s "$VENV_PATH" "$OLD_VENV_PATH" ln -s "$VENV_PATH" "$OLD_VENV_PATH"
fi fi
RerunWithArgs "$@" RerunWithArgs "$@"
# Otherwise bootstrap needs to be done manually by the user.
else else
error "Skipping upgrade because new OS dependencies may need to be installed." # If it is because bootstrapping is interactive, --non-interactive will be of no use.
error if [ "$INTERACTIVE_BOOTSTRAP" = 1 ]; then
error "To upgrade to a newer version, please run this script again manually so you can" error "Skipping upgrade because new OS dependencies may need to be installed."
error "approve changes or with --non-interactive on the command line to automatically" error "This requires manual user intervention: please run this script again manually."
error "install any required packages." # If this is because of the environment (eg. non interactive shell without
# --non-interactive flag set), help the user in that direction.
else
error "Skipping upgrade because new OS dependencies may need to be installed."
error
error "To upgrade to a newer version, please run this script again manually so you can"
error "approve changes or with --non-interactive on the command line to automatically"
error "install any required packages."
fi
# Set INSTALLED_VERSION to be the same so we don't update the venv # Set INSTALLED_VERSION to be the same so we don't update the venv
INSTALLED_VERSION="$LE_AUTO_VERSION" INSTALLED_VERSION="$LE_AUTO_VERSION"
# Continue to use OLD_VENV_PATH if the new venv doesn't exist # Continue to use OLD_VENV_PATH if the new venv doesn't exist
@@ -1372,18 +1503,18 @@ letsencrypt==0.7.0 \
--hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \ --hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \
--hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9 --hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9
certbot==1.0.0 \ certbot==1.1.0 \
--hash=sha256:8d074cff89dee002dec1c47cb0da04ea8e0ede8d68838b6d54aa41580d9262df \ --hash=sha256:66a5cab9267349941604c2c98082bfef85877653c023fc324b1c3869fb16add6 \
--hash=sha256:86b82d31db19fffffb0d6b218951e2121ef514e3ff659aa042deaf92a33e302a --hash=sha256:46e93661a0db53f416c0f5476d8d2e62bc7259b7660dd983453b85df9ef6e8b8
acme==1.0.0 \ acme==1.1.0 \
--hash=sha256:f6972e436e76f7f1e395e81e149f8713ca8462d465b14993bddc53fb18a40644 \ --hash=sha256:11b9beba706fb8f652c8910d46dd1939d670cac8169f3c66c18c080ed3353e71 \
--hash=sha256:6a08f12f848ce563b50bca421ba9db653df9f82cfefeaf8aba517f046d1386c2 --hash=sha256:c305a20eeb9cb02240347703d497891c13d43a47c794fa100d4dbb479a5370d9
certbot-apache==1.0.0 \ certbot-apache==1.1.0 \
--hash=sha256:e591d0cf773ad33ee978f7adb1b69288eac2c8847c643b06e70260e707626f8e \ --hash=sha256:9c847ff223c2e465e241c78d22f97cee77d5e551df608bed06c55f8627f4cbd2 \
--hash=sha256:7335ab5687a0a47d9041d9e13f3a2d67d0e8372da97ab639edb31c14b787cd68 --hash=sha256:05e84dfe96b72582cde97c490977d8e2d33d440c927a320debb4cf287f6fadcc
certbot-nginx==1.0.0 \ certbot-nginx==1.1.0 \
--hash=sha256:ce8a2e51165da7c15bfdc059cd6572d0f368c078f1e1a77633a2773310b2f231 \ --hash=sha256:bf06fa2f5059f0fdb7d352c8739e1ed0830db4f0d89e812dab4f081bda6ec7d6 \
--hash=sha256:63b4ae09d4f1c9ef0a1a2a49c3f651d8a7cb30303ec6f954239e987c5da45dc4 --hash=sha256:0a80ecbd2a30f3757c7652cabfff854ca07873b1cf02ebbe1892786c3b3a5874
UNLIKELY_EOF UNLIKELY_EOF
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
@@ -1617,6 +1748,9 @@ UNLIKELY_EOF
say "Installation succeeded." say "Installation succeeded."
fi fi
# If you're modifying any of the code after this point in this current `if` block, you
# may need to update the "$DEPRECATED_OS" = 1 case at the beginning of phase 2 as well.
if [ "$INSTALL_ONLY" = 1 ]; then if [ "$INSTALL_ONLY" = 1 ]; then
say "Certbot is installed." say "Certbot is installed."
exit 0 exit 0
@@ -1828,30 +1962,35 @@ UNLIKELY_EOF
error "WARNING: unable to check for updates." error "WARNING: unable to check for updates."
fi fi
LE_VERSION_STATE=`CompareVersions "$LE_PYTHON" "$LE_AUTO_VERSION" "$REMOTE_VERSION"` # If for any reason REMOTE_VERSION is not set, let's assume certbot-auto is up-to-date,
if [ "$LE_VERSION_STATE" = "UNOFFICIAL" ]; then # and do not go into the self-upgrading process.
say "Unofficial certbot-auto version detected, self-upgrade is disabled: $LE_AUTO_VERSION" if [ -n "$REMOTE_VERSION" ]; then
elif [ "$LE_VERSION_STATE" = "OUTDATED" ]; then LE_VERSION_STATE=`CompareVersions "$LE_PYTHON" "$LE_AUTO_VERSION" "$REMOTE_VERSION"`
say "Upgrading certbot-auto $LE_AUTO_VERSION to $REMOTE_VERSION..."
# Now we drop into Python so we don't have to install even more if [ "$LE_VERSION_STATE" = "UNOFFICIAL" ]; then
# dependencies (curl, etc.), for better flow control, and for the option of say "Unofficial certbot-auto version detected, self-upgrade is disabled: $LE_AUTO_VERSION"
# future Windows compatibility. elif [ "$LE_VERSION_STATE" = "OUTDATED" ]; then
"$LE_PYTHON" "$TEMP_DIR/fetch.py" --le-auto-script "v$REMOTE_VERSION" say "Upgrading certbot-auto $LE_AUTO_VERSION to $REMOTE_VERSION..."
# Install new copy of certbot-auto. # Now we drop into Python so we don't have to install even more
# TODO: Deal with quotes in pathnames. # dependencies (curl, etc.), for better flow control, and for the option of
say "Replacing certbot-auto..." # future Windows compatibility.
# Clone permissions with cp. chmod and chown don't have a --reference "$LE_PYTHON" "$TEMP_DIR/fetch.py" --le-auto-script "v$REMOTE_VERSION"
# option on macOS or BSD, and stat -c on Linux is stat -f on macOS and BSD:
cp -p "$0" "$TEMP_DIR/letsencrypt-auto.permission-clone" # Install new copy of certbot-auto.
cp "$TEMP_DIR/letsencrypt-auto" "$TEMP_DIR/letsencrypt-auto.permission-clone" # TODO: Deal with quotes in pathnames.
# Using mv rather than cp leaves the old file descriptor pointing to the say "Replacing certbot-auto..."
# original copy so the shell can continue to read it unmolested. mv across # Clone permissions with cp. chmod and chown don't have a --reference
# filesystems is non-atomic, doing `rm dest, cp src dest, rm src`, but the # option on macOS or BSD, and stat -c on Linux is stat -f on macOS and BSD:
# cp is unlikely to fail if the rm doesn't. cp -p "$0" "$TEMP_DIR/letsencrypt-auto.permission-clone"
mv -f "$TEMP_DIR/letsencrypt-auto.permission-clone" "$0" cp "$TEMP_DIR/letsencrypt-auto" "$TEMP_DIR/letsencrypt-auto.permission-clone"
fi # A newer version is available. # Using mv rather than cp leaves the old file descriptor pointing to the
# original copy so the shell can continue to read it unmolested. mv across
# filesystems is non-atomic, doing `rm dest, cp src dest, rm src`, but the
# cp is unlikely to fail if the rm doesn't.
mv -f "$TEMP_DIR/letsencrypt-auto.permission-clone" "$0"
fi # A newer version is available.
fi
fi # Self-upgrading is allowed. fi # Self-upgrading is allowed.
RerunWithArgs --le-auto-phase2 "$@" RerunWithArgs --le-auto-phase2 "$@"

View File

@@ -62,7 +62,7 @@ def _setup_primary_node(config):
""" """
Setup the environment for integration tests. Setup the environment for integration tests.
Will: Will:
- check runtime compatiblity (Docker, docker-compose, Nginx) - check runtime compatibility (Docker, docker-compose, Nginx)
- create a temporary workspace and the persistent GIT repositories space - create a temporary workspace and the persistent GIT repositories space
- configure and start paralleled ACME CA servers using Docker - configure and start paralleled ACME CA servers using Docker
- transfer ACME CA servers configurations to pytest nodes using env variables - transfer ACME CA servers configurations to pytest nodes using env variables

View File

@@ -189,7 +189,7 @@ class ACMEServer(object):
print('=> Finished configuring the HTTP proxy.') print('=> Finished configuring the HTTP proxy.')
def _launch_process(self, command, cwd=os.getcwd(), env=None): def _launch_process(self, command, cwd=os.getcwd(), env=None):
"""Launch silently an subprocess OS command""" """Launch silently a subprocess OS command"""
if not env: if not env:
env = os.environ env = os.environ
process = subprocess.Popen(command, stdout=self._stdout, stderr=subprocess.STDOUT, cwd=cwd, env=env) process = subprocess.Popen(command, stdout=self._stdout, stderr=subprocess.STDOUT, cwd=cwd, env=env)

View File

@@ -40,7 +40,7 @@ setup(
author="Certbot Project", author="Certbot Project",
author_email='client-dev@letsencrypt.org', author_email='client-dev@letsencrypt.org',
license='Apache License 2.0', license='Apache License 2.0',
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
classifiers=[ classifiers=[
'Development Status :: 3 - Alpha', 'Development Status :: 3 - Alpha',
'Intended Audience :: Developers', 'Intended Audience :: Developers',
@@ -49,7 +49,6 @@ setup(
'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.7',

View File

@@ -39,7 +39,7 @@ class ValidatorTest(unittest.TestCase):
cert, "test.com", "127.0.0.1")) cert, "test.com", "127.0.0.1"))
@mock.patch("certbot_compatibility_test.validator.requests.get") @mock.patch("certbot_compatibility_test.validator.requests.get")
def test_succesful_redirect(self, mock_get_request): def test_successful_redirect(self, mock_get_request):
mock_get_request.return_value = create_response( mock_get_request.return_value = create_response(
301, {"location": "https://test.com"}) 301, {"location": "https://test.com"})
self.assertTrue(self.validator.redirect("test.com")) self.assertTrue(self.validator.redirect("test.com"))

View File

@@ -3,7 +3,7 @@ import sys
from setuptools import find_packages from setuptools import find_packages
from setuptools import setup from setuptools import setup
version = '1.1.0.dev0' version = '1.2.0.dev0'
install_requires = [ install_requires = [
'certbot', 'certbot',
@@ -28,7 +28,7 @@ setup(
author="Certbot Project", author="Certbot Project",
author_email='client-dev@letsencrypt.org', author_email='client-dev@letsencrypt.org',
license='Apache License 2.0', license='Apache License 2.0',
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
classifiers=[ classifiers=[
'Development Status :: 3 - Alpha', 'Development Status :: 3 - Alpha',
'Intended Audience :: Developers', 'Intended Audience :: Developers',
@@ -37,7 +37,6 @@ setup(
'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.7',

View File

@@ -22,17 +22,40 @@ Credentials
Use of this plugin requires a configuration file containing Cloudflare API Use of this plugin requires a configuration file containing Cloudflare API
credentials, obtained from your Cloudflare credentials, obtained from your Cloudflare
`account page <https://www.cloudflare.com/a/account/my-account>`_. This plugin `account page <https://dash.cloudflare.com/profile/api-tokens>`_.
does not currently support Cloudflare's "API Tokens", so please ensure you use
the "Global API Key" for authentication. Previously, Cloudflare's "Global API Key" was used for authentication, however
this key can access the entire Cloudflare API for all domains in your account,
meaning it could cause a lot of damage if leaked.
Cloudflare's newer API Tokens can be restricted to specific domains and
operations, and are therefore now the recommended authentication option.
However, due to some shortcomings in Cloudflare's implementation of Tokens,
Tokens created for Certbot currently require ``Zone:Zone:Read`` and ``Zone:DNS:Edit``
permissions for **all** zones in your account. While this is not ideal, your Token
will still have fewer permission than the Global key, so it's still worth doing.
Hopefully Cloudflare will improve this in the future.
Using Cloudflare Tokens also requires at least version 2.3.1 of the ``cloudflare``
python module. If the version that automatically installed with this plugin is
older than that, and you can't upgrade it on your system, you'll have to stick to
the Global key.
.. code-block:: ini .. code-block:: ini
:name: credentials.ini :name: certbot_cloudflare_token.ini
:caption: Example credentials file: :caption: Example credentials file using restricted API Token (recommended):
# Cloudflare API token used by Certbot
dns_cloudflare_api_token = 0123456789abcdef0123456789abcdef01234567
.. code-block:: ini
:name: certbot_cloudflare_key.ini
:caption: Example credentials file using Global API Key (not recommended):
# Cloudflare API credentials used by Certbot # Cloudflare API credentials used by Certbot
dns_cloudflare_email = cloudflare@example.com dns_cloudflare_email = cloudflare@example.com
dns_cloudflare_api_key = 0123456789abcdef0123456789abcdef01234567 dns_cloudflare_api_key = 0123456789abcdef0123456789abcdef01234
The path to this file can be provided interactively or using the The path to this file can be provided interactively or using the
``--dns-cloudflare-credentials`` command-line argument. Certbot records the path ``--dns-cloudflare-credentials`` command-line argument. Certbot records the path

View File

@@ -4,6 +4,10 @@ import logging
import CloudFlare import CloudFlare
import zope.interface import zope.interface
from acme.magic_typing import Any
from acme.magic_typing import Dict
from acme.magic_typing import List
from certbot import errors from certbot import errors
from certbot import interfaces from certbot import interfaces
from certbot.plugins import dns_common from certbot.plugins import dns_common
@@ -38,14 +42,35 @@ class Authenticator(dns_common.DNSAuthenticator):
return 'This plugin configures a DNS TXT record to respond to a dns-01 challenge using ' + \ return 'This plugin configures a DNS TXT record to respond to a dns-01 challenge using ' + \
'the Cloudflare API.' 'the Cloudflare API.'
def _validate_credentials(self, credentials):
token = credentials.conf('api-token')
email = credentials.conf('email')
key = credentials.conf('api-key')
if token:
if email or key:
raise errors.PluginError('{}: dns_cloudflare_email and dns_cloudflare_api_key are '
'not needed when using an API Token'
.format(credentials.confobj.filename))
elif email or key:
if not email:
raise errors.PluginError('{}: dns_cloudflare_email is required when using a Global '
'API Key. (should be email address associated with '
'Cloudflare account)'.format(credentials.confobj.filename))
if not key:
raise errors.PluginError('{}: dns_cloudflare_api_key is required when using a '
'Global API Key. (see {})'
.format(credentials.confobj.filename, ACCOUNT_URL))
else:
raise errors.PluginError('{}: Either dns_cloudflare_api_token (recommended), or '
'dns_cloudflare_email and dns_cloudflare_api_key are required.'
' (see {})'.format(credentials.confobj.filename, ACCOUNT_URL))
def _setup_credentials(self): def _setup_credentials(self):
self.credentials = self._configure_credentials( self.credentials = self._configure_credentials(
'credentials', 'credentials',
'Cloudflare credentials INI file', 'Cloudflare credentials INI file',
{ None,
'email': 'email address associated with Cloudflare account', self._validate_credentials
'api-key': 'API key for Cloudflare account, obtained from {0}'.format(ACCOUNT_URL)
}
) )
def _perform(self, domain, validation_name, validation): def _perform(self, domain, validation_name, validation):
@@ -55,6 +80,8 @@ class Authenticator(dns_common.DNSAuthenticator):
self._get_cloudflare_client().del_txt_record(domain, validation_name, validation) self._get_cloudflare_client().del_txt_record(domain, validation_name, validation)
def _get_cloudflare_client(self): def _get_cloudflare_client(self):
if self.credentials.conf('api-token'):
return _CloudflareClient(None, self.credentials.conf('api-token'))
return _CloudflareClient(self.credentials.conf('email'), self.credentials.conf('api-key')) return _CloudflareClient(self.credentials.conf('email'), self.credentials.conf('api-key'))
@@ -88,8 +115,15 @@ class _CloudflareClient(object):
logger.debug('Attempting to add record to zone %s: %s', zone_id, data) logger.debug('Attempting to add record to zone %s: %s', zone_id, data)
self.cf.zones.dns_records.post(zone_id, data=data) # zones | pylint: disable=no-member self.cf.zones.dns_records.post(zone_id, data=data) # zones | pylint: disable=no-member
except CloudFlare.exceptions.CloudFlareAPIError as e: except CloudFlare.exceptions.CloudFlareAPIError as e:
code = int(e)
hint = None
if code == 9109:
hint = 'Does your API token have "Zone:DNS:Edit" permissions?'
logger.error('Encountered CloudFlareAPIError adding TXT record: %d %s', e, e) logger.error('Encountered CloudFlareAPIError adding TXT record: %d %s', e, e)
raise errors.PluginError('Error communicating with the Cloudflare API: {0}'.format(e)) raise errors.PluginError('Error communicating with the Cloudflare API: {0}{1}'
.format(e, ' ({0})'.format(hint) if hint else ''))
record_id = self._find_txt_record_id(zone_id, record_name, record_content) record_id = self._find_txt_record_id(zone_id, record_name, record_content)
logger.debug('Successfully added TXT record with record_id: %s', record_id) logger.debug('Successfully added TXT record with record_id: %s', record_id)
@@ -139,6 +173,8 @@ class _CloudflareClient(object):
""" """
zone_name_guesses = dns_common.base_domain_name_guesses(domain) zone_name_guesses = dns_common.base_domain_name_guesses(domain)
zones = [] # type: List[Dict[str, Any]]
code = msg = None
for zone_name in zone_name_guesses: for zone_name in zone_name_guesses:
params = {'name': zone_name, params = {'name': zone_name,
@@ -148,16 +184,26 @@ class _CloudflareClient(object):
zones = self.cf.zones.get(params=params) # zones | pylint: disable=no-member zones = self.cf.zones.get(params=params) # zones | pylint: disable=no-member
except CloudFlare.exceptions.CloudFlareAPIError as e: except CloudFlare.exceptions.CloudFlareAPIError as e:
code = int(e) code = int(e)
msg = str(e)
hint = None hint = None
if code == 6003: if code == 6003:
hint = 'Did you copy your entire API key?' hint = ('Did you copy your entire API token/key? To use Cloudflare tokens, '
'you\'ll need the python package cloudflare>=2.3.1.{}'
.format(' This certbot is running cloudflare ' + str(CloudFlare.__version__)
if hasattr(CloudFlare, '__version__') else ''))
elif code == 9103: elif code == 9103:
hint = 'Did you enter the correct email address?' hint = 'Did you enter the correct email address and Global key?'
elif code == 9109:
hint = 'Did you enter a valid Cloudflare Token?'
raise errors.PluginError('Error determining zone_id: {0} {1}. Please confirm that ' if hint:
'you have supplied valid Cloudflare API credentials.{2}' raise errors.PluginError('Error determining zone_id: {0} {1}. Please confirm '
.format(code, e, ' ({0})'.format(hint) if hint else '')) 'that you have supplied valid Cloudflare API credentials. ({2})'
.format(code, msg, hint))
else:
logger.debug('Unrecognised CloudFlareAPIError while finding zone_id: %d %s. '
'Continuing with next zone guess...', e, e)
if zones: if zones:
zone_id = zones[0]['id'] zone_id = zones[0]['id']
@@ -165,9 +211,10 @@ class _CloudflareClient(object):
return zone_id return zone_id
raise errors.PluginError('Unable to determine zone_id for {0} using zone names: {1}. ' raise errors.PluginError('Unable to determine zone_id for {0} using zone names: {1}. '
'Please confirm that the domain name has been entered correctly ' 'Please confirm that the domain name has been entered correctly '
'and is already associated with the supplied Cloudflare account.' 'and is already associated with the supplied Cloudflare account.{2}'
.format(domain, zone_name_guesses)) .format(domain, zone_name_guesses, ' The error from Cloudflare was:'
' {0} {1}'.format(code, msg) if code is not None else ''))
def _find_txt_record_id(self, zone_id, record_name, record_content): def _find_txt_record_id(self, zone_id, record_name, record_content):
""" """

View File

@@ -38,7 +38,7 @@ extensions = ['sphinx.ext.autodoc',
'sphinx.ext.viewcode'] 'sphinx.ext.viewcode']
autodoc_member_order = 'bysource' autodoc_member_order = 'bysource'
autodoc_default_flags = ['show-inheritance', 'private-members'] autodoc_default_flags = ['show-inheritance']
# Add any paths that contain templates here, relative to this directory. # Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates'] templates_path = ['_templates']

View File

@@ -1,3 +1,3 @@
# Remember to update setup.py to match the package versions below. # Remember to update setup.py to match the package versions below.
acme[dev]==0.29.0 acme[dev]==0.29.0
-e certbot[dev] certbot[dev]==1.1.0

View File

@@ -4,13 +4,13 @@ from setuptools import find_packages
from setuptools import setup from setuptools import setup
from setuptools.command.test import test as TestCommand from setuptools.command.test import test as TestCommand
version = '1.1.0.dev0' version = '1.2.0.dev0'
# Remember to update local-oldest-requirements.txt when changing the minimum # Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version. # acme/certbot version.
install_requires = [ install_requires = [
'acme>=0.29.0', 'acme>=0.29.0',
'certbot>=1.0.0.dev0', 'certbot>=1.1.0',
'cloudflare>=1.5.1', 'cloudflare>=1.5.1',
'mock', 'mock',
'setuptools', 'setuptools',
@@ -44,7 +44,7 @@ setup(
author="Certbot Project", author="Certbot Project",
author_email='client-dev@letsencrypt.org', author_email='client-dev@letsencrypt.org',
license='Apache License 2.0', license='Apache License 2.0',
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
classifiers=[ classifiers=[
'Development Status :: 5 - Production/Stable', 'Development Status :: 5 - Production/Stable',
'Environment :: Plugins', 'Environment :: Plugins',
@@ -55,7 +55,6 @@ setup(
'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.7',

View File

@@ -12,6 +12,9 @@ from certbot.plugins.dns_test_common import DOMAIN
from certbot.tests import util as test_util from certbot.tests import util as test_util
API_ERROR = CloudFlare.exceptions.CloudFlareAPIError(1000, '', '') API_ERROR = CloudFlare.exceptions.CloudFlareAPIError(1000, '', '')
API_TOKEN = 'an-api-token'
API_KEY = 'an-api-key' API_KEY = 'an-api-key'
EMAIL = 'example@example.com' EMAIL = 'example@example.com'
@@ -49,6 +52,50 @@ class AuthenticatorTest(test_util.TempDirTestCase, dns_test_common.BaseAuthentic
expected = [mock.call.del_txt_record(DOMAIN, '_acme-challenge.'+DOMAIN, mock.ANY)] expected = [mock.call.del_txt_record(DOMAIN, '_acme-challenge.'+DOMAIN, mock.ANY)]
self.assertEqual(expected, self.mock_client.mock_calls) self.assertEqual(expected, self.mock_client.mock_calls)
def test_api_token(self):
dns_test_common.write({"cloudflare_api_token": API_TOKEN},
self.config.cloudflare_credentials)
self.auth.perform([self.achall])
expected = [mock.call.add_txt_record(DOMAIN, '_acme-challenge.'+DOMAIN, mock.ANY, mock.ANY)]
self.assertEqual(expected, self.mock_client.mock_calls)
def test_no_creds(self):
dns_test_common.write({}, self.config.cloudflare_credentials)
self.assertRaises(errors.PluginError,
self.auth.perform,
[self.achall])
def test_missing_email_or_key(self):
dns_test_common.write({"cloudflare_api_key": API_KEY}, self.config.cloudflare_credentials)
self.assertRaises(errors.PluginError,
self.auth.perform,
[self.achall])
dns_test_common.write({"cloudflare_email": EMAIL}, self.config.cloudflare_credentials)
self.assertRaises(errors.PluginError,
self.auth.perform,
[self.achall])
def test_email_or_key_with_token(self):
dns_test_common.write({"cloudflare_api_token": API_TOKEN, "cloudflare_email": EMAIL},
self.config.cloudflare_credentials)
self.assertRaises(errors.PluginError,
self.auth.perform,
[self.achall])
dns_test_common.write({"cloudflare_api_token": API_TOKEN, "cloudflare_api_key": API_KEY},
self.config.cloudflare_credentials)
self.assertRaises(errors.PluginError,
self.auth.perform,
[self.achall])
dns_test_common.write({"cloudflare_api_token": API_TOKEN, "cloudflare_email": EMAIL,
"cloudflare_api_key": API_KEY}, self.config.cloudflare_credentials)
self.assertRaises(errors.PluginError,
self.auth.perform,
[self.achall])
class CloudflareClientTest(unittest.TestCase): class CloudflareClientTest(unittest.TestCase):
record_name = "foo" record_name = "foo"
@@ -83,7 +130,7 @@ class CloudflareClientTest(unittest.TestCase):
def test_add_txt_record_error(self): def test_add_txt_record_error(self):
self.cf.zones.get.return_value = [{'id': self.zone_id}] self.cf.zones.get.return_value = [{'id': self.zone_id}]
self.cf.zones.dns_records.post.side_effect = API_ERROR self.cf.zones.dns_records.post.side_effect = CloudFlare.exceptions.CloudFlareAPIError(9109, '', '')
self.assertRaises( self.assertRaises(
errors.PluginError, errors.PluginError,
@@ -106,6 +153,25 @@ class CloudflareClientTest(unittest.TestCase):
self.cloudflare_client.add_txt_record, self.cloudflare_client.add_txt_record,
DOMAIN, self.record_name, self.record_content, self.record_ttl) DOMAIN, self.record_name, self.record_content, self.record_ttl)
def test_add_txt_record_bad_creds(self):
self.cf.zones.get.side_effect = CloudFlare.exceptions.CloudFlareAPIError(6003, '', '')
self.assertRaises(
errors.PluginError,
self.cloudflare_client.add_txt_record,
DOMAIN, self.record_name, self.record_content, self.record_ttl)
self.cf.zones.get.side_effect = CloudFlare.exceptions.CloudFlareAPIError(9103, '', '')
self.assertRaises(
errors.PluginError,
self.cloudflare_client.add_txt_record,
DOMAIN, self.record_name, self.record_content, self.record_ttl)
self.cf.zones.get.side_effect = CloudFlare.exceptions.CloudFlareAPIError(9109, '', '')
self.assertRaises(
errors.PluginError,
self.cloudflare_client.add_txt_record,
DOMAIN, self.record_name, self.record_content, self.record_ttl)
def test_del_txt_record(self): def test_del_txt_record(self):
self.cf.zones.get.return_value = [{'id': self.zone_id}] self.cf.zones.get.return_value = [{'id': self.zone_id}]
self.cf.zones.dns_records.get.return_value = [{'id': self.record_id}] self.cf.zones.dns_records.get.return_value = [{'id': self.record_id}]

View File

@@ -38,7 +38,7 @@ extensions = ['sphinx.ext.autodoc',
'sphinx.ext.viewcode'] 'sphinx.ext.viewcode']
autodoc_member_order = 'bysource' autodoc_member_order = 'bysource'
autodoc_default_flags = ['show-inheritance', 'private-members'] autodoc_default_flags = ['show-inheritance']
# Add any paths that contain templates here, relative to this directory. # Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates'] templates_path = ['_templates']

View File

@@ -1,3 +1,3 @@
# Remember to update setup.py to match the package versions below. # Remember to update setup.py to match the package versions below.
acme[dev]==0.31.0 acme[dev]==0.31.0
-e certbot[dev] certbot[dev]==1.1.0

View File

@@ -4,13 +4,13 @@ from setuptools import find_packages
from setuptools import setup from setuptools import setup
from setuptools.command.test import test as TestCommand from setuptools.command.test import test as TestCommand
version = '1.1.0.dev0' version = '1.2.0.dev0'
# Remember to update local-oldest-requirements.txt when changing the minimum # Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version. # acme/certbot version.
install_requires = [ install_requires = [
'acme>=0.31.0', 'acme>=0.31.0',
'certbot>=1.0.0.dev0', 'certbot>=1.1.0',
'dns-lexicon>=2.2.1', # Support for >1 TXT record per name 'dns-lexicon>=2.2.1', # Support for >1 TXT record per name
'mock', 'mock',
'setuptools', 'setuptools',
@@ -44,7 +44,7 @@ setup(
author="Certbot Project", author="Certbot Project",
author_email='client-dev@letsencrypt.org', author_email='client-dev@letsencrypt.org',
license='Apache License 2.0', license='Apache License 2.0',
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
classifiers=[ classifiers=[
'Development Status :: 5 - Production/Stable', 'Development Status :: 5 - Production/Stable',
'Environment :: Plugins', 'Environment :: Plugins',
@@ -55,7 +55,6 @@ setup(
'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.7',

View File

@@ -38,7 +38,7 @@ extensions = ['sphinx.ext.autodoc',
'sphinx.ext.viewcode'] 'sphinx.ext.viewcode']
autodoc_member_order = 'bysource' autodoc_member_order = 'bysource'
autodoc_default_flags = ['show-inheritance', 'private-members'] autodoc_default_flags = ['show-inheritance']
# Add any paths that contain templates here, relative to this directory. # Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates'] templates_path = ['_templates']

View File

@@ -1,3 +1,3 @@
# Remember to update setup.py to match the package versions below. # Remember to update setup.py to match the package versions below.
acme[dev]==0.29.0 acme[dev]==0.29.0
-e certbot[dev] certbot[dev]==1.1.0

View File

@@ -4,13 +4,13 @@ from setuptools import find_packages
from setuptools import setup from setuptools import setup
from setuptools.command.test import test as TestCommand from setuptools.command.test import test as TestCommand
version = '1.1.0.dev0' version = '1.2.0.dev0'
# Remember to update local-oldest-requirements.txt when changing the minimum # Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version. # acme/certbot version.
install_requires = [ install_requires = [
'acme>=0.29.0', 'acme>=0.29.0',
'certbot>=1.0.0.dev0', 'certbot>=1.1.0',
'mock', 'mock',
'python-digitalocean>=1.11', 'python-digitalocean>=1.11',
'setuptools', 'setuptools',
@@ -45,7 +45,7 @@ setup(
author="Certbot Project", author="Certbot Project",
author_email='client-dev@letsencrypt.org', author_email='client-dev@letsencrypt.org',
license='Apache License 2.0', license='Apache License 2.0',
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
classifiers=[ classifiers=[
'Development Status :: 5 - Production/Stable', 'Development Status :: 5 - Production/Stable',
'Environment :: Plugins', 'Environment :: Plugins',
@@ -56,7 +56,6 @@ setup(
'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.7',

View File

@@ -38,7 +38,7 @@ extensions = ['sphinx.ext.autodoc',
'sphinx.ext.viewcode'] 'sphinx.ext.viewcode']
autodoc_member_order = 'bysource' autodoc_member_order = 'bysource'
autodoc_default_flags = ['show-inheritance', 'private-members'] autodoc_default_flags = ['show-inheritance']
# Add any paths that contain templates here, relative to this directory. # Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates'] templates_path = ['_templates']

View File

@@ -1,3 +1,3 @@
# Remember to update setup.py to match the package versions below. # Remember to update setup.py to match the package versions below.
acme[dev]==0.31.0 acme[dev]==0.31.0
-e certbot[dev] certbot[dev]==1.1.0

View File

@@ -5,13 +5,13 @@ from setuptools import find_packages
from setuptools import setup from setuptools import setup
from setuptools.command.test import test as TestCommand from setuptools.command.test import test as TestCommand
version = '1.1.0.dev0' version = '1.2.0.dev0'
# Remember to update local-oldest-requirements.txt when changing the minimum # Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version. # acme/certbot version.
install_requires = [ install_requires = [
'acme>=0.31.0', 'acme>=0.31.0',
'certbot>=1.0.0.dev0', 'certbot>=1.1.0',
'mock', 'mock',
'setuptools', 'setuptools',
'zope.interface', 'zope.interface',
@@ -56,7 +56,7 @@ setup(
author="Certbot Project", author="Certbot Project",
author_email='client-dev@letsencrypt.org', author_email='client-dev@letsencrypt.org',
license='Apache License 2.0', license='Apache License 2.0',
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
classifiers=[ classifiers=[
'Development Status :: 5 - Production/Stable', 'Development Status :: 5 - Production/Stable',
'Environment :: Plugins', 'Environment :: Plugins',
@@ -67,7 +67,6 @@ setup(
'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.7',

View File

@@ -38,7 +38,7 @@ extensions = ['sphinx.ext.autodoc',
'sphinx.ext.viewcode'] 'sphinx.ext.viewcode']
autodoc_member_order = 'bysource' autodoc_member_order = 'bysource'
autodoc_default_flags = ['show-inheritance', 'private-members'] autodoc_default_flags = ['show-inheritance']
# Add any paths that contain templates here, relative to this directory. # Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates'] templates_path = ['_templates']

View File

@@ -1,3 +1,3 @@
# Remember to update setup.py to match the package versions below. # Remember to update setup.py to match the package versions below.
acme[dev]==0.31.0 acme[dev]==0.31.0
-e certbot[dev] certbot[dev]==1.1.0

View File

@@ -4,13 +4,13 @@ from setuptools import find_packages
from setuptools import setup from setuptools import setup
from setuptools.command.test import test as TestCommand from setuptools.command.test import test as TestCommand
version = '1.1.0.dev0' version = '1.2.0.dev0'
# Remember to update local-oldest-requirements.txt when changing the minimum # Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version. # acme/certbot version.
install_requires = [ install_requires = [
'acme>=0.31.0', 'acme>=0.31.0',
'certbot>=1.0.0.dev0', 'certbot>=1.1.0',
'dns-lexicon>=2.2.1', # Support for >1 TXT record per name 'dns-lexicon>=2.2.1', # Support for >1 TXT record per name
'mock', 'mock',
'setuptools', 'setuptools',
@@ -44,7 +44,7 @@ setup(
author="Certbot Project", author="Certbot Project",
author_email='client-dev@letsencrypt.org', author_email='client-dev@letsencrypt.org',
license='Apache License 2.0', license='Apache License 2.0',
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
classifiers=[ classifiers=[
'Development Status :: 5 - Production/Stable', 'Development Status :: 5 - Production/Stable',
'Environment :: Plugins', 'Environment :: Plugins',
@@ -55,7 +55,6 @@ setup(
'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.7',

View File

@@ -1 +1 @@
Gehirn Infrastracture Service DNS Authenticator plugin for Certbot Gehirn Infrastructure Service DNS Authenticator plugin for Certbot

View File

@@ -1,14 +1,14 @@
""" """
The `~certbot_dns_gehirn.dns_gehirn` plugin automates the process of completing The `~certbot_dns_gehirn.dns_gehirn` plugin automates the process of completing
a ``dns-01`` challenge (`~acme.challenges.DNS01`) by creating, and subsequently a ``dns-01`` challenge (`~acme.challenges.DNS01`) by creating, and subsequently
removing, TXT records using the Gehirn Infrastracture Service DNS API. removing, TXT records using the Gehirn Infrastructure Service DNS API.
Named Arguments Named Arguments
--------------- ---------------
======================================== ===================================== ======================================== =====================================
``--dns-gehirn-credentials`` Gehirn Infrastracture Service ``--dns-gehirn-credentials`` Gehirn Infrastructure Service
credentials_ INI file. credentials_ INI file.
(Required) (Required)
``--dns-gehirn-propagation-seconds`` The number of seconds to wait for DNS ``--dns-gehirn-propagation-seconds`` The number of seconds to wait for DNS
@@ -22,15 +22,15 @@ Credentials
----------- -----------
Use of this plugin requires a configuration file containing Use of this plugin requires a configuration file containing
Gehirn Infrastracture Service DNS API credentials, Gehirn Infrastructure Service DNS API credentials,
obtained from your Gehirn Infrastracture Service obtained from your Gehirn Infrastructure Service
`dashboard <https://gis.gehirn.jp/>`_. `dashboard <https://gis.gehirn.jp/>`_.
.. code-block:: ini .. code-block:: ini
:name: credentials.ini :name: credentials.ini
:caption: Example credentials file: :caption: Example credentials file:
# Gehirn Infrastracture Service API credentials used by Certbot # Gehirn Infrastructure Service API credentials used by Certbot
dns_gehirn_api_token = 00000000-0000-0000-0000-000000000000 dns_gehirn_api_token = 00000000-0000-0000-0000-000000000000
dns_gehirn_api_secret = MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw dns_gehirn_api_secret = MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw
@@ -40,7 +40,7 @@ to this file for use during renewal, but does not store the file's contents.
.. caution:: .. caution::
You should protect these API credentials as you would the password to your You should protect these API credentials as you would the password to your
Gehirn Infrastracture Service account. Users who can read this file can use Gehirn Infrastructure Service account. Users who can read this file can use
these credentials to issue arbitrary API calls on your behalf. Users who can these credentials to issue arbitrary API calls on your behalf. Users who can
cause Certbot to run using these credentials can complete a ``dns-01`` cause Certbot to run using these credentials can complete a ``dns-01``
challenge to acquire new certificates or revoke existing certificates for challenge to acquire new certificates or revoke existing certificates for

View File

@@ -1,4 +1,4 @@
"""DNS Authenticator for Gehirn Infrastracture Service DNS.""" """DNS Authenticator for Gehirn Infrastructure Service DNS."""
import logging import logging
from lexicon.providers import gehirn from lexicon.providers import gehirn
@@ -15,14 +15,14 @@ DASHBOARD_URL = "https://gis.gehirn.jp/"
@zope.interface.implementer(interfaces.IAuthenticator) @zope.interface.implementer(interfaces.IAuthenticator)
@zope.interface.provider(interfaces.IPluginFactory) @zope.interface.provider(interfaces.IPluginFactory)
class Authenticator(dns_common.DNSAuthenticator): class Authenticator(dns_common.DNSAuthenticator):
"""DNS Authenticator for Gehirn Infrastracture Service DNS """DNS Authenticator for Gehirn Infrastructure Service DNS
This Authenticator uses the Gehirn Infrastracture Service API to fulfill This Authenticator uses the Gehirn Infrastructure Service API to fulfill
a dns-01 challenge. a dns-01 challenge.
""" """
description = 'Obtain certificates using a DNS TXT record ' + \ description = 'Obtain certificates using a DNS TXT record ' + \
'(if you are using Gehirn Infrastracture Service for DNS).' '(if you are using Gehirn Infrastructure Service for DNS).'
ttl = 60 ttl = 60
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@@ -32,20 +32,20 @@ class Authenticator(dns_common.DNSAuthenticator):
@classmethod @classmethod
def add_parser_arguments(cls, add): # pylint: disable=arguments-differ def add_parser_arguments(cls, add): # pylint: disable=arguments-differ
super(Authenticator, cls).add_parser_arguments(add, default_propagation_seconds=30) super(Authenticator, cls).add_parser_arguments(add, default_propagation_seconds=30)
add('credentials', help='Gehirn Infrastracture Service credentials file.') add('credentials', help='Gehirn Infrastructure Service credentials file.')
def more_info(self): # pylint: disable=missing-docstring,no-self-use def more_info(self): # pylint: disable=missing-docstring,no-self-use
return 'This plugin configures a DNS TXT record to respond to a dns-01 challenge using ' + \ return 'This plugin configures a DNS TXT record to respond to a dns-01 challenge using ' + \
'the Gehirn Infrastracture Service API.' 'the Gehirn Infrastructure Service API.'
def _setup_credentials(self): def _setup_credentials(self):
self.credentials = self._configure_credentials( self.credentials = self._configure_credentials(
'credentials', 'credentials',
'Gehirn Infrastracture Service credentials file', 'Gehirn Infrastructure Service credentials file',
{ {
'api-token': 'API token for Gehirn Infrastracture Service ' + \ 'api-token': 'API token for Gehirn Infrastructure Service ' + \
'API obtained from {0}'.format(DASHBOARD_URL), 'API obtained from {0}'.format(DASHBOARD_URL),
'api-secret': 'API secret for Gehirn Infrastracture Service ' + \ 'api-secret': 'API secret for Gehirn Infrastructure Service ' + \
'API obtained from {0}'.format(DASHBOARD_URL), 'API obtained from {0}'.format(DASHBOARD_URL),
} }
) )
@@ -66,7 +66,7 @@ class Authenticator(dns_common.DNSAuthenticator):
class _GehirnLexiconClient(dns_common_lexicon.LexiconClient): class _GehirnLexiconClient(dns_common_lexicon.LexiconClient):
""" """
Encapsulates all communication with the Gehirn Infrastracture Service via Lexicon. Encapsulates all communication with the Gehirn Infrastructure Service via Lexicon.
""" """
def __init__(self, api_token, api_secret, ttl): def __init__(self, api_token, api_secret, ttl):

View File

@@ -38,7 +38,7 @@ extensions = ['sphinx.ext.autodoc',
'sphinx.ext.viewcode'] 'sphinx.ext.viewcode']
autodoc_member_order = 'bysource' autodoc_member_order = 'bysource'
autodoc_default_flags = ['show-inheritance', 'private-members'] autodoc_default_flags = ['show-inheritance']
# Add any paths that contain templates here, relative to this directory. # Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates'] templates_path = ['_templates']

View File

@@ -1,3 +1,3 @@
# Remember to update setup.py to match the package versions below. # Remember to update setup.py to match the package versions below.
acme[dev]==0.31.0 acme[dev]==0.31.0
-e certbot[dev] certbot[dev]==1.1.0

View File

@@ -4,12 +4,12 @@ from setuptools import find_packages
from setuptools import setup from setuptools import setup
from setuptools.command.test import test as TestCommand from setuptools.command.test import test as TestCommand
version = '1.1.0.dev0' version = '1.2.0.dev0'
# Please update tox.ini when modifying dependency version requirements # Please update tox.ini when modifying dependency version requirements
install_requires = [ install_requires = [
'acme>=0.31.0', 'acme>=0.31.0',
'certbot>=1.0.0.dev0', 'certbot>=1.1.0',
'dns-lexicon>=2.1.22', 'dns-lexicon>=2.1.22',
'mock', 'mock',
'setuptools', 'setuptools',
@@ -38,12 +38,12 @@ class PyTest(TestCommand):
setup( setup(
name='certbot-dns-gehirn', name='certbot-dns-gehirn',
version=version, version=version,
description="Gehirn Infrastracture Service DNS Authenticator plugin for Certbot", description="Gehirn Infrastructure Service DNS Authenticator plugin for Certbot",
url='https://github.com/certbot/certbot', url='https://github.com/certbot/certbot',
author="Certbot Project", author="Certbot Project",
author_email='client-dev@letsencrypt.org', author_email='client-dev@letsencrypt.org',
license='Apache License 2.0', license='Apache License 2.0',
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
classifiers=[ classifiers=[
'Development Status :: 5 - Production/Stable', 'Development Status :: 5 - Production/Stable',
'Environment :: Plugins', 'Environment :: Plugins',
@@ -54,7 +54,6 @@ setup(
'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.7',

View File

@@ -39,7 +39,7 @@ extensions = ['sphinx.ext.autodoc',
'jsonlexer'] 'jsonlexer']
autodoc_member_order = 'bysource' autodoc_member_order = 'bysource'
autodoc_default_flags = ['show-inheritance', 'private-members'] autodoc_default_flags = ['show-inheritance']
# Add any paths that contain templates here, relative to this directory. # Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates'] templates_path = ['_templates']

View File

@@ -1,3 +1,3 @@
# Remember to update setup.py to match the package versions below. # Remember to update setup.py to match the package versions below.
acme[dev]==0.29.0 acme[dev]==0.29.0
-e certbot[dev] certbot[dev]==1.1.0

View File

@@ -4,13 +4,13 @@ from setuptools import find_packages
from setuptools import setup from setuptools import setup
from setuptools.command.test import test as TestCommand from setuptools.command.test import test as TestCommand
version = '1.1.0.dev0' version = '1.2.0.dev0'
# Remember to update local-oldest-requirements.txt when changing the minimum # Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version. # acme/certbot version.
install_requires = [ install_requires = [
'acme>=0.29.0', 'acme>=0.29.0',
'certbot>=1.0.0.dev0', 'certbot>=1.1.0',
'google-api-python-client>=1.5.5', 'google-api-python-client>=1.5.5',
'mock', 'mock',
'oauth2client>=4.0', 'oauth2client>=4.0',
@@ -47,7 +47,7 @@ setup(
author="Certbot Project", author="Certbot Project",
author_email='client-dev@letsencrypt.org', author_email='client-dev@letsencrypt.org',
license='Apache License 2.0', license='Apache License 2.0',
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
classifiers=[ classifiers=[
'Development Status :: 5 - Production/Stable', 'Development Status :: 5 - Production/Stable',
'Environment :: Plugins', 'Environment :: Plugins',
@@ -58,7 +58,6 @@ setup(
'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.7',

View File

@@ -38,7 +38,7 @@ extensions = ['sphinx.ext.autodoc',
'sphinx.ext.viewcode'] 'sphinx.ext.viewcode']
autodoc_member_order = 'bysource' autodoc_member_order = 'bysource'
autodoc_default_flags = ['show-inheritance', 'private-members'] autodoc_default_flags = ['show-inheritance']
# Add any paths that contain templates here, relative to this directory. # Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates'] templates_path = ['_templates']

View File

@@ -1,4 +1,4 @@
# Remember to update setup.py to match the package versions below. # Remember to update setup.py to match the package versions below.
acme[dev]==0.31.0 acme[dev]==0.31.0
-e certbot[dev] certbot[dev]==1.1.0
dns-lexicon==2.2.3 dns-lexicon==2.2.3

View File

@@ -4,12 +4,12 @@ from setuptools import find_packages
from setuptools import setup from setuptools import setup
from setuptools.command.test import test as TestCommand from setuptools.command.test import test as TestCommand
version = '1.1.0.dev0' version = '1.2.0.dev0'
# Please update tox.ini when modifying dependency version requirements # Please update tox.ini when modifying dependency version requirements
install_requires = [ install_requires = [
'acme>=0.31.0', 'acme>=0.31.0',
'certbot>=1.0.0.dev0', 'certbot>=1.1.0',
'dns-lexicon>=2.2.3', 'dns-lexicon>=2.2.3',
'mock', 'mock',
'setuptools', 'setuptools',
@@ -43,7 +43,7 @@ setup(
author="Certbot Project", author="Certbot Project",
author_email='client-dev@letsencrypt.org', author_email='client-dev@letsencrypt.org',
license='Apache License 2.0', license='Apache License 2.0',
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
classifiers=[ classifiers=[
'Development Status :: 5 - Production/Stable', 'Development Status :: 5 - Production/Stable',
'Environment :: Plugins', 'Environment :: Plugins',
@@ -54,7 +54,6 @@ setup(
'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.7',

View File

@@ -38,7 +38,7 @@ extensions = ['sphinx.ext.autodoc',
'sphinx.ext.viewcode'] 'sphinx.ext.viewcode']
autodoc_member_order = 'bysource' autodoc_member_order = 'bysource'
autodoc_default_flags = ['show-inheritance', 'private-members'] autodoc_default_flags = ['show-inheritance']
# Add any paths that contain templates here, relative to this directory. # Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates'] templates_path = ['_templates']

View File

@@ -1,3 +1,3 @@
# Remember to update setup.py to match the package versions below. # Remember to update setup.py to match the package versions below.
acme[dev]==0.31.0 acme[dev]==0.31.0
-e certbot[dev] certbot[dev]==1.1.0

View File

@@ -4,13 +4,13 @@ from setuptools import find_packages
from setuptools import setup from setuptools import setup
from setuptools.command.test import test as TestCommand from setuptools.command.test import test as TestCommand
version = '1.1.0.dev0' version = '1.2.0.dev0'
# Remember to update local-oldest-requirements.txt when changing the minimum # Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version. # acme/certbot version.
install_requires = [ install_requires = [
'acme>=0.31.0', 'acme>=0.31.0',
'certbot>=1.0.0.dev0', 'certbot>=1.1.0',
'dns-lexicon>=2.2.1', # Support for >1 TXT record per name 'dns-lexicon>=2.2.1', # Support for >1 TXT record per name
'mock', 'mock',
'setuptools', 'setuptools',
@@ -44,7 +44,7 @@ setup(
author="Certbot Project", author="Certbot Project",
author_email='client-dev@letsencrypt.org', author_email='client-dev@letsencrypt.org',
license='Apache License 2.0', license='Apache License 2.0',
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
classifiers=[ classifiers=[
'Development Status :: 5 - Production/Stable', 'Development Status :: 5 - Production/Stable',
'Environment :: Plugins', 'Environment :: Plugins',
@@ -55,7 +55,6 @@ setup(
'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.7',

View File

@@ -38,7 +38,7 @@ extensions = ['sphinx.ext.autodoc',
'sphinx.ext.viewcode'] 'sphinx.ext.viewcode']
autodoc_member_order = 'bysource' autodoc_member_order = 'bysource'
autodoc_default_flags = ['show-inheritance', 'private-members'] autodoc_default_flags = ['show-inheritance']
# Add any paths that contain templates here, relative to this directory. # Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates'] templates_path = ['_templates']

View File

@@ -1,3 +1,3 @@
# Remember to update setup.py to match the package versions below. # Remember to update setup.py to match the package versions below.
acme[dev]==0.31.0 acme[dev]==0.31.0
-e certbot[dev] certbot[dev]==1.1.0

View File

@@ -4,13 +4,13 @@ from setuptools import find_packages
from setuptools import setup from setuptools import setup
from setuptools.command.test import test as TestCommand from setuptools.command.test import test as TestCommand
version = '1.1.0.dev0' version = '1.2.0.dev0'
# Remember to update local-oldest-requirements.txt when changing the minimum # Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version. # acme/certbot version.
install_requires = [ install_requires = [
'acme>=0.31.0', 'acme>=0.31.0',
'certbot>=1.0.0.dev0', 'certbot>=1.1.0',
'dns-lexicon>=2.2.1', # Support for >1 TXT record per name 'dns-lexicon>=2.2.1', # Support for >1 TXT record per name
'mock', 'mock',
'setuptools', 'setuptools',
@@ -44,7 +44,7 @@ setup(
author="Certbot Project", author="Certbot Project",
author_email='client-dev@letsencrypt.org', author_email='client-dev@letsencrypt.org',
license='Apache License 2.0', license='Apache License 2.0',
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
classifiers=[ classifiers=[
'Development Status :: 5 - Production/Stable', 'Development Status :: 5 - Production/Stable',
'Environment :: Plugins', 'Environment :: Plugins',
@@ -55,7 +55,6 @@ setup(
'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.7',

View File

@@ -38,7 +38,7 @@ extensions = ['sphinx.ext.autodoc',
'sphinx.ext.viewcode'] 'sphinx.ext.viewcode']
autodoc_member_order = 'bysource' autodoc_member_order = 'bysource'
autodoc_default_flags = ['show-inheritance', 'private-members'] autodoc_default_flags = ['show-inheritance']
# Add any paths that contain templates here, relative to this directory. # Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates'] templates_path = ['_templates']

View File

@@ -1,4 +1,4 @@
# Remember to update setup.py to match the package versions below. # Remember to update setup.py to match the package versions below.
acme[dev]==0.31.0 acme[dev]==0.31.0
-e certbot[dev] certbot[dev]==1.1.0
dns-lexicon==2.7.14 dns-lexicon==2.7.14

View File

@@ -4,13 +4,13 @@ from setuptools import find_packages
from setuptools import setup from setuptools import setup
from setuptools.command.test import test as TestCommand from setuptools.command.test import test as TestCommand
version = '1.1.0.dev0' version = '1.2.0.dev0'
# Remember to update local-oldest-requirements.txt when changing the minimum # Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version. # acme/certbot version.
install_requires = [ install_requires = [
'acme>=0.31.0', 'acme>=0.31.0',
'certbot>=1.0.0.dev0', 'certbot>=1.1.0',
'dns-lexicon>=2.7.14', # Correct proxy use on OVH provider 'dns-lexicon>=2.7.14', # Correct proxy use on OVH provider
'mock', 'mock',
'setuptools', 'setuptools',
@@ -44,7 +44,7 @@ setup(
author="Certbot Project", author="Certbot Project",
author_email='client-dev@letsencrypt.org', author_email='client-dev@letsencrypt.org',
license='Apache License 2.0', license='Apache License 2.0',
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
classifiers=[ classifiers=[
'Development Status :: 5 - Production/Stable', 'Development Status :: 5 - Production/Stable',
'Environment :: Plugins', 'Environment :: Plugins',
@@ -55,7 +55,6 @@ setup(
'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.7',

View File

@@ -129,7 +129,7 @@ class _RFC2136Client(object):
rcode = response.rcode() rcode = response.rcode()
if rcode == dns.rcode.NOERROR: if rcode == dns.rcode.NOERROR:
logger.debug('Successfully added TXT record') logger.debug('Successfully added TXT record %s', record_name)
else: else:
raise errors.PluginError('Received response from server: {0}' raise errors.PluginError('Received response from server: {0}'
.format(dns.rcode.to_text(rcode))) .format(dns.rcode.to_text(rcode)))
@@ -164,7 +164,7 @@ class _RFC2136Client(object):
rcode = response.rcode() rcode = response.rcode()
if rcode == dns.rcode.NOERROR: if rcode == dns.rcode.NOERROR:
logger.debug('Successfully deleted TXT record') logger.debug('Successfully deleted TXT record %s', record_name)
else: else:
raise errors.PluginError('Received response from server: {0}' raise errors.PluginError('Received response from server: {0}'
.format(dns.rcode.to_text(rcode))) .format(dns.rcode.to_text(rcode)))

View File

@@ -38,7 +38,7 @@ extensions = ['sphinx.ext.autodoc',
'sphinx.ext.viewcode'] 'sphinx.ext.viewcode']
autodoc_member_order = 'bysource' autodoc_member_order = 'bysource'
autodoc_default_flags = ['show-inheritance', 'private-members'] autodoc_default_flags = ['show-inheritance']
# Add any paths that contain templates here, relative to this directory. # Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates'] templates_path = ['_templates']

View File

@@ -1,3 +1,3 @@
# Remember to update setup.py to match the package versions below. # Remember to update setup.py to match the package versions below.
acme[dev]==0.29.0 acme[dev]==0.29.0
-e certbot[dev] certbot[dev]==1.1.0

View File

@@ -4,13 +4,13 @@ from setuptools import find_packages
from setuptools import setup from setuptools import setup
from setuptools.command.test import test as TestCommand from setuptools.command.test import test as TestCommand
version = '1.1.0.dev0' version = '1.2.0.dev0'
# Remember to update local-oldest-requirements.txt when changing the minimum # Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version. # acme/certbot version.
install_requires = [ install_requires = [
'acme>=0.29.0', 'acme>=0.29.0',
'certbot>=1.0.0.dev0', 'certbot>=1.1.0',
'dnspython', 'dnspython',
'mock', 'mock',
'setuptools', 'setuptools',
@@ -44,7 +44,7 @@ setup(
author="Certbot Project", author="Certbot Project",
author_email='client-dev@letsencrypt.org', author_email='client-dev@letsencrypt.org',
license='Apache License 2.0', license='Apache License 2.0',
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
classifiers=[ classifiers=[
'Development Status :: 5 - Production/Stable', 'Development Status :: 5 - Production/Stable',
'Environment :: Plugins', 'Environment :: Plugins',
@@ -55,7 +55,6 @@ setup(
'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.7',

View File

@@ -38,7 +38,7 @@ extensions = ['sphinx.ext.autodoc',
'sphinx.ext.viewcode'] 'sphinx.ext.viewcode']
autodoc_member_order = 'bysource' autodoc_member_order = 'bysource'
autodoc_default_flags = ['show-inheritance', 'private-members'] autodoc_default_flags = ['show-inheritance']
# Add any paths that contain templates here, relative to this directory. # Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates'] templates_path = ['_templates']

View File

@@ -1,3 +1,3 @@
# Remember to update setup.py to match the package versions below. # Remember to update setup.py to match the package versions below.
acme[dev]==0.29.0 acme[dev]==0.29.0
-e certbot[dev] certbot[dev]==1.1.0

View File

@@ -4,13 +4,13 @@ from setuptools import find_packages
from setuptools import setup from setuptools import setup
from setuptools.command.test import test as TestCommand from setuptools.command.test import test as TestCommand
version = '1.1.0.dev0' version = '1.2.0.dev0'
# Remember to update local-oldest-requirements.txt when changing the minimum # Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version. # acme/certbot version.
install_requires = [ install_requires = [
'acme>=0.29.0', 'acme>=0.29.0',
'certbot>=1.0.0.dev0', 'certbot>=1.1.0',
'boto3', 'boto3',
'mock', 'mock',
'setuptools', 'setuptools',
@@ -39,7 +39,7 @@ setup(
author="Certbot Project", author="Certbot Project",
author_email='client-dev@letsencrypt.org', author_email='client-dev@letsencrypt.org',
license='Apache License 2.0', license='Apache License 2.0',
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
classifiers=[ classifiers=[
'Development Status :: 5 - Production/Stable', 'Development Status :: 5 - Production/Stable',
'Environment :: Plugins', 'Environment :: Plugins',
@@ -50,7 +50,6 @@ setup(
'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.7',

View File

@@ -38,7 +38,7 @@ extensions = ['sphinx.ext.autodoc',
'sphinx.ext.viewcode'] 'sphinx.ext.viewcode']
autodoc_member_order = 'bysource' autodoc_member_order = 'bysource'
autodoc_default_flags = ['show-inheritance', 'private-members'] autodoc_default_flags = ['show-inheritance']
# Add any paths that contain templates here, relative to this directory. # Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates'] templates_path = ['_templates']

View File

@@ -1,3 +1,3 @@
# Remember to update setup.py to match the package versions below. # Remember to update setup.py to match the package versions below.
acme[dev]==0.31.0 acme[dev]==0.31.0
-e certbot[dev] certbot[dev]==1.1.0

View File

@@ -4,12 +4,12 @@ from setuptools import find_packages
from setuptools import setup from setuptools import setup
from setuptools.command.test import test as TestCommand from setuptools.command.test import test as TestCommand
version = '1.1.0.dev0' version = '1.2.0.dev0'
# Please update tox.ini when modifying dependency version requirements # Please update tox.ini when modifying dependency version requirements
install_requires = [ install_requires = [
'acme>=0.31.0', 'acme>=0.31.0',
'certbot>=1.0.0.dev0', 'certbot>=1.1.0',
'dns-lexicon>=2.1.23', 'dns-lexicon>=2.1.23',
'mock', 'mock',
'setuptools', 'setuptools',
@@ -43,7 +43,7 @@ setup(
author="Certbot Project", author="Certbot Project",
author_email='client-dev@letsencrypt.org', author_email='client-dev@letsencrypt.org',
license='Apache License 2.0', license='Apache License 2.0',
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
classifiers=[ classifiers=[
'Development Status :: 5 - Production/Stable', 'Development Status :: 5 - Production/Stable',
'Environment :: Plugins', 'Environment :: Plugins',
@@ -54,7 +54,6 @@ setup(
'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.7',

View File

@@ -10,4 +10,4 @@ ssl_session_timeout 1440m;
ssl_protocols TLSv1.2; ssl_protocols TLSv1.2;
ssl_prefer_server_ciphers off; ssl_prefer_server_ciphers off;
ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA"; ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";

View File

@@ -11,4 +11,4 @@ ssl_session_tickets off;
ssl_protocols TLSv1.2; ssl_protocols TLSv1.2;
ssl_prefer_server_ciphers off; ssl_prefer_server_ciphers off;
ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA"; ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";

View File

@@ -10,4 +10,4 @@ ssl_session_timeout 1440m;
ssl_protocols TLSv1.2 TLSv1.3; ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off; ssl_prefer_server_ciphers off;
ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA"; ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";

View File

@@ -11,4 +11,4 @@ ssl_session_tickets off;
ssl_protocols TLSv1.2 TLSv1.3; ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off; ssl_prefer_server_ciphers off;
ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA"; ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";

View File

@@ -1,3 +1,3 @@
# Remember to update setup.py to match the package versions below. # Remember to update setup.py to match the package versions below.
acme[dev]==1.0.0 acme[dev]==1.0.0
-e certbot[dev] certbot[dev]==1.1.0

View File

@@ -4,13 +4,13 @@ from setuptools import find_packages
from setuptools import setup from setuptools import setup
from setuptools.command.test import test as TestCommand from setuptools.command.test import test as TestCommand
version = '1.1.0.dev0' version = '1.2.0.dev0'
# Remember to update local-oldest-requirements.txt when changing the minimum # Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version. # acme/certbot version.
install_requires = [ install_requires = [
'acme>=1.0.0', 'acme>=1.0.0',
'certbot>=1.0.0.dev0', 'certbot>=1.1.0',
'mock', 'mock',
'PyOpenSSL', 'PyOpenSSL',
'pyparsing>=1.5.5', # Python3 support; perhaps unnecessary? 'pyparsing>=1.5.5', # Python3 support; perhaps unnecessary?
@@ -42,7 +42,7 @@ setup(
author="Certbot Project", author="Certbot Project",
author_email='client-dev@letsencrypt.org', author_email='client-dev@letsencrypt.org',
license='Apache License 2.0', license='Apache License 2.0',
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
classifiers=[ classifiers=[
'Development Status :: 5 - Production/Stable', 'Development Status :: 5 - Production/Stable',
'Environment :: Plugins', 'Environment :: Plugins',
@@ -53,7 +53,6 @@ setup(
'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.7',

View File

@@ -2,7 +2,27 @@
Certbot adheres to [Semantic Versioning](https://semver.org/). Certbot adheres to [Semantic Versioning](https://semver.org/).
## 1.1.0 - master ## 1.2.0 - master
### Added
* Added support for Cloudflare's limited-scope API Tokens
### Changed
* Add directory field to error message when field is missing.
* If MD5 hasher is not available, try it in non-security mode (fix for FIPS systems) -- [#1948](https://github.com/certbot/certbot/issues/1948)
* Disable old SSL versions and ciphersuites and remove `SSLCompression off` setting to follow Mozilla recommendations in Apache.
* Remove ECDHE-RSA-AES128-SHA from NGINX ciphers list now that Windows 2008 R2 and Windows 7 are EOLed
* Support for Python 3.4 has been removed.
### Fixed
* Fix collections.abc imports for Python 3.9.
More details about these changes can be found on our GitHub repo.
## 1.1.0 - 2020-01-14
### Added ### Added
@@ -13,6 +33,15 @@ Certbot adheres to [Semantic Versioning](https://semver.org/).
* Removed the fallback introduced with 0.34.0 in `acme` to retry a POST-as-GET * Removed the fallback introduced with 0.34.0 in `acme` to retry a POST-as-GET
request as a GET request when the targeted ACME CA server seems to not support request as a GET request when the targeted ACME CA server seems to not support
POST-as-GET requests. POST-as-GET requests.
* certbot-auto no longer supports architectures other than x86_64 on RHEL 6
based systems. Existing certbot-auto installations affected by this will
continue to work, but they will no longer receive updates. To install a
newer version of Certbot on these systems, you should update your OS.
* Support for Python 3.4 in Certbot and its ACME library is deprecated and will be
removed in the next release of Certbot. certbot-auto users on x86_64 systems running
RHEL 6 or derivatives will be asked to enable Software Collections (SCL) repository
so Python 3.6 can be installed. certbot-auto can enable the SCL repo for you on CentOS 6
while users on other RHEL 6 based systems will be asked to do this manually.
### Fixed ### Fixed
@@ -223,7 +252,7 @@ More details about these changes can be found on our GitHub repo.
### Added ### Added
* dns_rfc2136 plugin now supports explicitly specifing an authorative * dns_rfc2136 plugin now supports explicitly specifying an authoritative
base domain for cases when the automatic method does not work (e.g. base domain for cases when the automatic method does not work (e.g.
Split horizon DNS) Split horizon DNS)
@@ -607,7 +636,7 @@ https://github.com/certbot/certbot/milestone/62?closed=1
* Log warning about TLS-SNI deprecation in Certbot * Log warning about TLS-SNI deprecation in Certbot
* Stop preferring TLS-SNI in the Apache, Nginx, and standalone plugins * Stop preferring TLS-SNI in the Apache, Nginx, and standalone plugins
* OVH DNS plugin now relies on Lexicon>=2.7.14 to support HTTP proxies * OVH DNS plugin now relies on Lexicon>=2.7.14 to support HTTP proxies
* Default time the Linode plugin waits for DNS changes to propogate is now 1200 seconds. * Default time the Linode plugin waits for DNS changes to propagate is now 1200 seconds.
### Fixed ### Fixed
@@ -726,7 +755,7 @@ https://github.com/certbot/certbot/milestone/58?closed=1
increased over time. The max-age value is not increased to a large value increased over time. The max-age value is not increased to a large value
until you've successfully managed to renew your certificate. This enhancement until you've successfully managed to renew your certificate. This enhancement
can be requested with the --auto-hsts flag. can be requested with the --auto-hsts flag.
* New official DNS plugins have been created for Gehirn Infrastracture Service, * New official DNS plugins have been created for Gehirn Infrastructure Service,
Linode, OVH, and Sakura Cloud. These plugins can be found on our Docker Hub Linode, OVH, and Sakura Cloud. These plugins can be found on our Docker Hub
page at https://hub.docker.com/u/certbot and on PyPI. page at https://hub.docker.com/u/certbot and on PyPI.
* The ability to reuse ACME accounts from Let's Encrypt's ACMEv1 endpoint on * The ability to reuse ACME accounts from Let's Encrypt's ACMEv1 endpoint on

View File

@@ -1,4 +1,4 @@
"""Certbot client.""" """Certbot client."""
# version number like 1.2.3a0, must have at least 2 parts, like 1.2 # version number like 1.2.3a0, must have at least 2 parts, like 1.2
__version__ = '1.1.0.dev0' __version__ = '1.2.0.dev0'

View File

@@ -56,11 +56,18 @@ class Account(object):
tz=pytz.UTC).replace(microsecond=0), tz=pytz.UTC).replace(microsecond=0),
creation_host=socket.getfqdn()) if meta is None else meta creation_host=socket.getfqdn()) if meta is None else meta
self.id = hashlib.md5( # try MD5, else use MD5 in non-security mode (e.g. for FIPS systems / RHEL)
self.key.key.public_key().public_bytes( try:
encoding=serialization.Encoding.PEM, hasher = hashlib.md5()
format=serialization.PublicFormat.SubjectPublicKeyInfo) except ValueError:
).hexdigest() hasher = hashlib.new('md5', usedforsecurity=False) # type: ignore
hasher.update(self.key.key.public_key().public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo)
)
self.id = hasher.hexdigest()
# Implementation note: Email? Multiple accounts can have the # Implementation note: Email? Multiple accounts can have the
# same email address. Registration URI? Assigned by the # same email address. Registration URI? Assigned by the
# server, not guaranteed to be stable over time, nor # server, not guaranteed to be stable over time, nor

View File

@@ -92,8 +92,8 @@ obtain, install, and renew certificates:
manage certificates: manage certificates:
certificates Display information about certificates you have from Certbot certificates Display information about certificates you have from Certbot
revoke Revoke a certificate (supply --cert-path or --cert-name) revoke Revoke a certificate (supply --cert-name or --cert-path)
delete Delete a certificate delete Delete a certificate (supply --cert-name)
manage your account: manage your account:
register Create an ACME account register Create an ACME account
@@ -1414,7 +1414,7 @@ def _plugins_parsing(helpful, plugins):
helpful.add(["plugins", "certonly"], "--dns-gehirn", action="store_true", helpful.add(["plugins", "certonly"], "--dns-gehirn", action="store_true",
default=flag_default("dns_gehirn"), default=flag_default("dns_gehirn"),
help=("Obtain certificates using a DNS TXT record " help=("Obtain certificates using a DNS TXT record "
"(if you are using Gehirn Infrastracture Service for DNS).")) "(if you are using Gehirn Infrastructure Service for DNS)."))
helpful.add(["plugins", "certonly"], "--dns-google", action="store_true", helpful.add(["plugins", "certonly"], "--dns-google", action="store_true",
default=flag_default("dns_google"), default=flag_default("dns_google"),
help=("Obtain certificates using a DNS TXT record (if you are " help=("Obtain certificates using a DNS TXT record (if you are "

View File

@@ -192,7 +192,7 @@ def _check_ocsp_cryptography(cert_path, chain_path, url):
def _check_ocsp_response(response_ocsp, request_ocsp, issuer_cert, cert_path): def _check_ocsp_response(response_ocsp, request_ocsp, issuer_cert, cert_path):
"""Verify that the OCSP is valid for serveral criterias""" """Verify that the OCSP is valid for serveral criteria"""
# Assert OCSP response corresponds to the certificate we are talking about # Assert OCSP response corresponds to the certificate we are talking about
if response_ocsp.serial_number != request_ocsp.serial_number: if response_ocsp.serial_number != request_ocsp.serial_number:
raise AssertionError('the certificate in response does not correspond ' raise AssertionError('the certificate in response does not correspond '

View File

@@ -13,6 +13,12 @@ from certbot import errors
from certbot import interfaces from certbot import interfaces
from certbot._internal import constants from certbot._internal import constants
try:
# Python 3.3+
from collections.abc import Mapping
except ImportError: # pragma: no cover
from collections import Mapping
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -178,7 +184,7 @@ class PluginEntryPoint(object):
return "\n".join(lines) return "\n".join(lines)
class PluginsRegistry(collections.Mapping): class PluginsRegistry(Mapping):
"""Plugins registry.""" """Plugins registry."""
def __init__(self, plugins): def __init__(self, plugins):

View File

@@ -192,7 +192,7 @@ def _restore_pref_challs(unused_name, value):
:returns: converted option value to be stored in the runtime config :returns: converted option value to be stored in the runtime config
:rtype: `list` of `str` :rtype: `list` of `str`
:raises errors.Error: if value can't be converted to an bool :raises errors.Error: if value can't be converted to a bool
""" """
# If pref_challs has only one element, configobj saves the value # If pref_challs has only one element, configobj saves the value
@@ -203,7 +203,7 @@ def _restore_pref_challs(unused_name, value):
def _restore_bool(name, value): def _restore_bool(name, value):
"""Restores an boolean key-value pair from a renewal config file. """Restores a boolean key-value pair from a renewal config file.
:param str name: option name :param str name: option name
:param str value: option value :param str value: option value
@@ -211,7 +211,7 @@ def _restore_bool(name, value):
:returns: converted option value to be stored in the runtime config :returns: converted option value to be stored in the runtime config
:rtype: bool :rtype: bool
:raises errors.Error: if value can't be converted to an bool :raises errors.Error: if value can't be converted to a bool
""" """
lowercase_value = value.lower() lowercase_value = value.lower()
@@ -244,7 +244,7 @@ def _restore_int(name, value):
def _restore_str(unused_name, value): def _restore_str(unused_name, value):
"""Restores an string key-value pair from a renewal config file. """Restores a string key-value pair from a renewal config file.
:param str unused_name: option name :param str unused_name: option name
:param str value: option value :param str value: option value

View File

@@ -263,7 +263,7 @@ def replace(src, dst):
:param str dst: The new file path. :param str dst: The new file path.
""" """
if hasattr(os, 'replace'): if hasattr(os, 'replace'):
# Use replace if possible. On Windows, only Python >= 3.4 is supported # Use replace if possible. On Windows, only Python >= 3.5 is supported
# so we can assume that os.replace() is always available for this platform. # so we can assume that os.replace() is always available for this platform.
getattr(os, 'replace')(src, dst) getattr(os, 'replace')(src, dst)
else: else:
@@ -541,7 +541,7 @@ def _generate_windows_flags(rights_desc):
# write access on Linux: for Windows, FILE_GENERIC_WRITE does not include delete, move or # write access on Linux: for Windows, FILE_GENERIC_WRITE does not include delete, move or
# rename. This is something that requires ntsecuritycon.FILE_ALL_ACCESS. # rename. This is something that requires ntsecuritycon.FILE_ALL_ACCESS.
# So to reproduce the write right as POSIX, we will apply ntsecuritycon.FILE_ALL_ACCESS # So to reproduce the write right as POSIX, we will apply ntsecuritycon.FILE_ALL_ACCESS
# substracted of the rights corresponding to POSIX read and POSIX execute. # subtracted of the rights corresponding to POSIX read and POSIX execute.
# #
# Finally, having read + write + execute gives a ntsecuritycon.FILE_ALL_ACCESS, # Finally, having read + write + execute gives a ntsecuritycon.FILE_ALL_ACCESS,
# so a "Full Control" on the file. # so a "Full Control" on the file.

View File

@@ -340,7 +340,7 @@ def validated_input(validator, *args, **kwargs):
"""Like `~certbot.interfaces.IDisplay.input`, but with validation. """Like `~certbot.interfaces.IDisplay.input`, but with validation.
:param callable validator: A method which will be called on the :param callable validator: A method which will be called on the
supplied input. If the method raises a `errors.Error`, its supplied input. If the method raises an `errors.Error`, its
text will be displayed and the user will be re-prompted. text will be displayed and the user will be re-prompted.
:param list `*args`: Arguments to be passed to `~certbot.interfaces.IDisplay.input`. :param list `*args`: Arguments to be passed to `~certbot.interfaces.IDisplay.input`.
:param dict `**kwargs`: Arguments to be passed to `~certbot.interfaces.IDisplay.input`. :param dict `**kwargs`: Arguments to be passed to `~certbot.interfaces.IDisplay.input`.
@@ -355,7 +355,7 @@ def validated_directory(validator, *args, **kwargs):
"""Like `~certbot.interfaces.IDisplay.directory_select`, but with validation. """Like `~certbot.interfaces.IDisplay.directory_select`, but with validation.
:param callable validator: A method which will be called on the :param callable validator: A method which will be called on the
supplied input. If the method raises a `errors.Error`, its supplied input. If the method raises an `errors.Error`, its
text will be displayed and the user will be re-prompted. text will be displayed and the user will be re-prompted.
:param list `*args`: Arguments to be passed to `~certbot.interfaces.IDisplay.directory_select`. :param list `*args`: Arguments to be passed to `~certbot.interfaces.IDisplay.directory_select`.
:param dict `**kwargs`: Arguments to be passed to :param dict `**kwargs`: Arguments to be passed to

View File

@@ -24,8 +24,8 @@ obtain, install, and renew certificates:
manage certificates: manage certificates:
certificates Display information about certificates you have from Certbot certificates Display information about certificates you have from Certbot
revoke Revoke a certificate (supply --cert-path or --cert-name) revoke Revoke a certificate (supply --cert-name or --cert-path)
delete Delete a certificate delete Delete a certificate (supply --cert-name)
manage your account: manage your account:
register Create an ACME account register Create an ACME account
@@ -113,7 +113,7 @@ optional arguments:
case, and to know when to deprecate support for past case, and to know when to deprecate support for past
Python versions and flags. If you wish to hide this Python versions and flags. If you wish to hide this
information from the Let's Encrypt server, set this to information from the Let's Encrypt server, set this to
"". (default: CertbotACMEClient/1.0.0 (certbot(-auto); "". (default: CertbotACMEClient/1.1.0 (certbot(-auto);
OS_NAME OS_VERSION) Authenticator/XXX Installer/YYY OS_NAME OS_VERSION) Authenticator/XXX Installer/YYY
(SUBCOMMAND; flags: FLAGS) Py/major.minor.patchlevel). (SUBCOMMAND; flags: FLAGS) Py/major.minor.patchlevel).
The flags encoded in the user agent are: --duplicate, The flags encoded in the user agent are: --duplicate,
@@ -451,7 +451,7 @@ plugins:
--dns-dnsmadeeasy Obtain certificates using a DNS TXT record (if you are --dns-dnsmadeeasy Obtain certificates using a DNS TXT record (if you are
using DNS Made Easy for DNS). (default: False) using DNS Made Easy for DNS). (default: False)
--dns-gehirn Obtain certificates using a DNS TXT record (if you are --dns-gehirn Obtain certificates using a DNS TXT record (if you are
using Gehirn Infrastracture Service for DNS). using Gehirn Infrastructure Service for DNS).
(default: False) (default: False)
--dns-google Obtain certificates using a DNS TXT record (if you are --dns-google Obtain certificates using a DNS TXT record (if you are
using Google Cloud DNS). (default: False) using Google Cloud DNS). (default: False)
@@ -560,14 +560,14 @@ dns-dnsmadeeasy:
dns-gehirn: dns-gehirn:
Obtain certificates using a DNS TXT record (if you are using Gehirn Obtain certificates using a DNS TXT record (if you are using Gehirn
Infrastracture Service for DNS). Infrastructure Service for DNS).
--dns-gehirn-propagation-seconds DNS_GEHIRN_PROPAGATION_SECONDS --dns-gehirn-propagation-seconds DNS_GEHIRN_PROPAGATION_SECONDS
The number of seconds to wait for DNS to propagate The number of seconds to wait for DNS to propagate
before asking the ACME server to verify the DNS before asking the ACME server to verify the DNS
record. (default: 30) record. (default: 30)
--dns-gehirn-credentials DNS_GEHIRN_CREDENTIALS --dns-gehirn-credentials DNS_GEHIRN_CREDENTIALS
Gehirn Infrastracture Service credentials file. Gehirn Infrastructure Service credentials file.
(default: None) (default: None)
dns-google: dns-google:

View File

@@ -0,0 +1,39 @@
=======================
Backwards Compatibility
=======================
All Certbot components including `acme <https://acme-python.readthedocs.io/>`_,
Certbot, and :ref:`non-third party plugins <plugins>` follow `Semantic
Versioning <https://semver.org/>`_ both for its Python :doc:`API <api>` and for the
application itself. This means that we will not change behavior in a backwards
incompatible way except in a new major version of the project.
.. note:: None of this applies to the behavior of Certbot distribution
mechanisms such as :ref:`certbot-auto <certbot-auto>` or OS packages whose
behavior may change at any time. Semantic versioning only applies to the
common Certbot components that are installed by various distribution
methods.
For Certbot as an application, the command line interface and non-interactive
behavior can be considered stable with two exceptions. The first is that no
aspects of Certbot's console or log output should be considered stable and it
may change at any time. The second is that Certbot's behavior should only be
considered stable with certain files but not all. Files with which users should
expect Certbot to maintain its current behavior with are:
* ``/etc/letsencrypt/live/<domain>/{cert,chain,fullchain,privkey}.pem`` where
``<domain>`` is the name given to ``--cert-name``. If ``--cert-name`` is not
set by the user, it is the first domain given to ``--domains``.
* :ref:`CLI configuration files <config-file>`
* Hook directories in ``/etc/letsencrypt/renewal-hooks``
Certbot's behavior with other files may change at any point.
Another area where Certbot should not be considered stable is its behavior when
not run in non-interactive mode which also may change at any point.
In general, if we're making a change that we expect will break some users, we
will bump the major version and will have warned about it in a prior release
when possible. For our Python API, we will issue warnings using Python's
warning module. For application level changes, we will print and log warning
messages.

View File

@@ -52,7 +52,7 @@ if sphinx.version_info >= (1, 6):
extensions.append('sphinx.ext.imgconverter') extensions.append('sphinx.ext.imgconverter')
autodoc_member_order = 'bysource' autodoc_member_order = 'bysource'
autodoc_default_flags = ['show-inheritance', 'private-members'] autodoc_default_flags = ['show-inheritance']
# Add any paths that contain templates here, relative to this directory. # Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates'] templates_path = ['_templates']

Some files were not shown because too many files have changed in this diff Show More