Compare commits
57 Commits
parser_ref
...
apache-int
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4dddb8f060 | ||
|
|
8cb57566c0 | ||
|
|
18e6c6c2a8 | ||
|
|
e402993c34 | ||
|
|
754c34c120 | ||
|
|
2883ca839e | ||
|
|
fb6aad28bd | ||
|
|
ab76834100 | ||
|
|
ada2f5c767 | ||
|
|
e4af1f3319 | ||
|
|
ab0e382829 | ||
|
|
ed0b8e4af5 | ||
|
|
8a570b18e9 | ||
|
|
deb0168c09 | ||
|
|
46a12d0127 | ||
|
|
6d4baec955 | ||
|
|
b1f3c6f859 | ||
|
|
d0c6be244f | ||
|
|
3c572b84ab | ||
|
|
d4f47e920b | ||
|
|
e1bae626f1 | ||
|
|
4eaa06d58e | ||
|
|
df40057bcc | ||
|
|
95f9ed247a | ||
|
|
3a411c092f | ||
|
|
3163801123 | ||
|
|
a68de55696 | ||
|
|
4bc473a2db | ||
|
|
23ec9afdb4 | ||
|
|
f401750b43 | ||
|
|
3ef88a68ed | ||
|
|
e6b2689dcb | ||
|
|
26aae00c36 | ||
|
|
0eeae8196d | ||
|
|
11d9107c95 | ||
|
|
3becf7be16 | ||
|
|
0fe28a6459 | ||
|
|
aaeb4582e2 | ||
|
|
fdb0a14812 | ||
|
|
0324d1740e | ||
|
|
ce325db4e4 | ||
|
|
74e6736c79 | ||
|
|
2ed7608ed3 | ||
|
|
eb02acfc4b | ||
|
|
4f19d516d6 | ||
|
|
3dd918b024 | ||
|
|
8320018978 | ||
|
|
c17f2ff6b0 | ||
|
|
46a2ef8ba1 | ||
|
|
17c1d016c1 | ||
|
|
70ed791709 | ||
|
|
d39f63feca | ||
|
|
6882f006ac | ||
|
|
9a047a6996 | ||
|
|
a8bd839223 | ||
|
|
a1aef4c15c | ||
|
|
cb7598b007 |
@@ -6,13 +6,13 @@ coverage:
|
||||
flags: linux
|
||||
# Fixed target instead of auto set by #7173, can
|
||||
# be removed when flags in Codecov are added back.
|
||||
target: 97.5
|
||||
target: 97.4
|
||||
threshold: 0.1
|
||||
base: auto
|
||||
windows:
|
||||
flags: windows
|
||||
# Fixed target instead of auto set by #7173, can
|
||||
# be removed when flags in Codecov are added back.
|
||||
target: 97.6
|
||||
target: 97.7
|
||||
threshold: 0.1
|
||||
base: auto
|
||||
|
||||
@@ -1,2 +1,5 @@
|
||||
[run]
|
||||
omit = */setup.py
|
||||
|
||||
[report]
|
||||
omit = */setup.py
|
||||
|
||||
140
.travis.yml
140
.travis.yml
@@ -1,13 +1,26 @@
|
||||
language: python
|
||||
dist: xenial
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.cache/pip
|
||||
|
||||
before_script:
|
||||
# Install required apt packages
|
||||
- |
|
||||
if [[ "$TRAVIS_OS_NAME" != "osx" ]]; then
|
||||
./certbot-auto --non-interactive --os-packages-only
|
||||
sudo -E apt-get -yq --no-install-suggests --no-install-recommends install nginx-light
|
||||
sudo -E /etc/init.d/nginx stop
|
||||
sudo -E apt-get -yq --no-install-suggests --no-install-recommends install apache2
|
||||
sudo -E /etc/init.d/apache2 stop
|
||||
sudo -E chmod 777 -R /var/lib/apache2/module
|
||||
fi
|
||||
- 'if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then ulimit -n 1024 ; fi'
|
||||
# On Travis, the fastest parallelization for integration tests has proved to be 4.
|
||||
- 'if [[ "$TOXENV" == *"integration"* ]]; then export PYTEST_ADDOPTS="--numprocesses 4"; fi'
|
||||
# Use Travis retry feature for farm tests since they are flaky
|
||||
- 'if [[ "$TOXENV" == "travis-test-farm"* ]]; then export TRAVIS_RETRY=travis_retry; fi'
|
||||
- export TOX_TESTENV_PASSENV=TRAVIS
|
||||
|
||||
# Only build pushes to the master branch, PRs, and branches beginning with
|
||||
@@ -37,8 +50,6 @@ matrix:
|
||||
# Main test suite
|
||||
- python: "2.7"
|
||||
env: ACME_SERVER=pebble TOXENV=integration
|
||||
sudo: required
|
||||
services: docker
|
||||
<<: *not-on-master
|
||||
|
||||
# This job is always executed, including on master
|
||||
@@ -60,45 +71,29 @@ matrix:
|
||||
# OpenSSL in Xenial or newer.
|
||||
dist: trusty
|
||||
env: TOXENV='py27-{acme,apache,certbot,dns,nginx}-oldest'
|
||||
sudo: required
|
||||
services: docker
|
||||
<<: *not-on-master
|
||||
- python: "3.4"
|
||||
env: TOXENV=py34
|
||||
sudo: required
|
||||
services: docker
|
||||
<<: *not-on-master
|
||||
- python: "3.7"
|
||||
dist: xenial
|
||||
env: TOXENV=py37
|
||||
sudo: required
|
||||
services: docker
|
||||
<<: *not-on-master
|
||||
- sudo: required
|
||||
env: TOXENV=apache_compat
|
||||
services: docker
|
||||
before_install:
|
||||
addons:
|
||||
- python: "3.8-dev"
|
||||
env: TOXENV=py38
|
||||
<<: *not-on-master
|
||||
- sudo: required
|
||||
env: TOXENV=le_auto_xenial
|
||||
services: docker
|
||||
- env: TOXENV=apache_compat
|
||||
<<: *not-on-master
|
||||
- env: TOXENV=le_auto_xenial
|
||||
<<: *not-on-master
|
||||
- python: "2.7"
|
||||
env: TOXENV=apacheconftest-with-pebble
|
||||
sudo: required
|
||||
services: docker
|
||||
<<: *not-on-master
|
||||
- python: "2.7"
|
||||
env: TOXENV=nginxroundtrip
|
||||
<<: *not-on-master
|
||||
|
||||
# Extended test suite on cron jobs and pushes to tested branches other than master
|
||||
- sudo: required
|
||||
env: TOXENV=nginx_compat
|
||||
services: docker
|
||||
before_install:
|
||||
addons:
|
||||
- env: TOXENV=nginx_compat
|
||||
<<: *extended-test-suite
|
||||
- python: "2.7"
|
||||
env:
|
||||
@@ -123,38 +118,41 @@ matrix:
|
||||
- secure: "f+j/Lj9s1lcuKo5sEFrlRd1kIAMnIJI4z0MTI7QF8jl9Fkmbx7KECGzw31TNgzrOSzxSapHbcueFYvNCLKST+kE/8ogMZBbwqXfEDuKpyF6BY3uYoJn+wPVE5pIb8Hhe08xPte8TTDSMIyHI3EyTfcAKrIreauoArePvh/cRvSw="
|
||||
<<: *extended-test-suite
|
||||
- python: "3.7"
|
||||
dist: xenial
|
||||
env: TOXENV=py37 CERTBOT_NO_PIN=1
|
||||
<<: *extended-test-suite
|
||||
- python: "2.7"
|
||||
env: ACME_SERVER=boulder-v1 TOXENV=integration
|
||||
sudo: required
|
||||
services: docker
|
||||
<<: *extended-test-suite
|
||||
- python: "2.7"
|
||||
env: ACME_SERVER=boulder-v2 TOXENV=integration
|
||||
sudo: required
|
||||
services: docker
|
||||
<<: *extended-test-suite
|
||||
- python: "2.7"
|
||||
env: ACME_SERVER=boulder-v1 TOXENV=integration-certbot-oldest
|
||||
sudo: required
|
||||
services: docker
|
||||
# Ubuntu Trusty or older must be used because the oldest version of
|
||||
# cryptography we support cannot be compiled against the version of
|
||||
# OpenSSL in Xenial or newer.
|
||||
dist: trusty
|
||||
<<: *extended-test-suite
|
||||
- python: "2.7"
|
||||
env: ACME_SERVER=boulder-v2 TOXENV=integration-certbot-oldest
|
||||
sudo: required
|
||||
services: docker
|
||||
# Ubuntu Trusty or older must be used because the oldest version of
|
||||
# cryptography we support cannot be compiled against the version of
|
||||
# OpenSSL in Xenial or newer.
|
||||
dist: trusty
|
||||
<<: *extended-test-suite
|
||||
- python: "2.7"
|
||||
env: ACME_SERVER=boulder-v1 TOXENV=integration-nginx-oldest
|
||||
sudo: required
|
||||
services: docker
|
||||
# Ubuntu Trusty or older must be used because the oldest version of
|
||||
# cryptography we support cannot be compiled against the version of
|
||||
# OpenSSL in Xenial or newer.
|
||||
dist: trusty
|
||||
<<: *extended-test-suite
|
||||
- python: "2.7"
|
||||
env: ACME_SERVER=boulder-v2 TOXENV=integration-nginx-oldest
|
||||
sudo: required
|
||||
services: docker
|
||||
# Ubuntu Trusty or older must be used because the oldest version of
|
||||
# cryptography we support cannot be compiled against the version of
|
||||
# OpenSSL in Xenial or newer.
|
||||
dist: trusty
|
||||
<<: *extended-test-suite
|
||||
- python: "3.4"
|
||||
env: TOXENV=py34
|
||||
@@ -166,66 +164,46 @@ matrix:
|
||||
env: TOXENV=py36
|
||||
<<: *extended-test-suite
|
||||
- python: "3.7"
|
||||
dist: xenial
|
||||
env: TOXENV=py37
|
||||
<<: *extended-test-suite
|
||||
- python: "3.8-dev"
|
||||
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"
|
||||
env: ACME_SERVER=boulder-v1 TOXENV=integration
|
||||
sudo: required
|
||||
services: docker
|
||||
<<: *extended-test-suite
|
||||
- python: "3.5"
|
||||
env: ACME_SERVER=boulder-v2 TOXENV=integration
|
||||
sudo: required
|
||||
services: docker
|
||||
<<: *extended-test-suite
|
||||
- python: "3.6"
|
||||
env: ACME_SERVER=boulder-v1 TOXENV=integration
|
||||
sudo: required
|
||||
services: docker
|
||||
<<: *extended-test-suite
|
||||
- python: "3.6"
|
||||
env: ACME_SERVER=boulder-v2 TOXENV=integration
|
||||
sudo: required
|
||||
services: docker
|
||||
<<: *extended-test-suite
|
||||
- python: "3.7"
|
||||
dist: xenial
|
||||
env: ACME_SERVER=boulder-v1 TOXENV=integration
|
||||
sudo: required
|
||||
services: docker
|
||||
<<: *extended-test-suite
|
||||
- python: "3.7"
|
||||
dist: xenial
|
||||
env: ACME_SERVER=boulder-v2 TOXENV=integration
|
||||
sudo: required
|
||||
services: docker
|
||||
<<: *extended-test-suite
|
||||
- sudo: required
|
||||
env: TOXENV=le_auto_jessie
|
||||
services: docker
|
||||
- python: "3.8-dev"
|
||||
env: ACME_SERVER=boulder-v1 TOXENV=integration
|
||||
<<: *extended-test-suite
|
||||
- sudo: required
|
||||
env: TOXENV=le_auto_centos6
|
||||
services: docker
|
||||
- python: "3.8-dev"
|
||||
env: ACME_SERVER=boulder-v2 TOXENV=integration
|
||||
<<: *extended-test-suite
|
||||
- sudo: required
|
||||
env: TOXENV=docker_dev
|
||||
services: docker
|
||||
addons:
|
||||
apt:
|
||||
packages: # don't install nginx and apache
|
||||
- libaugeas0
|
||||
- env: TOXENV=le_auto_jessie
|
||||
<<: *extended-test-suite
|
||||
- env: TOXENV=le_auto_centos6
|
||||
<<: *extended-test-suite
|
||||
- env: TOXENV=docker_dev
|
||||
<<: *extended-test-suite
|
||||
- language: generic
|
||||
env: TOXENV=py27
|
||||
@@ -252,29 +230,17 @@ matrix:
|
||||
- python3
|
||||
<<: *extended-test-suite
|
||||
|
||||
# container-based infrastructure
|
||||
sudo: false
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages: # Keep in sync with letsencrypt-auto-source/pieces/bootstrappers/deb_common.sh and Boulder.
|
||||
- python-dev
|
||||
- gcc
|
||||
- libaugeas0
|
||||
- libssl-dev
|
||||
- libffi-dev
|
||||
- ca-certificates
|
||||
# For certbot-nginx integration testing
|
||||
- nginx-light
|
||||
- openssl
|
||||
|
||||
# tools/pip_install.py is used to pin packages to a known working version
|
||||
# except in tests where the environment variable CERTBOT_NO_PIN is set.
|
||||
# virtualenv is listed here explicitly to make sure it is upgraded when
|
||||
# CERTBOT_NO_PIN is set to work around failures we've seen when using an older
|
||||
# version of virtualenv.
|
||||
install: "tools/pip_install.py -U codecov tox virtualenv"
|
||||
script: tox
|
||||
install: 'tools/pip_install.py -U codecov tox virtualenv'
|
||||
# Most of the time TRAVIS_RETRY is an empty string, and has no effect on the
|
||||
# script command. It is set only to `travis_retry` during farm tests, in
|
||||
# order to trigger the Travis retry feature, and compensate the inherent
|
||||
# flakiness of these specific tests.
|
||||
script: '$TRAVIS_RETRY tox'
|
||||
|
||||
after_success: '[ "$TOXENV" == "py27-cover" ] && codecov -F linux'
|
||||
|
||||
|
||||
29
CHANGELOG.md
29
CHANGELOG.md
@@ -2,21 +2,46 @@
|
||||
|
||||
Certbot adheres to [Semantic Versioning](https://semver.org/).
|
||||
|
||||
## 0.38.0 - master
|
||||
## 0.39.0 - master
|
||||
|
||||
### Added
|
||||
|
||||
* Support for Python 3.8 was added to Certbot and all of its components.
|
||||
|
||||
### Changed
|
||||
|
||||
* Don't send OCSP requests for expired certificates
|
||||
|
||||
### Fixed
|
||||
|
||||
*
|
||||
|
||||
More details about these changes can be found on our GitHub repo.
|
||||
|
||||
## 0.38.0 - 2019-09-03
|
||||
|
||||
### Added
|
||||
|
||||
* Disable session tickets for Nginx users when appropriate.
|
||||
|
||||
### Changed
|
||||
|
||||
* If Certbot fails to rollback your server configuration, the error message
|
||||
links to the Let's Encrypt forum. Change the link to the Help category now
|
||||
that the Server category has been closed.
|
||||
* Replace platform.linux_distribution with distro.linux_distribution as a step
|
||||
towards Python 3.8 support in Certbot.
|
||||
|
||||
### Fixed
|
||||
|
||||
*
|
||||
* Fixed OS detection in the Apache plugin on Scientific Linux.
|
||||
|
||||
More details about these changes can be found on our GitHub repo.
|
||||
|
||||
## 0.37.2 - 2019-08-21
|
||||
|
||||
* Stop disabling TLS session tickets in Nginx as it caused TLS failures on
|
||||
some systems.
|
||||
|
||||
More details about these changes can be found on our GitHub repo.
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ from setuptools import find_packages
|
||||
from setuptools.command.test import test as TestCommand
|
||||
import sys
|
||||
|
||||
version = '0.38.0.dev0'
|
||||
version = '0.39.0.dev0'
|
||||
|
||||
# Please update tox.ini when modifying dependency version requirements
|
||||
install_requires = [
|
||||
@@ -73,6 +73,7 @@ setup(
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Topic :: Internet :: WWW/HTTP',
|
||||
'Topic :: Security',
|
||||
],
|
||||
|
||||
@@ -31,6 +31,8 @@ OVERRIDE_CLASSES = {
|
||||
"gentoo base system": override_gentoo.GentooConfigurator,
|
||||
"opensuse": override_suse.OpenSUSEConfigurator,
|
||||
"suse": override_suse.OpenSUSEConfigurator,
|
||||
"scientific": override_centos.CentOSConfigurator,
|
||||
"scientific linux": override_centos.CentOSConfigurator,
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-
|
||||
|
||||
from certbot import achallenges
|
||||
from certbot import errors
|
||||
from certbot.compat import filesystem
|
||||
from certbot.compat import os
|
||||
from certbot.tests import acme_util
|
||||
|
||||
@@ -180,7 +181,7 @@ class ApacheHttp01Test(util.ApacheTest):
|
||||
self.assertEqual(self.http.perform(), expected_response)
|
||||
|
||||
self.assertTrue(os.path.isdir(self.http.challenge_dir))
|
||||
self._has_min_permissions(self.http.challenge_dir, 0o755)
|
||||
self.assertTrue(filesystem.has_min_permissions(self.http.challenge_dir, 0o755))
|
||||
self._test_challenge_conf()
|
||||
|
||||
for achall in achalls:
|
||||
@@ -218,15 +219,10 @@ class ApacheHttp01Test(util.ApacheTest):
|
||||
name = os.path.join(self.http.challenge_dir, achall.chall.encode("token"))
|
||||
validation = achall.validation(self.account_key)
|
||||
|
||||
self._has_min_permissions(name, 0o644)
|
||||
self.assertTrue(filesystem.has_min_permissions(name, 0o644))
|
||||
with open(name, 'rb') as f:
|
||||
self.assertEqual(f.read(), validation.encode())
|
||||
|
||||
def _has_min_permissions(self, path, min_mode):
|
||||
"""Tests the given file has at least the permissions in mode."""
|
||||
st_mode = os.stat(path).st_mode
|
||||
self.assertEqual(st_mode, st_mode | min_mode)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main() # pragma: no cover
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# Remember to update setup.py to match the package versions below.
|
||||
acme[dev]==0.29.0
|
||||
certbot[dev]==0.37.0
|
||||
-e .[dev]
|
||||
|
||||
@@ -4,13 +4,13 @@ from setuptools.command.test import test as TestCommand
|
||||
import sys
|
||||
|
||||
|
||||
version = '0.38.0.dev0'
|
||||
version = '0.39.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
install_requires = [
|
||||
'acme>=0.29.0',
|
||||
'certbot>=0.37.0',
|
||||
'certbot>=0.39.0.dev0',
|
||||
'mock',
|
||||
'python-augeas',
|
||||
'setuptools',
|
||||
@@ -62,6 +62,7 @@ setup(
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Topic :: Internet :: WWW/HTTP',
|
||||
'Topic :: Security',
|
||||
'Topic :: System :: Installation/Setup',
|
||||
|
||||
201
certbot-auto
201
certbot-auto
@@ -31,7 +31,7 @@ if [ -z "$VENV_PATH" ]; then
|
||||
fi
|
||||
VENV_BIN="$VENV_PATH/bin"
|
||||
BOOTSTRAP_VERSION_PATH="$VENV_PATH/certbot-auto-bootstrap-version.txt"
|
||||
LE_AUTO_VERSION="0.37.1"
|
||||
LE_AUTO_VERSION="0.38.0"
|
||||
BASENAME=$(basename $0)
|
||||
USAGE="Usage: $BASENAME [OPTIONS]
|
||||
A self-updating wrapper script for the Certbot ACME client. When run, updates
|
||||
@@ -1134,73 +1134,76 @@ if [ "$1" = "--le-auto-phase2" ]; then
|
||||
# To generate this, do (with docker and package hashin installed):
|
||||
# ```
|
||||
# letsencrypt-auto-source/rebuild_dependencies.py \
|
||||
# letsencrypt-auto-sources/pieces/dependency-requirements.txt
|
||||
# letsencrypt-auto-source/pieces/dependency-requirements.txt
|
||||
# ```
|
||||
# If you want to update a single dependency, run commands similar to these:
|
||||
# ```
|
||||
# pip install hashin
|
||||
# hashin -r dependency-requirements.txt cryptography==1.5.2
|
||||
# ```
|
||||
ConfigArgParse==0.14.0 \
|
||||
--hash=sha256:2e2efe2be3f90577aca9415e32cb629aa2ecd92078adbe27b53a03e53ff12e91
|
||||
asn1crypto==0.24.0 \
|
||||
--hash=sha256:2f1adbb7546ed199e3c90ef23ec95c5cf3585bac7d11fb7eb562a3fe89c64e87 \
|
||||
--hash=sha256:9d5c20441baf0cb60a4ac34cc447c6c189024b6b4c6cd7877034f4965c464e49
|
||||
certifi==2019.3.9 \
|
||||
--hash=sha256:59b7658e26ca9c7339e00f8f4636cdfe59d34fa37b9b04f6f9e9926b3cece1a5 \
|
||||
--hash=sha256:b26104d6835d1f5e49452a26eb2ff87fe7090b89dfcaee5ea2212697e1e1d7ae
|
||||
cffi==1.12.2 \
|
||||
--hash=sha256:00b97afa72c233495560a0793cdc86c2571721b4271c0667addc83c417f3d90f \
|
||||
--hash=sha256:0ba1b0c90f2124459f6966a10c03794082a2f3985cd699d7d63c4a8dae113e11 \
|
||||
--hash=sha256:0bffb69da295a4fc3349f2ec7cbe16b8ba057b0a593a92cbe8396e535244ee9d \
|
||||
--hash=sha256:21469a2b1082088d11ccd79dd84157ba42d940064abbfa59cf5f024c19cf4891 \
|
||||
--hash=sha256:2e4812f7fa984bf1ab253a40f1f4391b604f7fc424a3e21f7de542a7f8f7aedf \
|
||||
--hash=sha256:2eac2cdd07b9049dd4e68449b90d3ef1adc7c759463af5beb53a84f1db62e36c \
|
||||
--hash=sha256:2f9089979d7456c74d21303c7851f158833d48fb265876923edcb2d0194104ed \
|
||||
--hash=sha256:3dd13feff00bddb0bd2d650cdb7338f815c1789a91a6f68fdc00e5c5ed40329b \
|
||||
--hash=sha256:4065c32b52f4b142f417af6f33a5024edc1336aa845b9d5a8d86071f6fcaac5a \
|
||||
--hash=sha256:51a4ba1256e9003a3acf508e3b4f4661bebd015b8180cc31849da222426ef585 \
|
||||
--hash=sha256:59888faac06403767c0cf8cfb3f4a777b2939b1fbd9f729299b5384f097f05ea \
|
||||
--hash=sha256:59c87886640574d8b14910840327f5cd15954e26ed0bbd4e7cef95fa5aef218f \
|
||||
--hash=sha256:610fc7d6db6c56a244c2701575f6851461753c60f73f2de89c79bbf1cc807f33 \
|
||||
--hash=sha256:70aeadeecb281ea901bf4230c6222af0248c41044d6f57401a614ea59d96d145 \
|
||||
--hash=sha256:71e1296d5e66c59cd2c0f2d72dc476d42afe02aeddc833d8e05630a0551dad7a \
|
||||
--hash=sha256:8fc7a49b440ea752cfdf1d51a586fd08d395ff7a5d555dc69e84b1939f7ddee3 \
|
||||
--hash=sha256:9b5c2afd2d6e3771d516045a6cfa11a8da9a60e3d128746a7fe9ab36dfe7221f \
|
||||
--hash=sha256:9c759051ebcb244d9d55ee791259ddd158188d15adee3c152502d3b69005e6bd \
|
||||
--hash=sha256:b4d1011fec5ec12aa7cc10c05a2f2f12dfa0adfe958e56ae38dc140614035804 \
|
||||
--hash=sha256:b4f1d6332339ecc61275bebd1f7b674098a66fea11a00c84d1c58851e618dc0d \
|
||||
--hash=sha256:c030cda3dc8e62b814831faa4eb93dd9a46498af8cd1d5c178c2de856972fd92 \
|
||||
--hash=sha256:c2e1f2012e56d61390c0e668c20c4fb0ae667c44d6f6a2eeea5d7148dcd3df9f \
|
||||
--hash=sha256:c37c77d6562074452120fc6c02ad86ec928f5710fbc435a181d69334b4de1d84 \
|
||||
--hash=sha256:c8149780c60f8fd02752d0429246088c6c04e234b895c4a42e1ea9b4de8d27fb \
|
||||
--hash=sha256:cbeeef1dc3c4299bd746b774f019de9e4672f7cc666c777cd5b409f0b746dac7 \
|
||||
--hash=sha256:e113878a446c6228669144ae8a56e268c91b7f1fafae927adc4879d9849e0ea7 \
|
||||
--hash=sha256:e21162bf941b85c0cda08224dade5def9360f53b09f9f259adb85fc7dd0e7b35 \
|
||||
--hash=sha256:fb6934ef4744becbda3143d30c6604718871495a5e36c408431bf33d9c146889
|
||||
certifi==2019.6.16 \
|
||||
--hash=sha256:046832c04d4e752f37383b628bc601a7ea7211496b4638f6514d0e5b9acc4939 \
|
||||
--hash=sha256:945e3ba63a0b9f577b1395204e13c3a231f9bc0223888be653286534e5873695
|
||||
cffi==1.12.3 \
|
||||
--hash=sha256:041c81822e9f84b1d9c401182e174996f0bae9991f33725d059b771744290774 \
|
||||
--hash=sha256:046ef9a22f5d3eed06334d01b1e836977eeef500d9b78e9ef693f9380ad0b83d \
|
||||
--hash=sha256:066bc4c7895c91812eff46f4b1c285220947d4aa46fa0a2651ff85f2afae9c90 \
|
||||
--hash=sha256:066c7ff148ae33040c01058662d6752fd73fbc8e64787229ea8498c7d7f4041b \
|
||||
--hash=sha256:2444d0c61f03dcd26dbf7600cf64354376ee579acad77aef459e34efcb438c63 \
|
||||
--hash=sha256:300832850b8f7967e278870c5d51e3819b9aad8f0a2c8dbe39ab11f119237f45 \
|
||||
--hash=sha256:34c77afe85b6b9e967bd8154e3855e847b70ca42043db6ad17f26899a3df1b25 \
|
||||
--hash=sha256:46de5fa00f7ac09f020729148ff632819649b3e05a007d286242c4882f7b1dc3 \
|
||||
--hash=sha256:4aa8ee7ba27c472d429b980c51e714a24f47ca296d53f4d7868075b175866f4b \
|
||||
--hash=sha256:4d0004eb4351e35ed950c14c11e734182591465a33e960a4ab5e8d4f04d72647 \
|
||||
--hash=sha256:4e3d3f31a1e202b0f5a35ba3bc4eb41e2fc2b11c1eff38b362de710bcffb5016 \
|
||||
--hash=sha256:50bec6d35e6b1aaeb17f7c4e2b9374ebf95a8975d57863546fa83e8d31bdb8c4 \
|
||||
--hash=sha256:55cad9a6df1e2a1d62063f79d0881a414a906a6962bc160ac968cc03ed3efcfb \
|
||||
--hash=sha256:5662ad4e4e84f1eaa8efce5da695c5d2e229c563f9d5ce5b0113f71321bcf753 \
|
||||
--hash=sha256:59b4dc008f98fc6ee2bb4fd7fc786a8d70000d058c2bbe2698275bc53a8d3fa7 \
|
||||
--hash=sha256:73e1ffefe05e4ccd7bcea61af76f36077b914f92b76f95ccf00b0c1b9186f3f9 \
|
||||
--hash=sha256:a1f0fd46eba2d71ce1589f7e50a9e2ffaeb739fb2c11e8192aa2b45d5f6cc41f \
|
||||
--hash=sha256:a2e85dc204556657661051ff4bab75a84e968669765c8a2cd425918699c3d0e8 \
|
||||
--hash=sha256:a5457d47dfff24882a21492e5815f891c0ca35fefae8aa742c6c263dac16ef1f \
|
||||
--hash=sha256:a8dccd61d52a8dae4a825cdbb7735da530179fea472903eb871a5513b5abbfdc \
|
||||
--hash=sha256:ae61af521ed676cf16ae94f30fe202781a38d7178b6b4ab622e4eec8cefaff42 \
|
||||
--hash=sha256:b012a5edb48288f77a63dba0840c92d0504aa215612da4541b7b42d849bc83a3 \
|
||||
--hash=sha256:d2c5cfa536227f57f97c92ac30c8109688ace8fa4ac086d19d0af47d134e2909 \
|
||||
--hash=sha256:d42b5796e20aacc9d15e66befb7a345454eef794fdb0737d1af593447c6c8f45 \
|
||||
--hash=sha256:dee54f5d30d775f525894d67b1495625dd9322945e7fee00731952e0368ff42d \
|
||||
--hash=sha256:e070535507bd6aa07124258171be2ee8dfc19119c28ca94c9dfb7efd23564512 \
|
||||
--hash=sha256:e1ff2748c84d97b065cc95429814cdba39bcbd77c9c85c89344b317dc0d9cbff \
|
||||
--hash=sha256:ed851c75d1e0e043cbf5ca9a8e1b13c4c90f3fbd863dacb01c0808e2b5204201
|
||||
chardet==3.0.4 \
|
||||
--hash=sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae \
|
||||
--hash=sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691
|
||||
configobj==5.0.6 \
|
||||
--hash=sha256:a2f5650770e1c87fb335af19a9b7eb73fc05ccf22144eb68db7d00cd2bcb0902
|
||||
cryptography==2.6.1 \
|
||||
--hash=sha256:066f815f1fe46020877c5983a7e747ae140f517f1b09030ec098503575265ce1 \
|
||||
--hash=sha256:210210d9df0afba9e000636e97810117dc55b7157c903a55716bb73e3ae07705 \
|
||||
--hash=sha256:26c821cbeb683facb966045e2064303029d572a87ee69ca5a1bf54bf55f93ca6 \
|
||||
--hash=sha256:2afb83308dc5c5255149ff7d3fb9964f7c9ee3d59b603ec18ccf5b0a8852e2b1 \
|
||||
--hash=sha256:2db34e5c45988f36f7a08a7ab2b69638994a8923853dec2d4af121f689c66dc8 \
|
||||
--hash=sha256:409c4653e0f719fa78febcb71ac417076ae5e20160aec7270c91d009837b9151 \
|
||||
--hash=sha256:45a4f4cf4f4e6a55c8128f8b76b4c057027b27d4c67e3fe157fa02f27e37830d \
|
||||
--hash=sha256:48eab46ef38faf1031e58dfcc9c3e71756a1108f4c9c966150b605d4a1a7f659 \
|
||||
--hash=sha256:6b9e0ae298ab20d371fc26e2129fd683cfc0cfde4d157c6341722de645146537 \
|
||||
--hash=sha256:6c4778afe50f413707f604828c1ad1ff81fadf6c110cb669579dea7e2e98a75e \
|
||||
--hash=sha256:8c33fb99025d353c9520141f8bc989c2134a1f76bac6369cea060812f5b5c2bb \
|
||||
--hash=sha256:9873a1760a274b620a135054b756f9f218fa61ca030e42df31b409f0fb738b6c \
|
||||
--hash=sha256:9b069768c627f3f5623b1cbd3248c5e7e92aec62f4c98827059eed7053138cc9 \
|
||||
--hash=sha256:9e4ce27a507e4886efbd3c32d120db5089b906979a4debf1d5939ec01b9dd6c5 \
|
||||
--hash=sha256:acb424eaca214cb08735f1a744eceb97d014de6530c1ea23beb86d9c6f13c2ad \
|
||||
--hash=sha256:c8181c7d77388fe26ab8418bb088b1a1ef5fde058c6926790c8a0a3d94075a4a \
|
||||
--hash=sha256:d4afbb0840f489b60f5a580a41a1b9c3622e08ecb5eec8614d4fb4cd914c4460 \
|
||||
--hash=sha256:d9ed28030797c00f4bc43c86bf819266c76a5ea61d006cd4078a93ebf7da6bfd \
|
||||
--hash=sha256:e603aa7bb52e4e8ed4119a58a03b60323918467ef209e6ff9db3ac382e5cf2c6
|
||||
# Package enum34 needs to be explicitly limited to Python2.x, in order to avoid
|
||||
# certbot-auto failures on Python 3.6+ which enum34 doesn't support. See #5456.
|
||||
enum34==1.1.6 ; python_version < '3.4' \
|
||||
cryptography==2.7 \
|
||||
--hash=sha256:24b61e5fcb506424d3ec4e18bca995833839bf13c59fc43e530e488f28d46b8c \
|
||||
--hash=sha256:25dd1581a183e9e7a806fe0543f485103232f940fcfc301db65e630512cce643 \
|
||||
--hash=sha256:3452bba7c21c69f2df772762be0066c7ed5dc65df494a1d53a58b683a83e1216 \
|
||||
--hash=sha256:41a0be220dd1ed9e998f5891948306eb8c812b512dc398e5a01846d855050799 \
|
||||
--hash=sha256:5751d8a11b956fbfa314f6553d186b94aa70fdb03d8a4d4f1c82dcacf0cbe28a \
|
||||
--hash=sha256:5f61c7d749048fa6e3322258b4263463bfccefecb0dd731b6561cb617a1d9bb9 \
|
||||
--hash=sha256:72e24c521fa2106f19623a3851e9f89ddfdeb9ac63871c7643790f872a305dfc \
|
||||
--hash=sha256:7b97ae6ef5cba2e3bb14256625423413d5ce8d1abb91d4f29b6d1a081da765f8 \
|
||||
--hash=sha256:961e886d8a3590fd2c723cf07be14e2a91cf53c25f02435c04d39e90780e3b53 \
|
||||
--hash=sha256:96d8473848e984184b6728e2c9d391482008646276c3ff084a1bd89e15ff53a1 \
|
||||
--hash=sha256:ae536da50c7ad1e002c3eee101871d93abdc90d9c5f651818450a0d3af718609 \
|
||||
--hash=sha256:b0db0cecf396033abb4a93c95d1602f268b3a68bb0a9cc06a7cff587bb9a7292 \
|
||||
--hash=sha256:cfee9164954c186b191b91d4193989ca994703b2fff406f71cf454a2d3c7327e \
|
||||
--hash=sha256:e6347742ac8f35ded4a46ff835c60e68c22a536a8ae5c4422966d06946b6d4c6 \
|
||||
--hash=sha256:f27d93f0139a3c056172ebb5d4f9056e770fdf0206c2f422ff2ebbad142e09ed \
|
||||
--hash=sha256:f57b76e46a58b63d1c6375017f4564a28f19a5ca912691fd2e4261b3414b618d
|
||||
distro==1.4.0 \
|
||||
--hash=sha256:362dde65d846d23baee4b5c058c8586f219b5a54be1cf5fc6ff55c4578392f57 \
|
||||
--hash=sha256:eedf82a470ebe7d010f1872c17237c79ab04097948800029994fa458e52fb4b4
|
||||
enum34==1.1.6 \
|
||||
--hash=sha256:2d81cbbe0e73112bdfe6ef8576f2238f2ba27dd0d55752a776c41d38b7da2850 \
|
||||
--hash=sha256:644837f692e5f550741432dd3f223bbb9852018674981b1664e5dc339387588a \
|
||||
--hash=sha256:6bd0f6ad48ec2aa117d3d141940d484deccda84d4fcd884f5c3d93c23ecd8c79 \
|
||||
@@ -1216,18 +1219,18 @@ idna==2.8 \
|
||||
ipaddress==1.0.22 \
|
||||
--hash=sha256:64b28eec5e78e7510698f6d4da08800a5c575caa4a286c93d651c5d3ff7b6794 \
|
||||
--hash=sha256:b146c751ea45cad6188dd6cf2d9b757f6f4f8d6ffb96a023e6f2e26eea02a72c
|
||||
josepy==1.1.0 \
|
||||
--hash=sha256:1309a25aac3caeff5239729c58ff9b583f7d022ffdb1553406ddfc8e5b52b76e \
|
||||
--hash=sha256:fb5c62c77d26e04df29cb5ecd01b9ce69b6fcc9e521eb1ca193b7faa2afa7086
|
||||
josepy==1.2.0 \
|
||||
--hash=sha256:8ea15573203f28653c00f4ac0142520777b1c59d9eddd8da3f256c6ba3cac916 \
|
||||
--hash=sha256:9cec9a839fe9520f0420e4f38e7219525daccce4813296627436fe444cd002d3
|
||||
mock==1.3.0 \
|
||||
--hash=sha256:1e247dbecc6ce057299eb7ee019ad68314bb93152e81d9a6110d35f4d5eca0f6 \
|
||||
--hash=sha256:3f573a18be94de886d1191f27c168427ef693e8dcfcecf95b170577b2eb69cbb
|
||||
parsedatetime==2.4 \
|
||||
--hash=sha256:3d817c58fb9570d1eec1dd46fa9448cd644eeed4fb612684b02dfda3a79cb84b \
|
||||
--hash=sha256:9ee3529454bf35c40a77115f5a596771e59e1aee8c53306f346c461b8e913094
|
||||
pbr==5.1.3 \
|
||||
--hash=sha256:8257baf496c8522437e8a6cfe0f15e00aedc6c0e0e7c9d55eeeeab31e0853843 \
|
||||
--hash=sha256:8c361cc353d988e4f5b998555c88098b9d5964c2e11acf7b0d21925a66bb5824
|
||||
pbr==5.4.2 \
|
||||
--hash=sha256:56e52299170b9492513c64be44736d27a512fa7e606f21942160b68ce510b4bc \
|
||||
--hash=sha256:9b321c204a88d8ab5082699469f52cc94c5da45c51f114113d01b3d993c24cdf
|
||||
pyOpenSSL==19.0.0 \
|
||||
--hash=sha256:aeca66338f6de19d1aa46ed634c3b9ae519a64b458f8468aec688e7e3c20f200 \
|
||||
--hash=sha256:c727930ad54b10fc157015014b666f2d8b41f70c0d03e83ab67624fd3dd5d1e6
|
||||
@@ -1236,14 +1239,14 @@ pyRFC3339==1.1 \
|
||||
--hash=sha256:81b8cbe1519cdb79bed04910dd6fa4e181faf8c88dff1e1b987b5f7ab23a5b1a
|
||||
pycparser==2.19 \
|
||||
--hash=sha256:a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3
|
||||
pyparsing==2.3.1 \
|
||||
--hash=sha256:66c9268862641abcac4a96ba74506e594c884e3f57690a696d21ad8210ed667a \
|
||||
--hash=sha256:f6c5ef0d7480ad048c054c37632c67fca55299990fff127850181659eea33fc3
|
||||
pyparsing==2.4.2 \
|
||||
--hash=sha256:6f98a7b9397e206d78cc01df10131398f1c8b8510a2f4d97d9abd82e1aacdd80 \
|
||||
--hash=sha256:d9338df12903bbf5d65a0e4e87c2161968b10d2e489652bb47001d82a9b028b4
|
||||
python-augeas==0.5.0 \
|
||||
--hash=sha256:67d59d66cdba8d624e0389b87b2a83a176f21f16a87553b50f5703b23f29bac2
|
||||
pytz==2018.9 \
|
||||
--hash=sha256:32b0891edff07e28efe91284ed9c31e123d84bea3fd98e1f72be2508f43ef8d9 \
|
||||
--hash=sha256:d5f05e487007e29e03409f9398d074e158d920d36eb82eaf66fb1136b0c5374c
|
||||
pytz==2019.2 \
|
||||
--hash=sha256:26c0b32e437e54a18161324a2fca3c4b9846b74a8dccddd843113109e1116b32 \
|
||||
--hash=sha256:c894d57500a4cd2d5c71114aaab77dbab5eabd9022308ce5ac9bb93a60a6f0c7
|
||||
requests==2.21.0 \
|
||||
--hash=sha256:502a824f31acdacb3a35b6690b5fbf0bc41d63a24a45c4004352b0242707598e \
|
||||
--hash=sha256:7bf2a778576d825600030a110f3c0e3e8edc51dfaafe1c146e39a2027784957b
|
||||
@@ -1253,15 +1256,15 @@ requests-toolbelt==0.9.1 \
|
||||
six==1.12.0 \
|
||||
--hash=sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c \
|
||||
--hash=sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73
|
||||
urllib3==1.24.2 \
|
||||
--hash=sha256:4c291ca23bbb55c76518905869ef34bdd5f0e46af7afe6861e8375643ffee1a0 \
|
||||
--hash=sha256:9a247273df709c4fedb38c711e44292304f73f39ab01beda9f6b9fc375669ac3
|
||||
urllib3==1.24.3 \
|
||||
--hash=sha256:2393a695cd12afedd0dcb26fe5d50d0cf248e5a66f75dbd89a3d4eb333a61af4 \
|
||||
--hash=sha256:a637e5fae88995b256e3409dc4d52c2e2e0ba32c42a6365fee8bbd2238de3cfb
|
||||
zope.component==4.5 \
|
||||
--hash=sha256:6edfd626c3b593b72895a8cfcf79bff41f4619194ce996a85bce31ac02b94e55 \
|
||||
--hash=sha256:984a06ba3def0b02b1117fa4c45b56e772e8c29c0340820fbf367e440a93a3a4
|
||||
zope.deferredimport==4.3 \
|
||||
--hash=sha256:2ddef5a7ecfff132a2dd796253366ecf9748a446e30f1a0b3a636aec9d9c05c5 \
|
||||
--hash=sha256:4aae9cbacb2146cca58e62be0a914f0cec034d3b2d41135ea212ca8a96f4b5ec
|
||||
zope.deferredimport==4.3.1 \
|
||||
--hash=sha256:57b2345e7b5eef47efcd4f634ff16c93e4265de3dcf325afc7315ade48d909e1 \
|
||||
--hash=sha256:9a0c211df44aa95f1c4e6d2626f90b400f56989180d3ef96032d708da3d23e0a
|
||||
zope.deprecation==4.4.0 \
|
||||
--hash=sha256:0d453338f04bacf91bbfba545d8bcdf529aa829e67b705eac8c1a7fdce66e2df \
|
||||
--hash=sha256:f1480b74995958b24ce37b0ef04d3663d2683e5d6debc96726eff18acf4ea113
|
||||
@@ -1309,18 +1312,18 @@ zope.interface==4.6.0 \
|
||||
--hash=sha256:d788a3999014ddf416f2dc454efa4a5dbeda657c6aba031cf363741273804c6b \
|
||||
--hash=sha256:eed88ae03e1ef3a75a0e96a55a99d7937ed03e53d0cffc2451c208db445a2966 \
|
||||
--hash=sha256:f99451f3a579e73b5dd58b1b08d1179791d49084371d9a47baad3b22417f0317
|
||||
zope.proxy==4.3.1 \
|
||||
--hash=sha256:0cbcfcafaa3b5fde7ba7a7b9a2b5f09af25c9b90087ad65f9e61359fed0ca63b \
|
||||
--hash=sha256:3de631dd5054a3a20b9ebff0e375f39c0565f1fb9131200d589a6a8f379214cd \
|
||||
--hash=sha256:5429134d04d42262f4dac25f6dea907f6334e9a751ffc62cb1d40226fb52bdeb \
|
||||
--hash=sha256:563c2454b2d0f23bca54d2e0e4d781149b7b06cb5df67e253ca3620f37202dd2 \
|
||||
--hash=sha256:5bcf773345016b1461bb07f70c635b9386e5eaaa08e37d3939dcdf12d3fdbec5 \
|
||||
--hash=sha256:8d84b7aef38c693874e2f2084514522bf73fd720fde0ce2a9352a51315ffa475 \
|
||||
--hash=sha256:90de9473c05819b36816b6cb957097f809691836ed3142648bf62da84b4502fe \
|
||||
--hash=sha256:dd592a69fe872445542a6e1acbefb8e28cbe6b4007b8f5146da917e49b155cc3 \
|
||||
--hash=sha256:e7399ab865399fce322f9cefc6f2f3e4099d087ba581888a9fea1bbe1db42a08 \
|
||||
--hash=sha256:e7d1c280d86d72735a420610df592aac72332194e531a8beff43a592c3a1b8eb \
|
||||
--hash=sha256:e90243fee902adb0c39eceb3c69995c0f2004bc3fdb482fbf629efc656d124ed
|
||||
zope.proxy==4.3.2 \
|
||||
--hash=sha256:320a7619992e42142549ebf61e14ce27683b4d14b0cbc45f7c037ba64edb560c \
|
||||
--hash=sha256:824d4dbabbb7deb84f25fdb96ea1eeca436a1802c3c8d323b3eb4ac9d527d41c \
|
||||
--hash=sha256:8a32eb9c94908f3544da2dae3f4a9e6961d78819b88ac6b6f4a51cee2d65f4a0 \
|
||||
--hash=sha256:96265fd3bc3ea646f98482e16307a69de21402eeaaaaf4b841c1161ac2f71bb0 \
|
||||
--hash=sha256:ab6d6975d9c51c13cac828ff03168de21fb562b0664c59bcdc4a4b10f39a5b17 \
|
||||
--hash=sha256:af10cb772391772463f65a58348e2de5ecc06693c16d2078be276dc068bcbb54 \
|
||||
--hash=sha256:b8fd3a3de3f7b6452775e92af22af5977b17b69ac86a38a3ddfe870e40a0d05f \
|
||||
--hash=sha256:bb7088f1bed3b8214284a5e425dc23da56f2f28e8815b7580bfed9e245b6c0b6 \
|
||||
--hash=sha256:bc29b3665eac34f14c4aef5224bef045efcfb1a7d12d78c8685858de5fbf21c0 \
|
||||
--hash=sha256:c39fa6a159affeae5fe31b49d9f5b12bd674fe77271a9a324408b271440c50a7 \
|
||||
--hash=sha256:e946a036ac5b9f897e986ac9dc950a34cffc857d88eae6727b8434fbc4752366
|
||||
|
||||
# Contains the requirements for the letsencrypt package.
|
||||
#
|
||||
@@ -1333,18 +1336,18 @@ letsencrypt==0.7.0 \
|
||||
--hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \
|
||||
--hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9
|
||||
|
||||
certbot==0.37.1 \
|
||||
--hash=sha256:84dbdad204327b8d8ef9ab5b040f2be1e427a9f7e087affcc9a6051ea1b03fe7 \
|
||||
--hash=sha256:aace73e63b0c11cdb4b0bd33e1780c1fbe0ce5669dc72e80c3aa9500145daf16
|
||||
acme==0.37.1 \
|
||||
--hash=sha256:83a4f6f3c5eb6a85233d5ba87714b426f2d096df58d711f8a2fc4071eb3fd3fc \
|
||||
--hash=sha256:c069a761990751f7c4bf51d2e87ae10319bf460de6629d2908c9fa6f69e97111
|
||||
certbot-apache==0.37.1 \
|
||||
--hash=sha256:3ea832408877b12b3a60d17e8b2ee3387364f8c3023ac267161c25b99087cd42 \
|
||||
--hash=sha256:e46c2644451101c0e216aa1f525a577cc903efaf871e0e4da277224a4439040c
|
||||
certbot-nginx==0.37.1 \
|
||||
--hash=sha256:1f9af389d26f06634e2eefaace3354e7679dabb4295e1d55d05a4ee7e23a64bd \
|
||||
--hash=sha256:02a7ec15bd388d0f0e94a34c86a8f8d618ec7d5ffde0c206039bb4c46b294ce4
|
||||
certbot==0.38.0 \
|
||||
--hash=sha256:618abf3ae17c2fc3cb99baa4bf000dd5e2d7875b7811f5ef1edf6ebd7a33945f \
|
||||
--hash=sha256:c27712101794e3adf54f3a3067c63be5caa507a930a79865bc654b6864121c6b
|
||||
acme==0.38.0 \
|
||||
--hash=sha256:6231571b4a94d6d621b28bef6f6d4846b3c2ebca840f9718d3212036c3bd2af8 \
|
||||
--hash=sha256:1c1e9c0826a8f72d670b0ca28b7e6392ce4781eb33222f35133705b6551885d8
|
||||
certbot-apache==0.38.0 \
|
||||
--hash=sha256:0b5a2c2bcc430470b5131941ebdfde0a13e28dec38918c1a4ebea5dd35ad38bc \
|
||||
--hash=sha256:2d335543e0ae9292303238736907ce6b321ac49eb49fe4e0b775abdc0ba57c62
|
||||
certbot-nginx==0.38.0 \
|
||||
--hash=sha256:af82944e171d2e93c81438b185f8051e742c6f47f7382cb1a647b1c7ca2b53f2 \
|
||||
--hash=sha256:cecd1fa3de6e19980fdb9c3b3269b15b7da71b5748ee7ae5caddcc18dbb208ac
|
||||
|
||||
UNLIKELY_EOF
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
# Avoid false warnings because certbot packages are not installed in the thread that executes
|
||||
# the coverage: indeed, certbot is launched as a CLI from a subprocess.
|
||||
disable_warnings = module-not-imported,no-data-collected
|
||||
omit = **/*_test.py,**/tests/*,**/dns_common*,**/certbot_nginx/parser_obj.py
|
||||
|
||||
[report]
|
||||
# Exclude unit tests in coverage during integration tests.
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
import shutil
|
||||
import subprocess
|
||||
import os
|
||||
|
||||
import pkg_resources
|
||||
import getpass
|
||||
|
||||
|
||||
def construct_apache_config_dir(apache_root, http_port, https_port, key_path=None,
|
||||
cert_path=None, wtf_prefix='le'):
|
||||
config_path = os.path.join(apache_root, 'config')
|
||||
shutil.copytree('/etc/apache2', config_path, symlinks=True)
|
||||
|
||||
webroot_path = os.path.join(apache_root, 'www')
|
||||
os.mkdir(webroot_path)
|
||||
with open(os.path.join(webroot_path, 'index.html'), 'w') as file_h:
|
||||
file_h.write('Hello World!')
|
||||
|
||||
main_config_path = os.path.join(config_path, 'apache2.conf')
|
||||
with open(main_config_path, 'w') as file_h:
|
||||
file_h.write('''\
|
||||
ServerRoot "{config}"
|
||||
DefaultRuntimeDir ${{APACHE_RUN_DIR}}
|
||||
PidFile ${{APACHE_PID_FILE}}
|
||||
Timeout 300
|
||||
KeepAlive On
|
||||
MaxKeepAliveRequests 100
|
||||
KeepAliveTimeout 5
|
||||
User ${{APACHE_RUN_USER}}
|
||||
Group ${{APACHE_RUN_GROUP}}
|
||||
HostnameLookups Off
|
||||
ErrorLog ${{APACHE_LOG_DIR}}/error.log
|
||||
LogLevel warn
|
||||
|
||||
IncludeOptional mods-enabled/*.load
|
||||
IncludeOptional mods-enabled/*.conf
|
||||
|
||||
Include ports.conf
|
||||
|
||||
<Directory />
|
||||
Options FollowSymLinks
|
||||
AllowOverride None
|
||||
Require all denied
|
||||
</Directory>
|
||||
|
||||
<Directory /usr/share>
|
||||
AllowOverride None
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
<Directory {webroot}/>
|
||||
Options Indexes FollowSymLinks
|
||||
AllowOverride None
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
AccessFileName .htaccess
|
||||
|
||||
<FilesMatch "^\.ht">
|
||||
Require all denied
|
||||
</FilesMatch>
|
||||
|
||||
LogFormat "%v:%p %h %l %u %t \\"%r\\" %>s %O \\"%{{Referer}}i\\" \\"%{{User-Agent}}i\\"" vhost_combined
|
||||
LogFormat "%h %l %u %t \\"%r\\" %>s %O \\"%{{Referer}}i\\" \\"%{{User-Agent}}i\\"" combined
|
||||
LogFormat "%h %l %u %t \\"%r\\" %>s %O" common
|
||||
LogFormat "%{{Referer}}i -> %U" referer
|
||||
LogFormat "%{{User-agent}}i" agent
|
||||
|
||||
IncludeOptional conf-enabled/*.conf
|
||||
IncludeOptional sites-enabled/*.conf
|
||||
'''.format(config=config_path, webroot=webroot_path))
|
||||
|
||||
with open(os.path.join(config_path, 'ports.conf'), 'w') as file_h:
|
||||
file_h.write('''\
|
||||
Listen {http}
|
||||
<IfModule ssl_module>
|
||||
Listen {https}
|
||||
</IfModule>
|
||||
<IfModule mod_gnutls.c>
|
||||
Listen {https}
|
||||
</IfModule>
|
||||
'''.format(http=http_port, https=https_port))
|
||||
|
||||
new_environ = os.environ.copy()
|
||||
new_environ['APACHE_CONFDIR'] = config_path
|
||||
|
||||
run_path = os.path.join(apache_root, 'run')
|
||||
lock_path = os.path.join(apache_root, 'lock')
|
||||
logs_path = os.path.join(apache_root, 'logs')
|
||||
os.mkdir(run_path)
|
||||
os.mkdir(lock_path)
|
||||
os.mkdir(logs_path)
|
||||
|
||||
user = getpass.getuser()
|
||||
user = user if user != 'root' else 'www-data'
|
||||
group = user
|
||||
|
||||
pid_file = os.path.join(run_path, 'apache.pid')
|
||||
|
||||
with open(os.path.join(config_path, 'envvars'), 'w') as file_h:
|
||||
file_h.write('''\
|
||||
unset HOME
|
||||
export APACHE_RUN_USER={user}
|
||||
export APACHE_RUN_GROUP={group}
|
||||
export APACHE_PID_FILE={pid_file}
|
||||
export APACHE_RUN_DIR={run_path}
|
||||
export APACHE_LOCK_DIR={lock_path}
|
||||
export APACHE_LOG_DIR={logs_path}
|
||||
export LANG=C
|
||||
'''.format(user=user, group=group, pid_file=pid_file,
|
||||
run_path=run_path, lock_path=lock_path, logs_path=logs_path))
|
||||
|
||||
new_environ['APACHE_RUN_USER'] = user
|
||||
new_environ['APACHE_RUN_GROUP'] = group
|
||||
new_environ['APACHE_PID_FILE'] = pid_file
|
||||
new_environ['APACHE_RUN_DIR'] = run_path
|
||||
new_environ['APACHE_LOCK_DIR'] = lock_path
|
||||
new_environ['APACHE_LOG_DIR'] = logs_path
|
||||
|
||||
le_host = 'apache.{0}.wtf'.format(wtf_prefix)
|
||||
|
||||
with open(os.path.join(config_path, 'sites-available', '000-default.conf'), 'w') as file_h:
|
||||
file_h.write('''\
|
||||
<VirtualHost *:{http}>
|
||||
ServerAdmin webmaster@localhost
|
||||
ServerName {le_host}
|
||||
DocumentRoot {webroot}
|
||||
|
||||
ErrorLog ${{APACHE_LOG_DIR}}/error.log
|
||||
CustomLog ${{APACHE_LOG_DIR}}/access.log combined
|
||||
</VirtualHost>
|
||||
'''.format(http=http_port, le_host=le_host, webroot=webroot_path))
|
||||
|
||||
key_path = key_path if key_path \
|
||||
else pkg_resources.resource_filename('certbot_integration_tests', 'assets/key.pem')
|
||||
cert_path = cert_path if cert_path \
|
||||
else pkg_resources.resource_filename('certbot_integration_tests', 'assets/cert.pem')
|
||||
|
||||
with open(os.path.join(config_path, 'sites-available', 'default-ssl.conf'), 'w') as file_h:
|
||||
file_h.write('''\
|
||||
<IfModule mod_ssl.c>
|
||||
<VirtualHost _default_:{https}>
|
||||
ServerAdmin webmaster@localhost
|
||||
ServerName {le_host}
|
||||
DocumentRoot {webroot}
|
||||
|
||||
ErrorLog ${{APACHE_LOG_DIR}}/error.log
|
||||
CustomLog ${{APACHE_LOG_DIR}}/access.log combined
|
||||
|
||||
SSLEngine on
|
||||
SSLCertificateFile {cert_path}
|
||||
SSLCertificateKeyFile {key_path}
|
||||
|
||||
<FilesMatch "\.(cgi|shtml|phtml|php)$">
|
||||
SSLOptions +StdEnvVars
|
||||
</FilesMatch>
|
||||
|
||||
<Directory /usr/lib/cgi-bin>
|
||||
SSLOptions +StdEnvVars
|
||||
</Directory>
|
||||
</VirtualHost>
|
||||
</IfModule>
|
||||
'''.format(https=https_port, le_host=le_host, webroot=webroot_path,
|
||||
cert_path=cert_path, key_path=key_path))
|
||||
|
||||
return new_environ, config_path, pid_file
|
||||
|
||||
|
||||
def test():
|
||||
env = construct_apache_config_dir('/tmp/test1', 5001, 5002)
|
||||
subprocess.call(['apache2ctl', '-DFOREGROUND'], env=env)
|
||||
51
certbot-ci/certbot_integration_tests/apache_tests/context.py
Normal file
51
certbot-ci/certbot_integration_tests/apache_tests/context.py
Normal file
@@ -0,0 +1,51 @@
|
||||
import errno
|
||||
import os
|
||||
import signal
|
||||
import subprocess
|
||||
|
||||
from certbot_integration_tests.certbot_tests import context as certbot_context
|
||||
from certbot_integration_tests.apache_tests import apache_config
|
||||
from certbot_integration_tests.utils import certbot_call
|
||||
|
||||
|
||||
class IntegrationTestsContext(certbot_context.IntegrationTestsContext):
|
||||
def __init__(self, request):
|
||||
super(IntegrationTestsContext, self).__init__(request)
|
||||
|
||||
subprocess.check_output(['chmod', '+x', self.workspace])
|
||||
|
||||
self.apache_root = os.path.join(self.workspace, 'apache')
|
||||
os.mkdir(self.apache_root)
|
||||
|
||||
self.env, self.config_dir, self.pid_file = apache_config.construct_apache_config_dir(
|
||||
self.apache_root, self.http_01_port, self.tls_alpn_01_port,
|
||||
wtf_prefix=self.worker_id)
|
||||
|
||||
def cleanup(self):
|
||||
self._stop_apache()
|
||||
super(IntegrationTestsContext, self).cleanup()
|
||||
|
||||
def certbot_test_apache(self, args):
|
||||
command = ['--authenticator', 'apache', '--installer', 'apache',
|
||||
'--apache-server-root', self.config_dir,
|
||||
'--apache-challenge-location', self.apache_root]
|
||||
command.extend(args)
|
||||
|
||||
return certbot_call.certbot_test(
|
||||
command, self.directory_url, self.http_01_port, self.tls_alpn_01_port,
|
||||
self.config_dir, self.workspace, env=self.env, force_renew=True)
|
||||
|
||||
def _stop_apache(self):
|
||||
try:
|
||||
with open(self.pid_file) as file_h:
|
||||
pid = int(file_h.read().strip())
|
||||
except BaseException:
|
||||
pid = None
|
||||
|
||||
if pid:
|
||||
try:
|
||||
os.kill(pid, signal.SIGTERM)
|
||||
except OSError as err:
|
||||
# Ignore "No such process" error, Apache may already be stopped.
|
||||
if err.errno != errno.ESRCH:
|
||||
raise
|
||||
@@ -0,0 +1,18 @@
|
||||
import pytest
|
||||
|
||||
from certbot_integration_tests.apache_tests import context as apache_context
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def context(request):
|
||||
# Fixture request is a built-in pytest fixture describing current test request.
|
||||
integration_test_context = apache_context.IntegrationTestsContext(request)
|
||||
try:
|
||||
yield integration_test_context
|
||||
finally:
|
||||
integration_test_context.cleanup()
|
||||
|
||||
|
||||
def test_it(context):
|
||||
command = ['-d', 'apache.{0}.wtf'.format(context.worker_id)]
|
||||
context.certbot_test_apache(command)
|
||||
@@ -6,12 +6,12 @@ import subprocess
|
||||
import sys
|
||||
import os
|
||||
|
||||
from certbot_integration_tests.utils import misc
|
||||
import certbot_integration_tests
|
||||
from certbot_integration_tests.utils.constants import *
|
||||
|
||||
|
||||
def certbot_test(certbot_args, directory_url, http_01_port, tls_alpn_01_port,
|
||||
config_dir, workspace, force_renew=True):
|
||||
config_dir, workspace, env=None, force_renew=True):
|
||||
"""
|
||||
Invoke the certbot executable available in PATH in a test context for the given args.
|
||||
The test context consists in running certbot in debug mode, with various flags suitable
|
||||
@@ -23,28 +23,70 @@ def certbot_test(certbot_args, directory_url, http_01_port, tls_alpn_01_port,
|
||||
:param int tls_alpn_01_port: port for the TLS-ALPN-01 challenges
|
||||
:param str config_dir: certbot configuration directory to use
|
||||
:param str workspace: certbot current directory to use
|
||||
:param obj env: the environment variables to use (default: None, then current env will be used)
|
||||
:param bool force_renew: set False to not force renew existing certificates (default: True)
|
||||
:return: stdout as string
|
||||
:rtype: str
|
||||
"""
|
||||
new_environ = env if env else os.environ.copy()
|
||||
command, env = _prepare_args_env(certbot_args, directory_url, http_01_port, tls_alpn_01_port,
|
||||
config_dir, workspace, force_renew)
|
||||
config_dir, workspace, force_renew, new_environ)
|
||||
|
||||
return subprocess.check_output(command, universal_newlines=True, cwd=workspace, env=env)
|
||||
|
||||
|
||||
def _prepare_args_env(certbot_args, directory_url, http_01_port, tls_alpn_01_port,
|
||||
config_dir, workspace, force_renew):
|
||||
new_environ = os.environ.copy()
|
||||
def _prepare_environ(workspace, new_environ):
|
||||
new_environ = new_environ.copy()
|
||||
new_environ['TMPDIR'] = workspace
|
||||
|
||||
# So, pytest is nice, and a little too nice for our usage.
|
||||
# In order to help user to call seamlessly any piece of python code without requiring to
|
||||
# install it as a full-fledged setuptools distribution for instance, it may inject the path
|
||||
# to the test files into the PYTHONPATH. This allows the python interpreter to import
|
||||
# as modules any python file available at this path.
|
||||
# See https://docs.pytest.org/en/3.2.5/pythonpath.html for the explanation and description.
|
||||
# However this behavior is not good in integration tests, in particular the nginx oldest ones.
|
||||
# Indeed during these kind of tests certbot is installed as a transitive dependency to
|
||||
# certbot-nginx. Here is the trick: this certbot version is not necessarily the same as
|
||||
# the certbot codebase lying in current working directory. For instance in oldest tests
|
||||
# certbot==0.36.0 may be installed while the codebase corresponds to certbot==0.37.0.dev0.
|
||||
# Then during a pytest run, PYTHONPATH contains the path to the Certbot codebase, so invoking
|
||||
# certbot will import the modules from the codebase (0.37.0.dev0), not from the
|
||||
# required/installed version (0.36.0).
|
||||
# This will lead to funny and totally incomprehensible errors. To avoid that, we ensure that
|
||||
# if PYTHONPATH is set, it does not contain the path to the root of the codebase.
|
||||
if new_environ.get('PYTHONPATH'):
|
||||
# certbot_integration_tests.__file__ is:
|
||||
# '/path/to/certbot/certbot-ci/certbot_integration_tests/__init__.pyc'
|
||||
# ... and we want '/path/to/certbot'
|
||||
certbot_root = os.path.dirname(os.path.dirname(os.path.dirname(certbot_integration_tests.__file__)))
|
||||
python_paths = [path for path in new_environ['PYTHONPATH'].split(':') if path != certbot_root]
|
||||
new_environ['PYTHONPATH'] = ':'.join(python_paths)
|
||||
|
||||
return new_environ
|
||||
|
||||
|
||||
def _compute_additional_args(workspace, environ, force_renew):
|
||||
additional_args = []
|
||||
if misc.get_certbot_version() >= LooseVersion('0.30.0'):
|
||||
output = subprocess.check_output(['certbot', '--version'],
|
||||
universal_newlines=True, stderr=subprocess.STDOUT,
|
||||
cwd=workspace, env=environ)
|
||||
version_str = output.split(' ')[1].strip() # Typical response is: output = 'certbot 0.31.0.dev0'
|
||||
if LooseVersion(version_str) >= LooseVersion('0.30.0'):
|
||||
additional_args.append('--no-random-sleep-on-renew')
|
||||
|
||||
if force_renew:
|
||||
additional_args.append('--renew-by-default')
|
||||
|
||||
return additional_args
|
||||
|
||||
|
||||
def _prepare_args_env(certbot_args, directory_url, http_01_port, tls_alpn_01_port,
|
||||
config_dir, workspace, force_renew, new_environ):
|
||||
|
||||
new_environ = _prepare_environ(workspace, new_environ)
|
||||
additional_args = _compute_additional_args(workspace, new_environ, force_renew)
|
||||
|
||||
command = [
|
||||
'certbot',
|
||||
'--server', directory_url,
|
||||
|
||||
@@ -209,18 +209,6 @@ shutil.rmtree(well_known)
|
||||
shutil.rmtree(tempdir)
|
||||
|
||||
|
||||
def get_certbot_version():
|
||||
"""
|
||||
Find the version of the certbot available in PATH.
|
||||
:return str: the certbot version
|
||||
"""
|
||||
output = subprocess.check_output(['certbot', '--version'],
|
||||
universal_newlines=True, stderr=subprocess.STDOUT)
|
||||
# Typical response is: output = 'certbot 0.31.0.dev0'
|
||||
version_str = output.split(' ')[1].strip()
|
||||
return LooseVersion(version_str)
|
||||
|
||||
|
||||
def generate_csr(domains, key_path, csr_path, key_type=RSA_KEY_TYPE):
|
||||
"""
|
||||
Generate a private key, and a CSR for the given domains using this key.
|
||||
|
||||
@@ -51,6 +51,7 @@ setup(
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Topic :: Internet :: WWW/HTTP',
|
||||
'Topic :: Security',
|
||||
],
|
||||
|
||||
@@ -4,7 +4,7 @@ from setuptools import setup
|
||||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.38.0.dev0'
|
||||
version = '0.39.0.dev0'
|
||||
|
||||
install_requires = [
|
||||
'certbot',
|
||||
@@ -47,6 +47,7 @@ setup(
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Topic :: Internet :: WWW/HTTP',
|
||||
'Topic :: Security',
|
||||
],
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# Remember to update setup.py to match the package versions below.
|
||||
acme[dev]==0.29.0
|
||||
certbot[dev]==0.34.0
|
||||
-e .[dev]
|
||||
|
||||
@@ -2,13 +2,13 @@ from setuptools import setup
|
||||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.38.0.dev0'
|
||||
version = '0.39.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
install_requires = [
|
||||
'acme>=0.29.0',
|
||||
'certbot>=0.34.0',
|
||||
'certbot>=0.39.0.dev0',
|
||||
'cloudflare>=1.5.1',
|
||||
'mock',
|
||||
'setuptools',
|
||||
@@ -43,6 +43,7 @@ setup(
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Topic :: Internet :: WWW/HTTP',
|
||||
'Topic :: Security',
|
||||
'Topic :: System :: Installation/Setup',
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# Remember to update setup.py to match the package versions below.
|
||||
acme[dev]==0.31.0
|
||||
certbot[dev]==0.34.0
|
||||
-e .[dev]
|
||||
|
||||
@@ -2,13 +2,13 @@ from setuptools import setup
|
||||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.38.0.dev0'
|
||||
version = '0.39.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
install_requires = [
|
||||
'acme>=0.31.0',
|
||||
'certbot>=0.34.0',
|
||||
'certbot>=0.39.0.dev0',
|
||||
'dns-lexicon>=2.2.1', # Support for >1 TXT record per name
|
||||
'mock',
|
||||
'setuptools',
|
||||
@@ -43,6 +43,7 @@ setup(
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Topic :: Internet :: WWW/HTTP',
|
||||
'Topic :: Security',
|
||||
'Topic :: System :: Installation/Setup',
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# Remember to update setup.py to match the package versions below.
|
||||
acme[dev]==0.29.0
|
||||
certbot[dev]==0.34.0
|
||||
-e .[dev]
|
||||
|
||||
@@ -2,13 +2,13 @@ from setuptools import setup
|
||||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.38.0.dev0'
|
||||
version = '0.39.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
install_requires = [
|
||||
'acme>=0.29.0',
|
||||
'certbot>=0.34.0',
|
||||
'certbot>=0.39.0.dev0',
|
||||
'mock',
|
||||
'python-digitalocean>=1.11',
|
||||
'setuptools',
|
||||
@@ -44,6 +44,7 @@ setup(
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Topic :: Internet :: WWW/HTTP',
|
||||
'Topic :: Security',
|
||||
'Topic :: System :: Installation/Setup',
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# Remember to update setup.py to match the package versions below.
|
||||
acme[dev]==0.31.0
|
||||
certbot[dev]==0.34.0
|
||||
-e .[dev]
|
||||
|
||||
@@ -3,13 +3,13 @@ from setuptools import setup
|
||||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.38.0.dev0'
|
||||
version = '0.39.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
install_requires = [
|
||||
'acme>=0.31.0',
|
||||
'certbot>=0.34.0',
|
||||
'certbot>=0.39.0.dev0',
|
||||
'mock',
|
||||
'setuptools',
|
||||
'zope.interface',
|
||||
@@ -55,6 +55,7 @@ setup(
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Topic :: Internet :: WWW/HTTP',
|
||||
'Topic :: Security',
|
||||
'Topic :: System :: Installation/Setup',
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# Remember to update setup.py to match the package versions below.
|
||||
acme[dev]==0.31.0
|
||||
certbot[dev]==0.34.0
|
||||
-e .[dev]
|
||||
|
||||
@@ -2,13 +2,13 @@ from setuptools import setup
|
||||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.38.0.dev0'
|
||||
version = '0.39.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
install_requires = [
|
||||
'acme>=0.31.0',
|
||||
'certbot>=0.34.0',
|
||||
'certbot>=0.39.0.dev0',
|
||||
'dns-lexicon>=2.2.1', # Support for >1 TXT record per name
|
||||
'mock',
|
||||
'setuptools',
|
||||
@@ -43,6 +43,7 @@ setup(
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Topic :: Internet :: WWW/HTTP',
|
||||
'Topic :: Security',
|
||||
'Topic :: System :: Installation/Setup',
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# Remember to update setup.py to match the package versions below.
|
||||
acme[dev]==0.31.0
|
||||
certbot[dev]==0.34.0
|
||||
-e .[dev]
|
||||
|
||||
@@ -2,12 +2,12 @@ from setuptools import setup
|
||||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.38.0.dev0'
|
||||
version = '0.39.0.dev0'
|
||||
|
||||
# Please update tox.ini when modifying dependency version requirements
|
||||
install_requires = [
|
||||
'acme>=0.31.0',
|
||||
'certbot>=0.34.0',
|
||||
'certbot>=0.39.0.dev0',
|
||||
'dns-lexicon>=2.1.22',
|
||||
'mock',
|
||||
'setuptools',
|
||||
@@ -41,6 +41,8 @@ setup(
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Topic :: Internet :: WWW/HTTP',
|
||||
'Topic :: Security',
|
||||
'Topic :: System :: Installation/Setup',
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# Remember to update setup.py to match the package versions below.
|
||||
acme[dev]==0.29.0
|
||||
certbot[dev]==0.34.0
|
||||
-e .[dev]
|
||||
|
||||
@@ -2,13 +2,13 @@ from setuptools import setup
|
||||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.38.0.dev0'
|
||||
version = '0.39.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
install_requires = [
|
||||
'acme>=0.29.0',
|
||||
'certbot>=0.34.0',
|
||||
'certbot>=0.39.0.dev0',
|
||||
# 1.5 is the first version that supports oauth2client>=2.0
|
||||
'google-api-python-client>=1.5',
|
||||
'mock',
|
||||
@@ -48,6 +48,7 @@ setup(
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Topic :: Internet :: WWW/HTTP',
|
||||
'Topic :: Security',
|
||||
'Topic :: System :: Installation/Setup',
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Remember to update setup.py to match the package versions below.
|
||||
acme[dev]==0.31.0
|
||||
certbot[dev]==0.34.0
|
||||
-e .[dev]
|
||||
dns-lexicon==2.2.3
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
from setuptools import setup
|
||||
from setuptools import find_packages
|
||||
|
||||
version = '0.38.0.dev0'
|
||||
version = '0.39.0.dev0'
|
||||
|
||||
# Please update tox.ini when modifying dependency version requirements
|
||||
install_requires = [
|
||||
'acme>=0.31.0',
|
||||
'certbot>=0.34.0',
|
||||
'certbot>=0.39.0.dev0',
|
||||
'dns-lexicon>=2.2.3',
|
||||
'mock',
|
||||
'setuptools',
|
||||
@@ -41,6 +41,7 @@ setup(
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Topic :: Internet :: WWW/HTTP',
|
||||
'Topic :: Security',
|
||||
'Topic :: System :: Installation/Setup',
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# Remember to update setup.py to match the package versions below.
|
||||
acme[dev]==0.31.0
|
||||
certbot[dev]==0.34.0
|
||||
-e .[dev]
|
||||
|
||||
@@ -2,13 +2,13 @@ from setuptools import setup
|
||||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.38.0.dev0'
|
||||
version = '0.39.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
install_requires = [
|
||||
'acme>=0.31.0',
|
||||
'certbot>=0.34.0',
|
||||
'certbot>=0.39.0.dev0',
|
||||
'dns-lexicon>=2.2.1', # Support for >1 TXT record per name
|
||||
'mock',
|
||||
'setuptools',
|
||||
@@ -43,6 +43,7 @@ setup(
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Topic :: Internet :: WWW/HTTP',
|
||||
'Topic :: Security',
|
||||
'Topic :: System :: Installation/Setup',
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# Remember to update setup.py to match the package versions below.
|
||||
acme[dev]==0.31.0
|
||||
certbot[dev]==0.34.0
|
||||
-e .[dev]
|
||||
|
||||
@@ -2,13 +2,13 @@ from setuptools import setup
|
||||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.38.0.dev0'
|
||||
version = '0.39.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
install_requires = [
|
||||
'acme>=0.31.0',
|
||||
'certbot>=0.34.0',
|
||||
'certbot>=0.39.0.dev0',
|
||||
'dns-lexicon>=2.2.1', # Support for >1 TXT record per name
|
||||
'mock',
|
||||
'setuptools',
|
||||
@@ -43,6 +43,7 @@ setup(
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Topic :: Internet :: WWW/HTTP',
|
||||
'Topic :: Security',
|
||||
'Topic :: System :: Installation/Setup',
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Remember to update setup.py to match the package versions below.
|
||||
acme[dev]==0.31.0
|
||||
certbot[dev]==0.34.0
|
||||
-e .[dev]
|
||||
dns-lexicon==2.7.14
|
||||
|
||||
@@ -2,13 +2,13 @@ from setuptools import setup
|
||||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.38.0.dev0'
|
||||
version = '0.39.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
install_requires = [
|
||||
'acme>=0.31.0',
|
||||
'certbot>=0.34.0',
|
||||
'certbot>=0.39.0.dev0',
|
||||
'dns-lexicon>=2.7.14', # Correct proxy use on OVH provider
|
||||
'mock',
|
||||
'setuptools',
|
||||
@@ -42,6 +42,8 @@ setup(
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Topic :: Internet :: WWW/HTTP',
|
||||
'Topic :: Security',
|
||||
'Topic :: System :: Installation/Setup',
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# Remember to update setup.py to match the package versions below.
|
||||
acme[dev]==0.29.0
|
||||
certbot[dev]==0.34.0
|
||||
-e .[dev]
|
||||
|
||||
@@ -2,13 +2,13 @@ from setuptools import setup
|
||||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.38.0.dev0'
|
||||
version = '0.39.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
install_requires = [
|
||||
'acme>=0.29.0',
|
||||
'certbot>=0.34.0',
|
||||
'certbot>=0.39.0.dev0',
|
||||
'dnspython',
|
||||
'mock',
|
||||
'setuptools',
|
||||
@@ -43,6 +43,7 @@ setup(
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Topic :: Internet :: WWW/HTTP',
|
||||
'Topic :: Security',
|
||||
'Topic :: System :: Installation/Setup',
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# Remember to update setup.py to match the package versions below.
|
||||
acme[dev]==0.29.0
|
||||
certbot[dev]==0.34.0
|
||||
-e .[dev]
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
from setuptools import setup
|
||||
from setuptools import find_packages
|
||||
|
||||
version = '0.38.0.dev0'
|
||||
version = '0.39.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
install_requires = [
|
||||
'acme>=0.29.0',
|
||||
'certbot>=0.34.0',
|
||||
'certbot>=0.39.0.dev0',
|
||||
'boto3',
|
||||
'mock',
|
||||
'setuptools',
|
||||
@@ -37,6 +37,7 @@ setup(
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Topic :: Internet :: WWW/HTTP',
|
||||
'Topic :: Security',
|
||||
'Topic :: System :: Installation/Setup',
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# Remember to update setup.py to match the package versions below.
|
||||
acme[dev]==0.31.0
|
||||
certbot[dev]==0.34.0
|
||||
-e .[dev]
|
||||
|
||||
@@ -2,12 +2,12 @@ from setuptools import setup
|
||||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.38.0.dev0'
|
||||
version = '0.39.0.dev0'
|
||||
|
||||
# Please update tox.ini when modifying dependency version requirements
|
||||
install_requires = [
|
||||
'acme>=0.31.0',
|
||||
'certbot>=0.34.0',
|
||||
'certbot>=0.39.0.dev0',
|
||||
'dns-lexicon>=2.1.23',
|
||||
'mock',
|
||||
'setuptools',
|
||||
@@ -41,6 +41,8 @@ setup(
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Topic :: Internet :: WWW/HTTP',
|
||||
'Topic :: Security',
|
||||
'Topic :: System :: Installation/Setup',
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
"""Nginx Configuration"""
|
||||
# https://github.com/PyCQA/pylint/issues/73
|
||||
from distutils.version import LooseVersion # pylint: disable=no-name-in-module,import-error
|
||||
import logging
|
||||
import re
|
||||
import socket
|
||||
@@ -91,8 +93,12 @@ class NginxConfigurator(common.Installer):
|
||||
:param tup version: version of Nginx as a tuple (1, 4, 7)
|
||||
(used mostly for unittesting)
|
||||
|
||||
:param tup openssl_version: version of OpenSSL linked to Nginx as a tuple (1, 4, 7)
|
||||
(used mostly for unittesting)
|
||||
|
||||
"""
|
||||
version = kwargs.pop("version", None)
|
||||
openssl_version = kwargs.pop("openssl_version", None)
|
||||
super(NginxConfigurator, self).__init__(*args, **kwargs)
|
||||
|
||||
# Verify that all directories and files exist with proper permissions
|
||||
@@ -115,6 +121,7 @@ class NginxConfigurator(common.Installer):
|
||||
# These will be set in the prepare function
|
||||
self.parser = None
|
||||
self.version = version
|
||||
self.openssl_version = openssl_version
|
||||
self._enhance_func = {"redirect": self._enable_redirect,
|
||||
"ensure-http-header": self._set_http_header,
|
||||
"staple-ocsp": self._enable_ocsp_stapling}
|
||||
@@ -124,11 +131,33 @@ class NginxConfigurator(common.Installer):
|
||||
@property
|
||||
def mod_ssl_conf_src(self):
|
||||
"""Full absolute path to SSL configuration file source."""
|
||||
|
||||
# Why all this complexity? Well, we want to support Mozilla's intermediate
|
||||
# recommendations. But TLS1.3 is only supported by newer versions of Nginx.
|
||||
# And as for session tickets, our ideal is to turn them off across the board.
|
||||
# But! Turning them off at all is only supported with new enough versions of
|
||||
# Nginx. And older versions of OpenSSL have a bug that leads to browser errors
|
||||
# given certain configurations. While we'd prefer to have forward secrecy, we'd
|
||||
# rather fail open than error out. Unfortunately, Nginx can be compiled against
|
||||
# many versions of OpenSSL. So we have to check both for the two different features,
|
||||
# leading to four different combinations of options.
|
||||
# For a complete history, check out https://github.com/certbot/certbot/issues/7322
|
||||
|
||||
use_tls13 = self.version >= (1, 13, 0)
|
||||
session_tix_off = self.version >= (1, 5, 9) and self.openssl_version and\
|
||||
LooseVersion(self.openssl_version) >= LooseVersion('1.0.2l')
|
||||
|
||||
if use_tls13:
|
||||
if session_tix_off:
|
||||
config_filename = "options-ssl-nginx.conf"
|
||||
if self.version < (1, 5, 9):
|
||||
config_filename = "options-ssl-nginx-old.conf"
|
||||
elif self.version < (1, 13, 0):
|
||||
else:
|
||||
config_filename = "options-ssl-nginx-tls13-session-tix-on.conf"
|
||||
else:
|
||||
if session_tix_off:
|
||||
config_filename = "options-ssl-nginx-tls12-only.conf"
|
||||
else:
|
||||
config_filename = "options-ssl-nginx-old.conf"
|
||||
|
||||
return pkg_resources.resource_filename(
|
||||
"certbot_nginx", os.path.join("tls_configs", config_filename))
|
||||
|
||||
@@ -169,6 +198,9 @@ class NginxConfigurator(common.Installer):
|
||||
if self.version is None:
|
||||
self.version = self.get_version()
|
||||
|
||||
if self.openssl_version is None:
|
||||
self.openssl_version = self._get_openssl_version()
|
||||
|
||||
self.install_ssl_options_conf(self.mod_ssl_conf, self.updated_mod_ssl_conf_digest)
|
||||
|
||||
self.install_ssl_dhparams()
|
||||
@@ -909,17 +941,14 @@ class NginxConfigurator(common.Installer):
|
||||
util.make_or_verify_dir(self.config.backup_dir, core_constants.CONFIG_DIRS_MODE)
|
||||
util.make_or_verify_dir(self.config.config_dir, core_constants.CONFIG_DIRS_MODE)
|
||||
|
||||
def get_version(self):
|
||||
"""Return version of Nginx Server.
|
||||
def _nginx_version(self):
|
||||
"""Return results of nginx -V
|
||||
|
||||
Version is returned as tuple. (ie. 2.4.7 = (2, 4, 7))
|
||||
|
||||
:returns: version
|
||||
:rtype: tuple
|
||||
:returns: version text
|
||||
:rtype: str
|
||||
|
||||
:raises .PluginError:
|
||||
Unable to find Nginx version or version is unsupported
|
||||
|
||||
Unable to run Nginx version command
|
||||
"""
|
||||
try:
|
||||
proc = subprocess.Popen(
|
||||
@@ -932,6 +961,21 @@ class NginxConfigurator(common.Installer):
|
||||
logger.debug(str(error), exc_info=True)
|
||||
raise errors.PluginError(
|
||||
"Unable to run %s -V" % self.conf('ctl'))
|
||||
return text
|
||||
|
||||
def get_version(self):
|
||||
"""Return version of Nginx Server.
|
||||
|
||||
Version is returned as tuple. (ie. 2.4.7 = (2, 4, 7))
|
||||
|
||||
:returns: version
|
||||
:rtype: tuple
|
||||
|
||||
:raises .PluginError:
|
||||
Unable to find Nginx version or version is unsupported
|
||||
|
||||
"""
|
||||
text = self._nginx_version()
|
||||
|
||||
version_regex = re.compile(r"nginx version: ([^/]+)/([0-9\.]*)", re.IGNORECASE)
|
||||
version_matches = version_regex.findall(text)
|
||||
@@ -964,6 +1008,28 @@ class NginxConfigurator(common.Installer):
|
||||
|
||||
return nginx_version
|
||||
|
||||
def _get_openssl_version(self):
|
||||
"""Return version of OpenSSL linked to Nginx.
|
||||
|
||||
Version is returned as string. If no version can be found, empty string is returned.
|
||||
|
||||
:returns: openssl_version
|
||||
:rtype: str
|
||||
|
||||
:raises .PluginError:
|
||||
Unable to run Nginx version command
|
||||
"""
|
||||
text = self._nginx_version()
|
||||
|
||||
matches = re.findall(r"running with OpenSSL ([^ ]+) ", text)
|
||||
if not matches:
|
||||
matches = re.findall(r"built with OpenSSL ([^ ]+) ", text)
|
||||
if not matches:
|
||||
logger.warning("NGINX configured with OpenSSL alternatives is not officially"
|
||||
"supported by Certbot.")
|
||||
return ""
|
||||
return matches[0]
|
||||
|
||||
def more_info(self):
|
||||
"""Human-readable string to help understand the module"""
|
||||
return (
|
||||
|
||||
@@ -22,19 +22,6 @@ MOD_SSL_CONF_DEST = "options-ssl-nginx.conf"
|
||||
UPDATED_MOD_SSL_CONF_DIGEST = ".updated-options-ssl-nginx-conf-digest.txt"
|
||||
"""Name of the hash of the updated or informed mod_ssl_conf as saved in `IConfig.config_dir`."""
|
||||
|
||||
SSL_OPTIONS_HASHES_NEW = [
|
||||
'108c4555058a087496a3893aea5d9e1cee0f20a3085d44a52dc1a66522299ac3',
|
||||
]
|
||||
"""SHA256 hashes of the contents of versions of MOD_SSL_CONF_SRC for nginx >= 1.13.0"""
|
||||
|
||||
SSL_OPTIONS_HASHES_MEDIUM = [
|
||||
'63e2bddebb174a05c9d8a7cf2adf72f7af04349ba59a1a925fe447f73b2f1abf',
|
||||
'2901debc7ecbc10917edd9084c05464c9c5930b463677571eaf8c94bffd11ae2',
|
||||
'30baca73ed9a5b0e9a69ea40e30482241d8b1a7343aa79b49dc5d7db0bf53b6c',
|
||||
]
|
||||
"""SHA256 hashes of the contents of versions of MOD_SSL_CONF_SRC for nginx >= 1.5.9
|
||||
and nginx < 1.13.0"""
|
||||
|
||||
ALL_SSL_OPTIONS_HASHES = [
|
||||
'0f81093a1465e3d4eaa8b0c14e77b2a2e93568b0fc1351c2b87893a95f0de87c',
|
||||
'9a7b32c49001fed4cff8ad24353329472a50e86ade1ef9b2b9e43566a619612e',
|
||||
@@ -44,7 +31,13 @@ ALL_SSL_OPTIONS_HASHES = [
|
||||
'4b16fec2bcbcd8a2f3296d886f17f9953ffdcc0af54582452ca1e52f5f776f16',
|
||||
'c052ffff0ad683f43bffe105f7c606b339536163490930e2632a335c8d191cc4',
|
||||
'02329eb19930af73c54b3632b3165d84571383b8c8c73361df940cb3894dd426',
|
||||
] + SSL_OPTIONS_HASHES_MEDIUM + SSL_OPTIONS_HASHES_NEW
|
||||
'63e2bddebb174a05c9d8a7cf2adf72f7af04349ba59a1a925fe447f73b2f1abf',
|
||||
'2901debc7ecbc10917edd9084c05464c9c5930b463677571eaf8c94bffd11ae2',
|
||||
'30baca73ed9a5b0e9a69ea40e30482241d8b1a7343aa79b49dc5d7db0bf53b6c',
|
||||
'02329eb19930af73c54b3632b3165d84571383b8c8c73361df940cb3894dd426',
|
||||
'108c4555058a087496a3893aea5d9e1cee0f20a3085d44a52dc1a66522299ac3',
|
||||
'd5e021706ecdccc7090111b0ae9a29ef61523e927f020e410caf0a1fd7063981',
|
||||
]
|
||||
"""SHA256 hashes of the contents of all versions of MOD_SSL_CONF_SRC"""
|
||||
|
||||
def os_constant(key):
|
||||
|
||||
@@ -394,6 +394,68 @@ class NginxConfiguratorTest(util.NginxTest):
|
||||
mock_popen.side_effect = OSError("Can't find program")
|
||||
self.assertRaises(errors.PluginError, self.config.get_version)
|
||||
|
||||
@mock.patch("certbot_nginx.configurator.subprocess.Popen")
|
||||
def test_get_openssl_version(self, mock_popen):
|
||||
# pylint: disable=protected-access
|
||||
mock_popen().communicate.return_value = (
|
||||
"", """
|
||||
nginx version: nginx/1.15.5
|
||||
built by gcc 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)
|
||||
built with OpenSSL 1.0.2g 1 Mar 2016
|
||||
TLS SNI support enabled
|
||||
configure arguments:
|
||||
""")
|
||||
self.assertEqual(self.config._get_openssl_version(), "1.0.2g")
|
||||
|
||||
mock_popen().communicate.return_value = (
|
||||
"", """
|
||||
nginx version: nginx/1.15.5
|
||||
built by gcc 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)
|
||||
built with OpenSSL 1.0.2-beta1 1 Mar 2016
|
||||
TLS SNI support enabled
|
||||
configure arguments:
|
||||
""")
|
||||
self.assertEqual(self.config._get_openssl_version(), "1.0.2-beta1")
|
||||
|
||||
mock_popen().communicate.return_value = (
|
||||
"", """
|
||||
nginx version: nginx/1.15.5
|
||||
built by gcc 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)
|
||||
built with OpenSSL 1.0.2 1 Mar 2016
|
||||
TLS SNI support enabled
|
||||
configure arguments:
|
||||
""")
|
||||
self.assertEqual(self.config._get_openssl_version(), "1.0.2")
|
||||
|
||||
mock_popen().communicate.return_value = (
|
||||
"", """
|
||||
nginx version: nginx/1.15.5
|
||||
built by gcc 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)
|
||||
built with OpenSSL 1.0.2g 1 Mar 2016 (running with OpenSSL 1.0.2a 1 Mar 2016)
|
||||
TLS SNI support enabled
|
||||
configure arguments:
|
||||
""")
|
||||
self.assertEqual(self.config._get_openssl_version(), "1.0.2a")
|
||||
|
||||
mock_popen().communicate.return_value = (
|
||||
"", """
|
||||
nginx version: nginx/1.15.5
|
||||
built by gcc 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)
|
||||
built with LibreSSL 2.2.2
|
||||
TLS SNI support enabled
|
||||
configure arguments:
|
||||
""")
|
||||
self.assertEqual(self.config._get_openssl_version(), "")
|
||||
|
||||
mock_popen().communicate.return_value = (
|
||||
"", """
|
||||
nginx version: nginx/1.15.5
|
||||
built by gcc 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)
|
||||
TLS SNI support enabled
|
||||
configure arguments:
|
||||
""")
|
||||
self.assertEqual(self.config._get_openssl_version(), "")
|
||||
|
||||
@mock.patch("certbot_nginx.configurator.subprocess.Popen")
|
||||
def test_nginx_restart(self, mock_popen):
|
||||
mocked = mock_popen()
|
||||
@@ -920,13 +982,12 @@ class InstallSslOptionsConfTest(util.NginxTest):
|
||||
self._assert_current_file()
|
||||
|
||||
def test_prev_file_updates_to_current_old_nginx(self):
|
||||
from certbot_nginx.constants import ALL_SSL_OPTIONS_HASHES, SSL_OPTIONS_HASHES_NEW
|
||||
from certbot_nginx.constants import ALL_SSL_OPTIONS_HASHES
|
||||
self.config.version = (1, 5, 8)
|
||||
with mock.patch('certbot.crypto_util.sha256sum',
|
||||
new=self._mock_hash_except_ssl_conf_src(ALL_SSL_OPTIONS_HASHES[0])):
|
||||
self._call()
|
||||
self._assert_current_file()
|
||||
self.assertTrue(self._current_ssl_options_hash() not in SSL_OPTIONS_HASHES_NEW)
|
||||
|
||||
def test_manually_modified_current_file_does_not_update(self):
|
||||
with open(self.config.mod_ssl_conf, "a") as mod_ssl_conf:
|
||||
@@ -987,11 +1048,13 @@ class InstallSslOptionsConfTest(util.NginxTest):
|
||||
|
||||
def test_nginx_version_uses_correct_config(self):
|
||||
self.config.version = (1, 5, 8)
|
||||
self.config.openssl_version = "1.0.2g" # shouldn't matter
|
||||
self.assertEqual(os.path.basename(self.config.mod_ssl_conf_src),
|
||||
"options-ssl-nginx-old.conf")
|
||||
self._call()
|
||||
self._assert_current_file()
|
||||
self.config.version = (1, 5, 9)
|
||||
self.config.openssl_version = "1.0.2l"
|
||||
self.assertEqual(os.path.basename(self.config.mod_ssl_conf_src),
|
||||
"options-ssl-nginx-tls12-only.conf")
|
||||
self._call()
|
||||
@@ -999,6 +1062,12 @@ class InstallSslOptionsConfTest(util.NginxTest):
|
||||
self.config.version = (1, 13, 0)
|
||||
self.assertEqual(os.path.basename(self.config.mod_ssl_conf_src),
|
||||
"options-ssl-nginx.conf")
|
||||
self._call()
|
||||
self._assert_current_file()
|
||||
self.config.version = (1, 13, 0)
|
||||
self.config.openssl_version = "1.0.2k"
|
||||
self.assertEqual(os.path.basename(self.config.mod_ssl_conf_src),
|
||||
"options-ssl-nginx-tls13-session-tix-on.conf")
|
||||
|
||||
|
||||
class DetermineDefaultServerRootTest(certbot_test_util.ConfigTestCase):
|
||||
|
||||
@@ -30,8 +30,16 @@ class NginxParserTest(util.NginxTest): #pylint: disable=too-many-public-methods
|
||||
self.assertEqual(nparser.root, self.config_path)
|
||||
|
||||
def test_root_absolute(self):
|
||||
curr_dir = os.getcwd()
|
||||
try:
|
||||
# On Windows current directory may be on a different drive than self.tempdir.
|
||||
# However a relative path between two different drives is invalid. So we move to
|
||||
# self.tempdir to ensure that we stay on the same drive.
|
||||
os.chdir(self.temp_dir)
|
||||
nparser = parser.NginxParser(os.path.relpath(self.config_path))
|
||||
self.assertEqual(nparser.root, self.config_path)
|
||||
finally:
|
||||
os.chdir(curr_dir)
|
||||
|
||||
def test_root_no_trailing_slash(self):
|
||||
nparser = parser.NginxParser(self.config_path + os.path.sep)
|
||||
|
||||
@@ -3,7 +3,6 @@ import copy
|
||||
import shutil
|
||||
import tempfile
|
||||
import unittest
|
||||
import warnings
|
||||
|
||||
import josepy as jose
|
||||
import mock
|
||||
@@ -11,6 +10,7 @@ import pkg_resources
|
||||
import zope.component
|
||||
|
||||
from certbot import configuration
|
||||
from certbot import util
|
||||
from certbot.compat import os
|
||||
from certbot.plugins import common
|
||||
from certbot.tests import util as test_util
|
||||
@@ -34,20 +34,16 @@ class NginxTest(unittest.TestCase): # pylint: disable=too-few-public-methods
|
||||
"rsa512_key.pem"))
|
||||
|
||||
def tearDown(self):
|
||||
# On Windows we have various files which are not correctly closed at the time of tearDown.
|
||||
# For know, we log them until a proper file close handling is written.
|
||||
# Useful for development only, so no warning when we are on a CI process.
|
||||
def onerror_handler(_, path, excinfo):
|
||||
"""On error handler"""
|
||||
if not os.environ.get('APPVEYOR'): # pragma: no cover
|
||||
message = ('Following error occurred when deleting path {0}'
|
||||
'during tearDown process: {1}'.format(path, str(excinfo)))
|
||||
warnings.warn(message)
|
||||
# Cleanup opened resources after a test. This is usually done through atexit handlers in
|
||||
# Certbot, but during tests, atexit will not run registered functions before tearDown is
|
||||
# called and instead will run them right before the entire test process exits.
|
||||
# It is a problem on Windows, that does not accept to clean resources before closing them.
|
||||
util._release_locks() # pylint: disable=protected-access
|
||||
|
||||
shutil.rmtree(self.temp_dir, onerror=onerror_handler)
|
||||
shutil.rmtree(self.config_dir, onerror=onerror_handler)
|
||||
shutil.rmtree(self.work_dir, onerror=onerror_handler)
|
||||
shutil.rmtree(self.logs_dir, onerror=onerror_handler)
|
||||
shutil.rmtree(self.temp_dir)
|
||||
shutil.rmtree(self.config_dir)
|
||||
shutil.rmtree(self.work_dir)
|
||||
shutil.rmtree(self.logs_dir)
|
||||
|
||||
|
||||
def get_data_filename(filename):
|
||||
@@ -58,7 +54,7 @@ def get_data_filename(filename):
|
||||
|
||||
|
||||
def get_nginx_configurator(
|
||||
config_path, config_dir, work_dir, logs_dir, version=(1, 6, 2)):
|
||||
config_path, config_dir, work_dir, logs_dir, version=(1, 6, 2), openssl_version="1.0.2g"):
|
||||
"""Create an Nginx Configurator with the specified options."""
|
||||
|
||||
backups = os.path.join(work_dir, "backups")
|
||||
@@ -83,7 +79,8 @@ def get_nginx_configurator(
|
||||
https_port=5001,
|
||||
),
|
||||
name="nginx",
|
||||
version=version)
|
||||
version=version,
|
||||
openssl_version=openssl_version)
|
||||
config.prepare()
|
||||
|
||||
# Provide general config utility.
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
# 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.
|
||||
|
||||
ssl_session_cache shared:le_nginx_SSL:10m;
|
||||
ssl_session_timeout 1440m;
|
||||
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
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";
|
||||
@@ -4,7 +4,7 @@ from setuptools.command.test import test as TestCommand
|
||||
import sys
|
||||
|
||||
|
||||
version = '0.38.0.dev0'
|
||||
version = '0.39.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
@@ -62,6 +62,7 @@ setup(
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Topic :: Internet :: WWW/HTTP',
|
||||
'Topic :: Security',
|
||||
'Topic :: System :: Installation/Setup',
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Certbot client."""
|
||||
|
||||
# version number like 1.2.3a0, must have at least 2 parts, like 1.2
|
||||
__version__ = '0.38.0.dev0'
|
||||
__version__ = '0.39.0.dev0'
|
||||
|
||||
@@ -262,7 +262,7 @@ def human_readable_cert_info(config, cert, skip_filter_checks=False):
|
||||
reasons.append('TEST_CERT')
|
||||
if cert.target_expiry <= now:
|
||||
reasons.append('EXPIRED')
|
||||
if checker.ocsp_revoked(cert.cert, cert.chain):
|
||||
elif checker.ocsp_revoked(cert):
|
||||
reasons.append('REVOKED')
|
||||
|
||||
if reasons:
|
||||
|
||||
@@ -20,7 +20,7 @@ except ImportError:
|
||||
else:
|
||||
POSIX_MODE = False
|
||||
|
||||
from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module
|
||||
from acme.magic_typing import List, Union, Tuple # pylint: disable=unused-import, no-name-in-module
|
||||
|
||||
|
||||
def chmod(file_path, mode):
|
||||
@@ -166,11 +166,11 @@ def open(file_path, flags, mode=0o777): # pylint: disable=redefined-builtin
|
||||
# See https://docs.microsoft.com/en-us/windows/desktop/api/securitybaseapi/nf-securitybaseapi-setsecuritydescriptordacl # pylint: disable=line-too-long
|
||||
security.SetSecurityDescriptorDacl(1, dacl, 0)
|
||||
|
||||
handle = None
|
||||
try:
|
||||
handle = win32file.CreateFile(file_path, win32file.GENERIC_READ,
|
||||
win32file.FILE_SHARE_READ & win32file.FILE_SHARE_WRITE,
|
||||
attributes, disposition, 0, None)
|
||||
handle.Close()
|
||||
except pywintypes.error as err:
|
||||
# Handle native windows errors into python errors to be consistent with the API
|
||||
# of os.open in the situation of a file already existing or locked.
|
||||
@@ -179,6 +179,9 @@ def open(file_path, flags, mode=0o777): # pylint: disable=redefined-builtin
|
||||
if err.winerror == winerror.ERROR_SHARING_VIOLATION:
|
||||
raise OSError(errno.EACCES, err.strerror)
|
||||
raise err
|
||||
finally:
|
||||
if handle:
|
||||
handle.Close()
|
||||
|
||||
# At this point, the file that did not exist has been created with proper permissions,
|
||||
# so os.O_CREAT and os.O_EXCL are not needed anymore. We remove them from the flags to
|
||||
@@ -261,6 +264,7 @@ def replace(src, dst):
|
||||
|
||||
|
||||
def realpath(file_path):
|
||||
# type: (str) -> str
|
||||
"""
|
||||
Find the real path for the given path. This method resolves symlinks, including
|
||||
recursive symlinks, and is protected against symlinks that creates an infinite loop.
|
||||
@@ -297,10 +301,11 @@ def realpath(file_path):
|
||||
# requires to be run under a privileged shell, so the user will always benefit
|
||||
# from the highest (privileged one) set of permissions on a given file.
|
||||
def is_executable(path):
|
||||
# type: (str) -> bool
|
||||
"""
|
||||
Is path an executable file?
|
||||
:param str path: path to test
|
||||
:returns: True if path is an executable file
|
||||
:return: True if path is an executable file
|
||||
:rtype: bool
|
||||
"""
|
||||
if POSIX_MODE:
|
||||
@@ -309,6 +314,118 @@ def is_executable(path):
|
||||
return _win_is_executable(path)
|
||||
|
||||
|
||||
def has_world_permissions(path):
|
||||
# type: (str) -> bool
|
||||
"""
|
||||
Check if everybody/world has any right (read/write/execute) on a file given its path
|
||||
:param str path: path to test
|
||||
:return: True if everybody/world has any right to the file
|
||||
:rtype: bool
|
||||
"""
|
||||
if POSIX_MODE:
|
||||
return bool(stat.S_IMODE(os.stat(path).st_mode) & stat.S_IRWXO)
|
||||
|
||||
security = win32security.GetFileSecurity(path, win32security.DACL_SECURITY_INFORMATION)
|
||||
dacl = security.GetSecurityDescriptorDacl()
|
||||
|
||||
return bool(dacl.GetEffectiveRightsFromAcl({
|
||||
'TrusteeForm': win32security.TRUSTEE_IS_SID,
|
||||
'TrusteeType': win32security.TRUSTEE_IS_USER,
|
||||
'Identifier': win32security.ConvertStringSidToSid('S-1-1-0'),
|
||||
}))
|
||||
|
||||
|
||||
def compute_private_key_mode(old_key, base_mode):
|
||||
# type: (str, int) -> int
|
||||
"""
|
||||
Calculate the POSIX mode to apply to a private key given the previous private key
|
||||
:param str old_key: path to the previous private key
|
||||
:param int base_mode: the minimum modes to apply to a private key
|
||||
:return: the POSIX mode to apply
|
||||
:rtype: int
|
||||
"""
|
||||
if POSIX_MODE:
|
||||
# On Linux, we keep read/write/execute permissions
|
||||
# for group and read permissions for everybody.
|
||||
old_mode = (stat.S_IMODE(os.stat(old_key).st_mode) &
|
||||
(stat.S_IRGRP | stat.S_IWGRP | stat.S_IXGRP | stat.S_IROTH))
|
||||
return base_mode | old_mode
|
||||
|
||||
# On Windows, the mode returned by os.stat is not reliable,
|
||||
# so we do not keep any permission from the previous private key.
|
||||
return base_mode
|
||||
|
||||
|
||||
def has_same_ownership(path1, path2):
|
||||
# type: (str, str) -> bool
|
||||
"""
|
||||
Return True if the ownership of two files given their respective path is the same.
|
||||
On Windows, ownership is checked against owner only, since files do not have a group owner.
|
||||
:param str path1: path to the first file
|
||||
:param str path2: path to the second file
|
||||
:return: True if both files have the same ownership, False otherwise
|
||||
:rtype: bool
|
||||
|
||||
"""
|
||||
if POSIX_MODE:
|
||||
stats1 = os.stat(path1)
|
||||
stats2 = os.stat(path2)
|
||||
return (stats1.st_uid, stats1.st_gid) == (stats2.st_uid, stats2.st_gid)
|
||||
|
||||
security1 = win32security.GetFileSecurity(path1, win32security.OWNER_SECURITY_INFORMATION)
|
||||
user1 = security1.GetSecurityDescriptorOwner()
|
||||
|
||||
security2 = win32security.GetFileSecurity(path2, win32security.OWNER_SECURITY_INFORMATION)
|
||||
user2 = security2.GetSecurityDescriptorOwner()
|
||||
|
||||
return user1 == user2
|
||||
|
||||
|
||||
def has_min_permissions(path, min_mode):
|
||||
# type: (str, int) -> bool
|
||||
"""
|
||||
Check if a file given its path has at least the permissions defined by the given minimal mode.
|
||||
On Windows, group permissions are ignored since files do not have a group owner.
|
||||
:param str path: path to the file to check
|
||||
:param int min_mode: the minimal permissions expected
|
||||
:return: True if the file matches the minimal permissions expectations, False otherwise
|
||||
:rtype: bool
|
||||
"""
|
||||
if POSIX_MODE:
|
||||
st_mode = os.stat(path).st_mode
|
||||
return st_mode == st_mode | min_mode
|
||||
|
||||
# Resolve symlinks, to get a consistent result with os.stat on Linux,
|
||||
# that follows symlinks by default.
|
||||
path = realpath(path)
|
||||
|
||||
# Get owner sid of the file
|
||||
security = win32security.GetFileSecurity(
|
||||
path, win32security.OWNER_SECURITY_INFORMATION | win32security.DACL_SECURITY_INFORMATION)
|
||||
user = security.GetSecurityDescriptorOwner()
|
||||
dacl = security.GetSecurityDescriptorDacl()
|
||||
min_dacl = _generate_dacl(user, min_mode)
|
||||
|
||||
for index in range(min_dacl.GetAceCount()):
|
||||
min_ace = min_dacl.GetAce(index)
|
||||
|
||||
# On a given ACE, index 0 is the ACE type, 1 is the permission mask, and 2 is the SID.
|
||||
# See: http://timgolden.me.uk/pywin32-docs/PyACL__GetAce_meth.html
|
||||
mask = min_ace[1]
|
||||
user = min_ace[2]
|
||||
|
||||
effective_mask = dacl.GetEffectiveRightsFromAcl({
|
||||
'TrusteeForm': win32security.TRUSTEE_IS_SID,
|
||||
'TrusteeType': win32security.TRUSTEE_IS_USER,
|
||||
'Identifier': user,
|
||||
})
|
||||
|
||||
if effective_mask != effective_mask | mask:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def _win_is_executable(path):
|
||||
if not os.path.isfile(path):
|
||||
return False
|
||||
@@ -469,8 +586,8 @@ def _compare_dacls(dacl1, dacl2):
|
||||
This method compare the two given DACLs to check if they are identical.
|
||||
Identical means here that they contains the same set of ACEs in the same order.
|
||||
"""
|
||||
return ([dacl1.GetAce(index) for index in range(0, dacl1.GetAceCount())] ==
|
||||
[dacl2.GetAce(index) for index in range(0, dacl2.GetAceCount())])
|
||||
return ([dacl1.GetAce(index) for index in range(dacl1.GetAceCount())] ==
|
||||
[dacl2.GetAce(index) for index in range(dacl2.GetAceCount())])
|
||||
|
||||
|
||||
def _get_current_user():
|
||||
|
||||
@@ -5,7 +5,6 @@ particular category.
|
||||
from __future__ import absolute_import
|
||||
|
||||
import select
|
||||
import stat
|
||||
import sys
|
||||
|
||||
try:
|
||||
@@ -18,18 +17,6 @@ from certbot import errors
|
||||
from certbot.compat import os
|
||||
|
||||
|
||||
# MASK_FOR_PRIVATE_KEY_PERMISSIONS defines what are the permissions flags to keep
|
||||
# when transferring the permissions from an old private key to a new one.
|
||||
if POSIX_MODE:
|
||||
# On Linux, we keep read/write/execute permissions
|
||||
# for group and read permissions for everybody.
|
||||
MASK_FOR_PRIVATE_KEY_PERMISSIONS = stat.S_IRGRP | stat.S_IWGRP | stat.S_IXGRP | stat.S_IROTH
|
||||
else:
|
||||
# On Windows, the mode returned by os.stat is not reliable,
|
||||
# so we do not keep any permission from the previous private key.
|
||||
MASK_FOR_PRIVATE_KEY_PERMISSIONS = 0
|
||||
|
||||
|
||||
# For Linux: define OS specific standard binary directories
|
||||
STANDARD_BINARY_DIRS = ["/usr/sbin", "/usr/local/bin", "/usr/local/sbin"] if POSIX_MODE else []
|
||||
|
||||
|
||||
@@ -116,3 +116,21 @@ def access(*unused_args, **unused_kwargs):
|
||||
raise RuntimeError('Usage of os.access() is forbidden. '
|
||||
'Use certbot.compat.filesystem.check_mode() or '
|
||||
'certbot.compat.filesystem.is_executable() instead.')
|
||||
|
||||
|
||||
# On Windows os.stat call result is inconsistent, with a lot of flags that are not set or
|
||||
# meaningless. We need to use specialized functions from the certbot.compat.filesystem module.
|
||||
def stat(*unused_args, **unused_kwargs):
|
||||
"""Method os.stat() is forbidden"""
|
||||
raise RuntimeError('Usage of os.stat() is forbidden. '
|
||||
'Use certbot.compat.filesystem functions instead '
|
||||
'(eg. has_min_permissions, has_same_ownership).')
|
||||
|
||||
|
||||
# Method os.fstat has the same problem than os.stat, since it is the same function,
|
||||
# but accepting a file descriptor instead of a path.
|
||||
def fstat(*unused_args, **unused_kwargs):
|
||||
"""Method os.stat() is forbidden"""
|
||||
raise RuntimeError('Usage of os.fstat() is forbidden. '
|
||||
'Use certbot.compat.filesystem functions instead '
|
||||
'(eg. has_min_permissions, has_same_ownership).')
|
||||
|
||||
@@ -167,14 +167,18 @@ class _UnixLockMechanism(_BaseLockMechanism):
|
||||
:returns: True if the lock was successfully acquired
|
||||
:rtype: bool
|
||||
"""
|
||||
# Normally os module should not be imported in certbot codebase except in certbot.compat
|
||||
# for the sake of compatibility over Windows and Linux.
|
||||
# We make an exception here, since _lock_success is private and called only on Linux.
|
||||
from os import stat, fstat # pylint: disable=os-module-forbidden
|
||||
try:
|
||||
stat1 = os.stat(self._path)
|
||||
stat1 = stat(self._path)
|
||||
except OSError as err:
|
||||
if err.errno == errno.ENOENT:
|
||||
return False
|
||||
raise
|
||||
|
||||
stat2 = os.fstat(fd)
|
||||
stat2 = fstat(fd)
|
||||
# If our locked file descriptor and the file on disk refer to
|
||||
# the same device and inode, they're the same file.
|
||||
return stat1.st_dev == stat2.st_dev and stat1.st_ino == stat2.st_ino
|
||||
|
||||
@@ -16,11 +16,13 @@ from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
from cryptography.hazmat.primitives import hashes # type: ignore
|
||||
from cryptography.exceptions import UnsupportedAlgorithm, InvalidSignature
|
||||
import pytz
|
||||
import requests
|
||||
|
||||
from acme.magic_typing import Optional, Tuple # pylint: disable=unused-import, no-name-in-module
|
||||
from certbot import crypto_util
|
||||
from certbot import errors
|
||||
from certbot.storage import RenewableCert # pylint: disable=unused-import
|
||||
from certbot import util
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -48,21 +50,29 @@ class RevocationChecker(object):
|
||||
else:
|
||||
self.host_args = lambda host: ["Host", host]
|
||||
|
||||
def ocsp_revoked(self, cert_path, chain_path):
|
||||
# type: (str, str) -> bool
|
||||
def ocsp_revoked(self, cert):
|
||||
# type: (RenewableCert) -> bool
|
||||
"""Get revoked status for a particular cert version.
|
||||
|
||||
.. todo:: Make this a non-blocking call
|
||||
|
||||
:param str cert_path: Path to certificate
|
||||
:param str chain_path: Path to intermediate cert
|
||||
:returns: True if revoked; False if valid or the check failed
|
||||
:param `.storage.RenewableCert` cert: Certificate object
|
||||
:returns: True if revoked; False if valid or the check failed or cert is expired.
|
||||
:rtype: bool
|
||||
|
||||
"""
|
||||
cert_path, chain_path = cert.cert, cert.chain
|
||||
|
||||
if self.broken:
|
||||
return False
|
||||
|
||||
# Let's Encrypt doesn't update OCSP for expired certificates,
|
||||
# so don't check OCSP if the cert is expired.
|
||||
# https://github.com/certbot/certbot/issues/7152
|
||||
now = pytz.UTC.fromutc(datetime.utcnow())
|
||||
if cert.target_expiry <= now:
|
||||
return False
|
||||
|
||||
url, host = _determine_ocsp_server(cert_path)
|
||||
if not host or not url:
|
||||
return False
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
import abc
|
||||
import logging
|
||||
import stat
|
||||
from time import sleep
|
||||
|
||||
import configobj
|
||||
@@ -12,6 +11,7 @@ from acme import challenges
|
||||
|
||||
from certbot import errors
|
||||
from certbot import interfaces
|
||||
from certbot.compat import filesystem
|
||||
from certbot.compat import os
|
||||
from certbot.display import ops
|
||||
from certbot.display import util as display_util
|
||||
@@ -312,8 +312,7 @@ def validate_file_permissions(filename):
|
||||
|
||||
validate_file(filename)
|
||||
|
||||
permissions = stat.S_IMODE(os.stat(filename).st_mode)
|
||||
if permissions & stat.S_IRWXO:
|
||||
if filesystem.has_world_permissions(filename):
|
||||
logger.warning('Unsafe permissions on credentials configuration file: %s', filename)
|
||||
|
||||
|
||||
|
||||
@@ -7,14 +7,15 @@ import unittest
|
||||
import mock
|
||||
|
||||
from certbot import errors
|
||||
from certbot import util
|
||||
from certbot.compat import os
|
||||
from certbot.display import util as display_util
|
||||
from certbot.plugins import dns_common
|
||||
from certbot.plugins import dns_test_common
|
||||
from certbot.tests import util
|
||||
from certbot.tests import util as test_util
|
||||
|
||||
|
||||
class DNSAuthenticatorTest(util.TempDirTestCase, dns_test_common.BaseAuthenticatorTest):
|
||||
class DNSAuthenticatorTest(test_util.TempDirTestCase, dns_test_common.BaseAuthenticatorTest):
|
||||
# pylint: disable=protected-access
|
||||
|
||||
class _FakeDNSAuthenticator(dns_common.DNSAuthenticator):
|
||||
@@ -50,7 +51,7 @@ class DNSAuthenticatorTest(util.TempDirTestCase, dns_test_common.BaseAuthenticat
|
||||
|
||||
self.auth._cleanup.assert_called_once_with(dns_test_common.DOMAIN, mock.ANY, mock.ANY)
|
||||
|
||||
@util.patch_get_utility()
|
||||
@test_util.patch_get_utility()
|
||||
def test_prompt(self, mock_get_utility):
|
||||
mock_display = mock_get_utility()
|
||||
mock_display.input.side_effect = ((display_util.OK, "",),
|
||||
@@ -59,14 +60,14 @@ class DNSAuthenticatorTest(util.TempDirTestCase, dns_test_common.BaseAuthenticat
|
||||
self.auth._configure("other_key", "")
|
||||
self.assertEqual(self.auth.config.fake_other_key, "value")
|
||||
|
||||
@util.patch_get_utility()
|
||||
@test_util.patch_get_utility()
|
||||
def test_prompt_canceled(self, mock_get_utility):
|
||||
mock_display = mock_get_utility()
|
||||
mock_display.input.side_effect = ((display_util.CANCEL, "c",),)
|
||||
|
||||
self.assertRaises(errors.PluginError, self.auth._configure, "other_key", "")
|
||||
|
||||
@util.patch_get_utility()
|
||||
@test_util.patch_get_utility()
|
||||
def test_prompt_file(self, mock_get_utility):
|
||||
path = os.path.join(self.tempdir, 'file.ini')
|
||||
open(path, "wb").close()
|
||||
@@ -80,7 +81,7 @@ class DNSAuthenticatorTest(util.TempDirTestCase, dns_test_common.BaseAuthenticat
|
||||
self.auth._configure_file("file_path", "")
|
||||
self.assertEqual(self.auth.config.fake_file_path, path)
|
||||
|
||||
@util.patch_get_utility()
|
||||
@test_util.patch_get_utility()
|
||||
def test_prompt_file_canceled(self, mock_get_utility):
|
||||
mock_display = mock_get_utility()
|
||||
mock_display.directory_select.side_effect = ((display_util.CANCEL, "c",),)
|
||||
@@ -96,7 +97,7 @@ class DNSAuthenticatorTest(util.TempDirTestCase, dns_test_common.BaseAuthenticat
|
||||
|
||||
self.assertEqual(credentials.conf("test"), "value")
|
||||
|
||||
@util.patch_get_utility()
|
||||
@test_util.patch_get_utility()
|
||||
def test_prompt_credentials(self, mock_get_utility):
|
||||
bad_path = os.path.join(self.tempdir, 'bad-file.ini')
|
||||
dns_test_common.write({"fake_other": "other_value"}, bad_path)
|
||||
@@ -116,7 +117,7 @@ class DNSAuthenticatorTest(util.TempDirTestCase, dns_test_common.BaseAuthenticat
|
||||
self.assertEqual(credentials.conf("test"), "value")
|
||||
|
||||
|
||||
class CredentialsConfigurationTest(util.TempDirTestCase):
|
||||
class CredentialsConfigurationTest(test_util.TempDirTestCase):
|
||||
class _MockLoggingHandler(logging.Handler):
|
||||
messages = None
|
||||
|
||||
@@ -150,14 +151,14 @@ class CredentialsConfigurationTest(util.TempDirTestCase):
|
||||
dns_common.logger.addHandler(log)
|
||||
|
||||
path = os.path.join(self.tempdir, 'too-permissive-file.ini')
|
||||
open(path, "wb").close()
|
||||
util.safe_open(path, "wb", 0o744).close()
|
||||
|
||||
dns_common.CredentialsConfiguration(path)
|
||||
|
||||
self.assertEqual(1, len([_ for _ in log.messages['warning'] if _.startswith("Unsafe")]))
|
||||
|
||||
|
||||
class CredentialsConfigurationRequireTest(util.TempDirTestCase):
|
||||
class CredentialsConfigurationRequireTest(test_util.TempDirTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(CredentialsConfigurationRequireTest, self).setUp()
|
||||
|
||||
@@ -34,7 +34,13 @@ class AuthenticatorTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
from certbot.plugins.webroot import Authenticator
|
||||
self.path = tempfile.mkdtemp()
|
||||
# On Linux directories created by tempfile.mkdtemp inherit their permissions from their
|
||||
# parent directory. So the actual permissions are inconsistent over various tests env.
|
||||
# To circumvent this, a dedicated sub-workspace is created under the workspace, using
|
||||
# filesystem.mkdir to get consistent permissions.
|
||||
self.workspace = tempfile.mkdtemp()
|
||||
self.path = os.path.join(self.workspace, 'webroot')
|
||||
filesystem.mkdir(self.path)
|
||||
self.partial_root_challenge_path = os.path.join(
|
||||
self.path, ".well-known")
|
||||
self.root_challenge_path = os.path.join(
|
||||
@@ -170,17 +176,12 @@ class AuthenticatorTest(unittest.TestCase):
|
||||
self.assertTrue(filesystem.check_mode(self.validation_path, 0o644))
|
||||
|
||||
# Check permissions of the directories
|
||||
|
||||
for dirpath, dirnames, _ in os.walk(self.path):
|
||||
for directory in dirnames:
|
||||
full_path = os.path.join(dirpath, directory)
|
||||
self.assertTrue(filesystem.check_mode(full_path, 0o755))
|
||||
|
||||
parent_gid = os.stat(self.path).st_gid
|
||||
parent_uid = os.stat(self.path).st_uid
|
||||
|
||||
self.assertEqual(os.stat(self.validation_path).st_gid, parent_gid)
|
||||
self.assertEqual(os.stat(self.validation_path).st_uid, parent_uid)
|
||||
self.assertTrue(filesystem.has_same_ownership(self.validation_path, self.path))
|
||||
|
||||
def test_perform_cleanup(self):
|
||||
self.auth.prepare()
|
||||
|
||||
@@ -18,7 +18,6 @@ from certbot import crypto_util
|
||||
from certbot import error_handler
|
||||
from certbot import errors
|
||||
from certbot import util
|
||||
from certbot.compat import misc
|
||||
from certbot.compat import os
|
||||
from certbot.compat import filesystem
|
||||
from certbot.plugins import common as plugins_common
|
||||
@@ -1107,9 +1106,7 @@ class RenewableCert(object):
|
||||
f.write(new_privkey)
|
||||
# Preserve gid and (mode & MASK_FOR_PRIVATE_KEY_PERMISSIONS)
|
||||
# from previous privkey in this lineage.
|
||||
old_mode = (stat.S_IMODE(os.stat(old_privkey).st_mode) &
|
||||
misc.MASK_FOR_PRIVATE_KEY_PERMISSIONS)
|
||||
mode = BASE_PRIVKEY_MODE | old_mode
|
||||
mode = filesystem.compute_private_key_mode(old_privkey, BASE_PRIVKEY_MODE)
|
||||
filesystem.copy_ownership_and_apply_mode(
|
||||
old_privkey, target["privkey"], mode, copy_user=False, copy_group=True)
|
||||
|
||||
|
||||
@@ -23,10 +23,14 @@ PLUGINS = disco.PluginsRegistry.find_all()
|
||||
|
||||
|
||||
class TestReadFile(TempDirTestCase):
|
||||
'''Test cli.read_file'''
|
||||
|
||||
|
||||
"""Test cli.read_file"""
|
||||
def test_read_file(self):
|
||||
curr_dir = os.getcwd()
|
||||
try:
|
||||
# On Windows current directory may be on a different drive than self.tempdir.
|
||||
# However a relative path between two different drives is invalid. So we move to
|
||||
# self.tempdir to ensure that we stay on the same drive.
|
||||
os.chdir(self.tempdir)
|
||||
rel_test_path = os.path.relpath(os.path.join(self.tempdir, 'foo'))
|
||||
self.assertRaises(
|
||||
argparse.ArgumentTypeError, cli.read_file, rel_test_path)
|
||||
@@ -38,6 +42,8 @@ class TestReadFile(TempDirTestCase):
|
||||
path, contents = cli.read_file(rel_test_path)
|
||||
self.assertEqual(path, os.path.abspath(path))
|
||||
self.assertEqual(contents, test_contents)
|
||||
finally:
|
||||
os.chdir(curr_dir)
|
||||
|
||||
|
||||
class FlagDefaultTest(unittest.TestCase):
|
||||
|
||||
@@ -150,6 +150,24 @@ class WindowsChmodTests(TempDirTestCase):
|
||||
self.assertEqual(security_dacl.GetSecurityDescriptorDacl().GetAceCount(), 2)
|
||||
|
||||
|
||||
class ComputePrivateKeyModeTest(TempDirTestCase):
|
||||
def setUp(self):
|
||||
super(ComputePrivateKeyModeTest, self).setUp()
|
||||
self.probe_path = _create_probe(self.tempdir)
|
||||
|
||||
def test_compute_private_key_mode(self):
|
||||
filesystem.chmod(self.probe_path, 0o777)
|
||||
new_mode = filesystem.compute_private_key_mode(self.probe_path, 0o600)
|
||||
|
||||
if POSIX_MODE:
|
||||
# On Linux RWX permissions for group and R permission for world
|
||||
# are persisted from the existing moe
|
||||
self.assertEqual(new_mode, 0o674)
|
||||
else:
|
||||
# On Windows no permission is persisted
|
||||
self.assertEqual(new_mode, 0o600)
|
||||
|
||||
|
||||
@unittest.skipIf(POSIX_MODE, reason='Tests specific to Windows security')
|
||||
class WindowsOpenTest(TempDirTestCase):
|
||||
def test_new_file_correct_permissions(self):
|
||||
@@ -210,15 +228,15 @@ class WindowsOpenTest(TempDirTestCase):
|
||||
def _test_one_creation(self, num, file_exist, flags):
|
||||
one_file = os.path.join(self.tempdir, str(num))
|
||||
if file_exist and not os.path.exists(one_file):
|
||||
open(one_file, 'w').close()
|
||||
with open(one_file, 'w'):
|
||||
pass
|
||||
|
||||
handler = None
|
||||
try:
|
||||
handler = filesystem.open(one_file, flags)
|
||||
except BaseException as err:
|
||||
finally:
|
||||
if handler:
|
||||
os.close(handler)
|
||||
raise err
|
||||
|
||||
|
||||
@unittest.skipIf(POSIX_MODE, reason='Test specific to Windows security')
|
||||
@@ -262,14 +280,14 @@ class WindowsMkdirTests(test_util.TempDirTestCase):
|
||||
self.assertEqual(original_mkdir, std_os.mkdir)
|
||||
|
||||
|
||||
class CopyOwnershipTest(test_util.TempDirTestCase):
|
||||
"""Tests about replacement of chown: copy_ownership_and_apply_mode"""
|
||||
class OwnershipTest(test_util.TempDirTestCase):
|
||||
"""Tests about copy_ownership_and_apply_mode and has_same_ownership"""
|
||||
def setUp(self):
|
||||
super(CopyOwnershipTest, self).setUp()
|
||||
super(OwnershipTest, self).setUp()
|
||||
self.probe_path = _create_probe(self.tempdir)
|
||||
|
||||
@unittest.skipIf(POSIX_MODE, reason='Test specific to Windows security')
|
||||
def test_windows(self):
|
||||
def test_copy_ownership_windows(self):
|
||||
system = win32security.ConvertStringSidToSid(SYSTEM_SID)
|
||||
security = win32security.SECURITY_ATTRIBUTES().SECURITY_DESCRIPTOR
|
||||
security.SetSecurityDescriptorOwner(system, False)
|
||||
@@ -295,7 +313,7 @@ class CopyOwnershipTest(test_util.TempDirTestCase):
|
||||
if dacl.GetAce(index)[2] == everybody])
|
||||
|
||||
@unittest.skipUnless(POSIX_MODE, reason='Test specific to Linux security')
|
||||
def test_linux(self):
|
||||
def test_copy_ownership_linux(self):
|
||||
with mock.patch('os.chown') as mock_chown:
|
||||
with mock.patch('os.chmod') as mock_chmod:
|
||||
with mock.patch('os.stat') as mock_stat:
|
||||
@@ -307,8 +325,18 @@ class CopyOwnershipTest(test_util.TempDirTestCase):
|
||||
mock_chown.assert_called_once_with(self.probe_path, 50, 51)
|
||||
mock_chmod.assert_called_once_with(self.probe_path, 0o700)
|
||||
|
||||
def test_has_same_ownership(self):
|
||||
path1 = os.path.join(self.tempdir, 'test1')
|
||||
path2 = os.path.join(self.tempdir, 'test2')
|
||||
|
||||
util.safe_open(path1, 'w').close()
|
||||
util.safe_open(path2, 'w').close()
|
||||
|
||||
self.assertTrue(filesystem.has_same_ownership(path1, path2))
|
||||
|
||||
|
||||
class CheckPermissionsTest(test_util.TempDirTestCase):
|
||||
"""Tests relative to functions that check modes."""
|
||||
def setUp(self):
|
||||
super(CheckPermissionsTest, self).setUp()
|
||||
self.probe_path = _create_probe(self.tempdir)
|
||||
@@ -353,6 +381,23 @@ class CheckPermissionsTest(test_util.TempDirTestCase):
|
||||
mock_owner.return_value = False
|
||||
self.assertFalse(filesystem.check_permissions(self.probe_path, 0o744))
|
||||
|
||||
def test_check_min_permissions(self):
|
||||
filesystem.chmod(self.probe_path, 0o744)
|
||||
self.assertTrue(filesystem.has_min_permissions(self.probe_path, 0o744))
|
||||
|
||||
filesystem.chmod(self.probe_path, 0o700)
|
||||
self.assertFalse(filesystem.has_min_permissions(self.probe_path, 0o744))
|
||||
|
||||
filesystem.chmod(self.probe_path, 0o741)
|
||||
self.assertFalse(filesystem.has_min_permissions(self.probe_path, 0o744))
|
||||
|
||||
def test_is_world_reachable(self):
|
||||
filesystem.chmod(self.probe_path, 0o744)
|
||||
self.assertTrue(filesystem.has_world_permissions(self.probe_path))
|
||||
|
||||
filesystem.chmod(self.probe_path, 0o700)
|
||||
self.assertFalse(filesystem.has_world_permissions(self.probe_path))
|
||||
|
||||
|
||||
class OsReplaceTest(test_util.TempDirTestCase):
|
||||
"""Test to ensure consistent behavior of rename method"""
|
||||
|
||||
@@ -8,8 +8,8 @@ class OsTest(unittest.TestCase):
|
||||
"""Unit tests for os module."""
|
||||
def test_forbidden_methods(self):
|
||||
# Checks for os module
|
||||
for method in ['chmod', 'chown', 'open', 'mkdir',
|
||||
'makedirs', 'rename', 'replace', 'access']:
|
||||
for method in ['chmod', 'chown', 'open', 'mkdir', 'makedirs', 'rename',
|
||||
'replace', 'access', 'stat', 'fstat']:
|
||||
self.assertRaises(RuntimeError, getattr(os, method))
|
||||
# Checks for os.path module
|
||||
for method in ['realpath']:
|
||||
|
||||
@@ -82,7 +82,10 @@ class LockFileTest(test_util.TempDirTestCase):
|
||||
'Race conditions on lock are specific to the non-blocking file access approach on Linux.')
|
||||
def test_race(self):
|
||||
should_delete = [True, False]
|
||||
stat = os.stat
|
||||
# Normally os module should not be imported in certbot codebase except in certbot.compat
|
||||
# for the sake of compatibility over Windows and Linux.
|
||||
# We make an exception here, since test_race is a test function called only on Linux.
|
||||
from os import stat # pylint: disable=os-module-forbidden
|
||||
|
||||
def delete_and_stat(path):
|
||||
"""Wrap os.stat and maybe delete the file first."""
|
||||
@@ -90,7 +93,7 @@ class LockFileTest(test_util.TempDirTestCase):
|
||||
os.remove(path)
|
||||
return stat(path)
|
||||
|
||||
with mock.patch('certbot.lock.os.stat') as mock_stat:
|
||||
with mock.patch('certbot.lock.filesystem.os.stat') as mock_stat:
|
||||
mock_stat.side_effect = delete_and_stat
|
||||
self._call(self.lock_path)
|
||||
self.assertFalse(should_delete)
|
||||
@@ -117,7 +120,7 @@ class LockFileTest(test_util.TempDirTestCase):
|
||||
|
||||
def test_unexpected_os_err(self):
|
||||
if POSIX_MODE:
|
||||
mock_function = 'certbot.lock.os.stat'
|
||||
mock_function = 'certbot.lock.filesystem.os.stat'
|
||||
else:
|
||||
mock_function = 'certbot.lock.msvcrt.locking'
|
||||
# The only expected errno are ENOENT and EACCES in lock module.
|
||||
|
||||
@@ -16,6 +16,7 @@ try:
|
||||
except (ImportError, AttributeError): # pragma: no cover
|
||||
ocsp_lib = None # type: ignore
|
||||
import mock
|
||||
import pytz
|
||||
|
||||
from certbot import errors
|
||||
from certbot.tests import util as test_util
|
||||
@@ -72,21 +73,34 @@ class OCSPTestOpenSSL(unittest.TestCase):
|
||||
@mock.patch('certbot.ocsp._determine_ocsp_server')
|
||||
@mock.patch('certbot.util.run_script')
|
||||
def test_ocsp_revoked(self, mock_run, mock_determine):
|
||||
now = pytz.UTC.fromutc(datetime.utcnow())
|
||||
cert_obj = mock.MagicMock()
|
||||
cert_obj.cert = "x"
|
||||
cert_obj.chain = "y"
|
||||
cert_obj.target_expiry = now + timedelta(hours=2)
|
||||
|
||||
self.checker.broken = True
|
||||
mock_determine.return_value = ("", "")
|
||||
self.assertEqual(self.checker.ocsp_revoked("x", "y"), False)
|
||||
self.assertEqual(self.checker.ocsp_revoked(cert_obj), False)
|
||||
|
||||
self.checker.broken = False
|
||||
mock_run.return_value = tuple(openssl_happy[1:])
|
||||
self.assertEqual(self.checker.ocsp_revoked("x", "y"), False)
|
||||
self.assertEqual(self.checker.ocsp_revoked(cert_obj), False)
|
||||
self.assertEqual(mock_run.call_count, 0)
|
||||
|
||||
mock_determine.return_value = ("http://x.co", "x.co")
|
||||
self.assertEqual(self.checker.ocsp_revoked("blah.pem", "chain.pem"), False)
|
||||
self.assertEqual(self.checker.ocsp_revoked(cert_obj), False)
|
||||
mock_run.side_effect = errors.SubprocessError("Unable to load certificate launcher")
|
||||
self.assertEqual(self.checker.ocsp_revoked("x", "y"), False)
|
||||
self.assertEqual(self.checker.ocsp_revoked(cert_obj), False)
|
||||
self.assertEqual(mock_run.call_count, 2)
|
||||
|
||||
# cert expired
|
||||
cert_obj.target_expiry = now
|
||||
mock_determine.return_value = ("", "")
|
||||
count_before = mock_determine.call_count
|
||||
self.assertEqual(self.checker.ocsp_revoked(cert_obj), False)
|
||||
self.assertEqual(mock_determine.call_count, count_before)
|
||||
|
||||
def test_determine_ocsp_server(self):
|
||||
cert_path = test_util.vector_path('ocsp_certificate.pem')
|
||||
|
||||
@@ -131,18 +145,23 @@ class OSCPTestCryptography(unittest.TestCase):
|
||||
self.checker = ocsp.RevocationChecker()
|
||||
self.cert_path = test_util.vector_path('ocsp_certificate.pem')
|
||||
self.chain_path = test_util.vector_path('ocsp_issuer_certificate.pem')
|
||||
self.cert_obj = mock.MagicMock()
|
||||
self.cert_obj.cert = self.cert_path
|
||||
self.cert_obj.chain = self.chain_path
|
||||
now = pytz.UTC.fromutc(datetime.utcnow())
|
||||
self.cert_obj.target_expiry = now + timedelta(hours=2)
|
||||
|
||||
@mock.patch('certbot.ocsp._determine_ocsp_server')
|
||||
@mock.patch('certbot.ocsp._check_ocsp_cryptography')
|
||||
def test_ensure_cryptography_toggled(self, mock_revoke, mock_determine):
|
||||
mock_determine.return_value = ('http://example.com', 'example.com')
|
||||
self.checker.ocsp_revoked(self.cert_path, self.chain_path)
|
||||
self.checker.ocsp_revoked(self.cert_obj)
|
||||
|
||||
mock_revoke.assert_called_once_with(self.cert_path, self.chain_path, 'http://example.com')
|
||||
|
||||
def test_revoke(self):
|
||||
with _ocsp_mock(ocsp_lib.OCSPCertStatus.REVOKED, ocsp_lib.OCSPResponseStatus.SUCCESSFUL):
|
||||
revoked = self.checker.ocsp_revoked(self.cert_path, self.chain_path)
|
||||
revoked = self.checker.ocsp_revoked(self.cert_obj)
|
||||
self.assertTrue(revoked)
|
||||
|
||||
def test_responder_is_issuer(self):
|
||||
@@ -152,7 +171,7 @@ class OSCPTestCryptography(unittest.TestCase):
|
||||
with _ocsp_mock(ocsp_lib.OCSPCertStatus.REVOKED,
|
||||
ocsp_lib.OCSPResponseStatus.SUCCESSFUL) as mocks:
|
||||
mocks['mock_response'].return_value.responder_name = issuer.subject
|
||||
self.checker.ocsp_revoked(self.cert_path, self.chain_path)
|
||||
self.checker.ocsp_revoked(self.cert_obj)
|
||||
# Here responder and issuer are the same. So only the signature of the OCSP
|
||||
# response is checked (using the issuer/responder public key).
|
||||
self.assertEqual(mocks['mock_check'].call_count, 1)
|
||||
@@ -167,7 +186,7 @@ class OSCPTestCryptography(unittest.TestCase):
|
||||
|
||||
with _ocsp_mock(ocsp_lib.OCSPCertStatus.REVOKED,
|
||||
ocsp_lib.OCSPResponseStatus.SUCCESSFUL) as mocks:
|
||||
self.checker.ocsp_revoked(self.cert_path, self.chain_path)
|
||||
self.checker.ocsp_revoked(self.cert_obj)
|
||||
# Here responder and issuer are not the same. Two signatures will be checked then,
|
||||
# first to verify the responder cert (using the issuer public key), second to
|
||||
# to verify the OCSP response itself (using the responder public key).
|
||||
@@ -181,17 +200,17 @@ class OSCPTestCryptography(unittest.TestCase):
|
||||
# Server return an invalid HTTP response
|
||||
with _ocsp_mock(ocsp_lib.OCSPCertStatus.UNKNOWN, ocsp_lib.OCSPResponseStatus.SUCCESSFUL,
|
||||
http_status_code=400):
|
||||
revoked = self.checker.ocsp_revoked(self.cert_path, self.chain_path)
|
||||
revoked = self.checker.ocsp_revoked(self.cert_obj)
|
||||
self.assertFalse(revoked)
|
||||
|
||||
# OCSP response in invalid
|
||||
with _ocsp_mock(ocsp_lib.OCSPCertStatus.UNKNOWN, ocsp_lib.OCSPResponseStatus.UNAUTHORIZED):
|
||||
revoked = self.checker.ocsp_revoked(self.cert_path, self.chain_path)
|
||||
revoked = self.checker.ocsp_revoked(self.cert_obj)
|
||||
self.assertFalse(revoked)
|
||||
|
||||
# OCSP response is valid, but certificate status is unknown
|
||||
with _ocsp_mock(ocsp_lib.OCSPCertStatus.UNKNOWN, ocsp_lib.OCSPResponseStatus.SUCCESSFUL):
|
||||
revoked = self.checker.ocsp_revoked(self.cert_path, self.chain_path)
|
||||
revoked = self.checker.ocsp_revoked(self.cert_obj)
|
||||
self.assertFalse(revoked)
|
||||
|
||||
# The OCSP response says that the certificate is revoked, but certificate
|
||||
@@ -200,32 +219,32 @@ class OSCPTestCryptography(unittest.TestCase):
|
||||
with mock.patch('cryptography.x509.Extensions.get_extension_for_class',
|
||||
side_effect=x509.ExtensionNotFound(
|
||||
'Not found', x509.AuthorityInformationAccessOID.OCSP)):
|
||||
revoked = self.checker.ocsp_revoked(self.cert_path, self.chain_path)
|
||||
revoked = self.checker.ocsp_revoked(self.cert_obj)
|
||||
self.assertFalse(revoked)
|
||||
|
||||
# OCSP response uses an unsupported signature.
|
||||
with _ocsp_mock(ocsp_lib.OCSPCertStatus.REVOKED, ocsp_lib.OCSPResponseStatus.SUCCESSFUL,
|
||||
check_signature_side_effect=UnsupportedAlgorithm('foo')):
|
||||
revoked = self.checker.ocsp_revoked(self.cert_path, self.chain_path)
|
||||
revoked = self.checker.ocsp_revoked(self.cert_obj)
|
||||
self.assertFalse(revoked)
|
||||
|
||||
# OSCP signature response is invalid.
|
||||
with _ocsp_mock(ocsp_lib.OCSPCertStatus.REVOKED, ocsp_lib.OCSPResponseStatus.SUCCESSFUL,
|
||||
check_signature_side_effect=InvalidSignature('foo')):
|
||||
revoked = self.checker.ocsp_revoked(self.cert_path, self.chain_path)
|
||||
revoked = self.checker.ocsp_revoked(self.cert_obj)
|
||||
self.assertFalse(revoked)
|
||||
|
||||
# Assertion error on OCSP response validity
|
||||
with _ocsp_mock(ocsp_lib.OCSPCertStatus.REVOKED, ocsp_lib.OCSPResponseStatus.SUCCESSFUL,
|
||||
check_signature_side_effect=AssertionError('foo')):
|
||||
revoked = self.checker.ocsp_revoked(self.cert_path, self.chain_path)
|
||||
revoked = self.checker.ocsp_revoked(self.cert_obj)
|
||||
self.assertFalse(revoked)
|
||||
|
||||
# No responder cert in OCSP response
|
||||
with _ocsp_mock(ocsp_lib.OCSPCertStatus.REVOKED,
|
||||
ocsp_lib.OCSPResponseStatus.SUCCESSFUL) as mocks:
|
||||
mocks['mock_response'].return_value.certificates = []
|
||||
revoked = self.checker.ocsp_revoked(self.cert_path, self.chain_path)
|
||||
revoked = self.checker.ocsp_revoked(self.cert_obj)
|
||||
self.assertFalse(revoked)
|
||||
|
||||
# Responder cert is not signed by certificate issuer
|
||||
@@ -234,7 +253,7 @@ class OSCPTestCryptography(unittest.TestCase):
|
||||
cert = mocks['mock_response'].return_value.certificates[0]
|
||||
mocks['mock_response'].return_value.certificates[0] = mock.Mock(
|
||||
issuer='fake', subject=cert.subject)
|
||||
revoked = self.checker.ocsp_revoked(self.cert_path, self.chain_path)
|
||||
revoked = self.checker.ocsp_revoked(self.cert_obj)
|
||||
self.assertFalse(revoked)
|
||||
|
||||
with _ocsp_mock(ocsp_lib.OCSPCertStatus.REVOKED, ocsp_lib.OCSPResponseStatus.SUCCESSFUL):
|
||||
@@ -245,7 +264,7 @@ class OSCPTestCryptography(unittest.TestCase):
|
||||
with mock.patch('cryptography.x509.Extensions.get_extension_for_class',
|
||||
side_effect=x509.ExtensionNotFound(
|
||||
'Not found', x509.AuthorityInformationAccessOID.OCSP)):
|
||||
revoked = self.checker.ocsp_revoked(self.cert_path, self.chain_path)
|
||||
revoked = self.checker.ocsp_revoked(self.cert_obj)
|
||||
self.assertFalse(revoked)
|
||||
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
"""
|
||||
import logging
|
||||
import shutil
|
||||
import stat
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
@@ -339,16 +338,7 @@ class TempDirTestCase(unittest.TestCase):
|
||||
logging.getLogger().handlers = []
|
||||
util._release_locks() # pylint: disable=protected-access
|
||||
|
||||
def handle_rw_files(_, path, __):
|
||||
"""Handle read-only files, that will fail to be removed on Windows."""
|
||||
filesystem.chmod(path, stat.S_IWRITE)
|
||||
try:
|
||||
os.remove(path)
|
||||
except (IOError, OSError):
|
||||
# TODO: remote the try/except once all logic from windows file permissions is merged
|
||||
if os.name != 'nt':
|
||||
raise
|
||||
shutil.rmtree(self.tempdir, onerror=handle_rw_files)
|
||||
shutil.rmtree(self.tempdir)
|
||||
|
||||
|
||||
class ConfigTestCase(TempDirTestCase):
|
||||
|
||||
@@ -520,11 +520,11 @@ class OsInfoTest(unittest.TestCase):
|
||||
|
||||
with mock.patch('platform.system_alias',
|
||||
return_value=('linux', '', '')):
|
||||
with mock.patch('platform.linux_distribution',
|
||||
with mock.patch('distro.linux_distribution',
|
||||
return_value=('', '', '')):
|
||||
self.assertEqual(get_python_os_info(), ("linux", ""))
|
||||
|
||||
with mock.patch('platform.linux_distribution',
|
||||
with mock.patch('distro.linux_distribution',
|
||||
return_value=('testdist', '42', '')):
|
||||
self.assertEqual(get_python_os_info(), ("testdist", "42"))
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ import socket
|
||||
import subprocess
|
||||
|
||||
import configargparse
|
||||
import distro
|
||||
import six
|
||||
|
||||
from acme.magic_typing import Tuple, Union # pylint: disable=unused-import, no-name-in-module
|
||||
@@ -391,8 +392,8 @@ def get_python_os_info():
|
||||
os_type, os_ver, _ = info
|
||||
os_type = os_type.lower()
|
||||
if os_type.startswith('linux'):
|
||||
info = platform.linux_distribution()
|
||||
# On arch, platform.linux_distribution() is reportedly ('','',''),
|
||||
info = distro.linux_distribution()
|
||||
# On arch, distro.linux_distribution() is reportedly ('','',''),
|
||||
# so handle it defensively
|
||||
if info[0]:
|
||||
os_type = info[0]
|
||||
|
||||
@@ -113,7 +113,7 @@ optional arguments:
|
||||
case, and to know when to deprecate support for past
|
||||
Python versions and flags. If you wish to hide this
|
||||
information from the Let's Encrypt server, set this to
|
||||
"". (default: CertbotACMEClient/0.37.1
|
||||
"". (default: CertbotACMEClient/0.38.0
|
||||
(certbot(-auto); OS_NAME OS_VERSION) Authenticator/XXX
|
||||
Installer/YYY (SUBCOMMAND; flags: FLAGS)
|
||||
Py/major.minor.patchlevel). The flags encoded in the
|
||||
|
||||
@@ -200,23 +200,39 @@ Operating System Packages
|
||||
|
||||
**Debian**
|
||||
|
||||
If you run Debian Stretch or Debian Sid, you can install certbot packages.
|
||||
If you run Debian Buster or Debian testing/Sid, you can easily install certbot
|
||||
packages through commands like:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
sudo apt-get update
|
||||
sudo apt-get install certbot python-certbot-apache
|
||||
sudo apt-get install certbot
|
||||
|
||||
If you don't want to use the Apache plugin, you can omit the
|
||||
``python-certbot-apache`` package. Or you can install ``python-certbot-nginx`` instead.
|
||||
|
||||
Packages exist for Debian Jessie via backports. First you'll have to follow the
|
||||
instructions at http://backports.debian.org/Instructions/ to enable the Jessie backports
|
||||
repo, if you have not already done so. Then run:
|
||||
If you run Debian Stretch, we recommend you use the packages in Debian
|
||||
backports repository. First you'll have to follow the instructions at
|
||||
https://backports.debian.org/Instructions/ to enable the Stretch backports repo,
|
||||
if you have not already done so. Then run:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
sudo apt-get install certbot python-certbot-apache -t jessie-backports
|
||||
sudo apt-get install certbot -t stretch-backports
|
||||
|
||||
In all of these cases, there also packages available to help Certbot integrate
|
||||
with Apache, nginx, or various DNS services. If you are using Apache or nginx,
|
||||
we strongly recommend that you install the ``python-certbot-apache`` or
|
||||
``python-certbot-nginx`` package so that Certbot can fully automate HTTPS
|
||||
configuration for your server. A full list of these packages can be found
|
||||
through a command like:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
apt search 'python-certbot*'
|
||||
|
||||
They can be installed by running the same installation command above but
|
||||
replacing ``certbot`` with the name of the desired package.
|
||||
|
||||
There are no Certbot packages available for Debian Jessie and Jessie users
|
||||
should instead use certbot-auto_.
|
||||
|
||||
**Ubuntu**
|
||||
|
||||
|
||||
@@ -281,6 +281,7 @@ pritunl_ N Y Install certificates in pritunl distributed OpenVPN
|
||||
proxmox_ N Y Install certificates in Proxmox Virtualization servers
|
||||
heroku_ Y Y Integration with Heroku SSL
|
||||
dns-standalone_ Y N Obtain certificates via an integrated DNS server
|
||||
dns-ispconfig_ Y N DNS Authentication using ISPConfig as DNS server
|
||||
================== ==== ==== ===============================================================
|
||||
|
||||
.. _haproxy: https://github.com/greenhost/certbot-haproxy
|
||||
@@ -294,6 +295,7 @@ dns-standalone_ Y N Obtain certificates via an integrated DNS server
|
||||
.. _external: https://github.com/marcan/letsencrypt-external
|
||||
.. _heroku: https://github.com/gboudreau/certbot-heroku
|
||||
.. _dns-standalone: https://github.com/siilike/certbot-dns-standalone
|
||||
.. _dns-ispconfig: https://github.com/m42e/certbot-dns-ispconfig
|
||||
|
||||
If you're interested, you can also :ref:`write your own plugin <dev-plugin>`.
|
||||
|
||||
|
||||
201
letsencrypt-auto
201
letsencrypt-auto
@@ -31,7 +31,7 @@ if [ -z "$VENV_PATH" ]; then
|
||||
fi
|
||||
VENV_BIN="$VENV_PATH/bin"
|
||||
BOOTSTRAP_VERSION_PATH="$VENV_PATH/certbot-auto-bootstrap-version.txt"
|
||||
LE_AUTO_VERSION="0.37.1"
|
||||
LE_AUTO_VERSION="0.38.0"
|
||||
BASENAME=$(basename $0)
|
||||
USAGE="Usage: $BASENAME [OPTIONS]
|
||||
A self-updating wrapper script for the Certbot ACME client. When run, updates
|
||||
@@ -1134,73 +1134,76 @@ if [ "$1" = "--le-auto-phase2" ]; then
|
||||
# To generate this, do (with docker and package hashin installed):
|
||||
# ```
|
||||
# letsencrypt-auto-source/rebuild_dependencies.py \
|
||||
# letsencrypt-auto-sources/pieces/dependency-requirements.txt
|
||||
# letsencrypt-auto-source/pieces/dependency-requirements.txt
|
||||
# ```
|
||||
# If you want to update a single dependency, run commands similar to these:
|
||||
# ```
|
||||
# pip install hashin
|
||||
# hashin -r dependency-requirements.txt cryptography==1.5.2
|
||||
# ```
|
||||
ConfigArgParse==0.14.0 \
|
||||
--hash=sha256:2e2efe2be3f90577aca9415e32cb629aa2ecd92078adbe27b53a03e53ff12e91
|
||||
asn1crypto==0.24.0 \
|
||||
--hash=sha256:2f1adbb7546ed199e3c90ef23ec95c5cf3585bac7d11fb7eb562a3fe89c64e87 \
|
||||
--hash=sha256:9d5c20441baf0cb60a4ac34cc447c6c189024b6b4c6cd7877034f4965c464e49
|
||||
certifi==2019.3.9 \
|
||||
--hash=sha256:59b7658e26ca9c7339e00f8f4636cdfe59d34fa37b9b04f6f9e9926b3cece1a5 \
|
||||
--hash=sha256:b26104d6835d1f5e49452a26eb2ff87fe7090b89dfcaee5ea2212697e1e1d7ae
|
||||
cffi==1.12.2 \
|
||||
--hash=sha256:00b97afa72c233495560a0793cdc86c2571721b4271c0667addc83c417f3d90f \
|
||||
--hash=sha256:0ba1b0c90f2124459f6966a10c03794082a2f3985cd699d7d63c4a8dae113e11 \
|
||||
--hash=sha256:0bffb69da295a4fc3349f2ec7cbe16b8ba057b0a593a92cbe8396e535244ee9d \
|
||||
--hash=sha256:21469a2b1082088d11ccd79dd84157ba42d940064abbfa59cf5f024c19cf4891 \
|
||||
--hash=sha256:2e4812f7fa984bf1ab253a40f1f4391b604f7fc424a3e21f7de542a7f8f7aedf \
|
||||
--hash=sha256:2eac2cdd07b9049dd4e68449b90d3ef1adc7c759463af5beb53a84f1db62e36c \
|
||||
--hash=sha256:2f9089979d7456c74d21303c7851f158833d48fb265876923edcb2d0194104ed \
|
||||
--hash=sha256:3dd13feff00bddb0bd2d650cdb7338f815c1789a91a6f68fdc00e5c5ed40329b \
|
||||
--hash=sha256:4065c32b52f4b142f417af6f33a5024edc1336aa845b9d5a8d86071f6fcaac5a \
|
||||
--hash=sha256:51a4ba1256e9003a3acf508e3b4f4661bebd015b8180cc31849da222426ef585 \
|
||||
--hash=sha256:59888faac06403767c0cf8cfb3f4a777b2939b1fbd9f729299b5384f097f05ea \
|
||||
--hash=sha256:59c87886640574d8b14910840327f5cd15954e26ed0bbd4e7cef95fa5aef218f \
|
||||
--hash=sha256:610fc7d6db6c56a244c2701575f6851461753c60f73f2de89c79bbf1cc807f33 \
|
||||
--hash=sha256:70aeadeecb281ea901bf4230c6222af0248c41044d6f57401a614ea59d96d145 \
|
||||
--hash=sha256:71e1296d5e66c59cd2c0f2d72dc476d42afe02aeddc833d8e05630a0551dad7a \
|
||||
--hash=sha256:8fc7a49b440ea752cfdf1d51a586fd08d395ff7a5d555dc69e84b1939f7ddee3 \
|
||||
--hash=sha256:9b5c2afd2d6e3771d516045a6cfa11a8da9a60e3d128746a7fe9ab36dfe7221f \
|
||||
--hash=sha256:9c759051ebcb244d9d55ee791259ddd158188d15adee3c152502d3b69005e6bd \
|
||||
--hash=sha256:b4d1011fec5ec12aa7cc10c05a2f2f12dfa0adfe958e56ae38dc140614035804 \
|
||||
--hash=sha256:b4f1d6332339ecc61275bebd1f7b674098a66fea11a00c84d1c58851e618dc0d \
|
||||
--hash=sha256:c030cda3dc8e62b814831faa4eb93dd9a46498af8cd1d5c178c2de856972fd92 \
|
||||
--hash=sha256:c2e1f2012e56d61390c0e668c20c4fb0ae667c44d6f6a2eeea5d7148dcd3df9f \
|
||||
--hash=sha256:c37c77d6562074452120fc6c02ad86ec928f5710fbc435a181d69334b4de1d84 \
|
||||
--hash=sha256:c8149780c60f8fd02752d0429246088c6c04e234b895c4a42e1ea9b4de8d27fb \
|
||||
--hash=sha256:cbeeef1dc3c4299bd746b774f019de9e4672f7cc666c777cd5b409f0b746dac7 \
|
||||
--hash=sha256:e113878a446c6228669144ae8a56e268c91b7f1fafae927adc4879d9849e0ea7 \
|
||||
--hash=sha256:e21162bf941b85c0cda08224dade5def9360f53b09f9f259adb85fc7dd0e7b35 \
|
||||
--hash=sha256:fb6934ef4744becbda3143d30c6604718871495a5e36c408431bf33d9c146889
|
||||
certifi==2019.6.16 \
|
||||
--hash=sha256:046832c04d4e752f37383b628bc601a7ea7211496b4638f6514d0e5b9acc4939 \
|
||||
--hash=sha256:945e3ba63a0b9f577b1395204e13c3a231f9bc0223888be653286534e5873695
|
||||
cffi==1.12.3 \
|
||||
--hash=sha256:041c81822e9f84b1d9c401182e174996f0bae9991f33725d059b771744290774 \
|
||||
--hash=sha256:046ef9a22f5d3eed06334d01b1e836977eeef500d9b78e9ef693f9380ad0b83d \
|
||||
--hash=sha256:066bc4c7895c91812eff46f4b1c285220947d4aa46fa0a2651ff85f2afae9c90 \
|
||||
--hash=sha256:066c7ff148ae33040c01058662d6752fd73fbc8e64787229ea8498c7d7f4041b \
|
||||
--hash=sha256:2444d0c61f03dcd26dbf7600cf64354376ee579acad77aef459e34efcb438c63 \
|
||||
--hash=sha256:300832850b8f7967e278870c5d51e3819b9aad8f0a2c8dbe39ab11f119237f45 \
|
||||
--hash=sha256:34c77afe85b6b9e967bd8154e3855e847b70ca42043db6ad17f26899a3df1b25 \
|
||||
--hash=sha256:46de5fa00f7ac09f020729148ff632819649b3e05a007d286242c4882f7b1dc3 \
|
||||
--hash=sha256:4aa8ee7ba27c472d429b980c51e714a24f47ca296d53f4d7868075b175866f4b \
|
||||
--hash=sha256:4d0004eb4351e35ed950c14c11e734182591465a33e960a4ab5e8d4f04d72647 \
|
||||
--hash=sha256:4e3d3f31a1e202b0f5a35ba3bc4eb41e2fc2b11c1eff38b362de710bcffb5016 \
|
||||
--hash=sha256:50bec6d35e6b1aaeb17f7c4e2b9374ebf95a8975d57863546fa83e8d31bdb8c4 \
|
||||
--hash=sha256:55cad9a6df1e2a1d62063f79d0881a414a906a6962bc160ac968cc03ed3efcfb \
|
||||
--hash=sha256:5662ad4e4e84f1eaa8efce5da695c5d2e229c563f9d5ce5b0113f71321bcf753 \
|
||||
--hash=sha256:59b4dc008f98fc6ee2bb4fd7fc786a8d70000d058c2bbe2698275bc53a8d3fa7 \
|
||||
--hash=sha256:73e1ffefe05e4ccd7bcea61af76f36077b914f92b76f95ccf00b0c1b9186f3f9 \
|
||||
--hash=sha256:a1f0fd46eba2d71ce1589f7e50a9e2ffaeb739fb2c11e8192aa2b45d5f6cc41f \
|
||||
--hash=sha256:a2e85dc204556657661051ff4bab75a84e968669765c8a2cd425918699c3d0e8 \
|
||||
--hash=sha256:a5457d47dfff24882a21492e5815f891c0ca35fefae8aa742c6c263dac16ef1f \
|
||||
--hash=sha256:a8dccd61d52a8dae4a825cdbb7735da530179fea472903eb871a5513b5abbfdc \
|
||||
--hash=sha256:ae61af521ed676cf16ae94f30fe202781a38d7178b6b4ab622e4eec8cefaff42 \
|
||||
--hash=sha256:b012a5edb48288f77a63dba0840c92d0504aa215612da4541b7b42d849bc83a3 \
|
||||
--hash=sha256:d2c5cfa536227f57f97c92ac30c8109688ace8fa4ac086d19d0af47d134e2909 \
|
||||
--hash=sha256:d42b5796e20aacc9d15e66befb7a345454eef794fdb0737d1af593447c6c8f45 \
|
||||
--hash=sha256:dee54f5d30d775f525894d67b1495625dd9322945e7fee00731952e0368ff42d \
|
||||
--hash=sha256:e070535507bd6aa07124258171be2ee8dfc19119c28ca94c9dfb7efd23564512 \
|
||||
--hash=sha256:e1ff2748c84d97b065cc95429814cdba39bcbd77c9c85c89344b317dc0d9cbff \
|
||||
--hash=sha256:ed851c75d1e0e043cbf5ca9a8e1b13c4c90f3fbd863dacb01c0808e2b5204201
|
||||
chardet==3.0.4 \
|
||||
--hash=sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae \
|
||||
--hash=sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691
|
||||
configobj==5.0.6 \
|
||||
--hash=sha256:a2f5650770e1c87fb335af19a9b7eb73fc05ccf22144eb68db7d00cd2bcb0902
|
||||
cryptography==2.6.1 \
|
||||
--hash=sha256:066f815f1fe46020877c5983a7e747ae140f517f1b09030ec098503575265ce1 \
|
||||
--hash=sha256:210210d9df0afba9e000636e97810117dc55b7157c903a55716bb73e3ae07705 \
|
||||
--hash=sha256:26c821cbeb683facb966045e2064303029d572a87ee69ca5a1bf54bf55f93ca6 \
|
||||
--hash=sha256:2afb83308dc5c5255149ff7d3fb9964f7c9ee3d59b603ec18ccf5b0a8852e2b1 \
|
||||
--hash=sha256:2db34e5c45988f36f7a08a7ab2b69638994a8923853dec2d4af121f689c66dc8 \
|
||||
--hash=sha256:409c4653e0f719fa78febcb71ac417076ae5e20160aec7270c91d009837b9151 \
|
||||
--hash=sha256:45a4f4cf4f4e6a55c8128f8b76b4c057027b27d4c67e3fe157fa02f27e37830d \
|
||||
--hash=sha256:48eab46ef38faf1031e58dfcc9c3e71756a1108f4c9c966150b605d4a1a7f659 \
|
||||
--hash=sha256:6b9e0ae298ab20d371fc26e2129fd683cfc0cfde4d157c6341722de645146537 \
|
||||
--hash=sha256:6c4778afe50f413707f604828c1ad1ff81fadf6c110cb669579dea7e2e98a75e \
|
||||
--hash=sha256:8c33fb99025d353c9520141f8bc989c2134a1f76bac6369cea060812f5b5c2bb \
|
||||
--hash=sha256:9873a1760a274b620a135054b756f9f218fa61ca030e42df31b409f0fb738b6c \
|
||||
--hash=sha256:9b069768c627f3f5623b1cbd3248c5e7e92aec62f4c98827059eed7053138cc9 \
|
||||
--hash=sha256:9e4ce27a507e4886efbd3c32d120db5089b906979a4debf1d5939ec01b9dd6c5 \
|
||||
--hash=sha256:acb424eaca214cb08735f1a744eceb97d014de6530c1ea23beb86d9c6f13c2ad \
|
||||
--hash=sha256:c8181c7d77388fe26ab8418bb088b1a1ef5fde058c6926790c8a0a3d94075a4a \
|
||||
--hash=sha256:d4afbb0840f489b60f5a580a41a1b9c3622e08ecb5eec8614d4fb4cd914c4460 \
|
||||
--hash=sha256:d9ed28030797c00f4bc43c86bf819266c76a5ea61d006cd4078a93ebf7da6bfd \
|
||||
--hash=sha256:e603aa7bb52e4e8ed4119a58a03b60323918467ef209e6ff9db3ac382e5cf2c6
|
||||
# Package enum34 needs to be explicitly limited to Python2.x, in order to avoid
|
||||
# certbot-auto failures on Python 3.6+ which enum34 doesn't support. See #5456.
|
||||
enum34==1.1.6 ; python_version < '3.4' \
|
||||
cryptography==2.7 \
|
||||
--hash=sha256:24b61e5fcb506424d3ec4e18bca995833839bf13c59fc43e530e488f28d46b8c \
|
||||
--hash=sha256:25dd1581a183e9e7a806fe0543f485103232f940fcfc301db65e630512cce643 \
|
||||
--hash=sha256:3452bba7c21c69f2df772762be0066c7ed5dc65df494a1d53a58b683a83e1216 \
|
||||
--hash=sha256:41a0be220dd1ed9e998f5891948306eb8c812b512dc398e5a01846d855050799 \
|
||||
--hash=sha256:5751d8a11b956fbfa314f6553d186b94aa70fdb03d8a4d4f1c82dcacf0cbe28a \
|
||||
--hash=sha256:5f61c7d749048fa6e3322258b4263463bfccefecb0dd731b6561cb617a1d9bb9 \
|
||||
--hash=sha256:72e24c521fa2106f19623a3851e9f89ddfdeb9ac63871c7643790f872a305dfc \
|
||||
--hash=sha256:7b97ae6ef5cba2e3bb14256625423413d5ce8d1abb91d4f29b6d1a081da765f8 \
|
||||
--hash=sha256:961e886d8a3590fd2c723cf07be14e2a91cf53c25f02435c04d39e90780e3b53 \
|
||||
--hash=sha256:96d8473848e984184b6728e2c9d391482008646276c3ff084a1bd89e15ff53a1 \
|
||||
--hash=sha256:ae536da50c7ad1e002c3eee101871d93abdc90d9c5f651818450a0d3af718609 \
|
||||
--hash=sha256:b0db0cecf396033abb4a93c95d1602f268b3a68bb0a9cc06a7cff587bb9a7292 \
|
||||
--hash=sha256:cfee9164954c186b191b91d4193989ca994703b2fff406f71cf454a2d3c7327e \
|
||||
--hash=sha256:e6347742ac8f35ded4a46ff835c60e68c22a536a8ae5c4422966d06946b6d4c6 \
|
||||
--hash=sha256:f27d93f0139a3c056172ebb5d4f9056e770fdf0206c2f422ff2ebbad142e09ed \
|
||||
--hash=sha256:f57b76e46a58b63d1c6375017f4564a28f19a5ca912691fd2e4261b3414b618d
|
||||
distro==1.4.0 \
|
||||
--hash=sha256:362dde65d846d23baee4b5c058c8586f219b5a54be1cf5fc6ff55c4578392f57 \
|
||||
--hash=sha256:eedf82a470ebe7d010f1872c17237c79ab04097948800029994fa458e52fb4b4
|
||||
enum34==1.1.6 \
|
||||
--hash=sha256:2d81cbbe0e73112bdfe6ef8576f2238f2ba27dd0d55752a776c41d38b7da2850 \
|
||||
--hash=sha256:644837f692e5f550741432dd3f223bbb9852018674981b1664e5dc339387588a \
|
||||
--hash=sha256:6bd0f6ad48ec2aa117d3d141940d484deccda84d4fcd884f5c3d93c23ecd8c79 \
|
||||
@@ -1216,18 +1219,18 @@ idna==2.8 \
|
||||
ipaddress==1.0.22 \
|
||||
--hash=sha256:64b28eec5e78e7510698f6d4da08800a5c575caa4a286c93d651c5d3ff7b6794 \
|
||||
--hash=sha256:b146c751ea45cad6188dd6cf2d9b757f6f4f8d6ffb96a023e6f2e26eea02a72c
|
||||
josepy==1.1.0 \
|
||||
--hash=sha256:1309a25aac3caeff5239729c58ff9b583f7d022ffdb1553406ddfc8e5b52b76e \
|
||||
--hash=sha256:fb5c62c77d26e04df29cb5ecd01b9ce69b6fcc9e521eb1ca193b7faa2afa7086
|
||||
josepy==1.2.0 \
|
||||
--hash=sha256:8ea15573203f28653c00f4ac0142520777b1c59d9eddd8da3f256c6ba3cac916 \
|
||||
--hash=sha256:9cec9a839fe9520f0420e4f38e7219525daccce4813296627436fe444cd002d3
|
||||
mock==1.3.0 \
|
||||
--hash=sha256:1e247dbecc6ce057299eb7ee019ad68314bb93152e81d9a6110d35f4d5eca0f6 \
|
||||
--hash=sha256:3f573a18be94de886d1191f27c168427ef693e8dcfcecf95b170577b2eb69cbb
|
||||
parsedatetime==2.4 \
|
||||
--hash=sha256:3d817c58fb9570d1eec1dd46fa9448cd644eeed4fb612684b02dfda3a79cb84b \
|
||||
--hash=sha256:9ee3529454bf35c40a77115f5a596771e59e1aee8c53306f346c461b8e913094
|
||||
pbr==5.1.3 \
|
||||
--hash=sha256:8257baf496c8522437e8a6cfe0f15e00aedc6c0e0e7c9d55eeeeab31e0853843 \
|
||||
--hash=sha256:8c361cc353d988e4f5b998555c88098b9d5964c2e11acf7b0d21925a66bb5824
|
||||
pbr==5.4.2 \
|
||||
--hash=sha256:56e52299170b9492513c64be44736d27a512fa7e606f21942160b68ce510b4bc \
|
||||
--hash=sha256:9b321c204a88d8ab5082699469f52cc94c5da45c51f114113d01b3d993c24cdf
|
||||
pyOpenSSL==19.0.0 \
|
||||
--hash=sha256:aeca66338f6de19d1aa46ed634c3b9ae519a64b458f8468aec688e7e3c20f200 \
|
||||
--hash=sha256:c727930ad54b10fc157015014b666f2d8b41f70c0d03e83ab67624fd3dd5d1e6
|
||||
@@ -1236,14 +1239,14 @@ pyRFC3339==1.1 \
|
||||
--hash=sha256:81b8cbe1519cdb79bed04910dd6fa4e181faf8c88dff1e1b987b5f7ab23a5b1a
|
||||
pycparser==2.19 \
|
||||
--hash=sha256:a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3
|
||||
pyparsing==2.3.1 \
|
||||
--hash=sha256:66c9268862641abcac4a96ba74506e594c884e3f57690a696d21ad8210ed667a \
|
||||
--hash=sha256:f6c5ef0d7480ad048c054c37632c67fca55299990fff127850181659eea33fc3
|
||||
pyparsing==2.4.2 \
|
||||
--hash=sha256:6f98a7b9397e206d78cc01df10131398f1c8b8510a2f4d97d9abd82e1aacdd80 \
|
||||
--hash=sha256:d9338df12903bbf5d65a0e4e87c2161968b10d2e489652bb47001d82a9b028b4
|
||||
python-augeas==0.5.0 \
|
||||
--hash=sha256:67d59d66cdba8d624e0389b87b2a83a176f21f16a87553b50f5703b23f29bac2
|
||||
pytz==2018.9 \
|
||||
--hash=sha256:32b0891edff07e28efe91284ed9c31e123d84bea3fd98e1f72be2508f43ef8d9 \
|
||||
--hash=sha256:d5f05e487007e29e03409f9398d074e158d920d36eb82eaf66fb1136b0c5374c
|
||||
pytz==2019.2 \
|
||||
--hash=sha256:26c0b32e437e54a18161324a2fca3c4b9846b74a8dccddd843113109e1116b32 \
|
||||
--hash=sha256:c894d57500a4cd2d5c71114aaab77dbab5eabd9022308ce5ac9bb93a60a6f0c7
|
||||
requests==2.21.0 \
|
||||
--hash=sha256:502a824f31acdacb3a35b6690b5fbf0bc41d63a24a45c4004352b0242707598e \
|
||||
--hash=sha256:7bf2a778576d825600030a110f3c0e3e8edc51dfaafe1c146e39a2027784957b
|
||||
@@ -1253,15 +1256,15 @@ requests-toolbelt==0.9.1 \
|
||||
six==1.12.0 \
|
||||
--hash=sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c \
|
||||
--hash=sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73
|
||||
urllib3==1.24.2 \
|
||||
--hash=sha256:4c291ca23bbb55c76518905869ef34bdd5f0e46af7afe6861e8375643ffee1a0 \
|
||||
--hash=sha256:9a247273df709c4fedb38c711e44292304f73f39ab01beda9f6b9fc375669ac3
|
||||
urllib3==1.24.3 \
|
||||
--hash=sha256:2393a695cd12afedd0dcb26fe5d50d0cf248e5a66f75dbd89a3d4eb333a61af4 \
|
||||
--hash=sha256:a637e5fae88995b256e3409dc4d52c2e2e0ba32c42a6365fee8bbd2238de3cfb
|
||||
zope.component==4.5 \
|
||||
--hash=sha256:6edfd626c3b593b72895a8cfcf79bff41f4619194ce996a85bce31ac02b94e55 \
|
||||
--hash=sha256:984a06ba3def0b02b1117fa4c45b56e772e8c29c0340820fbf367e440a93a3a4
|
||||
zope.deferredimport==4.3 \
|
||||
--hash=sha256:2ddef5a7ecfff132a2dd796253366ecf9748a446e30f1a0b3a636aec9d9c05c5 \
|
||||
--hash=sha256:4aae9cbacb2146cca58e62be0a914f0cec034d3b2d41135ea212ca8a96f4b5ec
|
||||
zope.deferredimport==4.3.1 \
|
||||
--hash=sha256:57b2345e7b5eef47efcd4f634ff16c93e4265de3dcf325afc7315ade48d909e1 \
|
||||
--hash=sha256:9a0c211df44aa95f1c4e6d2626f90b400f56989180d3ef96032d708da3d23e0a
|
||||
zope.deprecation==4.4.0 \
|
||||
--hash=sha256:0d453338f04bacf91bbfba545d8bcdf529aa829e67b705eac8c1a7fdce66e2df \
|
||||
--hash=sha256:f1480b74995958b24ce37b0ef04d3663d2683e5d6debc96726eff18acf4ea113
|
||||
@@ -1309,18 +1312,18 @@ zope.interface==4.6.0 \
|
||||
--hash=sha256:d788a3999014ddf416f2dc454efa4a5dbeda657c6aba031cf363741273804c6b \
|
||||
--hash=sha256:eed88ae03e1ef3a75a0e96a55a99d7937ed03e53d0cffc2451c208db445a2966 \
|
||||
--hash=sha256:f99451f3a579e73b5dd58b1b08d1179791d49084371d9a47baad3b22417f0317
|
||||
zope.proxy==4.3.1 \
|
||||
--hash=sha256:0cbcfcafaa3b5fde7ba7a7b9a2b5f09af25c9b90087ad65f9e61359fed0ca63b \
|
||||
--hash=sha256:3de631dd5054a3a20b9ebff0e375f39c0565f1fb9131200d589a6a8f379214cd \
|
||||
--hash=sha256:5429134d04d42262f4dac25f6dea907f6334e9a751ffc62cb1d40226fb52bdeb \
|
||||
--hash=sha256:563c2454b2d0f23bca54d2e0e4d781149b7b06cb5df67e253ca3620f37202dd2 \
|
||||
--hash=sha256:5bcf773345016b1461bb07f70c635b9386e5eaaa08e37d3939dcdf12d3fdbec5 \
|
||||
--hash=sha256:8d84b7aef38c693874e2f2084514522bf73fd720fde0ce2a9352a51315ffa475 \
|
||||
--hash=sha256:90de9473c05819b36816b6cb957097f809691836ed3142648bf62da84b4502fe \
|
||||
--hash=sha256:dd592a69fe872445542a6e1acbefb8e28cbe6b4007b8f5146da917e49b155cc3 \
|
||||
--hash=sha256:e7399ab865399fce322f9cefc6f2f3e4099d087ba581888a9fea1bbe1db42a08 \
|
||||
--hash=sha256:e7d1c280d86d72735a420610df592aac72332194e531a8beff43a592c3a1b8eb \
|
||||
--hash=sha256:e90243fee902adb0c39eceb3c69995c0f2004bc3fdb482fbf629efc656d124ed
|
||||
zope.proxy==4.3.2 \
|
||||
--hash=sha256:320a7619992e42142549ebf61e14ce27683b4d14b0cbc45f7c037ba64edb560c \
|
||||
--hash=sha256:824d4dbabbb7deb84f25fdb96ea1eeca436a1802c3c8d323b3eb4ac9d527d41c \
|
||||
--hash=sha256:8a32eb9c94908f3544da2dae3f4a9e6961d78819b88ac6b6f4a51cee2d65f4a0 \
|
||||
--hash=sha256:96265fd3bc3ea646f98482e16307a69de21402eeaaaaf4b841c1161ac2f71bb0 \
|
||||
--hash=sha256:ab6d6975d9c51c13cac828ff03168de21fb562b0664c59bcdc4a4b10f39a5b17 \
|
||||
--hash=sha256:af10cb772391772463f65a58348e2de5ecc06693c16d2078be276dc068bcbb54 \
|
||||
--hash=sha256:b8fd3a3de3f7b6452775e92af22af5977b17b69ac86a38a3ddfe870e40a0d05f \
|
||||
--hash=sha256:bb7088f1bed3b8214284a5e425dc23da56f2f28e8815b7580bfed9e245b6c0b6 \
|
||||
--hash=sha256:bc29b3665eac34f14c4aef5224bef045efcfb1a7d12d78c8685858de5fbf21c0 \
|
||||
--hash=sha256:c39fa6a159affeae5fe31b49d9f5b12bd674fe77271a9a324408b271440c50a7 \
|
||||
--hash=sha256:e946a036ac5b9f897e986ac9dc950a34cffc857d88eae6727b8434fbc4752366
|
||||
|
||||
# Contains the requirements for the letsencrypt package.
|
||||
#
|
||||
@@ -1333,18 +1336,18 @@ letsencrypt==0.7.0 \
|
||||
--hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \
|
||||
--hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9
|
||||
|
||||
certbot==0.37.1 \
|
||||
--hash=sha256:84dbdad204327b8d8ef9ab5b040f2be1e427a9f7e087affcc9a6051ea1b03fe7 \
|
||||
--hash=sha256:aace73e63b0c11cdb4b0bd33e1780c1fbe0ce5669dc72e80c3aa9500145daf16
|
||||
acme==0.37.1 \
|
||||
--hash=sha256:83a4f6f3c5eb6a85233d5ba87714b426f2d096df58d711f8a2fc4071eb3fd3fc \
|
||||
--hash=sha256:c069a761990751f7c4bf51d2e87ae10319bf460de6629d2908c9fa6f69e97111
|
||||
certbot-apache==0.37.1 \
|
||||
--hash=sha256:3ea832408877b12b3a60d17e8b2ee3387364f8c3023ac267161c25b99087cd42 \
|
||||
--hash=sha256:e46c2644451101c0e216aa1f525a577cc903efaf871e0e4da277224a4439040c
|
||||
certbot-nginx==0.37.1 \
|
||||
--hash=sha256:1f9af389d26f06634e2eefaace3354e7679dabb4295e1d55d05a4ee7e23a64bd \
|
||||
--hash=sha256:02a7ec15bd388d0f0e94a34c86a8f8d618ec7d5ffde0c206039bb4c46b294ce4
|
||||
certbot==0.38.0 \
|
||||
--hash=sha256:618abf3ae17c2fc3cb99baa4bf000dd5e2d7875b7811f5ef1edf6ebd7a33945f \
|
||||
--hash=sha256:c27712101794e3adf54f3a3067c63be5caa507a930a79865bc654b6864121c6b
|
||||
acme==0.38.0 \
|
||||
--hash=sha256:6231571b4a94d6d621b28bef6f6d4846b3c2ebca840f9718d3212036c3bd2af8 \
|
||||
--hash=sha256:1c1e9c0826a8f72d670b0ca28b7e6392ce4781eb33222f35133705b6551885d8
|
||||
certbot-apache==0.38.0 \
|
||||
--hash=sha256:0b5a2c2bcc430470b5131941ebdfde0a13e28dec38918c1a4ebea5dd35ad38bc \
|
||||
--hash=sha256:2d335543e0ae9292303238736907ce6b321ac49eb49fe4e0b775abdc0ba57c62
|
||||
certbot-nginx==0.38.0 \
|
||||
--hash=sha256:af82944e171d2e93c81438b185f8051e742c6f47f7382cb1a647b1c7ca2b53f2 \
|
||||
--hash=sha256:cecd1fa3de6e19980fdb9c3b3269b15b7da71b5748ee7ae5caddcc18dbb208ac
|
||||
|
||||
UNLIKELY_EOF
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQEzBAABCAAdFiEEos+1H6J1pyhiNOeyTRfJlc2XdfIFAl1Mt7UACgkQTRfJlc2X
|
||||
dfIALggAhyS29bqwp7L2u31uJalZbZQzK2jb86+YyxYzJ/TNAOVHghZNrF7krXAV
|
||||
GCYEV6SXNHlScAtv7eIVbMcbiaSh/+6/1K3HsPBNP/7nR2sTZ/AOSQNPKdgUia5E
|
||||
jypTdGYcOiQBCqyP0yDKFXIKxJFOP63tIvidfuT0rBcyusrJ/QPJs6uhKLggOiFv
|
||||
9kNgZQsOhE3LpA9Yaqf0lsbKhA154c2Q662JiGCzQ2AST36bdzNEwsUeVoTbJda3
|
||||
o3qN5kg+mWZNrc9qgYjDA3gXxepNGxjXmFasJc1k1uVx9gxYhEO+/WC1UKMQJR1O
|
||||
Y/7Qrv3sR3KJ/Q/guhEB4jTKOnvXvw==
|
||||
=+61j
|
||||
iQEzBAABCAAdFiEEos+1H6J1pyhiNOeyTRfJlc2XdfIFAl1uw5wACgkQTRfJlc2X
|
||||
dfLRQggAium36If8RkfNxvNnKCpBteWx+wbPHhldn5gadRofFTyKXPaYpgtQ5e0P
|
||||
2BIOZTwpXLBR3uAS3Rxfw4ZdoMYyuhD0Cz6SjBFHYA8ChjtCBKdeToA4e2QEV9Vi
|
||||
42hBcacL7k3HhWQh+LZfu4D6pfr0ZZbZmkPWBjliEyN+g5Alfms3vzZ2aywcqoSv
|
||||
iXWVwBfTk3NzVktsJVDIq2uZ1CItmYr3SyF/KRDNXTt/TL7689UF7xD7vm0RmlCZ
|
||||
e6A5Si1q7RdS+OvPjyD4oKnJgJowWpFqIajOpgLVS4Z2pY3dEhe7eY7KVK5tDKhq
|
||||
fTC7Elp3OKjzTXv98cEMhG6Oo67jKw==
|
||||
=bbfh
|
||||
-----END PGP SIGNATURE-----
|
||||
|
||||
@@ -31,7 +31,7 @@ if [ -z "$VENV_PATH" ]; then
|
||||
fi
|
||||
VENV_BIN="$VENV_PATH/bin"
|
||||
BOOTSTRAP_VERSION_PATH="$VENV_PATH/certbot-auto-bootstrap-version.txt"
|
||||
LE_AUTO_VERSION="0.38.0.dev0"
|
||||
LE_AUTO_VERSION="0.39.0.dev0"
|
||||
BASENAME=$(basename $0)
|
||||
USAGE="Usage: $BASENAME [OPTIONS]
|
||||
A self-updating wrapper script for the Certbot ACME client. When run, updates
|
||||
@@ -1134,73 +1134,76 @@ if [ "$1" = "--le-auto-phase2" ]; then
|
||||
# To generate this, do (with docker and package hashin installed):
|
||||
# ```
|
||||
# letsencrypt-auto-source/rebuild_dependencies.py \
|
||||
# letsencrypt-auto-sources/pieces/dependency-requirements.txt
|
||||
# letsencrypt-auto-source/pieces/dependency-requirements.txt
|
||||
# ```
|
||||
# If you want to update a single dependency, run commands similar to these:
|
||||
# ```
|
||||
# pip install hashin
|
||||
# hashin -r dependency-requirements.txt cryptography==1.5.2
|
||||
# ```
|
||||
ConfigArgParse==0.14.0 \
|
||||
--hash=sha256:2e2efe2be3f90577aca9415e32cb629aa2ecd92078adbe27b53a03e53ff12e91
|
||||
asn1crypto==0.24.0 \
|
||||
--hash=sha256:2f1adbb7546ed199e3c90ef23ec95c5cf3585bac7d11fb7eb562a3fe89c64e87 \
|
||||
--hash=sha256:9d5c20441baf0cb60a4ac34cc447c6c189024b6b4c6cd7877034f4965c464e49
|
||||
certifi==2019.3.9 \
|
||||
--hash=sha256:59b7658e26ca9c7339e00f8f4636cdfe59d34fa37b9b04f6f9e9926b3cece1a5 \
|
||||
--hash=sha256:b26104d6835d1f5e49452a26eb2ff87fe7090b89dfcaee5ea2212697e1e1d7ae
|
||||
cffi==1.12.2 \
|
||||
--hash=sha256:00b97afa72c233495560a0793cdc86c2571721b4271c0667addc83c417f3d90f \
|
||||
--hash=sha256:0ba1b0c90f2124459f6966a10c03794082a2f3985cd699d7d63c4a8dae113e11 \
|
||||
--hash=sha256:0bffb69da295a4fc3349f2ec7cbe16b8ba057b0a593a92cbe8396e535244ee9d \
|
||||
--hash=sha256:21469a2b1082088d11ccd79dd84157ba42d940064abbfa59cf5f024c19cf4891 \
|
||||
--hash=sha256:2e4812f7fa984bf1ab253a40f1f4391b604f7fc424a3e21f7de542a7f8f7aedf \
|
||||
--hash=sha256:2eac2cdd07b9049dd4e68449b90d3ef1adc7c759463af5beb53a84f1db62e36c \
|
||||
--hash=sha256:2f9089979d7456c74d21303c7851f158833d48fb265876923edcb2d0194104ed \
|
||||
--hash=sha256:3dd13feff00bddb0bd2d650cdb7338f815c1789a91a6f68fdc00e5c5ed40329b \
|
||||
--hash=sha256:4065c32b52f4b142f417af6f33a5024edc1336aa845b9d5a8d86071f6fcaac5a \
|
||||
--hash=sha256:51a4ba1256e9003a3acf508e3b4f4661bebd015b8180cc31849da222426ef585 \
|
||||
--hash=sha256:59888faac06403767c0cf8cfb3f4a777b2939b1fbd9f729299b5384f097f05ea \
|
||||
--hash=sha256:59c87886640574d8b14910840327f5cd15954e26ed0bbd4e7cef95fa5aef218f \
|
||||
--hash=sha256:610fc7d6db6c56a244c2701575f6851461753c60f73f2de89c79bbf1cc807f33 \
|
||||
--hash=sha256:70aeadeecb281ea901bf4230c6222af0248c41044d6f57401a614ea59d96d145 \
|
||||
--hash=sha256:71e1296d5e66c59cd2c0f2d72dc476d42afe02aeddc833d8e05630a0551dad7a \
|
||||
--hash=sha256:8fc7a49b440ea752cfdf1d51a586fd08d395ff7a5d555dc69e84b1939f7ddee3 \
|
||||
--hash=sha256:9b5c2afd2d6e3771d516045a6cfa11a8da9a60e3d128746a7fe9ab36dfe7221f \
|
||||
--hash=sha256:9c759051ebcb244d9d55ee791259ddd158188d15adee3c152502d3b69005e6bd \
|
||||
--hash=sha256:b4d1011fec5ec12aa7cc10c05a2f2f12dfa0adfe958e56ae38dc140614035804 \
|
||||
--hash=sha256:b4f1d6332339ecc61275bebd1f7b674098a66fea11a00c84d1c58851e618dc0d \
|
||||
--hash=sha256:c030cda3dc8e62b814831faa4eb93dd9a46498af8cd1d5c178c2de856972fd92 \
|
||||
--hash=sha256:c2e1f2012e56d61390c0e668c20c4fb0ae667c44d6f6a2eeea5d7148dcd3df9f \
|
||||
--hash=sha256:c37c77d6562074452120fc6c02ad86ec928f5710fbc435a181d69334b4de1d84 \
|
||||
--hash=sha256:c8149780c60f8fd02752d0429246088c6c04e234b895c4a42e1ea9b4de8d27fb \
|
||||
--hash=sha256:cbeeef1dc3c4299bd746b774f019de9e4672f7cc666c777cd5b409f0b746dac7 \
|
||||
--hash=sha256:e113878a446c6228669144ae8a56e268c91b7f1fafae927adc4879d9849e0ea7 \
|
||||
--hash=sha256:e21162bf941b85c0cda08224dade5def9360f53b09f9f259adb85fc7dd0e7b35 \
|
||||
--hash=sha256:fb6934ef4744becbda3143d30c6604718871495a5e36c408431bf33d9c146889
|
||||
certifi==2019.6.16 \
|
||||
--hash=sha256:046832c04d4e752f37383b628bc601a7ea7211496b4638f6514d0e5b9acc4939 \
|
||||
--hash=sha256:945e3ba63a0b9f577b1395204e13c3a231f9bc0223888be653286534e5873695
|
||||
cffi==1.12.3 \
|
||||
--hash=sha256:041c81822e9f84b1d9c401182e174996f0bae9991f33725d059b771744290774 \
|
||||
--hash=sha256:046ef9a22f5d3eed06334d01b1e836977eeef500d9b78e9ef693f9380ad0b83d \
|
||||
--hash=sha256:066bc4c7895c91812eff46f4b1c285220947d4aa46fa0a2651ff85f2afae9c90 \
|
||||
--hash=sha256:066c7ff148ae33040c01058662d6752fd73fbc8e64787229ea8498c7d7f4041b \
|
||||
--hash=sha256:2444d0c61f03dcd26dbf7600cf64354376ee579acad77aef459e34efcb438c63 \
|
||||
--hash=sha256:300832850b8f7967e278870c5d51e3819b9aad8f0a2c8dbe39ab11f119237f45 \
|
||||
--hash=sha256:34c77afe85b6b9e967bd8154e3855e847b70ca42043db6ad17f26899a3df1b25 \
|
||||
--hash=sha256:46de5fa00f7ac09f020729148ff632819649b3e05a007d286242c4882f7b1dc3 \
|
||||
--hash=sha256:4aa8ee7ba27c472d429b980c51e714a24f47ca296d53f4d7868075b175866f4b \
|
||||
--hash=sha256:4d0004eb4351e35ed950c14c11e734182591465a33e960a4ab5e8d4f04d72647 \
|
||||
--hash=sha256:4e3d3f31a1e202b0f5a35ba3bc4eb41e2fc2b11c1eff38b362de710bcffb5016 \
|
||||
--hash=sha256:50bec6d35e6b1aaeb17f7c4e2b9374ebf95a8975d57863546fa83e8d31bdb8c4 \
|
||||
--hash=sha256:55cad9a6df1e2a1d62063f79d0881a414a906a6962bc160ac968cc03ed3efcfb \
|
||||
--hash=sha256:5662ad4e4e84f1eaa8efce5da695c5d2e229c563f9d5ce5b0113f71321bcf753 \
|
||||
--hash=sha256:59b4dc008f98fc6ee2bb4fd7fc786a8d70000d058c2bbe2698275bc53a8d3fa7 \
|
||||
--hash=sha256:73e1ffefe05e4ccd7bcea61af76f36077b914f92b76f95ccf00b0c1b9186f3f9 \
|
||||
--hash=sha256:a1f0fd46eba2d71ce1589f7e50a9e2ffaeb739fb2c11e8192aa2b45d5f6cc41f \
|
||||
--hash=sha256:a2e85dc204556657661051ff4bab75a84e968669765c8a2cd425918699c3d0e8 \
|
||||
--hash=sha256:a5457d47dfff24882a21492e5815f891c0ca35fefae8aa742c6c263dac16ef1f \
|
||||
--hash=sha256:a8dccd61d52a8dae4a825cdbb7735da530179fea472903eb871a5513b5abbfdc \
|
||||
--hash=sha256:ae61af521ed676cf16ae94f30fe202781a38d7178b6b4ab622e4eec8cefaff42 \
|
||||
--hash=sha256:b012a5edb48288f77a63dba0840c92d0504aa215612da4541b7b42d849bc83a3 \
|
||||
--hash=sha256:d2c5cfa536227f57f97c92ac30c8109688ace8fa4ac086d19d0af47d134e2909 \
|
||||
--hash=sha256:d42b5796e20aacc9d15e66befb7a345454eef794fdb0737d1af593447c6c8f45 \
|
||||
--hash=sha256:dee54f5d30d775f525894d67b1495625dd9322945e7fee00731952e0368ff42d \
|
||||
--hash=sha256:e070535507bd6aa07124258171be2ee8dfc19119c28ca94c9dfb7efd23564512 \
|
||||
--hash=sha256:e1ff2748c84d97b065cc95429814cdba39bcbd77c9c85c89344b317dc0d9cbff \
|
||||
--hash=sha256:ed851c75d1e0e043cbf5ca9a8e1b13c4c90f3fbd863dacb01c0808e2b5204201
|
||||
chardet==3.0.4 \
|
||||
--hash=sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae \
|
||||
--hash=sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691
|
||||
configobj==5.0.6 \
|
||||
--hash=sha256:a2f5650770e1c87fb335af19a9b7eb73fc05ccf22144eb68db7d00cd2bcb0902
|
||||
cryptography==2.6.1 \
|
||||
--hash=sha256:066f815f1fe46020877c5983a7e747ae140f517f1b09030ec098503575265ce1 \
|
||||
--hash=sha256:210210d9df0afba9e000636e97810117dc55b7157c903a55716bb73e3ae07705 \
|
||||
--hash=sha256:26c821cbeb683facb966045e2064303029d572a87ee69ca5a1bf54bf55f93ca6 \
|
||||
--hash=sha256:2afb83308dc5c5255149ff7d3fb9964f7c9ee3d59b603ec18ccf5b0a8852e2b1 \
|
||||
--hash=sha256:2db34e5c45988f36f7a08a7ab2b69638994a8923853dec2d4af121f689c66dc8 \
|
||||
--hash=sha256:409c4653e0f719fa78febcb71ac417076ae5e20160aec7270c91d009837b9151 \
|
||||
--hash=sha256:45a4f4cf4f4e6a55c8128f8b76b4c057027b27d4c67e3fe157fa02f27e37830d \
|
||||
--hash=sha256:48eab46ef38faf1031e58dfcc9c3e71756a1108f4c9c966150b605d4a1a7f659 \
|
||||
--hash=sha256:6b9e0ae298ab20d371fc26e2129fd683cfc0cfde4d157c6341722de645146537 \
|
||||
--hash=sha256:6c4778afe50f413707f604828c1ad1ff81fadf6c110cb669579dea7e2e98a75e \
|
||||
--hash=sha256:8c33fb99025d353c9520141f8bc989c2134a1f76bac6369cea060812f5b5c2bb \
|
||||
--hash=sha256:9873a1760a274b620a135054b756f9f218fa61ca030e42df31b409f0fb738b6c \
|
||||
--hash=sha256:9b069768c627f3f5623b1cbd3248c5e7e92aec62f4c98827059eed7053138cc9 \
|
||||
--hash=sha256:9e4ce27a507e4886efbd3c32d120db5089b906979a4debf1d5939ec01b9dd6c5 \
|
||||
--hash=sha256:acb424eaca214cb08735f1a744eceb97d014de6530c1ea23beb86d9c6f13c2ad \
|
||||
--hash=sha256:c8181c7d77388fe26ab8418bb088b1a1ef5fde058c6926790c8a0a3d94075a4a \
|
||||
--hash=sha256:d4afbb0840f489b60f5a580a41a1b9c3622e08ecb5eec8614d4fb4cd914c4460 \
|
||||
--hash=sha256:d9ed28030797c00f4bc43c86bf819266c76a5ea61d006cd4078a93ebf7da6bfd \
|
||||
--hash=sha256:e603aa7bb52e4e8ed4119a58a03b60323918467ef209e6ff9db3ac382e5cf2c6
|
||||
# Package enum34 needs to be explicitly limited to Python2.x, in order to avoid
|
||||
# certbot-auto failures on Python 3.6+ which enum34 doesn't support. See #5456.
|
||||
enum34==1.1.6 ; python_version < '3.4' \
|
||||
cryptography==2.7 \
|
||||
--hash=sha256:24b61e5fcb506424d3ec4e18bca995833839bf13c59fc43e530e488f28d46b8c \
|
||||
--hash=sha256:25dd1581a183e9e7a806fe0543f485103232f940fcfc301db65e630512cce643 \
|
||||
--hash=sha256:3452bba7c21c69f2df772762be0066c7ed5dc65df494a1d53a58b683a83e1216 \
|
||||
--hash=sha256:41a0be220dd1ed9e998f5891948306eb8c812b512dc398e5a01846d855050799 \
|
||||
--hash=sha256:5751d8a11b956fbfa314f6553d186b94aa70fdb03d8a4d4f1c82dcacf0cbe28a \
|
||||
--hash=sha256:5f61c7d749048fa6e3322258b4263463bfccefecb0dd731b6561cb617a1d9bb9 \
|
||||
--hash=sha256:72e24c521fa2106f19623a3851e9f89ddfdeb9ac63871c7643790f872a305dfc \
|
||||
--hash=sha256:7b97ae6ef5cba2e3bb14256625423413d5ce8d1abb91d4f29b6d1a081da765f8 \
|
||||
--hash=sha256:961e886d8a3590fd2c723cf07be14e2a91cf53c25f02435c04d39e90780e3b53 \
|
||||
--hash=sha256:96d8473848e984184b6728e2c9d391482008646276c3ff084a1bd89e15ff53a1 \
|
||||
--hash=sha256:ae536da50c7ad1e002c3eee101871d93abdc90d9c5f651818450a0d3af718609 \
|
||||
--hash=sha256:b0db0cecf396033abb4a93c95d1602f268b3a68bb0a9cc06a7cff587bb9a7292 \
|
||||
--hash=sha256:cfee9164954c186b191b91d4193989ca994703b2fff406f71cf454a2d3c7327e \
|
||||
--hash=sha256:e6347742ac8f35ded4a46ff835c60e68c22a536a8ae5c4422966d06946b6d4c6 \
|
||||
--hash=sha256:f27d93f0139a3c056172ebb5d4f9056e770fdf0206c2f422ff2ebbad142e09ed \
|
||||
--hash=sha256:f57b76e46a58b63d1c6375017f4564a28f19a5ca912691fd2e4261b3414b618d
|
||||
distro==1.4.0 \
|
||||
--hash=sha256:362dde65d846d23baee4b5c058c8586f219b5a54be1cf5fc6ff55c4578392f57 \
|
||||
--hash=sha256:eedf82a470ebe7d010f1872c17237c79ab04097948800029994fa458e52fb4b4
|
||||
enum34==1.1.6 \
|
||||
--hash=sha256:2d81cbbe0e73112bdfe6ef8576f2238f2ba27dd0d55752a776c41d38b7da2850 \
|
||||
--hash=sha256:644837f692e5f550741432dd3f223bbb9852018674981b1664e5dc339387588a \
|
||||
--hash=sha256:6bd0f6ad48ec2aa117d3d141940d484deccda84d4fcd884f5c3d93c23ecd8c79 \
|
||||
@@ -1216,18 +1219,18 @@ idna==2.8 \
|
||||
ipaddress==1.0.22 \
|
||||
--hash=sha256:64b28eec5e78e7510698f6d4da08800a5c575caa4a286c93d651c5d3ff7b6794 \
|
||||
--hash=sha256:b146c751ea45cad6188dd6cf2d9b757f6f4f8d6ffb96a023e6f2e26eea02a72c
|
||||
josepy==1.1.0 \
|
||||
--hash=sha256:1309a25aac3caeff5239729c58ff9b583f7d022ffdb1553406ddfc8e5b52b76e \
|
||||
--hash=sha256:fb5c62c77d26e04df29cb5ecd01b9ce69b6fcc9e521eb1ca193b7faa2afa7086
|
||||
josepy==1.2.0 \
|
||||
--hash=sha256:8ea15573203f28653c00f4ac0142520777b1c59d9eddd8da3f256c6ba3cac916 \
|
||||
--hash=sha256:9cec9a839fe9520f0420e4f38e7219525daccce4813296627436fe444cd002d3
|
||||
mock==1.3.0 \
|
||||
--hash=sha256:1e247dbecc6ce057299eb7ee019ad68314bb93152e81d9a6110d35f4d5eca0f6 \
|
||||
--hash=sha256:3f573a18be94de886d1191f27c168427ef693e8dcfcecf95b170577b2eb69cbb
|
||||
parsedatetime==2.4 \
|
||||
--hash=sha256:3d817c58fb9570d1eec1dd46fa9448cd644eeed4fb612684b02dfda3a79cb84b \
|
||||
--hash=sha256:9ee3529454bf35c40a77115f5a596771e59e1aee8c53306f346c461b8e913094
|
||||
pbr==5.1.3 \
|
||||
--hash=sha256:8257baf496c8522437e8a6cfe0f15e00aedc6c0e0e7c9d55eeeeab31e0853843 \
|
||||
--hash=sha256:8c361cc353d988e4f5b998555c88098b9d5964c2e11acf7b0d21925a66bb5824
|
||||
pbr==5.4.2 \
|
||||
--hash=sha256:56e52299170b9492513c64be44736d27a512fa7e606f21942160b68ce510b4bc \
|
||||
--hash=sha256:9b321c204a88d8ab5082699469f52cc94c5da45c51f114113d01b3d993c24cdf
|
||||
pyOpenSSL==19.0.0 \
|
||||
--hash=sha256:aeca66338f6de19d1aa46ed634c3b9ae519a64b458f8468aec688e7e3c20f200 \
|
||||
--hash=sha256:c727930ad54b10fc157015014b666f2d8b41f70c0d03e83ab67624fd3dd5d1e6
|
||||
@@ -1236,14 +1239,14 @@ pyRFC3339==1.1 \
|
||||
--hash=sha256:81b8cbe1519cdb79bed04910dd6fa4e181faf8c88dff1e1b987b5f7ab23a5b1a
|
||||
pycparser==2.19 \
|
||||
--hash=sha256:a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3
|
||||
pyparsing==2.3.1 \
|
||||
--hash=sha256:66c9268862641abcac4a96ba74506e594c884e3f57690a696d21ad8210ed667a \
|
||||
--hash=sha256:f6c5ef0d7480ad048c054c37632c67fca55299990fff127850181659eea33fc3
|
||||
pyparsing==2.4.2 \
|
||||
--hash=sha256:6f98a7b9397e206d78cc01df10131398f1c8b8510a2f4d97d9abd82e1aacdd80 \
|
||||
--hash=sha256:d9338df12903bbf5d65a0e4e87c2161968b10d2e489652bb47001d82a9b028b4
|
||||
python-augeas==0.5.0 \
|
||||
--hash=sha256:67d59d66cdba8d624e0389b87b2a83a176f21f16a87553b50f5703b23f29bac2
|
||||
pytz==2018.9 \
|
||||
--hash=sha256:32b0891edff07e28efe91284ed9c31e123d84bea3fd98e1f72be2508f43ef8d9 \
|
||||
--hash=sha256:d5f05e487007e29e03409f9398d074e158d920d36eb82eaf66fb1136b0c5374c
|
||||
pytz==2019.2 \
|
||||
--hash=sha256:26c0b32e437e54a18161324a2fca3c4b9846b74a8dccddd843113109e1116b32 \
|
||||
--hash=sha256:c894d57500a4cd2d5c71114aaab77dbab5eabd9022308ce5ac9bb93a60a6f0c7
|
||||
requests==2.21.0 \
|
||||
--hash=sha256:502a824f31acdacb3a35b6690b5fbf0bc41d63a24a45c4004352b0242707598e \
|
||||
--hash=sha256:7bf2a778576d825600030a110f3c0e3e8edc51dfaafe1c146e39a2027784957b
|
||||
@@ -1253,15 +1256,15 @@ requests-toolbelt==0.9.1 \
|
||||
six==1.12.0 \
|
||||
--hash=sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c \
|
||||
--hash=sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73
|
||||
urllib3==1.24.2 \
|
||||
--hash=sha256:4c291ca23bbb55c76518905869ef34bdd5f0e46af7afe6861e8375643ffee1a0 \
|
||||
--hash=sha256:9a247273df709c4fedb38c711e44292304f73f39ab01beda9f6b9fc375669ac3
|
||||
urllib3==1.24.3 \
|
||||
--hash=sha256:2393a695cd12afedd0dcb26fe5d50d0cf248e5a66f75dbd89a3d4eb333a61af4 \
|
||||
--hash=sha256:a637e5fae88995b256e3409dc4d52c2e2e0ba32c42a6365fee8bbd2238de3cfb
|
||||
zope.component==4.5 \
|
||||
--hash=sha256:6edfd626c3b593b72895a8cfcf79bff41f4619194ce996a85bce31ac02b94e55 \
|
||||
--hash=sha256:984a06ba3def0b02b1117fa4c45b56e772e8c29c0340820fbf367e440a93a3a4
|
||||
zope.deferredimport==4.3 \
|
||||
--hash=sha256:2ddef5a7ecfff132a2dd796253366ecf9748a446e30f1a0b3a636aec9d9c05c5 \
|
||||
--hash=sha256:4aae9cbacb2146cca58e62be0a914f0cec034d3b2d41135ea212ca8a96f4b5ec
|
||||
zope.deferredimport==4.3.1 \
|
||||
--hash=sha256:57b2345e7b5eef47efcd4f634ff16c93e4265de3dcf325afc7315ade48d909e1 \
|
||||
--hash=sha256:9a0c211df44aa95f1c4e6d2626f90b400f56989180d3ef96032d708da3d23e0a
|
||||
zope.deprecation==4.4.0 \
|
||||
--hash=sha256:0d453338f04bacf91bbfba545d8bcdf529aa829e67b705eac8c1a7fdce66e2df \
|
||||
--hash=sha256:f1480b74995958b24ce37b0ef04d3663d2683e5d6debc96726eff18acf4ea113
|
||||
@@ -1309,18 +1312,18 @@ zope.interface==4.6.0 \
|
||||
--hash=sha256:d788a3999014ddf416f2dc454efa4a5dbeda657c6aba031cf363741273804c6b \
|
||||
--hash=sha256:eed88ae03e1ef3a75a0e96a55a99d7937ed03e53d0cffc2451c208db445a2966 \
|
||||
--hash=sha256:f99451f3a579e73b5dd58b1b08d1179791d49084371d9a47baad3b22417f0317
|
||||
zope.proxy==4.3.1 \
|
||||
--hash=sha256:0cbcfcafaa3b5fde7ba7a7b9a2b5f09af25c9b90087ad65f9e61359fed0ca63b \
|
||||
--hash=sha256:3de631dd5054a3a20b9ebff0e375f39c0565f1fb9131200d589a6a8f379214cd \
|
||||
--hash=sha256:5429134d04d42262f4dac25f6dea907f6334e9a751ffc62cb1d40226fb52bdeb \
|
||||
--hash=sha256:563c2454b2d0f23bca54d2e0e4d781149b7b06cb5df67e253ca3620f37202dd2 \
|
||||
--hash=sha256:5bcf773345016b1461bb07f70c635b9386e5eaaa08e37d3939dcdf12d3fdbec5 \
|
||||
--hash=sha256:8d84b7aef38c693874e2f2084514522bf73fd720fde0ce2a9352a51315ffa475 \
|
||||
--hash=sha256:90de9473c05819b36816b6cb957097f809691836ed3142648bf62da84b4502fe \
|
||||
--hash=sha256:dd592a69fe872445542a6e1acbefb8e28cbe6b4007b8f5146da917e49b155cc3 \
|
||||
--hash=sha256:e7399ab865399fce322f9cefc6f2f3e4099d087ba581888a9fea1bbe1db42a08 \
|
||||
--hash=sha256:e7d1c280d86d72735a420610df592aac72332194e531a8beff43a592c3a1b8eb \
|
||||
--hash=sha256:e90243fee902adb0c39eceb3c69995c0f2004bc3fdb482fbf629efc656d124ed
|
||||
zope.proxy==4.3.2 \
|
||||
--hash=sha256:320a7619992e42142549ebf61e14ce27683b4d14b0cbc45f7c037ba64edb560c \
|
||||
--hash=sha256:824d4dbabbb7deb84f25fdb96ea1eeca436a1802c3c8d323b3eb4ac9d527d41c \
|
||||
--hash=sha256:8a32eb9c94908f3544da2dae3f4a9e6961d78819b88ac6b6f4a51cee2d65f4a0 \
|
||||
--hash=sha256:96265fd3bc3ea646f98482e16307a69de21402eeaaaaf4b841c1161ac2f71bb0 \
|
||||
--hash=sha256:ab6d6975d9c51c13cac828ff03168de21fb562b0664c59bcdc4a4b10f39a5b17 \
|
||||
--hash=sha256:af10cb772391772463f65a58348e2de5ecc06693c16d2078be276dc068bcbb54 \
|
||||
--hash=sha256:b8fd3a3de3f7b6452775e92af22af5977b17b69ac86a38a3ddfe870e40a0d05f \
|
||||
--hash=sha256:bb7088f1bed3b8214284a5e425dc23da56f2f28e8815b7580bfed9e245b6c0b6 \
|
||||
--hash=sha256:bc29b3665eac34f14c4aef5224bef045efcfb1a7d12d78c8685858de5fbf21c0 \
|
||||
--hash=sha256:c39fa6a159affeae5fe31b49d9f5b12bd674fe77271a9a324408b271440c50a7 \
|
||||
--hash=sha256:e946a036ac5b9f897e986ac9dc950a34cffc857d88eae6727b8434fbc4752366
|
||||
|
||||
# Contains the requirements for the letsencrypt package.
|
||||
#
|
||||
@@ -1333,18 +1336,18 @@ letsencrypt==0.7.0 \
|
||||
--hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \
|
||||
--hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9
|
||||
|
||||
certbot==0.37.1 \
|
||||
--hash=sha256:84dbdad204327b8d8ef9ab5b040f2be1e427a9f7e087affcc9a6051ea1b03fe7 \
|
||||
--hash=sha256:aace73e63b0c11cdb4b0bd33e1780c1fbe0ce5669dc72e80c3aa9500145daf16
|
||||
acme==0.37.1 \
|
||||
--hash=sha256:83a4f6f3c5eb6a85233d5ba87714b426f2d096df58d711f8a2fc4071eb3fd3fc \
|
||||
--hash=sha256:c069a761990751f7c4bf51d2e87ae10319bf460de6629d2908c9fa6f69e97111
|
||||
certbot-apache==0.37.1 \
|
||||
--hash=sha256:3ea832408877b12b3a60d17e8b2ee3387364f8c3023ac267161c25b99087cd42 \
|
||||
--hash=sha256:e46c2644451101c0e216aa1f525a577cc903efaf871e0e4da277224a4439040c
|
||||
certbot-nginx==0.37.1 \
|
||||
--hash=sha256:1f9af389d26f06634e2eefaace3354e7679dabb4295e1d55d05a4ee7e23a64bd \
|
||||
--hash=sha256:02a7ec15bd388d0f0e94a34c86a8f8d618ec7d5ffde0c206039bb4c46b294ce4
|
||||
certbot==0.38.0 \
|
||||
--hash=sha256:618abf3ae17c2fc3cb99baa4bf000dd5e2d7875b7811f5ef1edf6ebd7a33945f \
|
||||
--hash=sha256:c27712101794e3adf54f3a3067c63be5caa507a930a79865bc654b6864121c6b
|
||||
acme==0.38.0 \
|
||||
--hash=sha256:6231571b4a94d6d621b28bef6f6d4846b3c2ebca840f9718d3212036c3bd2af8 \
|
||||
--hash=sha256:1c1e9c0826a8f72d670b0ca28b7e6392ce4781eb33222f35133705b6551885d8
|
||||
certbot-apache==0.38.0 \
|
||||
--hash=sha256:0b5a2c2bcc430470b5131941ebdfde0a13e28dec38918c1a4ebea5dd35ad38bc \
|
||||
--hash=sha256:2d335543e0ae9292303238736907ce6b321ac49eb49fe4e0b775abdc0ba57c62
|
||||
certbot-nginx==0.38.0 \
|
||||
--hash=sha256:af82944e171d2e93c81438b185f8051e742c6f47f7382cb1a647b1c7ca2b53f2 \
|
||||
--hash=sha256:cecd1fa3de6e19980fdb9c3b3269b15b7da71b5748ee7ae5caddcc18dbb208ac
|
||||
|
||||
UNLIKELY_EOF
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
Binary file not shown.
@@ -1,12 +1,12 @@
|
||||
certbot==0.37.1 \
|
||||
--hash=sha256:84dbdad204327b8d8ef9ab5b040f2be1e427a9f7e087affcc9a6051ea1b03fe7 \
|
||||
--hash=sha256:aace73e63b0c11cdb4b0bd33e1780c1fbe0ce5669dc72e80c3aa9500145daf16
|
||||
acme==0.37.1 \
|
||||
--hash=sha256:83a4f6f3c5eb6a85233d5ba87714b426f2d096df58d711f8a2fc4071eb3fd3fc \
|
||||
--hash=sha256:c069a761990751f7c4bf51d2e87ae10319bf460de6629d2908c9fa6f69e97111
|
||||
certbot-apache==0.37.1 \
|
||||
--hash=sha256:3ea832408877b12b3a60d17e8b2ee3387364f8c3023ac267161c25b99087cd42 \
|
||||
--hash=sha256:e46c2644451101c0e216aa1f525a577cc903efaf871e0e4da277224a4439040c
|
||||
certbot-nginx==0.37.1 \
|
||||
--hash=sha256:1f9af389d26f06634e2eefaace3354e7679dabb4295e1d55d05a4ee7e23a64bd \
|
||||
--hash=sha256:02a7ec15bd388d0f0e94a34c86a8f8d618ec7d5ffde0c206039bb4c46b294ce4
|
||||
certbot==0.38.0 \
|
||||
--hash=sha256:618abf3ae17c2fc3cb99baa4bf000dd5e2d7875b7811f5ef1edf6ebd7a33945f \
|
||||
--hash=sha256:c27712101794e3adf54f3a3067c63be5caa507a930a79865bc654b6864121c6b
|
||||
acme==0.38.0 \
|
||||
--hash=sha256:6231571b4a94d6d621b28bef6f6d4846b3c2ebca840f9718d3212036c3bd2af8 \
|
||||
--hash=sha256:1c1e9c0826a8f72d670b0ca28b7e6392ce4781eb33222f35133705b6551885d8
|
||||
certbot-apache==0.38.0 \
|
||||
--hash=sha256:0b5a2c2bcc430470b5131941ebdfde0a13e28dec38918c1a4ebea5dd35ad38bc \
|
||||
--hash=sha256:2d335543e0ae9292303238736907ce6b321ac49eb49fe4e0b775abdc0ba57c62
|
||||
certbot-nginx==0.38.0 \
|
||||
--hash=sha256:af82944e171d2e93c81438b185f8051e742c6f47f7382cb1a647b1c7ca2b53f2 \
|
||||
--hash=sha256:cecd1fa3de6e19980fdb9c3b3269b15b7da71b5748ee7ae5caddcc18dbb208ac
|
||||
|
||||
@@ -2,73 +2,76 @@
|
||||
# To generate this, do (with docker and package hashin installed):
|
||||
# ```
|
||||
# letsencrypt-auto-source/rebuild_dependencies.py \
|
||||
# letsencrypt-auto-sources/pieces/dependency-requirements.txt
|
||||
# letsencrypt-auto-source/pieces/dependency-requirements.txt
|
||||
# ```
|
||||
# If you want to update a single dependency, run commands similar to these:
|
||||
# ```
|
||||
# pip install hashin
|
||||
# hashin -r dependency-requirements.txt cryptography==1.5.2
|
||||
# ```
|
||||
ConfigArgParse==0.14.0 \
|
||||
--hash=sha256:2e2efe2be3f90577aca9415e32cb629aa2ecd92078adbe27b53a03e53ff12e91
|
||||
asn1crypto==0.24.0 \
|
||||
--hash=sha256:2f1adbb7546ed199e3c90ef23ec95c5cf3585bac7d11fb7eb562a3fe89c64e87 \
|
||||
--hash=sha256:9d5c20441baf0cb60a4ac34cc447c6c189024b6b4c6cd7877034f4965c464e49
|
||||
certifi==2019.3.9 \
|
||||
--hash=sha256:59b7658e26ca9c7339e00f8f4636cdfe59d34fa37b9b04f6f9e9926b3cece1a5 \
|
||||
--hash=sha256:b26104d6835d1f5e49452a26eb2ff87fe7090b89dfcaee5ea2212697e1e1d7ae
|
||||
cffi==1.12.2 \
|
||||
--hash=sha256:00b97afa72c233495560a0793cdc86c2571721b4271c0667addc83c417f3d90f \
|
||||
--hash=sha256:0ba1b0c90f2124459f6966a10c03794082a2f3985cd699d7d63c4a8dae113e11 \
|
||||
--hash=sha256:0bffb69da295a4fc3349f2ec7cbe16b8ba057b0a593a92cbe8396e535244ee9d \
|
||||
--hash=sha256:21469a2b1082088d11ccd79dd84157ba42d940064abbfa59cf5f024c19cf4891 \
|
||||
--hash=sha256:2e4812f7fa984bf1ab253a40f1f4391b604f7fc424a3e21f7de542a7f8f7aedf \
|
||||
--hash=sha256:2eac2cdd07b9049dd4e68449b90d3ef1adc7c759463af5beb53a84f1db62e36c \
|
||||
--hash=sha256:2f9089979d7456c74d21303c7851f158833d48fb265876923edcb2d0194104ed \
|
||||
--hash=sha256:3dd13feff00bddb0bd2d650cdb7338f815c1789a91a6f68fdc00e5c5ed40329b \
|
||||
--hash=sha256:4065c32b52f4b142f417af6f33a5024edc1336aa845b9d5a8d86071f6fcaac5a \
|
||||
--hash=sha256:51a4ba1256e9003a3acf508e3b4f4661bebd015b8180cc31849da222426ef585 \
|
||||
--hash=sha256:59888faac06403767c0cf8cfb3f4a777b2939b1fbd9f729299b5384f097f05ea \
|
||||
--hash=sha256:59c87886640574d8b14910840327f5cd15954e26ed0bbd4e7cef95fa5aef218f \
|
||||
--hash=sha256:610fc7d6db6c56a244c2701575f6851461753c60f73f2de89c79bbf1cc807f33 \
|
||||
--hash=sha256:70aeadeecb281ea901bf4230c6222af0248c41044d6f57401a614ea59d96d145 \
|
||||
--hash=sha256:71e1296d5e66c59cd2c0f2d72dc476d42afe02aeddc833d8e05630a0551dad7a \
|
||||
--hash=sha256:8fc7a49b440ea752cfdf1d51a586fd08d395ff7a5d555dc69e84b1939f7ddee3 \
|
||||
--hash=sha256:9b5c2afd2d6e3771d516045a6cfa11a8da9a60e3d128746a7fe9ab36dfe7221f \
|
||||
--hash=sha256:9c759051ebcb244d9d55ee791259ddd158188d15adee3c152502d3b69005e6bd \
|
||||
--hash=sha256:b4d1011fec5ec12aa7cc10c05a2f2f12dfa0adfe958e56ae38dc140614035804 \
|
||||
--hash=sha256:b4f1d6332339ecc61275bebd1f7b674098a66fea11a00c84d1c58851e618dc0d \
|
||||
--hash=sha256:c030cda3dc8e62b814831faa4eb93dd9a46498af8cd1d5c178c2de856972fd92 \
|
||||
--hash=sha256:c2e1f2012e56d61390c0e668c20c4fb0ae667c44d6f6a2eeea5d7148dcd3df9f \
|
||||
--hash=sha256:c37c77d6562074452120fc6c02ad86ec928f5710fbc435a181d69334b4de1d84 \
|
||||
--hash=sha256:c8149780c60f8fd02752d0429246088c6c04e234b895c4a42e1ea9b4de8d27fb \
|
||||
--hash=sha256:cbeeef1dc3c4299bd746b774f019de9e4672f7cc666c777cd5b409f0b746dac7 \
|
||||
--hash=sha256:e113878a446c6228669144ae8a56e268c91b7f1fafae927adc4879d9849e0ea7 \
|
||||
--hash=sha256:e21162bf941b85c0cda08224dade5def9360f53b09f9f259adb85fc7dd0e7b35 \
|
||||
--hash=sha256:fb6934ef4744becbda3143d30c6604718871495a5e36c408431bf33d9c146889
|
||||
certifi==2019.6.16 \
|
||||
--hash=sha256:046832c04d4e752f37383b628bc601a7ea7211496b4638f6514d0e5b9acc4939 \
|
||||
--hash=sha256:945e3ba63a0b9f577b1395204e13c3a231f9bc0223888be653286534e5873695
|
||||
cffi==1.12.3 \
|
||||
--hash=sha256:041c81822e9f84b1d9c401182e174996f0bae9991f33725d059b771744290774 \
|
||||
--hash=sha256:046ef9a22f5d3eed06334d01b1e836977eeef500d9b78e9ef693f9380ad0b83d \
|
||||
--hash=sha256:066bc4c7895c91812eff46f4b1c285220947d4aa46fa0a2651ff85f2afae9c90 \
|
||||
--hash=sha256:066c7ff148ae33040c01058662d6752fd73fbc8e64787229ea8498c7d7f4041b \
|
||||
--hash=sha256:2444d0c61f03dcd26dbf7600cf64354376ee579acad77aef459e34efcb438c63 \
|
||||
--hash=sha256:300832850b8f7967e278870c5d51e3819b9aad8f0a2c8dbe39ab11f119237f45 \
|
||||
--hash=sha256:34c77afe85b6b9e967bd8154e3855e847b70ca42043db6ad17f26899a3df1b25 \
|
||||
--hash=sha256:46de5fa00f7ac09f020729148ff632819649b3e05a007d286242c4882f7b1dc3 \
|
||||
--hash=sha256:4aa8ee7ba27c472d429b980c51e714a24f47ca296d53f4d7868075b175866f4b \
|
||||
--hash=sha256:4d0004eb4351e35ed950c14c11e734182591465a33e960a4ab5e8d4f04d72647 \
|
||||
--hash=sha256:4e3d3f31a1e202b0f5a35ba3bc4eb41e2fc2b11c1eff38b362de710bcffb5016 \
|
||||
--hash=sha256:50bec6d35e6b1aaeb17f7c4e2b9374ebf95a8975d57863546fa83e8d31bdb8c4 \
|
||||
--hash=sha256:55cad9a6df1e2a1d62063f79d0881a414a906a6962bc160ac968cc03ed3efcfb \
|
||||
--hash=sha256:5662ad4e4e84f1eaa8efce5da695c5d2e229c563f9d5ce5b0113f71321bcf753 \
|
||||
--hash=sha256:59b4dc008f98fc6ee2bb4fd7fc786a8d70000d058c2bbe2698275bc53a8d3fa7 \
|
||||
--hash=sha256:73e1ffefe05e4ccd7bcea61af76f36077b914f92b76f95ccf00b0c1b9186f3f9 \
|
||||
--hash=sha256:a1f0fd46eba2d71ce1589f7e50a9e2ffaeb739fb2c11e8192aa2b45d5f6cc41f \
|
||||
--hash=sha256:a2e85dc204556657661051ff4bab75a84e968669765c8a2cd425918699c3d0e8 \
|
||||
--hash=sha256:a5457d47dfff24882a21492e5815f891c0ca35fefae8aa742c6c263dac16ef1f \
|
||||
--hash=sha256:a8dccd61d52a8dae4a825cdbb7735da530179fea472903eb871a5513b5abbfdc \
|
||||
--hash=sha256:ae61af521ed676cf16ae94f30fe202781a38d7178b6b4ab622e4eec8cefaff42 \
|
||||
--hash=sha256:b012a5edb48288f77a63dba0840c92d0504aa215612da4541b7b42d849bc83a3 \
|
||||
--hash=sha256:d2c5cfa536227f57f97c92ac30c8109688ace8fa4ac086d19d0af47d134e2909 \
|
||||
--hash=sha256:d42b5796e20aacc9d15e66befb7a345454eef794fdb0737d1af593447c6c8f45 \
|
||||
--hash=sha256:dee54f5d30d775f525894d67b1495625dd9322945e7fee00731952e0368ff42d \
|
||||
--hash=sha256:e070535507bd6aa07124258171be2ee8dfc19119c28ca94c9dfb7efd23564512 \
|
||||
--hash=sha256:e1ff2748c84d97b065cc95429814cdba39bcbd77c9c85c89344b317dc0d9cbff \
|
||||
--hash=sha256:ed851c75d1e0e043cbf5ca9a8e1b13c4c90f3fbd863dacb01c0808e2b5204201
|
||||
chardet==3.0.4 \
|
||||
--hash=sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae \
|
||||
--hash=sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691
|
||||
configobj==5.0.6 \
|
||||
--hash=sha256:a2f5650770e1c87fb335af19a9b7eb73fc05ccf22144eb68db7d00cd2bcb0902
|
||||
cryptography==2.6.1 \
|
||||
--hash=sha256:066f815f1fe46020877c5983a7e747ae140f517f1b09030ec098503575265ce1 \
|
||||
--hash=sha256:210210d9df0afba9e000636e97810117dc55b7157c903a55716bb73e3ae07705 \
|
||||
--hash=sha256:26c821cbeb683facb966045e2064303029d572a87ee69ca5a1bf54bf55f93ca6 \
|
||||
--hash=sha256:2afb83308dc5c5255149ff7d3fb9964f7c9ee3d59b603ec18ccf5b0a8852e2b1 \
|
||||
--hash=sha256:2db34e5c45988f36f7a08a7ab2b69638994a8923853dec2d4af121f689c66dc8 \
|
||||
--hash=sha256:409c4653e0f719fa78febcb71ac417076ae5e20160aec7270c91d009837b9151 \
|
||||
--hash=sha256:45a4f4cf4f4e6a55c8128f8b76b4c057027b27d4c67e3fe157fa02f27e37830d \
|
||||
--hash=sha256:48eab46ef38faf1031e58dfcc9c3e71756a1108f4c9c966150b605d4a1a7f659 \
|
||||
--hash=sha256:6b9e0ae298ab20d371fc26e2129fd683cfc0cfde4d157c6341722de645146537 \
|
||||
--hash=sha256:6c4778afe50f413707f604828c1ad1ff81fadf6c110cb669579dea7e2e98a75e \
|
||||
--hash=sha256:8c33fb99025d353c9520141f8bc989c2134a1f76bac6369cea060812f5b5c2bb \
|
||||
--hash=sha256:9873a1760a274b620a135054b756f9f218fa61ca030e42df31b409f0fb738b6c \
|
||||
--hash=sha256:9b069768c627f3f5623b1cbd3248c5e7e92aec62f4c98827059eed7053138cc9 \
|
||||
--hash=sha256:9e4ce27a507e4886efbd3c32d120db5089b906979a4debf1d5939ec01b9dd6c5 \
|
||||
--hash=sha256:acb424eaca214cb08735f1a744eceb97d014de6530c1ea23beb86d9c6f13c2ad \
|
||||
--hash=sha256:c8181c7d77388fe26ab8418bb088b1a1ef5fde058c6926790c8a0a3d94075a4a \
|
||||
--hash=sha256:d4afbb0840f489b60f5a580a41a1b9c3622e08ecb5eec8614d4fb4cd914c4460 \
|
||||
--hash=sha256:d9ed28030797c00f4bc43c86bf819266c76a5ea61d006cd4078a93ebf7da6bfd \
|
||||
--hash=sha256:e603aa7bb52e4e8ed4119a58a03b60323918467ef209e6ff9db3ac382e5cf2c6
|
||||
# Package enum34 needs to be explicitly limited to Python2.x, in order to avoid
|
||||
# certbot-auto failures on Python 3.6+ which enum34 doesn't support. See #5456.
|
||||
enum34==1.1.6 ; python_version < '3.4' \
|
||||
cryptography==2.7 \
|
||||
--hash=sha256:24b61e5fcb506424d3ec4e18bca995833839bf13c59fc43e530e488f28d46b8c \
|
||||
--hash=sha256:25dd1581a183e9e7a806fe0543f485103232f940fcfc301db65e630512cce643 \
|
||||
--hash=sha256:3452bba7c21c69f2df772762be0066c7ed5dc65df494a1d53a58b683a83e1216 \
|
||||
--hash=sha256:41a0be220dd1ed9e998f5891948306eb8c812b512dc398e5a01846d855050799 \
|
||||
--hash=sha256:5751d8a11b956fbfa314f6553d186b94aa70fdb03d8a4d4f1c82dcacf0cbe28a \
|
||||
--hash=sha256:5f61c7d749048fa6e3322258b4263463bfccefecb0dd731b6561cb617a1d9bb9 \
|
||||
--hash=sha256:72e24c521fa2106f19623a3851e9f89ddfdeb9ac63871c7643790f872a305dfc \
|
||||
--hash=sha256:7b97ae6ef5cba2e3bb14256625423413d5ce8d1abb91d4f29b6d1a081da765f8 \
|
||||
--hash=sha256:961e886d8a3590fd2c723cf07be14e2a91cf53c25f02435c04d39e90780e3b53 \
|
||||
--hash=sha256:96d8473848e984184b6728e2c9d391482008646276c3ff084a1bd89e15ff53a1 \
|
||||
--hash=sha256:ae536da50c7ad1e002c3eee101871d93abdc90d9c5f651818450a0d3af718609 \
|
||||
--hash=sha256:b0db0cecf396033abb4a93c95d1602f268b3a68bb0a9cc06a7cff587bb9a7292 \
|
||||
--hash=sha256:cfee9164954c186b191b91d4193989ca994703b2fff406f71cf454a2d3c7327e \
|
||||
--hash=sha256:e6347742ac8f35ded4a46ff835c60e68c22a536a8ae5c4422966d06946b6d4c6 \
|
||||
--hash=sha256:f27d93f0139a3c056172ebb5d4f9056e770fdf0206c2f422ff2ebbad142e09ed \
|
||||
--hash=sha256:f57b76e46a58b63d1c6375017f4564a28f19a5ca912691fd2e4261b3414b618d
|
||||
distro==1.4.0 \
|
||||
--hash=sha256:362dde65d846d23baee4b5c058c8586f219b5a54be1cf5fc6ff55c4578392f57 \
|
||||
--hash=sha256:eedf82a470ebe7d010f1872c17237c79ab04097948800029994fa458e52fb4b4
|
||||
enum34==1.1.6 \
|
||||
--hash=sha256:2d81cbbe0e73112bdfe6ef8576f2238f2ba27dd0d55752a776c41d38b7da2850 \
|
||||
--hash=sha256:644837f692e5f550741432dd3f223bbb9852018674981b1664e5dc339387588a \
|
||||
--hash=sha256:6bd0f6ad48ec2aa117d3d141940d484deccda84d4fcd884f5c3d93c23ecd8c79 \
|
||||
@@ -84,18 +87,18 @@ idna==2.8 \
|
||||
ipaddress==1.0.22 \
|
||||
--hash=sha256:64b28eec5e78e7510698f6d4da08800a5c575caa4a286c93d651c5d3ff7b6794 \
|
||||
--hash=sha256:b146c751ea45cad6188dd6cf2d9b757f6f4f8d6ffb96a023e6f2e26eea02a72c
|
||||
josepy==1.1.0 \
|
||||
--hash=sha256:1309a25aac3caeff5239729c58ff9b583f7d022ffdb1553406ddfc8e5b52b76e \
|
||||
--hash=sha256:fb5c62c77d26e04df29cb5ecd01b9ce69b6fcc9e521eb1ca193b7faa2afa7086
|
||||
josepy==1.2.0 \
|
||||
--hash=sha256:8ea15573203f28653c00f4ac0142520777b1c59d9eddd8da3f256c6ba3cac916 \
|
||||
--hash=sha256:9cec9a839fe9520f0420e4f38e7219525daccce4813296627436fe444cd002d3
|
||||
mock==1.3.0 \
|
||||
--hash=sha256:1e247dbecc6ce057299eb7ee019ad68314bb93152e81d9a6110d35f4d5eca0f6 \
|
||||
--hash=sha256:3f573a18be94de886d1191f27c168427ef693e8dcfcecf95b170577b2eb69cbb
|
||||
parsedatetime==2.4 \
|
||||
--hash=sha256:3d817c58fb9570d1eec1dd46fa9448cd644eeed4fb612684b02dfda3a79cb84b \
|
||||
--hash=sha256:9ee3529454bf35c40a77115f5a596771e59e1aee8c53306f346c461b8e913094
|
||||
pbr==5.1.3 \
|
||||
--hash=sha256:8257baf496c8522437e8a6cfe0f15e00aedc6c0e0e7c9d55eeeeab31e0853843 \
|
||||
--hash=sha256:8c361cc353d988e4f5b998555c88098b9d5964c2e11acf7b0d21925a66bb5824
|
||||
pbr==5.4.2 \
|
||||
--hash=sha256:56e52299170b9492513c64be44736d27a512fa7e606f21942160b68ce510b4bc \
|
||||
--hash=sha256:9b321c204a88d8ab5082699469f52cc94c5da45c51f114113d01b3d993c24cdf
|
||||
pyOpenSSL==19.0.0 \
|
||||
--hash=sha256:aeca66338f6de19d1aa46ed634c3b9ae519a64b458f8468aec688e7e3c20f200 \
|
||||
--hash=sha256:c727930ad54b10fc157015014b666f2d8b41f70c0d03e83ab67624fd3dd5d1e6
|
||||
@@ -104,14 +107,14 @@ pyRFC3339==1.1 \
|
||||
--hash=sha256:81b8cbe1519cdb79bed04910dd6fa4e181faf8c88dff1e1b987b5f7ab23a5b1a
|
||||
pycparser==2.19 \
|
||||
--hash=sha256:a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3
|
||||
pyparsing==2.3.1 \
|
||||
--hash=sha256:66c9268862641abcac4a96ba74506e594c884e3f57690a696d21ad8210ed667a \
|
||||
--hash=sha256:f6c5ef0d7480ad048c054c37632c67fca55299990fff127850181659eea33fc3
|
||||
pyparsing==2.4.2 \
|
||||
--hash=sha256:6f98a7b9397e206d78cc01df10131398f1c8b8510a2f4d97d9abd82e1aacdd80 \
|
||||
--hash=sha256:d9338df12903bbf5d65a0e4e87c2161968b10d2e489652bb47001d82a9b028b4
|
||||
python-augeas==0.5.0 \
|
||||
--hash=sha256:67d59d66cdba8d624e0389b87b2a83a176f21f16a87553b50f5703b23f29bac2
|
||||
pytz==2018.9 \
|
||||
--hash=sha256:32b0891edff07e28efe91284ed9c31e123d84bea3fd98e1f72be2508f43ef8d9 \
|
||||
--hash=sha256:d5f05e487007e29e03409f9398d074e158d920d36eb82eaf66fb1136b0c5374c
|
||||
pytz==2019.2 \
|
||||
--hash=sha256:26c0b32e437e54a18161324a2fca3c4b9846b74a8dccddd843113109e1116b32 \
|
||||
--hash=sha256:c894d57500a4cd2d5c71114aaab77dbab5eabd9022308ce5ac9bb93a60a6f0c7
|
||||
requests==2.21.0 \
|
||||
--hash=sha256:502a824f31acdacb3a35b6690b5fbf0bc41d63a24a45c4004352b0242707598e \
|
||||
--hash=sha256:7bf2a778576d825600030a110f3c0e3e8edc51dfaafe1c146e39a2027784957b
|
||||
@@ -121,15 +124,15 @@ requests-toolbelt==0.9.1 \
|
||||
six==1.12.0 \
|
||||
--hash=sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c \
|
||||
--hash=sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73
|
||||
urllib3==1.24.2 \
|
||||
--hash=sha256:4c291ca23bbb55c76518905869ef34bdd5f0e46af7afe6861e8375643ffee1a0 \
|
||||
--hash=sha256:9a247273df709c4fedb38c711e44292304f73f39ab01beda9f6b9fc375669ac3
|
||||
urllib3==1.24.3 \
|
||||
--hash=sha256:2393a695cd12afedd0dcb26fe5d50d0cf248e5a66f75dbd89a3d4eb333a61af4 \
|
||||
--hash=sha256:a637e5fae88995b256e3409dc4d52c2e2e0ba32c42a6365fee8bbd2238de3cfb
|
||||
zope.component==4.5 \
|
||||
--hash=sha256:6edfd626c3b593b72895a8cfcf79bff41f4619194ce996a85bce31ac02b94e55 \
|
||||
--hash=sha256:984a06ba3def0b02b1117fa4c45b56e772e8c29c0340820fbf367e440a93a3a4
|
||||
zope.deferredimport==4.3 \
|
||||
--hash=sha256:2ddef5a7ecfff132a2dd796253366ecf9748a446e30f1a0b3a636aec9d9c05c5 \
|
||||
--hash=sha256:4aae9cbacb2146cca58e62be0a914f0cec034d3b2d41135ea212ca8a96f4b5ec
|
||||
zope.deferredimport==4.3.1 \
|
||||
--hash=sha256:57b2345e7b5eef47efcd4f634ff16c93e4265de3dcf325afc7315ade48d909e1 \
|
||||
--hash=sha256:9a0c211df44aa95f1c4e6d2626f90b400f56989180d3ef96032d708da3d23e0a
|
||||
zope.deprecation==4.4.0 \
|
||||
--hash=sha256:0d453338f04bacf91bbfba545d8bcdf529aa829e67b705eac8c1a7fdce66e2df \
|
||||
--hash=sha256:f1480b74995958b24ce37b0ef04d3663d2683e5d6debc96726eff18acf4ea113
|
||||
@@ -177,15 +180,15 @@ zope.interface==4.6.0 \
|
||||
--hash=sha256:d788a3999014ddf416f2dc454efa4a5dbeda657c6aba031cf363741273804c6b \
|
||||
--hash=sha256:eed88ae03e1ef3a75a0e96a55a99d7937ed03e53d0cffc2451c208db445a2966 \
|
||||
--hash=sha256:f99451f3a579e73b5dd58b1b08d1179791d49084371d9a47baad3b22417f0317
|
||||
zope.proxy==4.3.1 \
|
||||
--hash=sha256:0cbcfcafaa3b5fde7ba7a7b9a2b5f09af25c9b90087ad65f9e61359fed0ca63b \
|
||||
--hash=sha256:3de631dd5054a3a20b9ebff0e375f39c0565f1fb9131200d589a6a8f379214cd \
|
||||
--hash=sha256:5429134d04d42262f4dac25f6dea907f6334e9a751ffc62cb1d40226fb52bdeb \
|
||||
--hash=sha256:563c2454b2d0f23bca54d2e0e4d781149b7b06cb5df67e253ca3620f37202dd2 \
|
||||
--hash=sha256:5bcf773345016b1461bb07f70c635b9386e5eaaa08e37d3939dcdf12d3fdbec5 \
|
||||
--hash=sha256:8d84b7aef38c693874e2f2084514522bf73fd720fde0ce2a9352a51315ffa475 \
|
||||
--hash=sha256:90de9473c05819b36816b6cb957097f809691836ed3142648bf62da84b4502fe \
|
||||
--hash=sha256:dd592a69fe872445542a6e1acbefb8e28cbe6b4007b8f5146da917e49b155cc3 \
|
||||
--hash=sha256:e7399ab865399fce322f9cefc6f2f3e4099d087ba581888a9fea1bbe1db42a08 \
|
||||
--hash=sha256:e7d1c280d86d72735a420610df592aac72332194e531a8beff43a592c3a1b8eb \
|
||||
--hash=sha256:e90243fee902adb0c39eceb3c69995c0f2004bc3fdb482fbf629efc656d124ed
|
||||
zope.proxy==4.3.2 \
|
||||
--hash=sha256:320a7619992e42142549ebf61e14ce27683b4d14b0cbc45f7c037ba64edb560c \
|
||||
--hash=sha256:824d4dbabbb7deb84f25fdb96ea1eeca436a1802c3c8d323b3eb4ac9d527d41c \
|
||||
--hash=sha256:8a32eb9c94908f3544da2dae3f4a9e6961d78819b88ac6b6f4a51cee2d65f4a0 \
|
||||
--hash=sha256:96265fd3bc3ea646f98482e16307a69de21402eeaaaaf4b841c1161ac2f71bb0 \
|
||||
--hash=sha256:ab6d6975d9c51c13cac828ff03168de21fb562b0664c59bcdc4a4b10f39a5b17 \
|
||||
--hash=sha256:af10cb772391772463f65a58348e2de5ecc06693c16d2078be276dc068bcbb54 \
|
||||
--hash=sha256:b8fd3a3de3f7b6452775e92af22af5977b17b69ac86a38a3ddfe870e40a0d05f \
|
||||
--hash=sha256:bb7088f1bed3b8214284a5e425dc23da56f2f28e8815b7580bfed9e245b6c0b6 \
|
||||
--hash=sha256:bc29b3665eac34f14c4aef5224bef045efcfb1a7d12d78c8685858de5fbf21c0 \
|
||||
--hash=sha256:c39fa6a159affeae5fe31b49d9f5b12bd674fe77271a9a324408b271440c50a7 \
|
||||
--hash=sha256:e946a036ac5b9f897e986ac9dc950a34cffc857d88eae6727b8434fbc4752366
|
||||
|
||||
@@ -33,7 +33,7 @@ DISTRIBUTION_LIST = [
|
||||
'fedora:29',
|
||||
]
|
||||
|
||||
# Theses constraints will be added while gathering dependencies on each distribution.
|
||||
# These constraints will be added while gathering dependencies on each distribution.
|
||||
# It can be used because a particular version for a package is required for any reason,
|
||||
# or to solve a version conflict between two distributions requirements.
|
||||
AUTHORITATIVE_CONSTRAINTS = {
|
||||
@@ -45,7 +45,10 @@ AUTHORITATIVE_CONSTRAINTS = {
|
||||
# Package enum34 needs to be explicitly limited to Python2.x, in order to avoid
|
||||
# certbot-auto failures on Python 3.6+ which enum34 doesn't support. See #5456.
|
||||
# TODO: hashin seems to overwrite environment markers in dependencies. This needs to be fixed.
|
||||
'enum34': '1.1.6 ; python_version < \'3.4\''
|
||||
'enum34': '1.1.6 ; python_version < \'3.4\'',
|
||||
# Newer versions of requests dropped support for python 3.4. Once Certbot does as well,
|
||||
# we should unpin the dependency.
|
||||
'requests': '2.21.0',
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ setup(
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Topic :: Internet :: WWW/HTTP',
|
||||
'Topic :: Security',
|
||||
'Topic :: System :: Installation/Setup',
|
||||
|
||||
10
setup.py
10
setup.py
@@ -41,6 +41,7 @@ install_requires = [
|
||||
'ConfigArgParse>=0.9.3',
|
||||
'configobj',
|
||||
'cryptography>=1.2.3', # load_pem_x509_certificate
|
||||
'distro>=1.0.1',
|
||||
# 1.1.0+ is required to avoid the warnings described at
|
||||
# https://github.com/certbot/josepy/issues/13.
|
||||
'josepy>=1.1.0',
|
||||
@@ -58,11 +59,17 @@ install_requires = [
|
||||
# However environment markers are supported only with setuptools >= 36.2.
|
||||
# So this dependency is not added for old Linux distributions with old setuptools,
|
||||
# in order to allow these systems to build certbot from sources.
|
||||
pywin32_req = 'pywin32>=224'
|
||||
if StrictVersion(setuptools_version) >= StrictVersion('36.2'):
|
||||
install_requires.append("pywin32>=224 ; sys_platform == 'win32'")
|
||||
install_requires.append(pywin32_req + " ; sys_platform == 'win32'")
|
||||
elif 'bdist_wheel' in sys.argv[1:]:
|
||||
raise RuntimeError('Error, you are trying to build certbot wheels using an old version '
|
||||
'of setuptools. Version 36.2+ of setuptools is required.')
|
||||
elif os.name == 'nt':
|
||||
# This branch exists to improve this package's behavior on Windows. Without
|
||||
# it, if the sdist is installed on Windows with an old version of
|
||||
# setuptools, pywin32 will not be specified as a dependency.
|
||||
install_requires.append(pywin32_req)
|
||||
|
||||
dev_extras = [
|
||||
'astroid==1.6.5',
|
||||
@@ -131,6 +138,7 @@ setup(
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Topic :: Internet :: WWW/HTTP',
|
||||
'Topic :: Security',
|
||||
'Topic :: System :: Installation/Setup',
|
||||
|
||||
@@ -23,18 +23,8 @@ if command -v python && [ $(python -V 2>&1 | cut -d" " -f 2 | cut -d. -f1,2 | se
|
||||
INITIAL_VERSION="0.20.0"
|
||||
RUN_RHEL6_TESTS=1
|
||||
else
|
||||
# 0.33.x is the oldest version of letsencrypt-auto that works on Fedora 29+.
|
||||
INITIAL_VERSION="0.33.1"
|
||||
fi
|
||||
|
||||
# If we're on RHEL 8, the initial version of certbot-auto will fail until we do
|
||||
# a release including https://github.com/certbot/certbot/pull/7240 and update
|
||||
# INITIAL_VERSION above to use a version containing this fix. This works around
|
||||
# the problem for now so we can successfully run tests on RHEL 8.
|
||||
RPM_DIST_NAME=`(. /etc/os-release 2> /dev/null && echo $ID) || echo "unknown"`
|
||||
RPM_DIST_VERSION=`(. /etc/os-release 2> /dev/null && echo $VERSION_ID) | cut -d '.' -f1 || echo "0"`
|
||||
if [ "$RPM_DIST_NAME" = "rhel" -a "$RPM_DIST_VERSION" -ge 8 ]; then
|
||||
sudo yum install python3-virtualenv -y
|
||||
# 0.37.x is the oldest version of letsencrypt-auto that works on RHEL 8.
|
||||
INITIAL_VERSION="0.37.1"
|
||||
fi
|
||||
|
||||
git checkout -f "v$INITIAL_VERSION" letsencrypt-auto
|
||||
|
||||
@@ -40,7 +40,7 @@ targets:
|
||||
# - [ apt-get, install, -y, curl ]
|
||||
#-----------------------------------------------------------------------------
|
||||
# Other Redhat Distros
|
||||
- ami: ami-a8d369c0
|
||||
- ami: ami-0916c408cb02e310b
|
||||
name: RHEL7
|
||||
type: centos
|
||||
virt: hvm
|
||||
|
||||
@@ -15,7 +15,7 @@ botocore==1.12.36
|
||||
cloudflare==1.5.1
|
||||
codecov==2.0.15
|
||||
configparser==3.7.4
|
||||
coverage==4.4.2
|
||||
coverage==4.5.4
|
||||
decorator==4.1.2
|
||||
dns-lexicon==3.2.1
|
||||
dnspython==1.15.0
|
||||
@@ -53,6 +53,9 @@ pyasn1==0.1.9
|
||||
pyasn1-modules==0.0.10
|
||||
Pygments==2.2.0
|
||||
pylint==1.9.4
|
||||
# If pynsist version is upgraded, our NSIS template windows-installer/template.nsi
|
||||
# must be upgraded if necessary using the new built-in one from pynsist.
|
||||
pynsist==2.4
|
||||
pytest==3.2.5
|
||||
pytest-cov==2.5.1
|
||||
pytest-forked==0.2
|
||||
@@ -76,7 +79,7 @@ Sphinx==1.7.5
|
||||
sphinx-rtd-theme==0.2.4
|
||||
sphinxcontrib-websupport==1.0.1
|
||||
tldextract==2.2.0
|
||||
tox==2.9.1
|
||||
tox==3.14.0
|
||||
tqdm==4.19.4
|
||||
traitlets==4.3.2
|
||||
twine==1.11.0
|
||||
|
||||
@@ -51,6 +51,7 @@ funcsigs==0.4
|
||||
zope.hookable==4.0.4
|
||||
|
||||
# Ubuntu Bionic constraints.
|
||||
distro==1.0.1
|
||||
# Lexicon oldest constraint is overridden appropriately on relevant DNS provider plugins
|
||||
# using their local-oldest-requirements.txt
|
||||
dns-lexicon==2.2.1
|
||||
|
||||
9
tox.ini
9
tox.ini
@@ -223,13 +223,14 @@ passenv = DOCKER_*
|
||||
|
||||
[testenv:integration]
|
||||
commands =
|
||||
{[base]pip_install} acme . certbot-nginx certbot-ci
|
||||
{[base]pip_install} acme . certbot-nginx certbot-apache certbot-ci
|
||||
pytest certbot-ci/certbot_integration_tests \
|
||||
--acme-server={env:ACME_SERVER:pebble} \
|
||||
--cov=acme --cov=certbot --cov=certbot_nginx --cov-report= \
|
||||
--cov-config=certbot-ci/certbot_integration_tests/.coveragerc
|
||||
coverage report --include 'certbot/*' --show-missing --fail-under=66
|
||||
--cov=acme --cov=certbot --cov=certbot_nginx --cov=certbot_apache \
|
||||
--cov-report= --cov-config=certbot-ci/certbot_integration_tests/.coveragerc
|
||||
coverage report --include 'certbot/*' --show-missing --fail-under=65
|
||||
coverage report --include 'certbot-nginx/*' --show-missing --fail-under=74
|
||||
coverage report --include 'certbot-apache/*' --show-missing --fail-under=55
|
||||
passenv = DOCKER_*
|
||||
|
||||
[testenv:integration-certbot]
|
||||
|
||||
2
windows-installer/.gitignore
vendored
Normal file
2
windows-installer/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
build
|
||||
build.*
|
||||
BIN
windows-installer/certbot.ico
Normal file
BIN
windows-installer/certbot.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 179 KiB |
143
windows-installer/construct.py
Normal file
143
windows-installer/construct.py
Normal file
@@ -0,0 +1,143 @@
|
||||
#!/usr/bin/env python3
|
||||
import ctypes
|
||||
import struct
|
||||
import subprocess
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
import time
|
||||
|
||||
|
||||
PYTHON_VERSION = (3, 7, 4)
|
||||
PYTHON_BITNESS = 32
|
||||
|
||||
|
||||
def main():
|
||||
build_path, repo_path, venv_path, venv_python = _prepare_environment()
|
||||
|
||||
_copy_assets(build_path, repo_path)
|
||||
|
||||
installer_cfg_path = _generate_pynsist_config(repo_path, build_path)
|
||||
|
||||
_prepare_build_tools(venv_path, venv_python, repo_path)
|
||||
_compile_wheels(repo_path, build_path, venv_python)
|
||||
_build_installer(installer_cfg_path, venv_path)
|
||||
|
||||
print('Done')
|
||||
|
||||
|
||||
def _build_installer(installer_cfg_path, venv_path):
|
||||
print('Build the installer')
|
||||
subprocess.check_call([os.path.join(venv_path, 'Scripts', 'pynsist.exe'), installer_cfg_path])
|
||||
|
||||
|
||||
def _compile_wheels(repo_path, build_path, venv_python):
|
||||
print('Compile wheels')
|
||||
|
||||
wheels_path = os.path.join(build_path, 'wheels')
|
||||
os.makedirs(wheels_path)
|
||||
|
||||
certbot_packages = ['acme', '.']
|
||||
# Uncomment following line to include all DNS plugins in the installer
|
||||
# certbot_packages.extend([name for name in os.listdir(repo_path) if name.startswith('certbot-dns-')])
|
||||
wheels_project = [os.path.join(repo_path, package) for package in certbot_packages]
|
||||
|
||||
command = [venv_python, '-m', 'pip', 'wheel', '-w', wheels_path]
|
||||
command.extend(wheels_project)
|
||||
subprocess.check_call(command)
|
||||
|
||||
|
||||
def _prepare_build_tools(venv_path, venv_python, repo_path):
|
||||
print('Prepare build tools')
|
||||
subprocess.check_call([sys.executable, '-m', 'venv', venv_path])
|
||||
subprocess.check_call(['choco', 'upgrade', '-y', 'nsis'])
|
||||
subprocess.check_call([venv_python, '-m', 'pip', 'install', '--upgrade', 'pip'])
|
||||
subprocess.check_call([venv_python, os.path.join(repo_path, 'tools', 'pip_install.py'), 'wheel', 'pynsist'])
|
||||
|
||||
|
||||
def _copy_assets(build_path, repo_path):
|
||||
print('Copy assets')
|
||||
if os.path.exists(build_path):
|
||||
os.rename(build_path, '{0}.{1}.bak'.format(build_path, int(time.time())))
|
||||
os.makedirs(build_path)
|
||||
shutil.copy(os.path.join(repo_path, 'windows-installer', 'certbot.ico'), build_path)
|
||||
shutil.copy(os.path.join(repo_path, 'windows-installer', 'run.bat'), build_path)
|
||||
shutil.copy(os.path.join(repo_path, 'windows-installer', 'template.nsi'), build_path)
|
||||
shutil.copy(os.path.join(repo_path, 'windows-installer', 'renew-up.ps1'), build_path)
|
||||
shutil.copy(os.path.join(repo_path, 'windows-installer', 'renew-down.ps1'), build_path)
|
||||
|
||||
|
||||
def _generate_pynsist_config(repo_path, build_path):
|
||||
print('Generate pynsist configuration')
|
||||
|
||||
installer_cfg_path = os.path.join(build_path, 'installer.cfg')
|
||||
|
||||
certbot_version = subprocess.check_output([sys.executable, '-c', 'import certbot; print(certbot.__version__)'],
|
||||
universal_newlines=True, cwd=repo_path).strip()
|
||||
|
||||
with open(os.path.join(installer_cfg_path), 'w') as file_h:
|
||||
file_h.write("""\
|
||||
[Application]
|
||||
name=Certbot
|
||||
version={certbot_version}
|
||||
icon=certbot.ico
|
||||
publisher=Electronic Frontier Foundation
|
||||
target=$INSTDIR\\run.bat
|
||||
|
||||
[Build]
|
||||
directory=nsis
|
||||
nsi_template=template.nsi
|
||||
installer_name=certbot-{certbot_version}-installer-{installer_suffix}.exe
|
||||
|
||||
[Python]
|
||||
version={python_version}
|
||||
bitness={python_bitness}
|
||||
|
||||
[Include]
|
||||
local_wheels=wheels\\*.whl
|
||||
files=run.bat
|
||||
renew-up.ps1
|
||||
renew-down.ps1
|
||||
|
||||
[Command certbot]
|
||||
entry_point=certbot.main:main
|
||||
""".format(certbot_version=certbot_version,
|
||||
installer_suffix='win_amd64' if PYTHON_BITNESS == 64 else 'win32',
|
||||
python_bitness=PYTHON_BITNESS,
|
||||
python_version='.'.join([str(item) for item in PYTHON_VERSION])))
|
||||
|
||||
return installer_cfg_path
|
||||
|
||||
|
||||
def _prepare_environment():
|
||||
print('Prepare environment')
|
||||
try:
|
||||
subprocess.check_output(['choco', '--version'])
|
||||
except subprocess.CalledProcessError:
|
||||
raise RuntimeError('Error: Chocolatey (https://chocolatey.org/) needs '
|
||||
'to be installed to run this script.')
|
||||
script_path = os.path.realpath(__file__)
|
||||
repo_path = os.path.dirname(os.path.dirname(script_path))
|
||||
build_path = os.path.join(repo_path, 'windows-installer', 'build')
|
||||
venv_path = os.path.join(build_path, 'venv-config')
|
||||
venv_python = os.path.join(venv_path, 'Scripts', 'python.exe')
|
||||
|
||||
return build_path, repo_path, venv_path, venv_python
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if not os.name == 'nt':
|
||||
raise RuntimeError('This script must be run under Windows.')
|
||||
|
||||
if ctypes.windll.shell32.IsUserAnAdmin() == 0:
|
||||
# Administrator privileges are required to properly install NSIS through Chocolatey
|
||||
raise RuntimeError('This script must be run with administrator privileges.')
|
||||
|
||||
if sys.version_info[:2] != PYTHON_VERSION[:2]:
|
||||
raise RuntimeError('This script must be run with Python {0}'
|
||||
.format('.'.join([str(item) for item in PYTHON_VERSION[0:2]])))
|
||||
|
||||
if struct.calcsize('P') * 8 != PYTHON_BITNESS:
|
||||
raise RuntimeError('This script must be run with a {0} bit version of Python.'
|
||||
.format(PYTHON_BITNESS))
|
||||
main()
|
||||
6
windows-installer/renew-down.ps1
Normal file
6
windows-installer/renew-down.ps1
Normal file
@@ -0,0 +1,6 @@
|
||||
$taskName = "Certbot Renew Task"
|
||||
|
||||
$exists = Get-ScheduledTask | Where-Object {$_.TaskName -like $taskName}
|
||||
if ($exists) {
|
||||
Unregister-ScheduledTask -TaskName $taskName -Confirm:$false
|
||||
}
|
||||
15
windows-installer/renew-up.ps1
Normal file
15
windows-installer/renew-up.ps1
Normal file
@@ -0,0 +1,15 @@
|
||||
function Get-ScriptDirectory { Split-Path $MyInvocation.ScriptName }
|
||||
$down = Join-Path (Get-ScriptDirectory) 'renew-down.ps1'
|
||||
& $down
|
||||
|
||||
$taskName = "Certbot Renew Task"
|
||||
|
||||
$action = New-ScheduledTaskAction -Execute 'Powershell.exe' -Argument '-NoProfile -WindowStyle Hidden -Command "certbot renew"'
|
||||
$delay = New-TimeSpan -Hours 12
|
||||
$triggerAM = New-ScheduledTaskTrigger -Daily -At 12am -RandomDelay $delay
|
||||
$triggerPM = New-ScheduledTaskTrigger -Daily -At 12pm -RandomDelay $delay
|
||||
# NB: For now scheduled task is set up under SYSTEM account because Certbot Installer installs Certbot for all users.
|
||||
# If in the future we allow the Installer to install Certbot for one specific user, the scheduled task will need to
|
||||
# switch to this user, since Certbot will be available only for him.
|
||||
$principal = New-ScheduledTaskPrincipal -UserId SYSTEM -LogonType ServiceAccount -RunLevel Highest
|
||||
Register-ScheduledTask -Action $action -Trigger $triggerAM,$triggerPM -TaskName $taskName -Description "Execute twice a day the 'certbot renew' command, to renew managed certificates if needed." -Principal $principal
|
||||
31
windows-installer/run.bat
Normal file
31
windows-installer/run.bat
Normal file
@@ -0,0 +1,31 @@
|
||||
@echo off
|
||||
|
||||
:: BatchGotAdmin
|
||||
:-------------------------------------
|
||||
REM --> Check for permissions
|
||||
IF "%PROCESSOR_ARCHITECTURE%" EQU "amd64" (
|
||||
>nul 2>&1 "%SYSTEMROOT%\SysWOW64\cacls.exe" "%SYSTEMROOT%\SysWOW64\config\system"
|
||||
) ELSE (
|
||||
>nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system"
|
||||
)
|
||||
|
||||
REM --> If error flag set, we do not have admin.
|
||||
if '%errorlevel%' NEQ '0' (
|
||||
echo Requesting administrative privileges...
|
||||
goto UACPrompt
|
||||
) else ( goto gotAdmin )
|
||||
|
||||
:UACPrompt
|
||||
echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs"
|
||||
set params= %*
|
||||
echo UAC.ShellExecute "cmd.exe", "/c ""%~s0"" %params:"=""%", "", "runas", 1 >> "%temp%\getadmin.vbs"
|
||||
|
||||
"%temp%\getadmin.vbs"
|
||||
del "%temp%\getadmin.vbs"
|
||||
exit /B
|
||||
|
||||
:gotAdmin
|
||||
pushd "%CD%"
|
||||
CD /D "%~dp0"
|
||||
:--------------------------------------
|
||||
cmd.exe /k echo You can run 'certbot' commands here. Type 'certbot --help' for more information.
|
||||
257
windows-installer/template.nsi
Normal file
257
windows-installer/template.nsi
Normal file
@@ -0,0 +1,257 @@
|
||||
; This NSIS template is based on the built-in one in pynsist 2.3.
|
||||
; Added lines are enclosed within "CERTBOT CUSTOM BEGIN/END" comments.
|
||||
; If pynsist is upgraded, this template must be updated if necessary using the new built-in one.
|
||||
; Original file can be found here: https://github.com/takluyver/pynsist/blob/2.4/nsist/pyapp.nsi
|
||||
|
||||
!define PRODUCT_NAME "[[ib.appname]]"
|
||||
!define PRODUCT_VERSION "[[ib.version]]"
|
||||
!define PY_VERSION "[[ib.py_version]]"
|
||||
!define PY_MAJOR_VERSION "[[ib.py_major_version]]"
|
||||
!define BITNESS "[[ib.py_bitness]]"
|
||||
!define ARCH_TAG "[[arch_tag]]"
|
||||
!define INSTALLER_NAME "[[ib.installer_name]]"
|
||||
!define PRODUCT_ICON "[[icon]]"
|
||||
|
||||
; Marker file to tell the uninstaller that it's a user installation
|
||||
!define USER_INSTALL_MARKER _user_install_marker
|
||||
|
||||
SetCompressor lzma
|
||||
|
||||
; CERTBOT CUSTOM BEGIN
|
||||
; Administrator privileges are required to insert a new task in Windows Scheduler.
|
||||
; Also comment out some options to disable ability to choose AllUsers/CurrentUser install mode.
|
||||
; As a result, installer run always with admin privileges (because of MULTIUSER_EXECUTIONLEVEL),
|
||||
; using the AllUsers installation mode by default (because of MULTIUSER_INSTALLMODE_DEFAULT_CURRENTUSER
|
||||
; not set), and this default behavior cannot be overridden (because of MULTIUSER_MUI not set).
|
||||
; See https://nsis.sourceforge.io/Docs/MultiUser/Readme.html
|
||||
!define MULTIUSER_EXECUTIONLEVEL Admin
|
||||
;!define MULTIUSER_EXECUTIONLEVEL Highest
|
||||
;!define MULTIUSER_INSTALLMODE_DEFAULT_CURRENTUSER
|
||||
;!define MULTIUSER_MUI
|
||||
;!define MULTIUSER_INSTALLMODE_COMMANDLINE
|
||||
; CERTBOT CUSTOM END
|
||||
!define MULTIUSER_INSTALLMODE_INSTDIR "[[ib.appname]]"
|
||||
[% if ib.py_bitness == 64 %]
|
||||
!define MULTIUSER_INSTALLMODE_FUNCTION correct_prog_files
|
||||
[% endif %]
|
||||
!include MultiUser.nsh
|
||||
|
||||
[% block modernui %]
|
||||
; Modern UI installer stuff
|
||||
!include "MUI2.nsh"
|
||||
!define MUI_ABORTWARNING
|
||||
!define MUI_ICON "[[icon]]"
|
||||
!define MUI_UNICON "[[icon]]"
|
||||
|
||||
; UI pages
|
||||
[% block ui_pages %]
|
||||
!insertmacro MUI_PAGE_WELCOME
|
||||
[% if license_file %]
|
||||
!insertmacro MUI_PAGE_LICENSE [[license_file]]
|
||||
[% endif %]
|
||||
; CERTBOT CUSTOM BEGIN
|
||||
; Disable the installation mode page (AllUsers/CurrentUser)
|
||||
;!insertmacro MULTIUSER_PAGE_INSTALLMODE
|
||||
; CERTBOT CUSTOM END
|
||||
!insertmacro MUI_PAGE_DIRECTORY
|
||||
!insertmacro MUI_PAGE_INSTFILES
|
||||
!insertmacro MUI_PAGE_FINISH
|
||||
[% endblock ui_pages %]
|
||||
!insertmacro MUI_LANGUAGE "English"
|
||||
[% endblock modernui %]
|
||||
|
||||
Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"
|
||||
OutFile "${INSTALLER_NAME}"
|
||||
ShowInstDetails show
|
||||
|
||||
Section -SETTINGS
|
||||
SetOutPath "$INSTDIR"
|
||||
SetOverwrite ifnewer
|
||||
SectionEnd
|
||||
|
||||
[% block sections %]
|
||||
|
||||
Section "!${PRODUCT_NAME}" sec_app
|
||||
SetRegView [[ib.py_bitness]]
|
||||
SectionIn RO
|
||||
File ${PRODUCT_ICON}
|
||||
SetOutPath "$INSTDIR\pkgs"
|
||||
File /r "pkgs\*.*"
|
||||
SetOutPath "$INSTDIR"
|
||||
|
||||
; Marker file for per-user install
|
||||
StrCmp $MultiUser.InstallMode CurrentUser 0 +3
|
||||
FileOpen $0 "$INSTDIR\${USER_INSTALL_MARKER}" w
|
||||
FileClose $0
|
||||
SetFileAttributes "$INSTDIR\${USER_INSTALL_MARKER}" HIDDEN
|
||||
|
||||
[% block install_files %]
|
||||
; Install files
|
||||
[% for destination, group in grouped_files %]
|
||||
SetOutPath "[[destination]]"
|
||||
[% for file in group %]
|
||||
File "[[ file ]]"
|
||||
[% endfor %]
|
||||
[% endfor %]
|
||||
|
||||
; Install directories
|
||||
[% for dir, destination in ib.install_dirs %]
|
||||
SetOutPath "[[ pjoin(destination, dir) ]]"
|
||||
File /r "[[dir]]\*.*"
|
||||
[% endfor %]
|
||||
[% endblock install_files %]
|
||||
|
||||
[% block install_shortcuts %]
|
||||
; Install shortcuts
|
||||
; The output path becomes the working directory for shortcuts
|
||||
SetOutPath "%HOMEDRIVE%\%HOMEPATH%"
|
||||
[% if single_shortcut %]
|
||||
[% for scname, sc in ib.shortcuts.items() %]
|
||||
CreateShortCut "$SMPROGRAMS\[[scname]].lnk" "[[sc['target'] ]]" \
|
||||
'[[ sc['parameters'] ]]' "$INSTDIR\[[ sc['icon'] ]]"
|
||||
[% endfor %]
|
||||
[% else %]
|
||||
[# Multiple shortcuts: create a directory for them #]
|
||||
CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}"
|
||||
[% for scname, sc in ib.shortcuts.items() %]
|
||||
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\[[scname]].lnk" "[[sc['target'] ]]" \
|
||||
'[[ sc['parameters'] ]]' "$INSTDIR\[[ sc['icon'] ]]"
|
||||
[% endfor %]
|
||||
[% endif %]
|
||||
SetOutPath "$INSTDIR"
|
||||
[% endblock install_shortcuts %]
|
||||
|
||||
[% block install_commands %]
|
||||
[% if has_commands %]
|
||||
DetailPrint "Setting up command-line launchers..."
|
||||
nsExec::ExecToLog '[[ python ]] -Es "$INSTDIR\_assemble_launchers.py" [[ python ]] "$INSTDIR\bin"'
|
||||
|
||||
StrCmp $MultiUser.InstallMode CurrentUser 0 AddSysPathSystem
|
||||
; Add to PATH for current user
|
||||
nsExec::ExecToLog '[[ python ]] -Es "$INSTDIR\_system_path.py" add_user "$INSTDIR\bin"'
|
||||
GoTo AddedSysPath
|
||||
AddSysPathSystem:
|
||||
; Add to PATH for all users
|
||||
nsExec::ExecToLog '[[ python ]] -Es "$INSTDIR\_system_path.py" add "$INSTDIR\bin"'
|
||||
AddedSysPath:
|
||||
[% endif %]
|
||||
[% endblock install_commands %]
|
||||
|
||||
; Byte-compile Python files.
|
||||
DetailPrint "Byte-compiling Python modules..."
|
||||
nsExec::ExecToLog '[[ python ]] -m compileall -q "$INSTDIR\pkgs"'
|
||||
WriteUninstaller $INSTDIR\uninstall.exe
|
||||
; Add ourselves to Add/remove programs
|
||||
WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
|
||||
"DisplayName" "${PRODUCT_NAME}"
|
||||
WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
|
||||
"UninstallString" '"$INSTDIR\uninstall.exe"'
|
||||
WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
|
||||
"InstallLocation" "$INSTDIR"
|
||||
WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
|
||||
"DisplayIcon" "$INSTDIR\${PRODUCT_ICON}"
|
||||
[% if ib.publisher is not none %]
|
||||
WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
|
||||
"Publisher" "[[ib.publisher]]"
|
||||
[% endif %]
|
||||
WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
|
||||
"DisplayVersion" "${PRODUCT_VERSION}"
|
||||
WriteRegDWORD SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
|
||||
"NoModify" 1
|
||||
WriteRegDWORD SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
|
||||
"NoRepair" 1
|
||||
|
||||
; CERTBOT CUSTOM BEGIN
|
||||
; Execute ps script to create the certbot renew task
|
||||
DetailPrint "Setting up certbot renew scheduled task"
|
||||
nsExec::ExecToStack 'powershell -inputformat none -ExecutionPolicy RemoteSigned -File "$INSTDIR\renew-up.ps1"'
|
||||
; CERTBOT CUSTOM END
|
||||
|
||||
; Check if we need to reboot
|
||||
IfRebootFlag 0 noreboot
|
||||
MessageBox MB_YESNO "A reboot is required to finish the installation. Do you wish to reboot now?" \
|
||||
/SD IDNO IDNO noreboot
|
||||
Reboot
|
||||
noreboot:
|
||||
SectionEnd
|
||||
|
||||
Section "Uninstall"
|
||||
; CERTBOT CUSTOM BEGIN
|
||||
; Execute ps script to remove the certbot renew task
|
||||
nsExec::ExecToStack 'powershell -inputformat none -ExecutionPolicy RemoteSigned -File "$INSTDIR\renew-down.ps1"'
|
||||
; CERTBOT CUSTOM END
|
||||
|
||||
SetRegView [[ib.py_bitness]]
|
||||
SetShellVarContext all
|
||||
IfFileExists "$INSTDIR\${USER_INSTALL_MARKER}" 0 +3
|
||||
SetShellVarContext current
|
||||
Delete "$INSTDIR\${USER_INSTALL_MARKER}"
|
||||
|
||||
Delete $INSTDIR\uninstall.exe
|
||||
Delete "$INSTDIR\${PRODUCT_ICON}"
|
||||
RMDir /r "$INSTDIR\pkgs"
|
||||
|
||||
; Remove ourselves from %PATH%
|
||||
[% block uninstall_commands %]
|
||||
[% if has_commands %]
|
||||
nsExec::ExecToLog '[[ python ]] -Es "$INSTDIR\_system_path.py" remove "$INSTDIR\bin"'
|
||||
[% endif %]
|
||||
[% endblock uninstall_commands %]
|
||||
|
||||
[% block uninstall_files %]
|
||||
; Uninstall files
|
||||
[% for file, destination in ib.install_files %]
|
||||
Delete "[[pjoin(destination, file)]]"
|
||||
[% endfor %]
|
||||
; Uninstall directories
|
||||
[% for dir, destination in ib.install_dirs %]
|
||||
RMDir /r "[[pjoin(destination, dir)]]"
|
||||
[% endfor %]
|
||||
[% endblock uninstall_files %]
|
||||
|
||||
[% block uninstall_shortcuts %]
|
||||
; Uninstall shortcuts
|
||||
[% if single_shortcut %]
|
||||
[% for scname in ib.shortcuts %]
|
||||
Delete "$SMPROGRAMS\[[scname]].lnk"
|
||||
[% endfor %]
|
||||
[% else %]
|
||||
RMDir /r "$SMPROGRAMS\${PRODUCT_NAME}"
|
||||
[% endif %]
|
||||
[% endblock uninstall_shortcuts %]
|
||||
RMDir $INSTDIR
|
||||
DeleteRegKey SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
|
||||
SectionEnd
|
||||
|
||||
[% endblock sections %]
|
||||
|
||||
; Functions
|
||||
|
||||
Function .onMouseOverSection
|
||||
; Find which section the mouse is over, and set the corresponding description.
|
||||
FindWindow $R0 "#32770" "" $HWNDPARENT
|
||||
GetDlgItem $R0 $R0 1043 ; description item (must be added to the UI)
|
||||
|
||||
[% block mouseover_messages %]
|
||||
StrCmp $0 ${sec_app} "" +2
|
||||
SendMessage $R0 ${WM_SETTEXT} 0 "STR:${PRODUCT_NAME}"
|
||||
|
||||
[% endblock mouseover_messages %]
|
||||
FunctionEnd
|
||||
|
||||
Function .onInit
|
||||
!insertmacro MULTIUSER_INIT
|
||||
FunctionEnd
|
||||
|
||||
Function un.onInit
|
||||
!insertmacro MULTIUSER_UNINIT
|
||||
FunctionEnd
|
||||
|
||||
[% if ib.py_bitness == 64 %]
|
||||
Function correct_prog_files
|
||||
; The multiuser machinery doesn't know about the different Program files
|
||||
; folder for 64-bit applications. Override the install dir it set.
|
||||
StrCmp $MultiUser.InstallMode AllUsers 0 +2
|
||||
StrCpy $INSTDIR "$PROGRAMFILES64\${MULTIUSER_INSTALLMODE_INSTDIR}"
|
||||
FunctionEnd
|
||||
[% endif %]
|
||||
Reference in New Issue
Block a user