Compare commits

...

103 Commits

Author SHA1 Message Date
Brad Warren
6c72f45e5c Use certbot-common. 2019-10-08 15:20:20 -07:00
Adrien Ferrand
fcc398831b Create a new CI for Certbot on Windows using Azure Pipelines (#7377)
This PR defines pipelines that can be run on Azure Pipelines. Currently there are two:
* `.azure-pipelines/main.yml` is the main one, executed on PRs for master, and pushes to master,
* `.azure-pipelines/advanced.yml` add installer testing on top of the main pipeline, and is executed for `test-*` branches, release branches, and nightly run for master.

These two pipelines covers all existing stuff done by AppVeyor currently, and so AppVeyor can be decommissioned once Azure Pipelines is operational.

You can see working pipeline in my fork:
* a PR for `master` (so using main pipeline): https://github.com/adferrand/certbot/pull/65
* a PR for `test-something` (so using advanced pipeline): https://github.com/adferrand/certbot/pull/66
* uploaded coverage from Azure Pipelines: 499aa2cbf2/build

Once this PR is merged, we need to enable Azure Pipelines for Certbot. Instructions are written in `azure-pipelines/INSTALL.md`. This document also references all access rights required to Azure Pipelines onto GitHub to make the CI process work.

Future work for future PRs:
* create a CD pipeline for the releases that will push the installer to GitHub releases
* implement a solution to generate notification on IRC or Mattermost when a nightly build fails

* Define pipelines

* Update locations

* Update nightly

* Use x86

* Update nightly.yml for Azure Pipelines

* Run script

* Use script

* Update install

* Use local installation

* Register warnings

* Fix pywin32 loading

* Clean context

* Enable coverage publication

* Consume codecov token

* Document installation

* Update tool to upload coverage

* Prepare pipeline artifacts

* Update artifact ignore

* Protect against codecov failures

* Add a comment about codecov

* Add a comment on RW access asked by Azure

* Add instructions

* Rename pipeline file

* Update instructions

* Update .azure-pipelines/templates/tests-suite.yml

Co-Authored-By: Brad Warren <bmw@users.noreply.github.com>

* Update .azure-pipelines/INSTALL.md

Co-Authored-By: Brad Warren <bmw@users.noreply.github.com>

* Modified scheduled pipeline

* Add comment

* Remove dynamic version-based installer name
2019-10-08 14:40:17 -07:00
Andrzej Górski
9da07590bd Remove --fast from the test farm tests (#7427) 2019-10-08 21:24:55 +02:00
Brad Warren
0cfedbc5f5 Add test farm tests for Debian 10 (#7421)
Fixes #7225.

I got the AMI ID from https://wiki.debian.org/Cloud/AmazonEC2Image/Buster.

You can see all test farm tests including test_tests.sh passing with these changes at https://travis-ci.com/certbot/certbot/builds/130318446.
2019-10-03 15:08:24 -07:00
Jacob Hoffman-Andrews
3608abb01a Remove unnecessary account ID match check. (#7416)
* Remove unnecessary account ID match check.

Right now the Account object calculates an ID using md5. This is
unnecessary and causes problems on FIPS systems that forbid md5. It's
just as good to pick a random series of bytes for the ID, since the ID
gets read out of renewal/foo.conf.

However, if we switched the algorithm right now, we could wind up
breaking forward compatibility / downgradeability, since older versions
would run into this check.

Removing this check now lays the ground to change the ID-calculation
algorithm in the future.

Related to #1948 and
https://github.com/certbot/certbot/pull/1013#issuecomment-149983479.

* Remove test.

* Remove unused import.
2019-10-02 14:44:25 -07:00
Brad Warren
4739a0616d Merge pull request #7415 from certbot/candidate-0.39.0
Candidate 0.39.0
2019-10-01 13:34:47 -07:00
Erica Portnoy
6e38ad9cce Bump version to 0.40.0 2019-10-01 13:04:10 -07:00
Erica Portnoy
4599aff07f Add contents to CHANGELOG.md for next version 2019-10-01 13:04:10 -07:00
Erica Portnoy
0b605333d9 Release 0.39.0 2019-10-01 13:04:08 -07:00
Erica Portnoy
9c18de993d Update changelog for 0.39.0 release 2019-10-01 12:48:40 -07:00
Brad Warren
e3dbd9ce4a Keep compatibility with IE11 in the Nginx plugin (#7414)
As discussed at https://github.com/mozilla/server-side-tls/issues/263, Mozilla's current intermediate recommendations drop support for some non-EOL'd versions of IE. [Their TLS recommendations were updated to suggest a couple possible workarounds for people who need this support](https://github.com/mozilla/server-side-tls/pull/264) and [April suggested that we make this change in Certbot](https://github.com/mozilla/server-side-tls/issues/263#issuecomment-537085728).

We know `TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA` translates to `ECDHE-RSA-AES128-SHA` because [nginx uses the same cipher format as OpenSSL](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_ciphers) and the translation is shown in the table at https://github.com/mozilla/server-side-tls/blob/gh-pages/Cipher_Suites.mediawiki.

The risk of regressions making this change is low as we always had this ciphersuite enabled just a few releases ago: https://github.com/certbot/certbot/tree/v0.36.0/certbot-nginx/certbot_nginx

* Keep compatibility with IE11

* update changelog
2019-10-01 10:34:11 -07:00
Brad Warren
c2480b29f7 Add CentOS 8 support to certbot-auto. (#7406)
Fixes #7396.
2019-09-30 09:19:05 -07:00
Brad Warren
6ac8633363 Remove listing for broken icecast plugin. (#7408)
The repo description for the [3rd party Icecast plugin](https://github.com/e00E/lets-encrypt-icecast) says that the plugin isn't currently working and the repository hasn't been updated since 2017. Since it seems broken and unmaintained, let's remove it from the list of third party plugins.

I would happily add it again to the list of third party plugins if people fix and maintain it.
2019-09-27 12:47:12 -07:00
Brad Warren
8a4c2f505f Remove listing for broken heroku plugin (#7409)
The README for the [3rd party heroku plugin](https://github.com/gboudreau/certbot-heroku) says it has been deprecated. Because of this, let's remove it from the list of third party plugins.
2019-09-27 12:46:56 -07:00
Joona Hoikkala
ca3077d034 Try to use platform.linux_distribution() before distro equivalent (#7403)
Try to primarily fall back to using `platform.linux_distribution()` if `/etc/os-release` isn't available. Only use `distro.linux_distribution()` on Python >= 3.8.

* Try to use platform.linux_distribution() before distro equivalent

* Fix tests for py38

* Added changelog entry
2019-09-27 09:50:38 -07:00
Kenichi Maehashi
6c89aa5227 Fix to run with Apache on RHEL 6 (#7401)
This PR fixes a regression in #7337 (0.38.0) that certbot cannot run with Apache on RHEL 6.

In RHEL 6, `distro.linux_distribution()` returns `RedHatEnterpriseServer`.

In RHEL 6:

```py
>>> import distro
>>> distro.linux_distribution()
(u'RedHatEnterpriseServer', u'6.10', u'Santiago')

>>> import platform
>>> platform.linux_distribution()
('Red Hat Enterprise Linux Server', '6.10', 'Santiago')
```

In RHEL 7:

```py
>>> import distro
>>> distro.linux_distribution()
('Red Hat Enterprise Linux Server', '7.6', 'Maipo')

>>> import platform
>>> platform.linux_distribution()
('Red Hat Enterprise Linux Server', '7.6', 'Maipo')
```

* fix to run with Apache on RHEL 6

* fix docs
2019-09-26 13:25:48 -07:00
Brad Warren
8cb57566c0 List support for Python 3.8 (#7392)
Fixes #7368.

When updating the changelog, I replaced the line about running tests on Python 3.8 because I personally think that support for Python 3.8 is the most relevant information for our users/packagers about our changes in this area.

* List support for Python 3.8.

* Update changelog.
2019-09-24 11:38:38 -07:00
ohemorange
18e6c6c2a8 Don't send OCSP requests for expired certificates (#7387)
Fixes #7152.

* don't check ocsp if cert is expired when getting cert information

* don't check ocsp if the cert is expired in ocsp_revoked

* update tests

* update changelog

* move pytz import to the top of the test file
2019-09-23 17:20:11 -07:00
Adrien Ferrand
e402993c34 [Windows] Create a certbot renew scheduled task using the installer (#7371)
This PR implements the item "register a scheduled task for certificate renewal" from the list of requirements described in #7365.

This PR adds required instructions in the NSIS installer for Certbot to create a task, named "Certbot Renew Task" in the Windows Scheduler. This task is run twice a day, to execute the command certbot renew and keep the certificates up-to-date.

Uninstalling Certbot will also remove this scheduled task.

* Implementation

* Corrections

* Update template.nsi

* Improve scripts

* Add a random delay of 12 hours

* Synchronize template against default one in pynsist 2.4

* Clean config of scheduled task

* Install only in AllUsers mode

* Add comments

* Remove the logic of single user install
2019-09-23 12:29:18 -07:00
Brad Warren
754c34c120 Fix Windows sdist. (#7384) 2019-09-20 17:21:07 +02:00
Brad Warren
2883ca839e Use xenial globally (#7380)
As described at https://github.com/certbot/certbot/pull/7372#discussion_r323592366, Travis is transitioning people to Xenial, but it seems this transition still may not be complete as some of our jobs ran on Trusty with all references to `dist` removed as seen at https://travis-ci.com/certbot/certbot/builds/127960999.

This PR sets `dist: xenial` globally and overrides it as needed for the oldest tests.

* Set xenial globally.

* Use trusty in all oldest tests.
2019-09-17 15:24:53 -07:00
ohemorange
fb6aad28bd Get integration tests working on python 3.8 (#7372)
* Get integration tests working on python 3.8

* Run unit tests on py38

* Update coveragercs to use coverage 4.5+ format

* remove line added to tox.ini

* update changelog

* xenial is the new travis default; no need to specify in .travis.yml
2019-09-16 14:14:26 -04:00
Adrien Ferrand
ab76834100 [Windows|Linux] Forbid os.stat and os.fstat (#7325)
Fixes #7212

This PR forbid os.stat and os.fstat, and fix or provide alternatives to avoid its usage in certbot outside of certbot.compat.filesystem.

* Reimplement private key mode propagation

* Remove other os.stat

* Remove last call of os.stat in certbot package

* Forbid stat and fstat

* Implement mode comparison checks

* Add unit tests

* Update certbot/compat/filesystem.py

Co-Authored-By: Brad Warren <bmw@users.noreply.github.com>

* Update certbot/compat/filesystem.py

Co-Authored-By: Brad Warren <bmw@users.noreply.github.com>

* Handle case where multiple ace concerns a given SID in has_min_permissions

* Add a new test scenario

* Add a simple test for has_same_ownership

* Fix name function

* Add a comment explaining an ACE structure

* Move a test in its dedicated class

* Improve a message error

* Calculate has_min_permission result using effective permission rights to be more generic.

* Change an exception message

* Add comments, avoid to skip a test.

* Update certbot/compat/filesystem.py

Co-Authored-By: Brad Warren <bmw@users.noreply.github.com>
2019-09-06 14:30:25 -07:00
Brad Warren
ada2f5c767 Simplify testing of RHEL 8. (#7323) 2019-09-06 08:59:24 +02:00
ohemorange
e4af1f3319 Disable TLS session tickets in Nginx (#7355)
* Find OpenSSL version

* Create and update various config files

* Update logic to use new version constraints

* SSL_OPTIONS_HASHES_NEW and SSL_OPTIONS_HASHES_MEDIUM were just being used for testing, and maintaining them is becoming untenable, so remove them.

* if we don't know the openssl version, we can't turn off session tickets

* add unit test for _get_openssl_version

* add unit tests

* placate lint

* Fix docs and tests and clean up code

* use python correctly

* update changelog

* Lint

* make comment a comment
2019-09-05 13:51:56 -07:00
ohemorange
ab0e382829 Merge pull request #7364 from certbot/candidate-0.38.0
Update files from 0.38.0 release
2019-09-04 18:23:50 -04:00
Adrien Ferrand
ed0b8e4af5 [Windows] Create an installer for Certbot (#7324)
This PR is the first step to create an official distribution channel of Certbot for Windows. It consists essentially in creating a proper Certbot Windows installer.

Usually distributing an application requires, in a way or another, to stabilize the application logic and its dependencies around a given version. On Windows, this usually takes the form of a freezed application, that vendors its dependencies into a single executable.

There are two well-known solutions to create an executable shipping a Python application on Windows: [py2exe](http://www.py2exe.org/) and [pyinstaller](https://www.pyinstaller.org/). However these solutions create self-executable `.EXE` files: you run the `.EXE` file that launches immediately the software.

This is not a end-user solution. Indeed when a Windows user wants to install a piece of software, he expects to find and download an installer. When run the installer would interface with Windows to setup configuration entries in the Registry, update the environment variable, add shortcuts in the Start Menu, and declare a uninstaller entry into the Uninstaller Manager. Quite similarly, this is what you would get from a `.deb` or `.rpm` package.

A solution that builds proper installers is [pynsis](https://pynsist.readthedocs.io/en/latest/). It is a Python project that constructs installers for Python software using [NSIS](https://sourceforge.net/projects/nsis/), the most known free Windows installer builder solution.

This PR uses pynsist to build a Windows installer. The Python script to launch the installer build is `.\windows-installer\construct.py`. Once finished, the installer is located in `.\windows-installer\build\nsis`.

This installer will do the following operations during the installation:
* copy in the install path a full python distribution used exclusively for Certbot
* copy all Python requirements gathered from the `setup.py` of relevant certbot projects
* copy `certbot` and `acme`
* pre-build python binary assets
* register the existence of the application correctly in Windows Registry
* prepare a procedure to uninstall Certbot
* and of course, expose `certbot` executable to the Windows command line, like on Linux, to be able to launch it as any CLI application from Batch or Powershell

This installer support updates: downloading a new version of it and running it on a Windows with existing installation of Certbot will replace it with the new version.

Future capabilities not included in this PR:
* auto-update of Certbot when a new release is available
* online documentation for Windows
* register a scheduled task for certificate renewal
* installer distribution (continuous deployment + distribution channels)
* method to check the downloaded installer is untampered

* Setup config

* Fix shortcut

* Various improvments

* Update windows-installer/construct.py

Co-Authored-By: Brad Warren <bmw@users.noreply.github.com>

* Split into several method

* Change installer name

* Remove DNS plugins for now

* Add a comment about administrator privileges

* Update welcome

* Control python version

* Control bitness

* Update windows-installer/construct.py

Co-Authored-By: Brad Warren <bmw@users.noreply.github.com>

* Update windows-installer/construct.py

Co-Authored-By: Brad Warren <bmw@users.noreply.github.com>

* Update windows-installer/construct.py

Co-Authored-By: Brad Warren <bmw@users.noreply.github.com>
2019-09-03 16:30:13 -07:00
Brad Warren
8a570b18e9 Bump version to 0.39.0 2019-09-03 12:49:30 -07:00
Brad Warren
deb0168c09 Add contents to CHANGELOG.md for next version 2019-09-03 12:49:29 -07:00
Brad Warren
46a12d0127 Release 0.38.0 2019-09-03 12:49:28 -07:00
Brad Warren
6d4baec955 Update changelog for 0.38.0 release 2019-09-03 12:42:35 -07:00
Brad Warren
4eaa06d58e list py37 support (#7360)
These plugins also support Python 3.7. You can see tests passing at https://travis-ci.com/certbot/certbot/jobs/228820500.
2019-08-28 11:10:13 -07:00
ohemorange
0fe28a6459 Replace platform.linux_distribution with distro.linux_distribution (#7337)
Smallest possible fix for #7106 

* Replace platform.linux_dependencies with distro.linux_dependencies

* run build.py

* Add minimum version of 1.0.1

* Pin back requests package

* Update changelog
2019-08-27 18:31:35 -07:00
Adrien Ferrand
aaeb4582e2 Fix PYTHONPATH in integration tests (#7357)
This PR supersedes #7353.

It fixes the execution of nginx oldest tests when these tests are executed on top of the modifications made in #7337. This execution failure revealed the fact that in some cases, the wrong version of certbot logic was used during integration tests (namely the logic lying in the codebase of the branch built, instead of the logic from the version of certbot declared by certbot-nginx for instance).

I let you appreciate my inline comment for the explanation and the workaround.

Thanks a lot to @bmw who found this python/pytest madness.

You can see the oldest tests succeeding with the logic of #7337 + this PR here: https://travis-ci.com/certbot/certbot/builds/124816254

* Remove certbot root from PYTHONPATH during integration tests

* Add a biiiiig comment.
2019-08-27 16:25:31 -07:00
schoen
fdb0a14812 Merge pull request #7336 from certbot/update-debian-instructions
Update Debian instructions in docs
2019-08-23 13:39:55 -07:00
Adrien Ferrand
0324d1740e Ensure relpath is executed on paths in the same drive (#7335)
On Windows you can have several drives (`C:`, `D:`, ...), that is the roughly (really roughly) equivalent of mount points, since each drive is usually associated to a specific physical partition.

So you can have paths like `C:\one\path`, `D:\another\path`.

In parallel, `os.path.relpath(path, start='.')` calculates the relative path between the given `path` and a `start` path (current directory if not provided). In recent versions of Python, `os.path.relpath` will fail if `path` and `start` are not on the same drive, because a relative path between two paths like `C:\one\path`, `D:\another\path` is not possible.

In saw unit tests failing because of this in two locations. This occurs when the certbot codebase that is tested is on a given drive (like `D:`) while the default temporary directory used by `tempfile` is on another drive (most of the time located in `C:` drive).

This PR fixes that.
2019-08-23 12:53:30 -07:00
Brad Warren
ce325db4e4 address review comments 2019-08-23 12:43:05 -07:00
Brad Warren
74e6736c79 use latest RHEL 7 AMI (#7349) 2019-08-22 09:28:57 -07:00
ohemorange
2ed7608ed3 Merge pull request #7347 from certbot/candidate-0.37.2
Release 0.37.2
2019-08-21 16:21:23 -07:00
ohemorange
eb02acfc4b Merge branch 'master' into candidate-0.37.2 2019-08-21 16:03:51 -07:00
Erica Portnoy
4f19d516d6 Bump version to 0.38.0 2019-08-21 15:23:15 -07:00
Erica Portnoy
3dd918b024 Add contents to CHANGELOG.md for next version 2019-08-21 15:23:15 -07:00
Erica Portnoy
8320018978 Release 0.37.2 2019-08-21 15:23:14 -07:00
Erica Portnoy
c17f2ff6b0 Update changelog for 0.37.2 release 2019-08-21 14:48:40 -07:00
Brad Warren
46a2ef8ba1 Stop turning session tickets off in Nginx (#7344) (#7345)
Related to #7322.

* Stop turning session tickets off in Nginx

* update changelog

(cherry picked from commit 17c1d016c1)
2019-08-21 14:44:09 -07:00
ohemorange
17c1d016c1 Stop turning session tickets off in Nginx (#7344)
Related to #7322.

* Stop turning session tickets off in Nginx

* update changelog
2019-08-21 14:29:10 -07:00
Brad Warren
70ed791709 Update Debian instructions in docs. 2019-08-16 11:42:34 -07:00
Adrien Ferrand
d39f63feca Use travis_retry for farm tests (#7327)
* Use travis_retry in travis builds to retry the farm tests

* travis_retry is a bash function, so it can be called only from current bash

* Update .travis.yml

* Update .travis.yml
2019-08-16 14:55:45 +02:00
Adrien Ferrand
6882f006ac [Windows] Fix closing files descriptors during unit tests (#7326)
* Fix file descriptor cleanup during tests on Windows

* Fix lint

* Remove useless tearDown

* Clean pylint
2019-08-16 11:08:42 +02:00
Adrien Ferrand
9a047a6996 Clean travis config (#7328)
This PR removes some useless capabilities in .travis.yml that are associated to the jobs. This concerns mainly sudo and docker.
2019-08-15 16:41:51 -07:00
Matthias Bilger
a8bd839223 Added DNS plugin for ISPConfig to list (#7332) 2019-08-15 14:43:14 -07:00
tyborr
a1aef4c15c Fix Certbot's Apache plugin doesn't work on Scientific Linux (#7294)
This PR adds OVERRIDE_CLASS in certbot-apache/entrypoint.py for Scientific Linux. Fixes #7248.

* add OVERRIDE_CLASS for Scientific Linux os name

* add entry for Scientific Linux using "scientific" as key

* Update changelog
2019-08-12 12:59:29 -07:00
ohemorange
cb7598b007 Merge pull request #7320 from certbot/merge-cand-0.37.1
Merge cand 0.37.1
2019-08-08 18:01:27 -07:00
Brad Warren
55cf49cebe Merge pull request #7318 from certbot/candidate-0.37.1
Candidate 0.37.1
2019-08-08 17:56:57 -07:00
ohemorange
933f60a3c1 Merge branch 'master' into candidate-0.37.1 2019-08-08 17:48:22 -07:00
Erica Portnoy
44eb048098 Bump version to 0.38.0 2019-08-08 17:01:39 -07:00
Erica Portnoy
794ce57356 Add contents to CHANGELOG.md for next version 2019-08-08 17:01:38 -07:00
Erica Portnoy
48d9715bd5 Release 0.37.1 2019-08-08 17:01:32 -07:00
Erica Portnoy
c5e1be4fd7 Update changelog for 0.37.1 release 2019-08-08 16:39:43 -07:00
Brad Warren
e21401004b Revert disabling TLS session tickets in Apache (#7315) (#7316)
See https://community.letsencrypt.org/t/ssl-error-after-cert-renew/99430.

The first commit of this PR is a simple, clean revert of #7191. Subsequent commits add back pieces of that PR we want to keep.

I also reverted #7299 which landed in a separate PR, but needs to be reverted to keep including the TLS config files in the certbot-apache package when it is built.

I tested this on Ubuntu 18.04 by installing a cert to Apache using Certbot master and then running certbot renew with this branch. I watched the Apache plugin update the configuration file to remove SSLSessionTickets off.

* Revert "Disable TLS session tickets for Apache 2.4.11+ (#7191)"

This reverts commit 9174c631d9.

* Keep hashes with TLS session tickets disabled.

* dont delete changelog entries

* add changelog entry

* Revert "Clean the useless entries in MANIFEST.in (#7299)"

This reverts commit f4d17d9a6b.

(cherry picked from commit 120137eb8d)
2019-08-08 16:36:45 -07:00
Brad Warren
120137eb8d Revert disabling TLS session tickets in Apache (#7315)
See https://community.letsencrypt.org/t/ssl-error-after-cert-renew/99430.

The first commit of this PR is a simple, clean revert of #7191. Subsequent commits add back pieces of that PR we want to keep.

I also reverted #7299 which landed in a separate PR, but needs to be reverted to keep including the TLS config files in the certbot-apache package when it is built.

I tested this on Ubuntu 18.04 by installing a cert to Apache using Certbot master and then running certbot renew with this branch. I watched the Apache plugin update the configuration file to remove SSLSessionTickets off.

* Revert "Disable TLS session tickets for Apache 2.4.11+ (#7191)"

This reverts commit 9174c631d9.

* Keep hashes with TLS session tickets disabled.

* dont delete changelog entries

* add changelog entry

* Revert "Clean the useless entries in MANIFEST.in (#7299)"

This reverts commit f4d17d9a6b.
2019-08-08 16:23:37 -07:00
Matt Nordhoff
2911eda3bd Update link to the Server forum category (#7309)
Let's Encrypt closed it in favor of the Help category.

https://community.letsencrypt.org/t/closing-the-server-category/93016
2019-08-08 11:44:21 -07:00
ohemorange
f1ea37dd71 Merge pull request #7311 from certbot/candidate-0.37.0
Update from 0.37.0 release
2019-08-07 17:44:16 -07:00
Brad Warren
3d3cbc0d16 Don't run tox -e cover. (#7312) 2019-08-08 00:07:37 +02:00
Brad Warren
d978440cb5 Bump version to 0.38.0 2019-08-07 10:35:13 -07:00
Brad Warren
0c04ce3c32 Add contents to CHANGELOG.md for next version 2019-08-07 10:35:13 -07:00
Brad Warren
987ce2c6b2 Release 0.37.0 2019-08-07 10:35:11 -07:00
Brad Warren
dded9290b7 Update changelog for 0.37.0 release 2019-08-07 10:26:34 -07:00
Brad Warren
745ef6e869 Merge pull request #7302 from certbot/rhel8_fix-with-tests
This PR builds off of #7240 to fix #7241.

The code in certbot-auto is unchanged which I +1. Someone else should give it a 2nd review.

For the code in the tests, you can see all tests passing (including test_tests.sh) at  https://travis-ci.com/certbot/certbot/builds/122198270.

I created #7301 to track removing the temporary code in test_leauto_upgrades.sh as suggested at #7282 (comment).

One noteworthy thing here is I did not add the RHEL 8 AMI to the Apache tests due to #7273. This problem is not related to support in certbot-auto though, is an edge case, and I do not personally believe it should block this PR.
2019-08-06 17:02:57 -07:00
Brad Warren
e2844bd0ad Add RHEL8 to test farm targets
* Add RHEL 8 to targets

* Use latest certbot-auto to bootstrap.

* Workaround leauto failures.
2019-08-06 16:39:35 -07:00
Adrien Ferrand
b67fda8832 Fix integration tests on Windows (#7271)
* Fix account_tests

* Fix hook executable test

* Remove the temporary decorator @broken_on_windows

* Fix util_test

* No broken unit test on Windows anymore

* More elegant mock

* Fix context manager

* Fix lint

* Fix mypy

* Adapt coverage

* Corrections

* Fix lint

* Adapt coverage

* Update certbot/tests/compat/filesystem_test.py

Co-Authored-By: Brad Warren <bmw@users.noreply.github.com>

* Update util_test.py

* Fix pylint

* Forbid os.access

* Update os_test.py

* Update os.py

* Fix lint

* Update filesystem.py

* Update filesystem.py

* Update filesystem.py

* Update os.py

* Start fixing tests

* Platform independent hooks

* Fix probe fd close

* Add broken_on_windows for integration tests

* Fix a lot of tests

* Use a python hook script, to prepare cross-platform

* New approach to be compliant with Linux and Windows on hook scripts

* New tests fixed

* Test for permissions on Windows

* Permissions comparison for Windows

* No broken tests in certbot core anymore

* Change mode

* Specific config for appveyor

* Use forked pebble for now

* Various fixes

* Assert file permissions for world on private keys

* Clean code

* Fix several things

* Add integration target

* Optimize integration env

* Re-enable all AppVeyor envs

* Use again official pebble

* Update pebble_artifacts.py

* Set PYTEST_ADDOPTS silently

* Update appveyor.yml

* Pin pywin32 for tests, give a minimal requirement for certbot.

* Remove injection of nginx in PATH

* Clean debug code

* Various cleanup, ensure to remove workspace after tests

* Update tox target

* Improve assertions. Control the keyword echoed in hooks

* Fix for virtualenv on Python 3.7.4 for Windows

* Update certbot-ci/certbot_integration_tests/certbot_tests/assertions.py

Co-Authored-By: Brad Warren <bmw@users.noreply.github.com>

* Add conditionally pywin in certbot-ci like in certbot
2019-08-07 00:02:16 +02:00
Michael Watters
d6e6d64848 Update certbot-auto script to work with RHEL 8
/usr/bin/python no longer exists in RHEL 8.  This patch updates
the certbot-auto script to use python3 on nodes running RHEL 8.

Also fixed a bug in the RPM_DIST_VERSION logic which would cause
letsencrypt-auto to fail on servers running CentOS/RHEL 6.
2019-08-06 09:16:14 -04:00
Adrien Ferrand
f4d17d9a6b Clean the useless entries in MANIFEST.in (#7299)
Since #7191, TLS configuration files for Apache have been moved to a dedicated folder tls_configs. Then the entries in MANIFEST.in removed by this PR do not correspond to an existing path, and so are not useful anymore.
2019-08-05 15:57:20 -07:00
Adrien Ferrand
8bcb04af4a Move Nginx TLS configuration files into a specific folder (#7300)
Following discussions in #7298.

This PR moves the three Nginx TLS configuration files into a specific folder, tls_configs, update the MANIFEST to include this folder and its content into the certbot-nginx package, and update tests accordingly.

* Move tls configuration files in a specific folder

* Move new file
2019-08-05 15:45:08 -07:00
ohemorange
14e10f40e5 Follow Mozilla recs for Nginx ssl_protocols, ssl_ciphers, and ssl_prefer_server_ciphers (#7274)
* Follow Mozilla recs for Nginx ssl_protocols, ssl_ciphers, and ssl_prefer_server_ciphers

* Add tests and fix if statement

* Update CHANGELOG.md

Co-Authored-By: Brad Warren <bmw@users.noreply.github.com>

* Test that the hashes of all of the current configuration files are in ALL_SSL_OPTIONS_HASHES

* Remove conditioning on OpenSSL version, since Nginx behaves cleanly if its linked OpenSSL doesn't support TLS1.3
2019-08-02 12:25:40 -07:00
Adrien Ferrand
1c7105a940 Create a mock OCSP server for Pebble integration tests (#7281)
* Implement a logic, miss the private key of pebble

* Complete process

* Fix nginx cert path

* Check conditionnally docker

* Update gitignore, fix apacheconftest

* Full object

* Carriage return

* Work in progress

* Move to official v2.1.0 of pebble

* Fix name

* Update acme_server.py

* Link things together with new version of pebble

* Plug the logic to tests

* Update config

* Reinitiate config

* Add OCSP config to pebble

* Working.

* Simplify logic

* Clean code

* Use forked pebble for now

# Conflicts:
#	certbot-ci/certbot_integration_tests/utils/pebble_artifacts.py

* Move full logic of mock at the acme server config

* Continue work

* Finish fixing the date parsing

* Update module name

* Use again official pebble

* Activate mock OCSP server

* Clean code

* Update pebble_artifacts.py

* Remove OCSP stale test

* Add executable permissions

* Clean code

* Update setup.py

* Simplify code

* On-demand import of pebble_ocsp_server

* Revert "Remove OCSP stale test"

This reverts commit 2e4c985b427120cc15526bbcfd15806d02a6f3fc.

# Conflicts:
#	certbot-ci/certbot_integration_tests/utils/misc.py

* Fix for virtualenv on Python 3.7.4 for Windows

* Update acme_server.py
2019-08-02 11:46:12 -07:00
Adrien Ferrand
36b4c312c6 Upgrade virtualenv in dev/tests environments (#7287)
AppVeyor recently upgrade the Python 3.7.x installed in their VM to 3.7.4. However, virtualenv 16.6.1 is broken on that specific version of Python for Windows.

This PR upgrade virtualenv installed for a dev/test environment from 16.6.1 to 16.6.2 in order to fix this issue, and repair the CI jobs execute by AppVeyor on PRs.
2019-08-02 09:47:36 -07:00
Adrien Ferrand
56f609d4f5 Fix unit tests on Windows (#7270)
Fixes #6850

This PR makes the last corrections needed to run all unit tests on Windows:

add a function to check if a hook is executable in a cross-platform compatible way
handle correctly the PATH surgery for Windows during hook execution
handle correctly an account compatibility over both ACMEv1 and ACMEv2
remove (finally!) the @broken_on_windows decorator.

* Fix account_tests

* Fix hook executable test

* Remove the temporary decorator @broken_on_windows

* Fix util_test

* No broken unit test on Windows anymore

* More elegant mock

* Fix context manager

* Adapt coverage

* Corrections

* Adapt coverage

* Forbid os.access
2019-08-01 10:39:46 -07:00
Mikel Kew
2d3f3a042a Update dns-cloudflare docs regarding API Tokens (#7285)
A quick update to the docs to explicitly mention that the Cloudflare Global API Key must me used instead of an API Token.
2019-07-31 10:31:05 +02:00
Brad Warren
bfd4955bad Bump timeout waiting for ACME server to 4 minutes. (#7284)
* Bump timeout to 4 minutes.

* address review comments
2019-07-30 21:28:18 +02:00
Adrien Ferrand
9174c631d9 Disable TLS session tickets for Apache 2.4.11+ (#7191)
* Implement the logic

* Update tests

* Fix lint and changelog

* Update configurator.py

* Move the TLS configs in a dedicated folder. Fix the formalism of their naming and location.

* Improve existing test to check all TLS config have their hash registered in Certbot

* Corrections after review

* Improve a test

* Remove commented useless lines in TLS configs

* Add a nice warning. Because I am nice.

* Fix lint

* Add a test
2019-07-29 22:54:51 +03:00
Adrien Ferrand
81e0b92b43 Refer to ubuntu in install.rst (#6986)
Fixes #5758
2019-07-29 10:27:09 -07:00
Brad Warren
d3da19919f Remove duplicate, failing oldest tests. (#7272)
Nightly tests failed last night at https://travis-ci.com/certbot/certbot/builds/120816454.

The cause was the oldest the version of Ubuntu used in the tests suddenly changed from Trusty to Xenial. You can see Xenial being used in the failing test at  https://travis-ci.com/certbot/certbot/jobs/219873088#L9 and Trusty being used at the last passing test at https://travis-ci.com/certbot/certbot/jobs/218936290#L9. The change in the default doesn't seem to be documented (yet) at https://docs.travis-ci.com/user/reference/overview/.

I started to pin Trusty in these tests, however, I noticed that we are running these same unit tests at e6bf3fe7f8/.travis.yml (L58). These other tests are still succeeding because it appears that including `sudo: required` causes Travis to still default to Trusty.

Deleting these duplicated tests fixes our Travis failures and speeds things up ever so slightly.

* Remove duplicate, failing oldest tests.

* pin trusty
2019-07-26 13:37:16 -07:00
Adrien Ferrand
e6bf3fe7f8 [Windows] Security model for files permissions - STEP 3f (#7233)
* Correct file permissions on TempHandler

* Forbid os.chown and os.geteuid, as theses functions can be harmful to the security model on Windows.

* Implement copy_ownership

* Apply copy_ownership

* Correct webroot tests (and activate another broken test !)

* Correct lint and mypy

* Ensure to apply mode in makedirs

* Apply strict permissions on directories created with tempfile.mkdtemp(), like on Unix.

* Ensure streamHandler has 0600 on Windows

* Reactivate a test on windows

* Pin oldest requirements to current internal libraries (acme and certbot)

* Add dynamically pywin32 in dependencies: always except for certbot-oldest to avoid to break the relevant tests.

* Administrative privileges are always required.

* Correct security implementation (not the logic yet)

* First correction. Allow to manipulate finely file permissions during their generation

* Align to master + fix lint + resolve correctly symbolic links

* Add a test for windows about default paths

* Strenghthen the detection of Linux/Windows to check the standard files layout.

* Fix lint and mypy

* Reflect non usage of cache discovery from dns google plugin to its tests, solving Windows tests on the way

* Apply suggestions from code review

Co-Authored-By: adferrand <adferrand@users.noreply.github.com>

* Add more details in a comment

* Retrigger build.

* Add documentation.

* Fix a test

* Correct RW clear down

* Update util.py

* Remove unused code

* Fix code style

* Adapt certbot coverage threshold on Linux due to Windows specific LOC addition.

* Various optimizations around file owner and file mode

* Fix last error

* Fix copy_ownership_and_apply_mode

* Fix lint

* Correct mypy

* Extract out first part from windows-file-permissions

* Ignore new_compat in coverage for now

* Create test package for compat

* Add unit tests for security module.

* Add pywin32

* Adapt linux coverages to the windows-specific LOCs added

* Clean imports

* Correct import

* Trigger CI

* Reactivate a test

* Create the certbot.compat package. Move logic in certbot.compat.misc

* Clean comment

* Add doc

* Fix lint

* Correct mypy

* Add executable permissions

* Add the delegate certbot.compat.os module, add check coding style to enforce usage of certbot.compat.os instead of standard os

* Load certbot.compat.os instead of os

* Move existing compat test

* Update local oldest requirements

* Import sys

* Fix some mocks

* Update account_test.py

* Update os.py

* Update os.py

* Update local oldest requirements

* Implement the new linter_plugin

* Fix remaining linting errors

* Fix local oldest for nginx

* Remove custom check in favor of pylint plugin

* Remove check coding style

* Update linter_plugin.py

Co-Authored-By: adferrand <adferrand@users.noreply.github.com>

* Add several comments

* Update the setup.py

* Add documentation

* Update acme dependencies

* Update certbot/compat/os.py

Co-Authored-By: adferrand <adferrand@users.noreply.github.com>

* Update certbot/compat/os.py

Co-Authored-By: adferrand <adferrand@users.noreply.github.com>

* Update certbot/compat/os.py

Co-Authored-By: adferrand <adferrand@users.noreply.github.com>

* Update docs/contributing.rst

Co-Authored-By: adferrand <adferrand@users.noreply.github.com>

* Update linter_plugin.py

Co-Authored-By: adferrand <adferrand@users.noreply.github.com>

* Update linter_plugin.py

Co-Authored-By: adferrand <adferrand@users.noreply.github.com>

* Update docs/contributing.rst

Co-Authored-By: adferrand <adferrand@users.noreply.github.com>

* Update docs/contributing.rst

Co-Authored-By: adferrand <adferrand@users.noreply.github.com>

* Corrections

* Handle os.path. Simplify checker.

* Add a comment to a reference implementation

* Update changelog

* Fix module registering

* Update docs/contributing.rst

Co-Authored-By: adferrand <adferrand@users.noreply.github.com>

* Update docs/contributing.rst

Co-Authored-By: adferrand <adferrand@users.noreply.github.com>

* Update docs/contributing.rst

Co-Authored-By: adferrand <adferrand@users.noreply.github.com>

* Update config and changelog

* Correction

* Correct os

* Fix merge

* Disable pylint checks

* Normalize imports

* Simplify security

* Corrections

* Reorganize module

* Clean code

* Clean code

* Remove coverage

* No cover

* Implement security.chmod

* Disable a test for now

* Disable hard error for now

* Add a first test. Remove unused import

* Recalibrate coverage

* Modifications for misc

* Correct function call

* Add some types

* Remove newline

* Use os_rename

* Implement security.open

* Revert to windows-files-permissions approach

* Fix lint

* Implement security.mkdir and security.makedirs

* Fix lint

* Clean lint

* Clean lint

* Revert "Clean lint"

This reverts commit 83bf81960ac6bf3f76c286ca065a5ac850c6870b.

* Correct mock

* Conditionally add pywin32 on setuptools versions that support environment markers.

* Fix separator

* Fix separator

* Rename security into filesystem

* Change module security to filesystem

* Move rename into filesystem

* Rename security into filesystem

* Rename security into filesystem

* Rerun CI

* Fix import

* Fix pylint

* Implement copy_ownership_and_apply_mode

* Fix pylint

* Update certbot/compat/os.py

Co-Authored-By: Brad Warren <bmw@users.noreply.github.com>

* Remove default values

* Rewrite a comment.

* Relaunch CI

* Pass as keyword arguments

* Update certbot/compat/filesystem.py

Co-Authored-By: Brad Warren <bmw@users.noreply.github.com>

* Update certbot/compat/filesystem.py

Co-Authored-By: Brad Warren <bmw@users.noreply.github.com>

* Update certbot/compat/filesystem.py

Co-Authored-By: Brad Warren <bmw@users.noreply.github.com>

* Make the private key permissions transfer platform specific

* Update certbot/compat/filesystem.py

Co-Authored-By: Brad Warren <bmw@users.noreply.github.com>

* Rename variable

* Fix comment0

* Add unit test for copy_ownership_and_apply_mode

* Adapt coverage

* Implement new methods.

* Remove the old method

* Reimplement make_or_verify_dir

* Finish migration

* Start to fix tests

* Fix ownership when creating a file with filesystem.open

* Fix security on TempHandler

* Fix validation path permissions

* Fix owner on mkdir

* Use a proper workdir for crypto tests

* Fix pylint

* Adapt coverage

* Update storage_test.py

* Update util_test.py

* Clean code

* Update certbot/compat/filesystem.py

Co-Authored-By: ohemorange <ebportnoy@gmail.com>

* Add comment

* Update certbot/compat/filesystem.py

Co-Authored-By: ohemorange <ebportnoy@gmail.com>

* Check permissions

* Change test mode

* Add unit test for filesystem.check_* functions

* Update filesystem_test.py

* Better logic for TempHandler

* Adapt coverage
2019-07-26 00:25:36 +02:00
alexzorin
40da709792 docs: s/certbot_tests/certbot_test/ (#7267) 2019-07-25 10:23:28 +02:00
Brad Warren
bf9c681c4f fix backwards logic (#7265) 2019-07-25 10:20:52 +02:00
alexzorin
391f301dd8 acme: Implement authz deactivation (#7254)
Resolves #4945. First PR in order to address #5116.

* acme: Implement authz deactivation

Resolves #4945

* update AUTHORS and CHANGELOG

* typos in mypy annotations

* formatting: missing newline

* improve test_deactivate_authorization

* improve deactivate_authorization

* test: s/STATUS_INVALID/STATUS_DEACTIVATED/

* simplify dict to keyword argument

* acme: add UpdateAuthorization

* acme: use UpdateAuthorization in deactivate_authz

and add mypy annotation

This allows deactivate_authorization to succeed for both ACME v1
and v2 servers.
2019-07-24 18:04:59 -07:00
Brad Warren
06a0dae67f Fix test_symlink_resolution on macOS. (#7263)
This fixes the test failures which can be seen at
https://travis-ci.com/certbot/certbot/builds/120123338.

The problem here is the path returned by tempfile.mkdtemp() contains a symlink.
For instance, one run of the function produced
'/var/folders/3b/zg8fdh5j71x92yyzc1tyllfw0000gp/T/tmp3k9ytfj1' which is a
symlink to
'/private/var/folders/3b/zg8fdh5j71x92yyzc1tyllfw0000gp/T/tmp3k9ytfj1'.

Removing this symlink before testing filesystem.realpath solves the problem.

You can see the macOS tests passing with this change at https://travis-ci.com/certbot/certbot/builds/120250667.
2019-07-23 11:01:29 -07:00
Adrien Ferrand
a35470292e Remove Dockerfiles (#7257) 2019-07-22 13:43:58 +03:00
Brad Warren
47f64c7280 Remove list of packaging efforts. (#7258)
I think this list maybe had value when distros were first starting to package Certbot, but now I don't think it does. What function does this list serve? The instruction generator at https://certbot.eff.org/instructions does a much better job telling users how to use these packages. On the packaging side, I think anyone capable of packaging Certbot at the various distros would be able to search their repositories to see if a Certbot package is available.

Since this list is hard to maintain as links semi-regularly break and keeping it up to date with all distros and all Certbot components is a fair bit of work, let's just remove it.

This PR was motivated by the Travis failures at https://travis-ci.com/certbot/website/builds/119588518 due to GNU Guix changing the layout of their site.
2019-07-19 10:44:17 -07:00
Brad Warren
f7c736da6f Update pexpect to fix Python 3.7 dev venvs. (#7259) 2019-07-18 15:44:01 -07:00
Adrien Ferrand
71ff47daad Implement a consistent realpath function in certbot.compat.filesystem (#7242)
Fixes #7115 

This PR creates a `realpath` method in `filesystem`, whose goal is to replace any call to `os.path.realpath` in Certbot. The reason is that `os.path.realpath` is broken on some versions of Python for Windows. See https://bugs.python.org/issue9949. The function created here works consistently across Linux and Windows.

As for the other forbidden functions in `os` module, our `certbot.compat.os` will raise an exception if its `path.realpath` function is invoked, and using the `os` module from Python is forbidden from the pylint check implemented in our CI.

Every call to `os.path.realpath` is corrected in `certbot` and `certbot-apache` modules.

* Forbid os.path.realpath

* Finish implementation

* Use filesystem.realpath

* Control symlink loops also for Linux

* Add a test for forbidden method

* Import a new object from os.path module

* Use same approach of wrapping than certbot.compat.os

* Correct errors

* Fix dependencies

* Make path module internal
2019-07-18 14:31:39 -07:00
J0WI
41a17f913e Use Buster as base image (#7251) 2019-07-17 13:05:02 -07:00
Po-Chuan Hsieh
750d6a9686 Unify license filename (LICENSE.txt) (#7239)
* Unify license filename (LICENSE.txt)
2019-07-12 22:53:43 +03:00
Adrien Ferrand
c4684f187a Add a test for the default directories on Windows (#7238)
There is a unit test to check that the default directories for Certbot are not diverging, in certbot.tests.cli_test:FlagDefaultTests:test_linux_directories.

But this test is not done on Windows.

This PR fixes that.
2019-07-11 17:49:52 -07:00
Lucid One
82ad736120 Fixes #7220 to allow config to be loaded from <(envsubst < template) (#7221)
* Fixes #7220 to allow config to be loaded from <(envsubst < template)
2019-07-11 14:40:24 -07:00
Brad Warren
ca893bd836 Merge pull request #7236 from certbot/candidate-0.36.0
Release 0.36.0
2019-07-11 14:00:49 -07:00
Erica Portnoy
d1934e36fe Bump version to 0.37.0 2019-07-11 12:31:53 -07:00
Erica Portnoy
15b1d8e5a7 Add contents to CHANGELOG.md for next version 2019-07-11 12:31:53 -07:00
Erica Portnoy
cbd0a37c7a Release 0.36.0 2019-07-11 12:31:51 -07:00
Erica Portnoy
13c44a0595 Update changelog for 0.36.0 release 2019-07-11 12:12:24 -07:00
Brad Warren
89f52ca9f9 Add mypy to contributing checklist. (#7224) 2019-07-10 18:14:12 -07:00
Brad Warren
d0a9695b09 Make PR template a checklist and suggest mypy. (#7223) 2019-07-10 18:14:01 -07:00
173 changed files with 3100 additions and 1397 deletions

117
.azure-pipelines/INSTALL.md Normal file
View File

@@ -0,0 +1,117 @@
# Configuring Azure Pipelines with Certbot
Let's begin. All pipelines are defined in `.azure-pipelines`. Currently there are two:
* `.azure-pipelines/main.yml` is the main one, executed on PRs for master, and pushes to master,
* `.azure-pipelines/advanced.yml` add installer testing on top of the main pipeline, and is executed for `test-*` branches, release branches, and nightly run for master.
Several templates are defined in `.azure-pipelines/templates`. These YAML files aggregate common jobs configuration that can be reused in several pipelines.
Unlike Travis, where CodeCov is working without any action required, CodeCov supports Azure Pipelines
using the coverage-bash utility (not python-coverage for now) only if you provide the Codecov repo token
using the `CODECOV_TOKEN` environment variable. So `CODECOV_TOKEN` needs to be set as a secured
environment variable to allow the main pipeline to publish coverage reports to CodeCov.
This INSTALL.md file explains how to configure Azure Pipelines with Certbot in order to execute the CI/CD logic defined in `.azure-pipelines` folder with it.
During this installation step, warnings describing user access and legal comitments will be displayed like this:
```
!!! ACCESS REQUIRED !!!
```
This document suppose that the Azure DevOps organization is named _certbot_, and the Azure DevOps project is also _certbot_.
## Useful links
* https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&tabs=schema
* https://www.azuredevopslabs.com/labs/azuredevops/github-integration/
* https://docs.microsoft.com/en-us/azure/devops/pipelines/ecosystems/python?view=azure-devops
## Prerequisites
### Having a GitHub account
Use your GitHub user for a normal GitHub account, or a user that has administrative rights to the GitHub organization if relevant.
### Having an Azure DevOps account
- Go to https://dev.azure.com/, click "Start free with GitHub"
- Login to GitHub
```
!!! ACCESS REQUIRED !!!
Personal user data (email + profile info, in read-only)
```
- Microsoft will create a Live account using the email referenced for the GitHub account. This account is also linked to GitHub account (meaning you can log it using GitHub authentication)
- Proceed with account registration (birth date, country), add details about name and email contact
```
!!! ACCESS REQUIRED !!!
Microsoft proposes to send commercial links to this mail
Azure DevOps terms of service need to be accepted
```
_Logged to Azure DevOps, account is ready._
### Installing Azure Pipelines to GitHub
- On GitHub, go to Marketplace
- Select Azure Pipeline, and "Set up a plan"
- Select Free, then "Install it for free"
- Click "Complete order and begin installation"
```
!!! ACCESS !!!
Azure Pipeline needs RW on code, RO on metadata, RW on checks, commit statuses, deployments, issues, pull requests.
RW access here is required to allow update of the pipelines YAML files from Azure DevOps interface, and to
update the status of builds and PRs on GitHub side when Azure Pipelines are triggered.
Note however that no admin access is defined here: this means that Azure Pipelines cannot do anything with
protected branches, like master, and cannot modify the security context around this on GitHub.
Access can be defined for all or only selected repositories, which is nice.
```
- Redirected to Azure DevOps, select the account created in _Having an Azure DevOps account_ section.
- Select the organization, and click "Create a new project" (let's name it the same than the targetted github repo)
- The Visibility is public, to profit from 10 parallel jobs
```
!!! ACCESS !!!
Azure Pipelines needs access to the GitHub account (in term of beeing able to check it is valid), and the Resources shared between the GitHub account and Azure Pipelines.
```
_Done. We can move to pipelines configuration._
## Import an existing pipelines from `.azure-pipelines` folder
- On Azure DevOps, go to your organization (eg. _certbot_) then your project (eg. _certbot_)
- Click "Pipelines" tab
- Click "New pipeline"
- Where is your code?: select "__Use the classic editor__"
__Warning: Do not choose the GitHub option in Where is your code? section. Indeed, this option will trigger an OAuth
grant permissions from Azure Pipelines to GitHub in order to setup a GitHub OAuth Application. The permissions asked
then are way too large (admin level on almost everything), while the classic approach does not add any more
permissions, and works perfectly well.__
- Select GitHub in "Select your repository section", choose certbot/certbot in Repository, master in default branch.
- Click on YAML option for "Select a template"
- Choose a name for the pipeline (eg. test-pipeline), and browse to the actual pipeline YAML definition in the
"YAML file path" input (eg. `.azure-pipelines/test-pipeline.yml`)
- Click "Save & queue", choose the master branch to build the first pipeline, and click "Save and run" button.
_Done. Pipeline is operational. Repeat to add more pipelines from existing YAML files in `.azure-pipelines`._
## Add a secret variable to a pipeline (like `CODECOV_TOKEN`)
__NB: Following steps suppose that you already setup the YAML pipeline file to
consume the secret variable that these steps will create as an environment variable.
For a variable named `CODECOV_TOKEN` consuming the variable `codecov_token`,
in the YAML file this setup would take the form of the following:
```
steps:
- script: ./do_something_that_consumes_CODECOV_TOKEN # Eg. `codecov -F windows`
env:
CODECOV_TOKEN: $(codecov_token)
```
- On Azure DevOps, go to you organization, project, pipeline tab
- Select the pipeline, click "Edit" button, then click "Variables" button
- Set name (eg `codecov_token`), value, tick "Keep this value secret"

View File

@@ -0,0 +1,18 @@
# Advanced pipeline for isolated checks and release purpose
trigger:
- test-*
- '*.x'
pr:
- test-*
- '*.x'
# This pipeline is also nightly run on master
schedules:
- cron: "4 0 * * *"
displayName: Nightly build
branches:
include:
- master
jobs:
- template: templates/tests-suite.yml
- template: templates/installer-tests.yml

11
.azure-pipelines/main.yml Normal file
View File

@@ -0,0 +1,11 @@
trigger:
# apache-parser-v2 is a temporary branch for doing work related to
# rewriting the parser in the Apache plugin.
- apache-parser-v2
- master
pr:
- apache-parser-v2
- master
jobs:
- template: templates/tests-suite.yml

View File

@@ -0,0 +1,31 @@
jobs:
- job: installer
pool:
vmImage: vs2017-win2016
steps:
- task: UsePythonVersion@0
inputs:
versionSpec: 3.7
architecture: x86
addToPath: true
- script: python windows-installer/construct.py
displayName: Build Certbot installer
- task: CopyFiles@2
inputs:
sourceFolder: $(System.DefaultWorkingDirectory)/windows-installer/build/nsis
contents: '*.exe'
targetFolder: $(Build.ArtifactStagingDirectory)
- task: PublishPipelineArtifact@1
inputs:
path: $(Build.ArtifactStagingDirectory)
artifact: WindowsInstaller
- script: $(Build.ArtifactStagingDirectory)\certbot-installer-win32.exe /S
displayName: Install Certbot
- script: |
python -m venv venv
venv\Scripts\python tools\pip_install.py -e certbot-ci
displayName: Prepare Certbot-CI
- script: |
set PATH=%ProgramFiles(x86)%\Certbot\bin;%PATH%
venv\Scripts\python -m pytest certbot-ci\certbot_integration_tests\certbot_tests -n 4
displayName: Run integration tests

View File

@@ -0,0 +1,38 @@
jobs:
- job: test
pool:
vmImage: vs2017-win2016
strategy:
matrix:
py35:
PYTHON_VERSION: 3.5
TOXENV: py35
py37-cover:
PYTHON_VERSION: 3.7
TOXENV: py37-cover
integration-certbot:
PYTHON_VERSION: 3.7
TOXENV: integration-certbot
PYTEST_ADDOPTS: --numprocesses 4
variables:
- group: certbot-common
steps:
- task: UsePythonVersion@0
inputs:
versionSpec: $(PYTHON_VERSION)
addToPath: true
- script: python tools/pip_install.py -U tox coverage
displayName: Install dependencies
- script: python -m tox
displayName: Run tox
# We do not require codecov report upload to succeed. So to avoid to break the pipeline if
# something goes wrong, each command is suffixed with a command that hides any non zero exit
# codes and echoes an informative message instead.
- bash: |
curl -s https://codecov.io/bash -o codecov-bash || echo "Failed to download codecov-bash"
chmod +x codecov-bash || echo "Failed to apply execute permissions on codecov-bash"
./codecov-bash -F windows || echo "Codecov did not collect coverage reports"
condition: eq(variables['TOXENV'], 'py37-cover')
env:
CODECOV_TOKEN: $(codecov_token)
displayName: Publish coverage

View File

@@ -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.6
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.0
target: 97.7
threshold: 0.1
base: auto

View File

@@ -1,2 +1,5 @@
[run]
omit = */setup.py
[report]
omit = */setup.py

View File

@@ -1,4 +1,5 @@
language: python
dist: xenial
cache:
directories:
@@ -8,6 +9,8 @@ before_script:
- '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 +40,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
@@ -55,20 +56,20 @@ matrix:
env: TOXENV=mypy
<<: *not-on-master
- python: "2.7"
# 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
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
- python: "3.8-dev"
env: TOXENV=py38
<<: *not-on-master
- sudo: required
env: TOXENV=apache_compat
@@ -82,8 +83,6 @@ matrix:
<<: *not-on-master
- python: "2.7"
env: TOXENV=apacheconftest-with-pebble
sudo: required
services: docker
<<: *not-on-master
- python: "2.7"
env: TOXENV=nginxroundtrip
@@ -119,7 +118,6 @@ 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"
@@ -132,29 +130,39 @@ matrix:
sudo: required
services: docker
<<: *extended-test-suite
- python: "2.7"
env: TOXENV=py27-certbot-oldest
<<: *extended-test-suite
- python: "2.7"
env: TOXENV=py27-nginx-oldest
<<: *extended-test-suite
- python: "2.7"
env: ACME_SERVER=boulder-v1 TOXENV=integration-certbot-oldest
# 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
sudo: required
services: docker
<<: *extended-test-suite
- python: "2.7"
env: ACME_SERVER=boulder-v2 TOXENV=integration-certbot-oldest
# 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
sudo: required
services: docker
<<: *extended-test-suite
- python: "2.7"
env: ACME_SERVER=boulder-v1 TOXENV=integration-nginx-oldest
# 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
sudo: required
services: docker
<<: *extended-test-suite
- python: "2.7"
env: ACME_SERVER=boulder-v2 TOXENV=integration-nginx-oldest
# 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
sudo: required
services: docker
<<: *extended-test-suite
@@ -168,9 +176,11 @@ 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
@@ -202,17 +212,21 @@ matrix:
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
- python: "3.8-dev"
env: ACME_SERVER=boulder-v1 TOXENV=integration
<<: *extended-test-suite
- python: "3.8-dev"
env: ACME_SERVER=boulder-v2 TOXENV=integration
<<: *extended-test-suite
- sudo: required
env: TOXENV=le_auto_jessie
services: docker
@@ -275,8 +289,12 @@ addons:
# 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'

View File

@@ -15,8 +15,10 @@ Authors
* [Alex Gaynor](https://github.com/alex)
* [Alex Halderman](https://github.com/jhalderm)
* [Alex Jordan](https://github.com/strugee)
* [Alex Zorin](https://github.com/alexzorin)
* [Amjad Mashaal](https://github.com/TheNavigat)
* [Andrew Murray](https://github.com/radarhere)
* [Andrzej Górski](https://github.com/andrzej3393)
* [Anselm Levskaya](https://github.com/levskaya)
* [Antoine Jacoutot](https://github.com/ajacoutot)
* [asaph](https://github.com/asaph)
@@ -126,6 +128,7 @@ Authors
* [Joubin Jabbari](https://github.com/joubin)
* [Juho Juopperi](https://github.com/jkjuopperi)
* [Kane York](https://github.com/riking)
* [Kenichi Maehashi](https://github.com/kmaehashi)
* [Kenneth Skovhede](https://github.com/kenkendk)
* [Kevin Burke](https://github.com/kevinburke)
* [Kevin London](https://github.com/kevinlondon)
@@ -161,6 +164,7 @@ Authors
* [Michael Schumacher](https://github.com/schumaml)
* [Michael Strache](https://github.com/Jarodiv)
* [Michael Sverdlin](https://github.com/sveder)
* [Michael Watters](https://github.com/blackknight36)
* [Michal Moravec](https://github.com/https://github.com/Majkl578)
* [Michal Papis](https://github.com/mpapis)
* [Minn Soe](https://github.com/MinnSoe)

View File

@@ -2,7 +2,96 @@
Certbot adheres to [Semantic Versioning](https://semver.org/).
## 0.36.0 - master
## 0.40.0 - master
### Added
*
### Changed
* Removed `--fast` flag from the test farm tests
### Fixed
*
More details about these changes can be found on our GitHub repo.
## 0.39.0 - 2019-10-01
### Added
* Support for Python 3.8 was added to Certbot and all of its components.
* Support for CentOS 8 was added to certbot-auto.
### Changed
* Don't send OCSP requests for expired certificates
* Return to using platform.linux_distribution instead of distro.linux_distribution in OS fingerprinting for Python < 3.8
* Updated the Nginx plugin's TLS configuration to keep support for some versions of IE11.
### Fixed
* Fixed OS detection in the Apache plugin on RHEL 6.
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.
## 0.37.1 - 2019-08-08
### Fixed
* Stop disabling TLS session tickets in Apache as it caused TLS failures on
some systems.
More details about these changes can be found on our GitHub repo.
## 0.37.0 - 2019-08-07
### Added
* Turn off session tickets for apache plugin by default
* acme: Authz deactivation added to `acme` module.
### Changed
* Follow updated Mozilla recommendations for Nginx ssl_protocols, ssl_ciphers,
and ssl_prefer_server_ciphers
### Fixed
* Fix certbot-auto failures on RHEL 8.
More details about these changes can be found on our GitHub repo.
## 0.36.0 - 2019-07-11
### Added

View File

@@ -1,35 +0,0 @@
FROM python:2-alpine3.9
ENTRYPOINT [ "certbot" ]
EXPOSE 80 443
VOLUME /etc/letsencrypt /var/lib/letsencrypt
WORKDIR /opt/certbot
COPY CHANGELOG.md README.rst setup.py src/
# Generate constraints file to pin dependency versions
COPY letsencrypt-auto-source/pieces/dependency-requirements.txt .
COPY tools /opt/certbot/tools
RUN sh -c 'cat dependency-requirements.txt | /opt/certbot/tools/strip_hashes.py > unhashed_requirements.txt'
RUN sh -c 'cat tools/dev_constraints.txt unhashed_requirements.txt | /opt/certbot/tools/merge_requirements.py > docker_constraints.txt'
COPY acme src/acme
COPY certbot src/certbot
RUN apk add --no-cache --virtual .certbot-deps \
libffi \
libssl1.1 \
openssl \
ca-certificates \
binutils
RUN apk add --no-cache --virtual .build-deps \
gcc \
linux-headers \
openssl-dev \
musl-dev \
libffi-dev \
&& pip install -r /opt/certbot/dependency-requirements.txt \
&& pip install --no-cache-dir --no-deps \
--editable /opt/certbot/src/acme \
--editable /opt/certbot/src \
&& apk del .build-deps

View File

@@ -1,5 +1,5 @@
# This Dockerfile builds an image for development.
FROM ubuntu:xenial
FROM debian:buster
# Note: this only exposes the port to other docker containers.
EXPOSE 80 443

View File

@@ -123,6 +123,21 @@ class ClientBase(object): # pylint: disable=too-many-instance-attributes
"""
return self.update_registration(regr, update={'status': 'deactivated'})
def deactivate_authorization(self, authzr):
# type: (messages.AuthorizationResource) -> messages.AuthorizationResource
"""Deactivate authorization.
:param messages.AuthorizationResource authzr: The Authorization resource
to be deactivated.
:returns: The Authorization resource that was deactivated.
:rtype: `.AuthorizationResource`
"""
body = messages.UpdateAuthorization(status='deactivated')
response = self._post(authzr.uri, body)
return self._authzr_from_response(response)
def _authzr_from_response(self, response, identifier=None, uri=None):
authzr = messages.AuthorizationResource(
body=messages.Authorization.from_json(response.json()),

View File

@@ -637,6 +637,14 @@ class ClientTest(ClientTestBase):
errors.PollError, self.client.poll_and_request_issuance,
csr, authzrs, mintime=mintime, max_attempts=2)
def test_deactivate_authorization(self):
authzb = self.authzr.body.update(status=messages.STATUS_DEACTIVATED)
self.response.json.return_value = authzb.to_json()
authzr = self.client.deactivate_authorization(self.authzr)
self.assertEqual(authzb, authzr.body)
self.assertEqual(self.client.net.post.call_count, 1)
self.assertTrue(self.authzr.uri in self.net.post.call_args_list[0][0])
def test_check_cert(self):
self.response.headers['Location'] = self.certr.uri
self.response.content = CERT_DER

View File

@@ -168,6 +168,7 @@ STATUS_VALID = Status('valid')
STATUS_INVALID = Status('invalid')
STATUS_REVOKED = Status('revoked')
STATUS_READY = Status('ready')
STATUS_DEACTIVATED = Status('deactivated')
class IdentifierType(_Constant):
@@ -471,7 +472,7 @@ class Authorization(ResourceBody):
:ivar datetime.datetime expires:
"""
identifier = jose.Field('identifier', decoder=Identifier.from_json)
identifier = jose.Field('identifier', decoder=Identifier.from_json, omitempty=True)
challenges = jose.Field('challenges', omitempty=True)
combinations = jose.Field('combinations', omitempty=True)
@@ -501,6 +502,12 @@ class NewAuthorization(Authorization):
resource = fields.Resource(resource_type)
class UpdateAuthorization(Authorization):
"""Update authorization."""
resource_type = 'authz'
resource = fields.Resource(resource_type)
class AuthorizationResource(ResourceWithURI):
"""Authorization Resource.

View File

@@ -3,7 +3,7 @@ from setuptools import find_packages
from setuptools.command.test import test as TestCommand
import sys
version = '0.36.0.dev0'
version = '0.40.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',
],

View File

@@ -4,6 +4,7 @@ environment:
matrix:
- TOXENV: py35
- TOXENV: py37-cover
- TOXENV: integration-certbot
branches:
only:
@@ -24,14 +25,16 @@ init:
install:
# Use Python 3.7 by default
- "SET PATH=C:\\Python37;C:\\Python37\\Scripts;%PATH%"
- SET PATH=C:\\Python37;C:\\Python37\\Scripts;%PATH%
# Using 4 processes is proven to be the most efficient integration tests config for AppVeyor
- IF %TOXENV%==integration-certbot SET PYTEST_ADDOPTS=--numprocesses=4
# Check env
- "python --version"
- python --version
# Upgrade pip to avoid warnings
- "python -m pip install --upgrade pip"
- python -m pip install --upgrade pip
# Ready to install tox and coverage
# tools/pip_install.py is used to pin packages to a known working version.
- "python tools\\pip_install.py tox codecov"
- python tools\\pip_install.py tox codecov
build: off

View File

@@ -23,6 +23,7 @@ from certbot import interfaces
from certbot import util
from certbot.achallenges import KeyAuthorizationAnnotatedChallenge # pylint: disable=unused-import
from certbot.compat import filesystem
from certbot.compat import os
from certbot.plugins import common
from certbot.plugins.util import path_surgery
@@ -895,7 +896,7 @@ class ApacheConfigurator(common.Installer):
if not new_vhost:
continue
internal_path = apache_util.get_internal_aug_path(new_vhost.path)
realpath = os.path.realpath(new_vhost.filep)
realpath = filesystem.realpath(new_vhost.filep)
if realpath not in file_paths:
file_paths[realpath] = new_vhost.filep
internal_paths[realpath].add(internal_path)
@@ -1221,11 +1222,11 @@ class ApacheConfigurator(common.Installer):
"""
if self.conf("vhost-root") and os.path.exists(self.conf("vhost-root")):
fp = os.path.join(os.path.realpath(self.option("vhost_root")),
fp = os.path.join(filesystem.realpath(self.option("vhost_root")),
os.path.basename(non_ssl_vh_fp))
else:
# Use non-ssl filepath
fp = os.path.realpath(non_ssl_vh_fp)
fp = filesystem.realpath(non_ssl_vh_fp)
if fp.endswith(".conf"):
return fp[:-(len(".conf"))] + self.option("le_vhost_ext")

View File

@@ -9,6 +9,7 @@ MOD_SSL_CONF_DEST = "options-ssl-apache.conf"
UPDATED_MOD_SSL_CONF_DIGEST = ".updated-options-ssl-apache-conf-digest.txt"
"""Name of the hash of the updated or informed mod_ssl_conf as saved in `IConfig.config_dir`."""
# NEVER REMOVE A SINGLE HASH FROM THIS LIST UNLESS YOU KNOW EXACTLY WHAT YOU ARE DOING!
ALL_SSL_OPTIONS_HASHES = [
'2086bca02db48daf93468332543c60ac6acdb6f0b58c7bfdf578a5d47092f82a',
'4844d36c9a0f587172d9fa10f4f1c9518e3bcfa1947379f155e16a70a728c21a',
@@ -18,6 +19,10 @@ ALL_SSL_OPTIONS_HASHES = [
'cfdd7c18d2025836ea3307399f509cfb1ebf2612c87dd600a65da2a8e2f2797b',
'80720bd171ccdc2e6b917ded340defae66919e4624962396b992b7218a561791',
'c0c022ea6b8a51ecc8f1003d0a04af6c3f2bc1c3ce506b3c2dfc1f11ef931082',
'717b0a89f5e4c39b09a42813ac6e747cfbdeb93439499e73f4f70a1fe1473f20',
'0fcdc81280cd179a07ec4d29d3595068b9326b455c488de4b09f585d5dafc137',
'86cc09ad5415cd6d5f09a947fe2501a9344328b1e8a8b458107ea903e80baa6c',
'06675349e457eae856120cdebb564efe546f0b87399f2264baeb41e442c724c7',
]
"""SHA256 hashes of the contents of previous versions of all versions of MOD_SSL_CONF_SRC"""

View File

@@ -24,6 +24,7 @@ OVERRIDE_CLASSES = {
"fedora_old": override_centos.CentOSConfigurator,
"fedora": override_fedora.FedoraConfigurator,
"ol": override_centos.CentOSConfigurator,
"redhatenterpriseserver": override_centos.CentOSConfigurator,
"red hat enterprise linux server": override_centos.CentOSConfigurator,
"rhel": override_centos.CentOSConfigurator,
"amazon": override_centos.CentOSConfigurator,
@@ -31,6 +32,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,
}

View File

@@ -7,6 +7,7 @@ import zope.interface
from certbot import errors
from certbot import interfaces
from certbot import util
from certbot.compat import filesystem
from certbot.compat import os
from certbot_apache import apache_util
@@ -65,7 +66,7 @@ class DebianConfigurator(configurator.ApacheConfigurator):
try:
os.symlink(vhost.filep, enabled_path)
except OSError as err:
if os.path.islink(enabled_path) and os.path.realpath(
if os.path.islink(enabled_path) and filesystem.realpath(
enabled_path) == vhost.filep:
# Already in shape
vhost.enabled = True

View File

@@ -4,6 +4,7 @@ import unittest
import mock
from certbot import errors
from certbot.compat import filesystem
from certbot.compat import os
from certbot_apache import obj
@@ -160,7 +161,7 @@ class MultipleVhostsTestCentOS(util.ApacheTest):
"""Make sure we read the sysconfig OPTIONS variable correctly"""
# Return nothing for the process calls
mock_cfg.return_value = ""
self.config.parser.sysconfig_filep = os.path.realpath(
self.config.parser.sysconfig_filep = filesystem.realpath(
os.path.join(self.config.parser.root, "../sysconfig/httpd"))
self.config.parser.variables = {}

View File

@@ -675,8 +675,7 @@ class MultipleVhostsTest(util.ApacheTest):
def test_make_vhost_ssl_nonexistent_vhost_path(self):
ssl_vhost = self.config.make_vhost_ssl(self.vh_truth[1])
self.assertEqual(os.path.dirname(ssl_vhost.filep),
os.path.dirname(os.path.realpath(
self.vh_truth[1].filep)))
os.path.dirname(filesystem.realpath(self.vh_truth[1].filep)))
def test_make_vhost_ssl(self):
ssl_vhost = self.config.make_vhost_ssl(self.vh_truth[0])
@@ -1336,7 +1335,7 @@ class MultipleVhostsTest(util.ApacheTest):
self.config.parser.modules.add("ssl_module")
self.config.parser.modules.add("mod_ssl.c")
self.config.parser.modules.add("socache_shmcb_module")
tmp_path = os.path.realpath(tempfile.mkdtemp("vhostroot"))
tmp_path = filesystem.realpath(tempfile.mkdtemp("vhostroot"))
filesystem.chmod(tmp_path, 0o755)
mock_p = "certbot_apache.configurator.ApacheConfigurator._get_ssl_vhost_path"
mock_a = "certbot_apache.parser.ApacheParser.add_include"

View File

@@ -79,9 +79,9 @@ class MultipleVhostsTestDebian(util.ApacheTest):
def test_enable_site_failure(self):
self.config.parser.root = "/tmp/nonexistent"
with mock.patch("os.path.isdir") as mock_dir:
with mock.patch("certbot.compat.os.path.isdir") as mock_dir:
mock_dir.return_value = True
with mock.patch("os.path.islink") as mock_link:
with mock.patch("certbot.compat.os.path.islink") as mock_link:
mock_link.return_value = False
self.assertRaises(
errors.NotSupportedError,

View File

@@ -4,6 +4,7 @@ import unittest
import mock
from certbot import errors
from certbot.compat import filesystem
from certbot.compat import os
from certbot_apache import obj
@@ -160,7 +161,7 @@ class MultipleVhostsTestFedora(util.ApacheTest):
"""Make sure we read the sysconfig OPTIONS variable correctly"""
# Return nothing for the process calls
mock_cfg.return_value = ""
self.config.parser.sysconfig_filep = os.path.realpath(
self.config.parser.sysconfig_filep = filesystem.realpath(
os.path.join(self.config.parser.root, "../sysconfig/httpd"))
self.config.parser.variables = {}

View File

@@ -4,6 +4,7 @@ import unittest
import mock
from certbot import errors
from certbot.compat import filesystem
from certbot.compat import os
from certbot_apache import obj
@@ -81,7 +82,7 @@ class MultipleVhostsTestGentoo(util.ApacheTest):
"""Make sure we read the Gentoo APACHE2_OPTS variable correctly"""
defines = ['DEFAULT_VHOST', 'INFO',
'SSL', 'SSL_DEFAULT_VHOST', 'LANGUAGE']
self.config.parser.apacheconfig_filep = os.path.realpath(
self.config.parser.apacheconfig_filep = filesystem.realpath(
os.path.join(self.config.parser.root, "../conf.d/apache2"))
self.config.parser.variables = {}
with mock.patch("certbot_apache.override_gentoo.GentooParser.update_modules"):

View File

@@ -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

View File

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

View File

@@ -4,13 +4,13 @@ from setuptools.command.test import test as TestCommand
import sys
version = '0.36.0.dev0'
version = '0.40.0.dev0'
# Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version.
install_requires = [
'acme>=0.29.0',
'certbot>=0.36.0.dev0',
'certbot>=0.39.0',
'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',

View File

@@ -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.35.1"
LE_AUTO_VERSION="0.39.0"
BASENAME=$(basename $0)
USAGE="Usage: $BASENAME [OPTIONS]
A self-updating wrapper script for the Certbot ACME client. When run, updates
@@ -755,13 +755,33 @@ elif [ -f /etc/redhat-release ]; then
prev_le_python="$LE_PYTHON"
unset LE_PYTHON
DeterminePythonVersion "NOCRASH"
# Starting to Fedora 29, python2 is on a deprecation path. Let's move to python3 then.
RPM_DIST_NAME=`(. /etc/os-release 2> /dev/null && echo $ID) || echo "unknown"`
RPM_DIST_VERSION=0
if [ "$RPM_DIST_NAME" = "fedora" ]; then
RPM_DIST_VERSION=`(. /etc/os-release 2> /dev/null && echo $VERSION_ID) || echo "0"`
# Set RPM_DIST_VERSION to VERSION_ID from /etc/os-release after splitting on
# '.' characters (e.g. "8.0" becomes "8"). If the command exits with an
# error, RPM_DIST_VERSION is set to "unknown".
RPM_DIST_VERSION=$( (. /etc/os-release 2> /dev/null && echo "$VERSION_ID") | cut -d '.' -f1 || echo "unknown")
# If RPM_DIST_VERSION is an empty string or it contains any nonnumeric
# characters, the value is unexpected so we set RPM_DIST_VERSION to 0.
if [ -z "$RPM_DIST_VERSION" ] || [ -n "$(echo "$RPM_DIST_VERSION" | tr -d '[0-9]')" ]; then
RPM_DIST_VERSION=0
fi
# Starting to Fedora 29, python2 is on a deprecation path. Let's move to python3 then.
# RHEL 8 also uses python3 by default.
if [ "$RPM_DIST_NAME" = "fedora" -a "$RPM_DIST_VERSION" -ge 29 -o "$PYVER" -eq 26 ]; then
RPM_USE_PYTHON_3=1
elif [ "$RPM_DIST_NAME" = "rhel" -a "$RPM_DIST_VERSION" -ge 8 ]; then
RPM_USE_PYTHON_3=1
elif [ "$RPM_DIST_NAME" = "centos" -a "$RPM_DIST_VERSION" -ge 8 ]; then
RPM_USE_PYTHON_3=1
else
RPM_USE_PYTHON_3=0
fi
if [ "$RPM_USE_PYTHON_3" = 1 ]; then
Bootstrap() {
BootstrapMessage "RedHat-based OSes that will use Python3"
BootstrapRpmPython3
@@ -775,6 +795,7 @@ elif [ -f /etc/redhat-release ]; then
}
BOOTSTRAP_VERSION="BootstrapRpmCommon $BOOTSTRAP_RPM_COMMON_VERSION"
fi
LE_PYTHON="$prev_le_python"
elif [ -f /etc/os-release ] && `grep -q openSUSE /etc/os-release` ; then
Bootstrap() {
@@ -1115,73 +1136,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 \
@@ -1197,18 +1221,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
@@ -1217,14 +1241,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
@@ -1234,15 +1258,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
@@ -1290,18 +1314,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.
#
@@ -1314,18 +1338,18 @@ letsencrypt==0.7.0 \
--hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \
--hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9
certbot==0.35.1 \
--hash=sha256:24821e10b05084a45c5bf29da704115f2637af613866589737cff502294dad2a \
--hash=sha256:d7e8ecc14e06ed1dc691c6069bc9ce42dce04e8db1684ddfab446fbd71290860
acme==0.35.1 \
--hash=sha256:3ec62f638f2b3684bcb3d8476345c7ae37c8f3b28f2999622ff836aec6e73d64 \
--hash=sha256:a988b8b418cc74075e68b4acf3ff64c026bf52c377b0d01223233660a755c423
certbot-apache==0.35.1 \
--hash=sha256:ee4fe10cbd18e0aa7fe36d43ad7792187f41a7298f383610b87049c3a6493bbb \
--hash=sha256:69962eafe0ec9be8eb2845e3622da6f37ecaeee7e517ea172d71d7b31f01be71
certbot-nginx==0.35.1 \
--hash=sha256:22150f13b3c0bd1c3c58b11a64886dad9695796aac42f5809da7ec66de187760 \
--hash=sha256:85e9a48b4b549f6989304f66cb2fad822c3f8717d361bde0d6a43aabb792d461
certbot==0.39.0 \
--hash=sha256:f1a70651a6c5137a448f4a8db17b09af619f80a077326caae6b74278bf1db488 \
--hash=sha256:885cee1c4d05888af86b626cbbfc29d3c6c842ef4fe8f4a486994cef9daddfe0
acme==0.39.0 \
--hash=sha256:4f8be913df289b981852042719469cc367a7e436256f232c799d0bd1521db710 \
--hash=sha256:a2fcb75d16de6804f4b4d773a457ee2f6434ebaf8fd1aa60862a91d4e8f73608
certbot-apache==0.39.0 \
--hash=sha256:c7a8630a85b753a52ca0b8c19e24b8f85ac4ba028292a95745e250c2e72faab9 \
--hash=sha256:4651a0212c9ebc3087281dad92ad3cb355bb2730f432d0180a8d23325d11825a
certbot-nginx==0.39.0 \
--hash=sha256:76e5862ad5cc0fbc099df3502987c101c60dee1c188a579eac990edee7a910df \
--hash=sha256:ceac88df52d3b27d14c3052b9e90ada327d7e14ecd6e4af7519918182d6138b4
UNLIKELY_EOF
# -------------------------------------------------------------------------

View File

@@ -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.

View File

@@ -0,0 +1,11 @@
#!/usr/bin/env python
import sys
import os
hook_script_type = os.path.basename(os.path.dirname(sys.argv[1]))
if hook_script_type == 'deploy' and ('RENEWED_DOMAINS' not in os.environ or 'RENEWED_LINEAGE' not in os.environ):
sys.stderr.write('Environment variables not properly set!\n')
sys.exit(1)
with open(sys.argv[2], 'a') as file_h:
file_h.write(hook_script_type + '\n')

View File

@@ -1,6 +1,17 @@
"""This module contains advanced assertions for the certbot integration tests."""
import os
import grp
try:
import grp
POSIX_MODE = True
except ImportError:
import win32api
import win32security
import ntsecuritycon
POSIX_MODE = False
EVERYBODY_SID = 'S-1-1-0'
SYSTEM_SID = 'S-1-5-18'
ADMINS_SID = 'S-1-5-32-544'
def assert_hook_execution(probe_path, probe_content):
@@ -10,9 +21,10 @@ def assert_hook_execution(probe_path, probe_content):
:param probe_content: content expected when the hook is executed
"""
with open(probe_path, 'r') as file:
lines = file.readlines()
data = file.read()
assert '{0}{1}'.format(probe_content, os.linesep) in lines
lines = [line.strip() for line in data.splitlines()]
assert probe_content in lines
def assert_saved_renew_hook(config_dir, lineage):
@@ -38,16 +50,51 @@ def assert_cert_count_for_lineage(config_dir, lineage, count):
assert len(certs) == count
def assert_equals_permissions(file1, file2, mask):
def assert_equals_group_permissions(file1, file2):
"""
Assert that permissions on two files are identical in respect to a given umask.
Assert that two files have the same permissions for group owner.
:param file1: first file path to compare
:param file2: second file path to compare
:param mask: 3-octal representation of a POSIX umask under which the two files mode
should match (eg. 0o074 will test RWX on group and R on world)
"""
mode_file1 = os.stat(file1).st_mode & mask
mode_file2 = os.stat(file2).st_mode & mask
# On Windows there is no group, so this assertion does nothing on this platform
if POSIX_MODE:
mode_file1 = os.stat(file1).st_mode & 0o070
mode_file2 = os.stat(file2).st_mode & 0o070
assert mode_file1 == mode_file2
def assert_equals_world_read_permissions(file1, file2):
"""
Assert that two files have the same read permissions for everyone.
:param file1: first file path to compare
:param file2: second file path to compare
"""
if POSIX_MODE:
mode_file1 = os.stat(file1).st_mode & 0o004
mode_file2 = os.stat(file2).st_mode & 0o004
else:
everybody = win32security.ConvertStringSidToSid(EVERYBODY_SID)
security1 = win32security.GetFileSecurity(file1, win32security.DACL_SECURITY_INFORMATION)
dacl1 = security1.GetSecurityDescriptorDacl()
mode_file1 = dacl1.GetEffectiveRightsFromAcl({
'TrusteeForm': win32security.TRUSTEE_IS_SID,
'TrusteeType': win32security.TRUSTEE_IS_USER,
'Identifier': everybody,
})
mode_file1 = mode_file1 & ntsecuritycon.FILE_GENERIC_READ
security2 = win32security.GetFileSecurity(file2, win32security.DACL_SECURITY_INFORMATION)
dacl2 = security2.GetSecurityDescriptorDacl()
mode_file2 = dacl2.GetEffectiveRightsFromAcl({
'TrusteeForm': win32security.TRUSTEE_IS_SID,
'TrusteeType': win32security.TRUSTEE_IS_USER,
'Identifier': everybody,
})
mode_file2 = mode_file2 & ntsecuritycon.FILE_GENERIC_READ
assert mode_file1 == mode_file2
@@ -57,20 +104,57 @@ def assert_equals_group_owner(file1, file2):
Assert that two files have the same group owner.
:param file1: first file path to compare
:param file2: second file path to compare
:return:
"""
group_owner_file1 = grp.getgrgid(os.stat(file1).st_gid)[0]
group_owner_file2 = grp.getgrgid(os.stat(file2).st_gid)[0]
# On Windows there is no group, so this assertion does nothing on this platform
if POSIX_MODE:
group_owner_file1 = grp.getgrgid(os.stat(file1).st_gid)[0]
group_owner_file2 = grp.getgrgid(os.stat(file2).st_gid)[0]
assert group_owner_file1 == group_owner_file2
assert group_owner_file1 == group_owner_file2
def assert_world_permissions(file, mode):
def assert_world_no_permissions(file):
"""
Assert that a file has the expected world permission.
:param file: file path to check
:param mode: world permissions mode expected
Assert that the given file is not world-readable.
:param file: path of the file to check
"""
mode_file_all = os.stat(file).st_mode & 0o007
if POSIX_MODE:
mode_file_all = os.stat(file).st_mode & 0o007
assert mode_file_all == 0
else:
security = win32security.GetFileSecurity(file, win32security.DACL_SECURITY_INFORMATION)
dacl = security.GetSecurityDescriptorDacl()
mode = dacl.GetEffectiveRightsFromAcl({
'TrusteeForm': win32security.TRUSTEE_IS_SID,
'TrusteeType': win32security.TRUSTEE_IS_USER,
'Identifier': win32security.ConvertStringSidToSid(EVERYBODY_SID),
})
assert mode_file_all == mode
assert not mode
def assert_world_read_permissions(file):
"""
Assert that the given file is world-readable, but not world-writable or world-executable.
:param file: path of the file to check
"""
if POSIX_MODE:
mode_file_all = os.stat(file).st_mode & 0o007
assert mode_file_all == 4
else:
security = win32security.GetFileSecurity(file, win32security.DACL_SECURITY_INFORMATION)
dacl = security.GetSecurityDescriptorDacl()
mode = dacl.GetEffectiveRightsFromAcl({
'TrusteeForm': win32security.TRUSTEE_IS_SID,
'TrusteeType': win32security.TRUSTEE_IS_USER,
'Identifier': win32security.ConvertStringSidToSid(EVERYBODY_SID),
})
assert not mode & ntsecuritycon.FILE_GENERIC_WRITE
assert not mode & ntsecuritycon.FILE_GENERIC_EXECUTE
assert mode & ntsecuritycon.FILE_GENERIC_READ == ntsecuritycon.FILE_GENERIC_READ
def _get_current_user():
account_name = win32api.GetUserNameEx(win32api.NameSamCompatible)
return win32security.LookupAccountName(None, account_name)[0]

View File

@@ -1,10 +1,11 @@
"""Module to handle the context of integration tests."""
import logging
import os
import shutil
import sys
import tempfile
from certbot_integration_tests.utils import misc, certbot_call
from certbot_integration_tests.utils import certbot_call
class IntegrationTestsContext(object):
@@ -19,7 +20,7 @@ class IntegrationTestsContext(object):
self.worker_id = 'primary'
acme_xdist = request.config.acme_xdist
self.acme_server =acme_xdist['acme_server']
self.acme_server = acme_xdist['acme_server']
self.directory_url = acme_xdist['directory_url']
self.tls_alpn_01_port = acme_xdist['https_port'][self.worker_id]
self.http_01_port = acme_xdist['http_port'][self.worker_id]
@@ -30,7 +31,10 @@ class IntegrationTestsContext(object):
self.workspace = tempfile.mkdtemp()
self.config_dir = os.path.join(self.workspace, 'conf')
self.hook_probe = tempfile.mkstemp(dir=self.workspace)[1]
probe = tempfile.mkstemp(dir=self.workspace)
os.close(probe[0])
self.hook_probe = probe[1]
self.manual_dns_auth_hook = (
'{0} -c "import os; import requests; import json; '

View File

@@ -11,8 +11,11 @@ from os.path import join, exists
import pytest
from certbot_integration_tests.certbot_tests import context as certbot_context
from certbot_integration_tests.certbot_tests.assertions import (
assert_hook_execution, assert_saved_renew_hook, assert_cert_count_for_lineage,
assert_world_permissions, assert_equals_group_owner, assert_equals_permissions,
assert_hook_execution, assert_saved_renew_hook,
assert_cert_count_for_lineage,
assert_world_no_permissions, assert_world_read_permissions,
assert_equals_group_owner, assert_equals_group_permissions, assert_equals_world_read_permissions,
EVERYBODY_SID
)
from certbot_integration_tests.utils import misc
@@ -84,9 +87,9 @@ def test_http_01(context):
context.certbot([
'--domains', certname, '--preferred-challenges', 'http-01', 'run',
'--cert-name', certname,
'--pre-hook', 'echo wtf.pre >> "{0}"'.format(context.hook_probe),
'--post-hook', 'echo wtf.post >> "{0}"'.format(context.hook_probe),
'--deploy-hook', 'echo deploy >> "{0}"'.format(context.hook_probe)
'--pre-hook', misc.echo('wtf_pre', context.hook_probe),
'--post-hook', misc.echo('wtf_post', context.hook_probe),
'--deploy-hook', misc.echo('deploy', context.hook_probe),
])
assert_hook_execution(context.hook_probe, 'deploy')
@@ -104,9 +107,9 @@ def test_manual_http_auth(context):
'--cert-name', certname,
'--manual-auth-hook', scripts[0],
'--manual-cleanup-hook', scripts[1],
'--pre-hook', 'echo wtf.pre >> "{0}"'.format(context.hook_probe),
'--post-hook', 'echo wtf.post >> "{0}"'.format(context.hook_probe),
'--renew-hook', 'echo renew >> "{0}"'.format(context.hook_probe)
'--pre-hook', misc.echo('wtf_pre', context.hook_probe),
'--post-hook', misc.echo('wtf_post', context.hook_probe),
'--renew-hook', misc.echo('renew', context.hook_probe),
])
with pytest.raises(AssertionError):
@@ -122,9 +125,9 @@ def test_manual_dns_auth(context):
'run', '--cert-name', certname,
'--manual-auth-hook', context.manual_dns_auth_hook,
'--manual-cleanup-hook', context.manual_dns_cleanup_hook,
'--pre-hook', 'echo wtf.pre >> "{0}"'.format(context.hook_probe),
'--post-hook', 'echo wtf.post >> "{0}"'.format(context.hook_probe),
'--renew-hook', 'echo renew >> "{0}"'.format(context.hook_probe)
'--pre-hook', misc.echo('wtf_pre', context.hook_probe),
'--post-hook', misc.echo('wtf_post', context.hook_probe),
'--renew-hook', misc.echo('renew', context.hook_probe),
])
with pytest.raises(AssertionError):
@@ -173,21 +176,19 @@ def test_renew_files_permissions(context):
certname = context.get_domain('renew')
context.certbot(['-d', certname])
privkey1 = join(context.config_dir, 'archive', certname, 'privkey1.pem')
privkey2 = join(context.config_dir, 'archive', certname, 'privkey2.pem')
assert_cert_count_for_lineage(context.config_dir, certname, 1)
assert_world_permissions(
join(context.config_dir, 'archive', certname, 'privkey1.pem'), 0)
assert_world_no_permissions(privkey1)
context.certbot(['renew'])
assert_cert_count_for_lineage(context.config_dir, certname, 2)
assert_world_permissions(
join(context.config_dir, 'archive', certname, 'privkey2.pem'), 0)
assert_equals_group_owner(
join(context.config_dir, 'archive', certname, 'privkey1.pem'),
join(context.config_dir, 'archive', certname, 'privkey2.pem'))
assert_equals_permissions(
join(context.config_dir, 'archive', certname, 'privkey1.pem'),
join(context.config_dir, 'archive', certname, 'privkey2.pem'), 0o074)
assert_world_no_permissions(privkey2)
assert_equals_group_owner(privkey1, privkey2)
assert_equals_world_read_permissions(privkey1, privkey2)
assert_equals_group_permissions(privkey1, privkey2)
def test_renew_with_hook_scripts(context):
@@ -211,15 +212,35 @@ def test_renew_files_propagate_permissions(context):
assert_cert_count_for_lineage(context.config_dir, certname, 1)
os.chmod(join(context.config_dir, 'archive', certname, 'privkey1.pem'), 0o444)
privkey1 = join(context.config_dir, 'archive', certname, 'privkey1.pem')
privkey2 = join(context.config_dir, 'archive', certname, 'privkey2.pem')
if os.name != 'nt':
os.chmod(privkey1, 0o444)
else:
import win32security
import ntsecuritycon
# Get the current DACL of the private key
security = win32security.GetFileSecurity(privkey1, win32security.DACL_SECURITY_INFORMATION)
dacl = security.GetSecurityDescriptorDacl()
# Create a read permission for Everybody group
everybody = win32security.ConvertStringSidToSid(EVERYBODY_SID)
dacl.AddAccessAllowedAce(win32security.ACL_REVISION, ntsecuritycon.FILE_GENERIC_READ, everybody)
# Apply the updated DACL to the private key
security.SetSecurityDescriptorDacl(1, dacl, 0)
win32security.SetFileSecurity(privkey1, win32security.DACL_SECURITY_INFORMATION, security)
context.certbot(['renew'])
assert_cert_count_for_lineage(context.config_dir, certname, 2)
assert_world_permissions(
join(context.config_dir, 'archive', certname, 'privkey2.pem'), 4)
assert_equals_permissions(
join(context.config_dir, 'archive', certname, 'privkey1.pem'),
join(context.config_dir, 'archive', certname, 'privkey2.pem'), 0o074)
if os.name != 'nt':
# On Linux, read world permissions + all group permissions will be copied from the previous private key
assert_world_read_permissions(privkey2)
assert_equals_world_read_permissions(privkey1, privkey2)
assert_equals_group_permissions(privkey1, privkey2)
else:
# On Windows, world will never have any permissions, and group permission is irrelevant for this platform
assert_world_no_permissions(privkey2)
def test_graceful_renew_it_is_not_time(context):
@@ -229,7 +250,7 @@ def test_graceful_renew_it_is_not_time(context):
assert_cert_count_for_lineage(context.config_dir, certname, 1)
context.certbot(['renew', '--deploy-hook', 'echo deploy >> "{0}"'.format(context.hook_probe)],
context.certbot(['renew', '--deploy-hook', misc.echo('deploy', context.hook_probe)],
force_renew=False)
assert_cert_count_for_lineage(context.config_dir, certname, 1)
@@ -250,7 +271,7 @@ def test_graceful_renew_it_is_time(context):
with open(join(context.config_dir, 'renewal', '{0}.conf'.format(certname)), 'w') as file:
file.writelines(lines)
context.certbot(['renew', '--deploy-hook', 'echo deploy >> "{0}"'.format(context.hook_probe)],
context.certbot(['renew', '--deploy-hook', misc.echo('deploy', context.hook_probe)],
force_renew=False)
assert_cert_count_for_lineage(context.config_dir, certname, 2)
@@ -317,9 +338,9 @@ def test_renew_hook_override(context):
context.certbot([
'certonly', '-d', certname,
'--preferred-challenges', 'http-01',
'--pre-hook', 'echo pre >> "{0}"'.format(context.hook_probe),
'--post-hook', 'echo post >> "{0}"'.format(context.hook_probe),
'--deploy-hook', 'echo deploy >> "{0}"'.format(context.hook_probe)
'--pre-hook', misc.echo('pre', context.hook_probe),
'--post-hook', misc.echo('post', context.hook_probe),
'--deploy-hook', misc.echo('deploy', context.hook_probe),
])
assert_hook_execution(context.hook_probe, 'pre')
@@ -330,14 +351,14 @@ def test_renew_hook_override(context):
open(context.hook_probe, 'w').close()
context.certbot([
'renew', '--cert-name', certname,
'--pre-hook', 'echo pre-override >> "{0}"'.format(context.hook_probe),
'--post-hook', 'echo post-override >> "{0}"'.format(context.hook_probe),
'--deploy-hook', 'echo deploy-override >> "{0}"'.format(context.hook_probe)
'--pre-hook', misc.echo('pre_override', context.hook_probe),
'--post-hook', misc.echo('post_override', context.hook_probe),
'--deploy-hook', misc.echo('deploy_override', context.hook_probe),
])
assert_hook_execution(context.hook_probe, 'pre-override')
assert_hook_execution(context.hook_probe, 'post-override')
assert_hook_execution(context.hook_probe, 'deploy-override')
assert_hook_execution(context.hook_probe, 'pre_override')
assert_hook_execution(context.hook_probe, 'post_override')
assert_hook_execution(context.hook_probe, 'deploy_override')
with pytest.raises(AssertionError):
assert_hook_execution(context.hook_probe, 'pre')
with pytest.raises(AssertionError):
@@ -349,11 +370,11 @@ def test_renew_hook_override(context):
open(context.hook_probe, 'w').close()
context.certbot(['renew', '--cert-name', certname])
assert_hook_execution(context.hook_probe, 'pre-override')
assert_hook_execution(context.hook_probe, 'post-override')
assert_hook_execution(context.hook_probe, 'deploy-override')
assert_hook_execution(context.hook_probe, 'pre_override')
assert_hook_execution(context.hook_probe, 'post_override')
assert_hook_execution(context.hook_probe, 'deploy_override')
def test_invalid_domain_with_dns_challenge(context):
"""Test certificate issuance failure with DNS-01 challenge."""
# Manual dns auth hooks from misc are designed to fail if the domain contains 'fail-*'.
@@ -512,7 +533,7 @@ def test_revoke_multiple_lineages(context):
data = file.read()
data = re.sub('archive_dir = .*\n',
'archive_dir = {0}\n'.format(join(context.config_dir, 'archive', cert1)),
'archive_dir = {0}\n'.format(join(context.config_dir, 'archive', cert1).replace('\\', '\\\\')),
data)
with open(join(context.config_dir, 'renewal', '{0}.conf'.format(cert2)), 'w') as file:
@@ -555,11 +576,9 @@ def test_ocsp_status_stale(context):
def test_ocsp_status_live(context):
"""Test retrieval of OCSP statuses for live config"""
if context.acme_server == 'pebble':
pytest.skip('Pebble does not support OCSP status requests.')
cert = context.get_domain('ocsp-check')
# OSCP 1: Check live certificate OCSP status (VALID)
cert = context.get_domain('ocsp-check')
context.certbot(['--domains', cert])
output = context.certbot(['certificates'])

View File

@@ -134,6 +134,13 @@ class ACMEServer(object):
[challtestsrv_path, '-management', ':{0}'.format(CHALLTESTSRV_PORT), '-defaultIPv6', '""',
'-defaultIPv4', '127.0.0.1', '-http01', '""', '-tlsalpn01', '""', '-https01', '""'])
# pebble_ocsp_server is imported here and not at the top of module in order to avoid a useless
# ImportError, in the case where cryptography dependency is too old to support ocsp, but
# Boulder is used instead of Pebble, so pebble_ocsp_server is not used. This is the typical
# situation of integration-certbot-oldest tox testenv.
from certbot_integration_tests.utils import pebble_ocsp_server
self._launch_process([sys.executable, pebble_ocsp_server.__file__])
# Wait for the ACME CA server to be up.
print('=> Waiting for pebble instance to respond...')
misc.check_until_timeout(self.acme_xdist['directory_url'])
@@ -159,7 +166,7 @@ class ACMEServer(object):
# Wait for the ACME CA server to be up.
print('=> Waiting for boulder instance to respond...')
misc.check_until_timeout(self.acme_xdist['directory_url'])
misc.check_until_timeout(self.acme_xdist['directory_url'], attempts=240)
# Configure challtestsrv to answer any A record request with ip of the docker host.
response = requests.post('http://localhost:{0}/set-default-ipv4'.format(CHALLTESTSRV_PORT),

View File

@@ -6,7 +6,7 @@ import subprocess
import sys
import os
from certbot_integration_tests.utils import misc
import certbot_integration_tests
from certbot_integration_tests.utils.constants import *
@@ -33,18 +33,58 @@ def certbot_test(certbot_args, directory_url, http_01_port, tls_alpn_01_port,
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):
def _prepare_environ(workspace):
new_environ = os.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 = _prepare_environ(workspace)
additional_args = _compute_additional_args(workspace, new_environ, force_renew)
command = [
'certbot',
'--server', directory_url,

View File

@@ -5,3 +5,5 @@ CHALLTESTSRV_PORT = 8055
BOULDER_V1_DIRECTORY_URL = 'http://localhost:4000/directory'
BOULDER_V2_DIRECTORY_URL = 'http://localhost:4001/directory'
PEBBLE_DIRECTORY_URL = 'https://localhost:14000/dir'
PEBBLE_MANAGEMENT_URL = 'https://localhost:15000'
MOCK_OCSP_SERVER_PORT = 4002

View File

@@ -3,9 +3,11 @@ Misc module contains stateless functions that could be used during pytest execut
or outside during setup/teardown of the integration tests environment.
"""
import contextlib
import logging
import errno
import multiprocessing
import os
import re
import shutil
import stat
import subprocess
@@ -23,17 +25,17 @@ from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives.serialization import Encoding, PrivateFormat, NoEncryption
from six.moves import socketserver, SimpleHTTPServer
RSA_KEY_TYPE = 'rsa'
ECDSA_KEY_TYPE = 'ecdsa'
def check_until_timeout(url):
def check_until_timeout(url, attempts=30):
"""
Wait and block until given url responds with status 200, or raise an exception
after 150 attempts.
after the specified number of attempts.
:param str url: the URL to test
:raise ValueError: exception raised after 150 unsuccessful attempts to reach the URL
:param int attempts: the number of times to try to connect to the URL
:raise ValueError: exception raised if unable to reach the URL
"""
try:
import urllib3
@@ -43,7 +45,7 @@ def check_until_timeout(url):
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
for _ in range(0, 150):
for _ in range(attempts):
time.sleep(1)
try:
if requests.get(url, verify=False).status_code == 200:
@@ -51,7 +53,7 @@ def check_until_timeout(url):
except requests.exceptions.ConnectionError:
pass
raise ValueError('Error, url did not respond after 150 attempts: {0}'.format(url))
raise ValueError('Error, url did not respond after {0} attempts: {1}'.format(attempts, url))
class GracefulTCPServer(socketserver.TCPServer):
@@ -62,6 +64,10 @@ class GracefulTCPServer(socketserver.TCPServer):
allow_reuse_address = True
def _run_server(port):
GracefulTCPServer(('', port), SimpleHTTPServer.SimpleHTTPRequestHandler).serve_forever()
@contextlib.contextmanager
def create_http_server(port):
"""
@@ -74,10 +80,7 @@ def create_http_server(port):
current_cwd = os.getcwd()
webroot = tempfile.mkdtemp()
def run():
GracefulTCPServer(('', port), SimpleHTTPServer.SimpleHTTPRequestHandler).serve_forever()
process = multiprocessing.Process(target=run)
process = multiprocessing.Process(target=_run_server, args=(port,))
try:
# SimpleHTTPServer is designed to serve files from the current working directory at the
@@ -119,15 +122,9 @@ def generate_test_file_hooks(config_dir, hook_probe):
:param str config_dir: current certbot config directory
:param hook_probe: path to the hook probe to test hook scripts execution
"""
if sys.platform == 'win32':
extension = 'bat'
else:
extension = 'sh'
hook_path = pkg_resources.resource_filename('certbot_integration_tests', 'assets/hook.py')
renewal_hooks_dirs = list_renewal_hooks_dirs(config_dir)
renewal_deploy_hook_path = os.path.join(renewal_hooks_dirs[1], 'hook.sh')
for hook_dir in renewal_hooks_dirs:
for hook_dir in list_renewal_hooks_dirs(config_dir):
# We want an equivalent of bash `chmod -p $HOOK_DIR, that does not fail if one folder of
# the hierarchy already exists. It is not the case of os.makedirs. Python 3 has an
# optional parameter `exists_ok` to not fail on existing dir, but Python 2.7 does not.
@@ -137,26 +134,25 @@ def generate_test_file_hooks(config_dir, hook_probe):
except OSError as error:
if error.errno != errno.EEXIST:
raise
hook_path = os.path.join(hook_dir, 'hook.{0}'.format(extension))
if extension == 'sh':
data = '''\
#!/bin/bash -xe
if [ "$0" = "{0}" ]; then
if [ -z "$RENEWED_DOMAINS" -o -z "$RENEWED_LINEAGE" ]; then
echo "Environment variables not properly set!" >&2
exit 1
fi
fi
echo $(basename $(dirname "$0")) >> "{1}"\
'''.format(renewal_deploy_hook_path, hook_probe)
else:
# TODO: Write the equivalent bat file for Windows
data = '''\
'''
with open(hook_path, 'w') as file:
file.write(data)
os.chmod(hook_path, os.stat(hook_path).st_mode | stat.S_IEXEC)
if os.name != 'nt':
entrypoint_script_path = os.path.join(hook_dir, 'entrypoint.sh')
entrypoint_script = '''\
#!/usr/bin/env bash
set -e
"{0}" "{1}" "{2}" "{3}"
'''.format(sys.executable, hook_path, entrypoint_script_path, hook_probe)
else:
entrypoint_script_path = os.path.join(hook_dir, 'entrypoint.bat')
entrypoint_script = '''\
@echo off
"{0}" "{1}" "{2}" "{3}"
'''.format(sys.executable, hook_path, entrypoint_script_path, hook_probe)
with open(entrypoint_script_path, 'w') as file_h:
file_h.write(entrypoint_script)
os.chmod(entrypoint_script_path, os.stat(entrypoint_script_path).st_mode | stat.S_IEXEC)
@contextlib.contextmanager
@@ -193,7 +189,7 @@ for _ in range(0, 10):
except requests.exceptions.ConnectionError:
pass
raise ValueError('Error, url did not respond after 10 attempts: {{0}}'.format(url))
'''.format(http_server_root, http_port))
'''.format(http_server_root.replace('\\', '\\\\'), http_port))
os.chmod(auth_script_path, 0o755)
cleanup_script_path = os.path.join(tempdir, 'cleanup.py')
@@ -204,7 +200,7 @@ import os
import shutil
well_known = os.path.join('{0}', '.well-known')
shutil.rmtree(well_known)
'''.format(http_server_root))
'''.format(http_server_root.replace('\\', '\\\\')))
os.chmod(cleanup_script_path, 0o755)
yield ('{0} {1}'.format(sys.executable, auth_script_path),
@@ -213,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.
@@ -287,4 +271,32 @@ def load_sample_data_path(workspace):
original = pkg_resources.resource_filename('certbot_integration_tests', 'assets/sample-config')
copied = os.path.join(workspace, 'sample-config')
shutil.copytree(original, copied, symlinks=True)
if os.name == 'nt':
# Fix the symlinks on Windows since GIT is not creating them upon checkout
for lineage in ['a.encryption-example.com', 'b.encryption-example.com']:
current_live = os.path.join(copied, 'live', lineage)
for name in os.listdir(current_live):
if name != 'README':
current_file = os.path.join(current_live, name)
with open(current_file) as file_h:
src = file_h.read()
os.unlink(current_file)
os.symlink(os.path.join(current_live, src), current_file)
return copied
def echo(keyword, path=None):
"""
Generate a platform independent executable command
that echoes the given keyword into the given file.
:param keyword: the keyword to echo (must be a single keyword)
:param path: path to the file were keyword is echoed
:return: the executable command
"""
if not re.match(r'^\w+$', keyword):
raise ValueError('Error, keyword `{0}` is not a single keyword.'
.format(keyword))
return '{0} -c "from __future__ import print_function; print(\'{1}\')"{2}'.format(
os.path.basename(sys.executable), keyword, ' >> "{0}"'.format(path) if path else '')

View File

@@ -1,19 +1,18 @@
import json
import platform
import os
import stat
import pkg_resources
import requests
PEBBLE_VERSION = 'v2.1.0'
from certbot_integration_tests.utils.constants import MOCK_OCSP_SERVER_PORT
PEBBLE_VERSION = 'v2.2.1'
ASSETS_PATH = pkg_resources.resource_filename('certbot_integration_tests', 'assets')
def fetch(workspace):
suffix = '{0}-{1}{2}'.format(platform.system().lower(),
platform.machine().lower().replace('x86_64', 'amd64'),
'.exe' if platform.system() == 'Windows' else '')
suffix = 'linux-amd64' if os.name != 'nt' else 'windows-amd64.exe'
pebble_path = _fetch_asset('pebble', suffix)
challtestsrv_path = _fetch_asset('pebble-challtestsrv', suffix)
@@ -42,10 +41,12 @@ def _build_pebble_config(workspace):
file_h.write(json.dumps({
'pebble': {
'listenAddress': '0.0.0.0:14000',
'managementListenAddress': '0.0.0.0:15000',
'certificate': os.path.join(ASSETS_PATH, 'cert.pem'),
'privateKey': os.path.join(ASSETS_PATH, 'key.pem'),
'httpPort': 5002,
'tlsPort': 5001,
'ocspResponderURL': 'http://127.0.0.1:{0}'.format(MOCK_OCSP_SERVER_PORT),
},
}))

View File

@@ -0,0 +1,71 @@
#!/usr/bin/env python
"""
This runnable module interfaces itself with the Pebble management interface in order
to serve a mock OCSP responder during integration tests against Pebble.
"""
import datetime
import re
import requests
from dateutil import parser
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization, hashes
from cryptography import x509
from cryptography.x509 import ocsp
from six.moves import BaseHTTPServer
from certbot_integration_tests.utils.misc import GracefulTCPServer
from certbot_integration_tests.utils.constants import MOCK_OCSP_SERVER_PORT, PEBBLE_MANAGEMENT_URL
class _ProxyHandler(BaseHTTPServer.BaseHTTPRequestHandler):
def do_POST(self):
request = requests.get(PEBBLE_MANAGEMENT_URL + '/intermediate-keys/0', verify=False)
issuer_key = serialization.load_pem_private_key(request.content, None, default_backend())
request = requests.get(PEBBLE_MANAGEMENT_URL + '/intermediates/0', verify=False)
issuer_cert = x509.load_pem_x509_certificate(request.content, default_backend())
try:
content_len = int(self.headers.getheader('content-length', 0))
except AttributeError:
content_len = int(self.headers.get('Content-Length'))
ocsp_request = ocsp.load_der_ocsp_request(self.rfile.read(content_len))
response = requests.get('{0}/cert-status-by-serial/{1}'.format(
PEBBLE_MANAGEMENT_URL, str(hex(ocsp_request.serial_number)).replace('0x', '')), verify=False)
if not response.ok:
ocsp_response = ocsp.OCSPResponseBuilder.build_unsuccessful(ocsp.OCSPResponseStatus.UNAUTHORIZED)
else:
data = response.json()
now = datetime.datetime.utcnow()
cert = x509.load_pem_x509_certificate(data['Certificate'].encode(), default_backend())
if data['Status'] != 'Revoked':
ocsp_status, revocation_time, revocation_reason = ocsp.OCSPCertStatus.GOOD, None, None
else:
ocsp_status, revocation_reason = ocsp.OCSPCertStatus.REVOKED, x509.ReasonFlags.unspecified
revoked_at = re.sub(r'( \+\d{4}).*$', r'\1', data['RevokedAt']) # "... +0000 UTC" => "+0000"
revocation_time = parser.parse(revoked_at)
ocsp_response = ocsp.OCSPResponseBuilder().add_response(
cert=cert, issuer=issuer_cert, algorithm=hashes.SHA1(),
cert_status=ocsp_status,
this_update=now, next_update=now + datetime.timedelta(hours=1),
revocation_time=revocation_time, revocation_reason=revocation_reason
).responder_id(
ocsp.OCSPResponderEncoding.NAME, issuer_cert
).sign(issuer_key, hashes.SHA256())
self.send_response(200)
self.end_headers()
self.wfile.write(ocsp_response.public_bytes(serialization.Encoding.DER))
if __name__ == '__main__':
try:
GracefulTCPServer(('', MOCK_OCSP_SERVER_PORT), _ProxyHandler).serve_forever()
except KeyboardInterrupt:
pass

View File

@@ -1,5 +1,7 @@
from setuptools import setup
from setuptools import find_packages
import sys
from distutils.version import StrictVersion
from setuptools import setup, find_packages, __version__ as setuptools_version
version = '0.32.0.dev0'
@@ -11,11 +13,23 @@ install_requires = [
'pytest',
'pytest-cov',
'pytest-xdist',
'python-dateutil',
'pyyaml',
'requests',
'six',
]
# Add pywin32 on Windows platforms to handle low-level system calls.
# This dependency needs to be added using environment markers to avoid its installation on Linux.
# 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.
if StrictVersion(setuptools_version) >= StrictVersion('36.2'):
install_requires.append("pywin32>=224 ; 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.')
setup(
name='certbot-ci',
version=version,
@@ -37,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',
],

View File

@@ -4,7 +4,7 @@ from setuptools import setup
from setuptools import find_packages
version = '0.36.0.dev0'
version = '0.40.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',
],

View File

@@ -1,5 +0,0 @@
FROM certbot/certbot
COPY . src/certbot-dns-cloudflare
RUN pip install --constraint docker_constraints.txt --no-cache-dir --editable src/certbot-dns-cloudflare

View File

@@ -22,7 +22,9 @@ Credentials
Use of this plugin requires a configuration file containing Cloudflare API
credentials, obtained from your Cloudflare
`account page <https://www.cloudflare.com/a/account/my-account>`_.
`account page <https://www.cloudflare.com/a/account/my-account>`_. This plugin
does not currently support Cloudflare's "API Tokens", so please ensure you use
the "Global API Key" for authentication.
.. code-block:: ini
:name: credentials.ini

View File

@@ -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
certbot[dev]==0.39.0

View File

@@ -2,13 +2,13 @@ from setuptools import setup
from setuptools import find_packages
version = '0.36.0.dev0'
version = '0.40.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',
'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',

View File

@@ -1,5 +0,0 @@
FROM certbot/certbot
COPY . src/certbot-dns-cloudxns
RUN pip install --constraint docker_constraints.txt --no-cache-dir --editable src/certbot-dns-cloudxns

View File

@@ -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
certbot[dev]==0.39.0

View File

@@ -2,13 +2,13 @@ from setuptools import setup
from setuptools import find_packages
version = '0.36.0.dev0'
version = '0.40.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',
'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',

View File

@@ -1,5 +0,0 @@
FROM certbot/certbot
COPY . src/certbot-dns-digitalocean
RUN pip install --constraint docker_constraints.txt --no-cache-dir --editable src/certbot-dns-digitalocean

View File

@@ -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
certbot[dev]==0.39.0

View File

@@ -2,13 +2,13 @@ from setuptools import setup
from setuptools import find_packages
version = '0.36.0.dev0'
version = '0.40.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',
'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',

View File

@@ -1,5 +0,0 @@
FROM certbot/certbot
COPY . src/certbot-dns-dnsimple
RUN pip install --constraint docker_constraints.txt --no-cache-dir --editable src/certbot-dns-dnsimple

View File

@@ -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
certbot[dev]==0.39.0

View File

@@ -3,13 +3,13 @@ from setuptools import setup
from setuptools import find_packages
version = '0.36.0.dev0'
version = '0.40.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',
'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',

View File

@@ -1,5 +0,0 @@
FROM certbot/certbot
COPY . src/certbot-dns-dnsmadeeasy
RUN pip install --constraint docker_constraints.txt --no-cache-dir --editable src/certbot-dns-dnsmadeeasy

View File

@@ -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
certbot[dev]==0.39.0

View File

@@ -2,13 +2,13 @@ from setuptools import setup
from setuptools import find_packages
version = '0.36.0.dev0'
version = '0.40.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',
'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',

View File

@@ -1,5 +0,0 @@
FROM certbot/certbot
COPY . src/certbot-dns-gehirn
RUN pip install --constraint docker_constraints.txt --no-cache-dir --editable src/certbot-dns-gehirn

View File

@@ -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
certbot[dev]==0.39.0

View File

@@ -2,12 +2,12 @@ from setuptools import setup
from setuptools import find_packages
version = '0.36.0.dev0'
version = '0.40.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',
'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',

View File

@@ -1,5 +0,0 @@
FROM certbot/certbot
COPY . src/certbot-dns-google
RUN pip install --constraint docker_constraints.txt --no-cache-dir --editable src/certbot-dns-google

View File

@@ -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
certbot[dev]==0.39.0

View File

@@ -2,13 +2,13 @@ from setuptools import setup
from setuptools import find_packages
version = '0.36.0.dev0'
version = '0.40.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',
# 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',

View File

@@ -1,5 +0,0 @@
FROM certbot/certbot
COPY . src/certbot-dns-linode
RUN pip install --constraint docker_constraints.txt --no-cache-dir --editable src/certbot-dns-linode

View File

@@ -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
certbot[dev]==0.39.0
dns-lexicon==2.2.3

View File

@@ -1,12 +1,12 @@
from setuptools import setup
from setuptools import find_packages
version = '0.36.0.dev0'
version = '0.40.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',
'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',

View File

@@ -1,5 +0,0 @@
FROM certbot/certbot
COPY . src/certbot-dns-luadns
RUN pip install --constraint docker_constraints.txt --no-cache-dir --editable src/certbot-dns-luadns

View File

@@ -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
certbot[dev]==0.39.0

View File

@@ -2,13 +2,13 @@ from setuptools import setup
from setuptools import find_packages
version = '0.36.0.dev0'
version = '0.40.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',
'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',

View File

@@ -1,5 +0,0 @@
FROM certbot/certbot
COPY . src/certbot-dns-nsone
RUN pip install --constraint docker_constraints.txt --no-cache-dir --editable src/certbot-dns-nsone

View File

@@ -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
certbot[dev]==0.39.0

View File

@@ -2,13 +2,13 @@ from setuptools import setup
from setuptools import find_packages
version = '0.36.0.dev0'
version = '0.40.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',
'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',

View File

@@ -1,5 +0,0 @@
FROM certbot/certbot
COPY . src/certbot-dns-ovh
RUN pip install --constraint docker_constraints.txt --no-cache-dir --editable src/certbot-dns-ovh

View File

@@ -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
certbot[dev]==0.39.0
dns-lexicon==2.7.14

View File

@@ -2,13 +2,13 @@ from setuptools import setup
from setuptools import find_packages
version = '0.36.0.dev0'
version = '0.40.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',
'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',

View File

@@ -1,5 +0,0 @@
FROM certbot/certbot
COPY . src/certbot-dns-rfc2136
RUN pip install --constraint docker_constraints.txt --no-cache-dir --editable src/certbot-dns-rfc2136

View File

@@ -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
certbot[dev]==0.39.0

View File

@@ -2,13 +2,13 @@ from setuptools import setup
from setuptools import find_packages
version = '0.36.0.dev0'
version = '0.40.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',
'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',

View File

@@ -1,5 +0,0 @@
FROM certbot/certbot
COPY . src/certbot-dns-route53
RUN pip install --constraint docker_constraints.txt --no-cache-dir --editable src/certbot-dns-route53

View File

@@ -1,3 +1,3 @@
include LICENSE
include LICENSE.txt
include README
recursive-include docs *

View File

@@ -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
certbot[dev]==0.39.0

View File

@@ -1,13 +1,13 @@
from setuptools import setup
from setuptools import find_packages
version = '0.36.0.dev0'
version = '0.40.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',
'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',

View File

@@ -1,5 +0,0 @@
FROM certbot/certbot
COPY . src/certbot-dns-sakuracloud
RUN pip install --constraint docker_constraints.txt --no-cache-dir --editable src/certbot-dns-sakuracloud

View File

@@ -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
certbot[dev]==0.39.0

View File

@@ -2,12 +2,12 @@ from setuptools import setup
from setuptools import find_packages
version = '0.36.0.dev0'
version = '0.40.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',
'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',

View File

@@ -2,5 +2,4 @@ include LICENSE.txt
include README.rst
recursive-include docs *
recursive-include certbot_nginx/tests/testdata *
include certbot_nginx/options-ssl-nginx.conf
include certbot_nginx/options-ssl-nginx-old.conf
recursive-include certbot_nginx/tls_configs *.conf

View File

@@ -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
@@ -20,7 +22,6 @@ from certbot import crypto_util
from certbot import errors
from certbot import interfaces
from certbot import util
from certbot.compat import misc
from certbot.compat import os
from certbot.plugins import common
@@ -92,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
@@ -116,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}
@@ -125,10 +131,35 @@ class NginxConfigurator(common.Installer):
@property
def mod_ssl_conf_src(self):
"""Full absolute path to SSL configuration file source."""
config_filename = "options-ssl-nginx.conf"
if self.version < (1, 5, 9):
config_filename = "options-ssl-nginx-old.conf"
return pkg_resources.resource_filename("certbot_nginx", config_filename)
# 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"
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))
@property
def mod_ssl_conf(self):
@@ -167,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()
@@ -903,13 +937,31 @@ class NginxConfigurator(common.Installer):
have permissions of root.
"""
uid = misc.os_geteuid()
util.make_or_verify_dir(
self.config.work_dir, core_constants.CONFIG_DIRS_MODE, uid)
util.make_or_verify_dir(
self.config.backup_dir, core_constants.CONFIG_DIRS_MODE, uid)
util.make_or_verify_dir(
self.config.config_dir, core_constants.CONFIG_DIRS_MODE, uid)
util.make_or_verify_dir(self.config.work_dir, core_constants.CONFIG_DIRS_MODE)
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 _nginx_version(self):
"""Return results of nginx -V
:returns: version text
:rtype: str
:raises .PluginError:
Unable to run Nginx version command
"""
try:
proc = subprocess.Popen(
[self.conf('ctl'), "-c", self.nginx_conf, "-V"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True)
text = proc.communicate()[1] # nginx prints output to stderr
except (OSError, ValueError) as error:
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.
@@ -923,17 +975,7 @@ class NginxConfigurator(common.Installer):
Unable to find Nginx version or version is unsupported
"""
try:
proc = subprocess.Popen(
[self.conf('ctl'), "-c", self.nginx_conf, "-V"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True)
text = proc.communicate()[1] # nginx prints output to stderr
except (OSError, ValueError) as error:
logger.debug(str(error), exc_info=True)
raise errors.PluginError(
"Unable to run %s -V" % self.conf('ctl'))
text = self._nginx_version()
version_regex = re.compile(r"nginx version: ([^/]+)/([0-9\.]*)", re.IGNORECASE)
version_matches = version_regex.findall(text)
@@ -966,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 (

View File

@@ -22,12 +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 = [
'63e2bddebb174a05c9d8a7cf2adf72f7af04349ba59a1a925fe447f73b2f1abf',
'2901debc7ecbc10917edd9084c05464c9c5930b463677571eaf8c94bffd11ae2',
]
"""SHA256 hashes of the contents of versions of MOD_SSL_CONF_SRC for nginx >= 1.5.9"""
ALL_SSL_OPTIONS_HASHES = [
'0f81093a1465e3d4eaa8b0c14e77b2a2e93568b0fc1351c2b87893a95f0de87c',
'9a7b32c49001fed4cff8ad24353329472a50e86ade1ef9b2b9e43566a619612e',
@@ -36,7 +30,18 @@ ALL_SSL_OPTIONS_HASHES = [
'394732f2bbe3e5e637c3fb5c6e980a1f1b90b01e2e8d6b7cff41dde16e2a756d',
'4b16fec2bcbcd8a2f3296d886f17f9953ffdcc0af54582452ca1e52f5f776f16',
'c052ffff0ad683f43bffe105f7c606b339536163490930e2632a335c8d191cc4',
] + SSL_OPTIONS_HASHES_NEW
'02329eb19930af73c54b3632b3165d84571383b8c8c73361df940cb3894dd426',
'63e2bddebb174a05c9d8a7cf2adf72f7af04349ba59a1a925fe447f73b2f1abf',
'2901debc7ecbc10917edd9084c05464c9c5930b463677571eaf8c94bffd11ae2',
'30baca73ed9a5b0e9a69ea40e30482241d8b1a7343aa79b49dc5d7db0bf53b6c',
'02329eb19930af73c54b3632b3165d84571383b8c8c73361df940cb3894dd426',
'108c4555058a087496a3893aea5d9e1cee0f20a3085d44a52dc1a66522299ac3',
'd5e021706ecdccc7090111b0ae9a29ef61523e927f020e410caf0a1fd7063981',
'ef11e3fb17213e74d3e1816cde0ec37b8b95b4167cf21e7b8ff1eaa9c6f918ee',
'af85f6193808a44789a1d293e6cffa249cad9a21135940800958b8e3c72dbc69',
'a2a612fd21b02abaa32d9d11ac63d987d6e3054dbfa356de5800eea0d7ce17f3',
'2d9648302e3588a172c318e46bff88ade46fc7a16d6afc85322776a04800d473',
]
"""SHA256 hashes of the contents of all versions of MOD_SSL_CONF_SRC"""
def os_constant(key):

View File

@@ -1,13 +0,0 @@
# This file contains important security parameters. If you modify this file
# manually, Certbot will be unable to automatically provide future security
# updates. Instead, Certbot will print and log an error message with a path to
# the up-to-date file that you will need to refer to when manually updating
# this file.
ssl_session_cache shared:le_nginx_SSL:10m;
ssl_session_timeout 1440m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS";

View File

@@ -1,14 +0,0 @@
# This file contains important security parameters. If you modify this file
# manually, Certbot will be unable to automatically provide future security
# updates. Instead, Certbot will print and log an error message with a path to
# the up-to-date file that you will need to refer to when manually updating
# this file.
ssl_session_cache shared:le_nginx_SSL:10m;
ssl_session_timeout 1440m;
ssl_session_tickets off;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS";

View File

@@ -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:
@@ -963,15 +1024,50 @@ class InstallSslOptionsConfTest(util.NginxTest):
"Constants.ALL_SSL_OPTIONS_HASHES must be appended"
" with the sha256 hash of self.config.mod_ssl_conf when it is updated.")
def test_old_nginx_version_uses_old_config(self):
def test_ssl_config_files_hash_in_all_hashes(self):
"""
It is really critical that all TLS Nginx config files have their SHA256 hash registered in
constants.ALL_SSL_OPTIONS_HASHES. Otherwise Certbot will mistakenly assume that the config
file has been manually edited by the user, and will refuse to update it.
This test ensures that all necessary hashes are present.
"""
from certbot_nginx.constants import ALL_SSL_OPTIONS_HASHES
import pkg_resources
all_files = [
pkg_resources.resource_filename("certbot_nginx", os.path.join("tls_configs", x))
for x in ("options-ssl-nginx.conf",
"options-ssl-nginx-old.conf",
"options-ssl-nginx-tls12-only.conf")
]
self.assertTrue(all_files)
for one_file in all_files:
file_hash = crypto_util.sha256sum(one_file)
self.assertTrue(file_hash in ALL_SSL_OPTIONS_HASHES,
"Constants.ALL_SSL_OPTIONS_HASHES must be appended with the sha256 "
"hash of {0} when it is updated.".format(one_file))
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()
self._assert_current_file()
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):

View File

@@ -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):
nparser = parser.NginxParser(os.path.relpath(self.config_path))
self.assertEqual(nparser.root, self.config_path)
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)

View File

@@ -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.

View File

@@ -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;
ssl_prefer_server_ciphers off;
ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA";

View File

@@ -0,0 +1,14 @@
# 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_session_tickets off;
ssl_protocols TLSv1.2;
ssl_prefer_server_ciphers off;
ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA";

View File

@@ -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:ECDHE-RSA-AES128-SHA";

View File

@@ -0,0 +1,14 @@
# 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_session_tickets off;
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:ECDHE-RSA-AES128-SHA";

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