Showing preview only (4,936K chars total). Download the full file or copy to clipboard to get everything.
Repository: certbot/certbot
Branch: main
Commit: 9ed92009dbfe
Files: 1210
Total size: 4.5 MB
Directory structure:
gitextract_6brtvsg5/
├── .azure-pipelines/
│ ├── INSTALL.md
│ ├── advanced-test.yml
│ ├── main.yml
│ ├── nightly.yml
│ ├── release.yml
│ └── templates/
│ ├── jobs/
│ │ ├── common-deploy-jobs.yml
│ │ ├── extended-tests-jobs.yml
│ │ ├── packaging-jobs.yml
│ │ └── standard-tests-jobs.yml
│ ├── stages/
│ │ ├── changelog-stage.yml
│ │ ├── nightly-deploy-stage.yml
│ │ ├── release-deploy-stage.yml
│ │ └── test-and-package-stage.yml
│ └── steps/
│ ├── sphinx-steps.yml
│ └── tox-steps.yml
├── .coveragerc
├── .dockerignore
├── .editorconfig
├── .gitattributes
├── .github/
│ ├── CODEOWNERS
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug.yaml
│ │ ├── config.yml
│ │ ├── feature.yaml
│ │ └── task.yaml
│ ├── codecov.yml
│ ├── pull_request_template.md
│ └── workflows/
│ ├── assigned.yaml
│ ├── merged.yaml
│ ├── notify_weekly.yaml
│ ├── review_requested.yaml
│ └── stale.yml
├── .gitignore
├── .isort.cfg
├── .pylintrc
├── AUTHORS.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE.txt
├── SECURITY.md
├── acme/
│ ├── .readthedocs.yaml
│ ├── LICENSE.txt
│ ├── MANIFEST.in
│ ├── README.rst
│ ├── docs/
│ │ ├── .gitignore
│ │ ├── Makefile
│ │ ├── _static/
│ │ │ └── .gitignore
│ │ ├── _templates/
│ │ │ └── .gitignore
│ │ ├── api/
│ │ │ ├── challenges.rst
│ │ │ ├── client.rst
│ │ │ ├── crypto_util.rst
│ │ │ ├── errors.rst
│ │ │ ├── fields.rst
│ │ │ ├── jose.rst
│ │ │ ├── jws.rst
│ │ │ ├── messages.rst
│ │ │ ├── standalone.rst
│ │ │ └── util.rst
│ │ ├── api.rst
│ │ ├── conf.py
│ │ ├── index.rst
│ │ ├── jws-help.txt
│ │ ├── make.bat
│ │ └── man/
│ │ └── jws.rst
│ ├── examples/
│ │ └── http01_example.py
│ ├── pyproject.toml
│ ├── readthedocs.org.requirements.txt
│ ├── setup.py
│ └── src/
│ └── acme/
│ ├── __init__.py
│ ├── _internal/
│ │ ├── __init__.py
│ │ └── tests/
│ │ ├── __init__.py
│ │ ├── challenges_test.py
│ │ ├── client_test.py
│ │ ├── conftest.py
│ │ ├── crypto_util_test.py
│ │ ├── errors_test.py
│ │ ├── fields_test.py
│ │ ├── jose_test.py
│ │ ├── jws_test.py
│ │ ├── messages_test.py
│ │ ├── standalone_test.py
│ │ ├── test_util.py
│ │ ├── testdata/
│ │ │ ├── README
│ │ │ ├── cert-100sans.pem
│ │ │ ├── cert-idnsans.pem
│ │ │ ├── cert-ipsans.pem
│ │ │ ├── cert-ipv6sans.pem
│ │ │ ├── cert-nocn.der
│ │ │ ├── cert-san.pem
│ │ │ ├── cert.der
│ │ │ ├── cert.pem
│ │ │ ├── critical-san.pem
│ │ │ ├── csr-100sans.pem
│ │ │ ├── csr-6sans.pem
│ │ │ ├── csr-idnsans.pem
│ │ │ ├── csr-ipsans.pem
│ │ │ ├── csr-ipv6sans.pem
│ │ │ ├── csr-mixed.pem
│ │ │ ├── csr-nosans.pem
│ │ │ ├── csr-san.pem
│ │ │ ├── csr.der
│ │ │ ├── csr.pem
│ │ │ ├── dsa512_key.pem
│ │ │ ├── ec_secp384r1_key.pem
│ │ │ ├── rsa1024_cert.pem
│ │ │ ├── rsa1024_key.pem
│ │ │ ├── rsa2048_cert.pem
│ │ │ ├── rsa2048_key.pem
│ │ │ ├── rsa256_key.pem
│ │ │ ├── rsa4096_cert.pem
│ │ │ ├── rsa4096_key.pem
│ │ │ └── rsa512_key.pem
│ │ └── util_test.py
│ ├── challenges.py
│ ├── client.py
│ ├── crypto_util.py
│ ├── errors.py
│ ├── fields.py
│ ├── jws.py
│ ├── messages.py
│ ├── py.typed
│ ├── standalone.py
│ └── util.py
├── certbot/
│ ├── .readthedocs.yaml
│ ├── CHANGELOG.md
│ ├── LICENSE.txt
│ ├── MANIFEST.in
│ ├── README.rst
│ ├── docs/
│ │ ├── .gitignore
│ │ ├── Makefile
│ │ ├── _static/
│ │ │ └── .gitignore
│ │ ├── _templates/
│ │ │ └── footer.html
│ │ ├── api/
│ │ │ ├── certbot.achallenges.rst
│ │ │ ├── certbot.compat.filesystem.rst
│ │ │ ├── certbot.compat.misc.rst
│ │ │ ├── certbot.compat.os.rst
│ │ │ ├── certbot.compat.rst
│ │ │ ├── certbot.crypto_util.rst
│ │ │ ├── certbot.display.ops.rst
│ │ │ ├── certbot.display.rst
│ │ │ ├── certbot.display.util.rst
│ │ │ ├── certbot.errors.rst
│ │ │ ├── certbot.interfaces.rst
│ │ │ ├── certbot.main.rst
│ │ │ ├── certbot.plugins.common.rst
│ │ │ ├── certbot.plugins.dns_common.rst
│ │ │ ├── certbot.plugins.dns_common_lexicon.rst
│ │ │ ├── certbot.plugins.dns_test_common.rst
│ │ │ ├── certbot.plugins.dns_test_common_lexicon.rst
│ │ │ ├── certbot.plugins.enhancements.rst
│ │ │ ├── certbot.plugins.rst
│ │ │ ├── certbot.plugins.storage.rst
│ │ │ ├── certbot.plugins.util.rst
│ │ │ ├── certbot.reverter.rst
│ │ │ ├── certbot.rst
│ │ │ ├── certbot.tests.acme_util.rst
│ │ │ ├── certbot.tests.rst
│ │ │ ├── certbot.tests.util.rst
│ │ │ └── certbot.util.rst
│ │ ├── api.rst
│ │ ├── challenges.rst
│ │ ├── ciphers.rst
│ │ ├── cli-help.txt
│ │ ├── compatibility.rst
│ │ ├── conf.py
│ │ ├── contributing.rst
│ │ ├── index.rst
│ │ ├── install.rst
│ │ ├── intro.rst
│ │ ├── make.bat
│ │ ├── man/
│ │ │ └── certbot.rst
│ │ ├── packaging.rst
│ │ ├── resources.rst
│ │ ├── using.rst
│ │ └── what.rst
│ ├── examples/
│ │ ├── .gitignore
│ │ ├── cli.ini
│ │ ├── dev-cli.ini
│ │ ├── generate-csr.sh
│ │ ├── openssl.cnf
│ │ └── plugins/
│ │ ├── certbot_example_plugins.py
│ │ └── setup.py
│ ├── pyproject.toml
│ ├── readthedocs.org.requirements.txt
│ ├── setup.py
│ └── src/
│ └── certbot/
│ ├── __init__.py
│ ├── _internal/
│ │ ├── __init__.py
│ │ ├── account.py
│ │ ├── auth_handler.py
│ │ ├── cert_manager.py
│ │ ├── cli/
│ │ │ ├── __init__.py
│ │ │ ├── cli_constants.py
│ │ │ ├── cli_utils.py
│ │ │ ├── group_adder.py
│ │ │ ├── helpful.py
│ │ │ ├── paths_parser.py
│ │ │ ├── plugins_parsing.py
│ │ │ ├── subparsers.py
│ │ │ └── verb_help.py
│ │ ├── client.py
│ │ ├── constants.py
│ │ ├── display/
│ │ │ ├── __init__.py
│ │ │ ├── completer.py
│ │ │ ├── dummy_readline.py
│ │ │ ├── obj.py
│ │ │ └── util.py
│ │ ├── eff.py
│ │ ├── error_handler.py
│ │ ├── hooks.py
│ │ ├── lock.py
│ │ ├── log.py
│ │ ├── main.py
│ │ ├── ocsp.py
│ │ ├── plugins/
│ │ │ ├── __init__.py
│ │ │ ├── disco.py
│ │ │ ├── manual.py
│ │ │ ├── null.py
│ │ │ ├── selection.py
│ │ │ ├── standalone.py
│ │ │ └── webroot.py
│ │ ├── renewal.py
│ │ ├── san.py
│ │ ├── snap_config.py
│ │ ├── storage.py
│ │ ├── tests/
│ │ │ ├── __init__.py
│ │ │ ├── account_test.py
│ │ │ ├── auth_handler_test.py
│ │ │ ├── cert_manager_test.py
│ │ │ ├── cli_test.py
│ │ │ ├── client_test.py
│ │ │ ├── compat/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── filesystem_test.py
│ │ │ │ ├── misc_test.py
│ │ │ │ └── os_test.py
│ │ │ ├── configuration_test.py
│ │ │ ├── conftest.py
│ │ │ ├── crypto_util_test.py
│ │ │ ├── display/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── completer_test.py
│ │ │ │ ├── internal_util_test.py
│ │ │ │ ├── obj_test.py
│ │ │ │ ├── ops_test.py
│ │ │ │ └── util_test.py
│ │ │ ├── eff_test.py
│ │ │ ├── error_handler_test.py
│ │ │ ├── errors_test.py
│ │ │ ├── helpful_test.py
│ │ │ ├── hook_test.py
│ │ │ ├── lock_test.py
│ │ │ ├── log_test.py
│ │ │ ├── main_test.py
│ │ │ ├── ocsp_test.py
│ │ │ ├── plugins/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── common_test.py
│ │ │ │ ├── disco_test.py
│ │ │ │ ├── dns_common_test.py
│ │ │ │ ├── enhancements_test.py
│ │ │ │ ├── manual_test.py
│ │ │ │ ├── null_test.py
│ │ │ │ ├── selection_test.py
│ │ │ │ ├── standalone_test.py
│ │ │ │ ├── storage_test.py
│ │ │ │ ├── util_test.py
│ │ │ │ └── webroot_test.py
│ │ │ ├── renewal_test.py
│ │ │ ├── renewupdater_test.py
│ │ │ ├── reverter_test.py
│ │ │ ├── san_test.py
│ │ │ ├── storage_test.py
│ │ │ └── util_test.py
│ │ └── updater.py
│ ├── achallenges.py
│ ├── compat/
│ │ ├── __init__.py
│ │ ├── _path.py
│ │ ├── filesystem.py
│ │ ├── misc.py
│ │ └── os.py
│ ├── configuration.py
│ ├── crypto_util.py
│ ├── display/
│ │ ├── __init__.py
│ │ ├── ops.py
│ │ └── util.py
│ ├── errors.py
│ ├── interfaces.py
│ ├── main.py
│ ├── ocsp.py
│ ├── plugins/
│ │ ├── __init__.py
│ │ ├── common.py
│ │ ├── dns_common.py
│ │ ├── dns_common_lexicon.py
│ │ ├── dns_test_common.py
│ │ ├── dns_test_common_lexicon.py
│ │ ├── enhancements.py
│ │ ├── storage.py
│ │ └── util.py
│ ├── py.typed
│ ├── reverter.py
│ ├── ssl-dhparams.pem
│ ├── tests/
│ │ ├── __init__.py
│ │ ├── acme_util.py
│ │ ├── testdata/
│ │ │ ├── README
│ │ │ ├── cert-5sans_512.pem
│ │ │ ├── cert-nosans_nistp256.pem
│ │ │ ├── cert-san_512.pem
│ │ │ ├── cert_2048.pem
│ │ │ ├── cert_512.pem
│ │ │ ├── cert_512_bad.pem
│ │ │ ├── cert_fullchain_2048.pem
│ │ │ ├── cert_intermediate_1.pem
│ │ │ ├── cert_intermediate_2.pem
│ │ │ ├── cert_leaf.pem
│ │ │ ├── cli.ini
│ │ │ ├── csr-6sans_512.conf
│ │ │ ├── csr-6sans_512.pem
│ │ │ ├── csr-nonames_512.pem
│ │ │ ├── csr-nosans_512.conf
│ │ │ ├── csr-nosans_512.pem
│ │ │ ├── csr-nosans_nistp256.pem
│ │ │ ├── csr-san_512.pem
│ │ │ ├── csr_512.der
│ │ │ ├── csr_512.pem
│ │ │ ├── ec_prime256v1_key.pem
│ │ │ ├── ec_secp384r1_key.pem
│ │ │ ├── ec_secp521r1_key.pem
│ │ │ ├── nistp256_key.pem
│ │ │ ├── ocsp_certificate.pem
│ │ │ ├── ocsp_issuer_certificate.pem
│ │ │ ├── ocsp_responder_certificate.pem
│ │ │ ├── os-release
│ │ │ ├── rsa2048_key.pem
│ │ │ ├── rsa512_key.pem
│ │ │ ├── sample-archive/
│ │ │ │ ├── cert1.pem
│ │ │ │ ├── chain1.pem
│ │ │ │ ├── fullchain1.pem
│ │ │ │ └── privkey1.pem
│ │ │ ├── sample-archive-ec/
│ │ │ │ ├── cert1.pem
│ │ │ │ ├── chain1.pem
│ │ │ │ ├── fullchain1.pem
│ │ │ │ └── privkey1.pem
│ │ │ ├── sample-renewal-ancient.conf
│ │ │ ├── sample-renewal-deprecated-option.conf
│ │ │ ├── sample-renewal-ec.conf
│ │ │ ├── sample-renewal.conf
│ │ │ └── webrootconftest.ini
│ │ └── util.py
│ └── util.py
├── certbot-apache/
│ ├── LICENSE.txt
│ ├── MANIFEST.in
│ ├── README.rst
│ ├── pyproject.toml
│ ├── setup.py
│ └── src/
│ └── certbot_apache/
│ ├── __init__.py
│ ├── _internal/
│ │ ├── __init__.py
│ │ ├── apache_util.py
│ │ ├── apacheparser.py
│ │ ├── assertions.py
│ │ ├── augeas_lens/
│ │ │ ├── README
│ │ │ └── httpd.aug
│ │ ├── augeasparser.py
│ │ ├── configurator.py
│ │ ├── constants.py
│ │ ├── display_ops.py
│ │ ├── dualparser.py
│ │ ├── entrypoint.py
│ │ ├── http_01.py
│ │ ├── interfaces.py
│ │ ├── obj.py
│ │ ├── override_alpine.py
│ │ ├── override_arch.py
│ │ ├── override_centos.py
│ │ ├── override_darwin.py
│ │ ├── override_debian.py
│ │ ├── override_fedora.py
│ │ ├── override_gentoo.py
│ │ ├── override_suse.py
│ │ ├── override_void.py
│ │ ├── parser.py
│ │ ├── parsernode_util.py
│ │ ├── tests/
│ │ │ ├── __init__.py
│ │ │ ├── apache-conf-files/
│ │ │ │ ├── NEEDED.txt
│ │ │ │ ├── apache-conf-test
│ │ │ │ ├── apache-conf-test-pebble.py
│ │ │ │ ├── failing/
│ │ │ │ │ ├── missing-double-quote-1724.conf
│ │ │ │ │ ├── multivhost-1093.conf
│ │ │ │ │ └── multivhost-1093b.conf
│ │ │ │ └── passing/
│ │ │ │ ├── 1626-1531.conf
│ │ │ │ ├── README.modules
│ │ │ │ ├── anarcat-1531.conf
│ │ │ │ ├── comment-continuations-2050.conf
│ │ │ │ ├── drupal-errordocument-arg-1724.conf
│ │ │ │ ├── drupal-htaccess-1531.conf
│ │ │ │ ├── escaped-space-arguments-2735.conf
│ │ │ │ ├── example-1755.conf
│ │ │ │ ├── example-ssl.conf
│ │ │ │ ├── example.conf
│ │ │ │ ├── finalize-1243.apache2.conf.txt
│ │ │ │ ├── finalize-1243.conf
│ │ │ │ ├── graphite-quote-1934.conf
│ │ │ │ ├── ipv6-1143.conf
│ │ │ │ ├── ipv6-1143b.conf
│ │ │ │ ├── ipv6-1143c.conf
│ │ │ │ ├── ipv6-1143d.conf
│ │ │ │ ├── missing-quote-1724.conf
│ │ │ │ ├── modmacro-1385.conf
│ │ │ │ ├── owncloud-1264.conf
│ │ │ │ ├── rewrite-quote-1960.conf
│ │ │ │ ├── roundcube-1222.conf
│ │ │ │ ├── section-continuations-2525.conf
│ │ │ │ ├── section-empty-continuations-2731.conf
│ │ │ │ ├── semacode-1598.conf
│ │ │ │ ├── sslrequire-wordlist-1827.htaccess
│ │ │ │ └── two-blocks-one-line-1693.conf
│ │ │ ├── augeasnode_test.py
│ │ │ ├── autohsts_test.py
│ │ │ ├── centos_test.py
│ │ │ ├── complex_parsing_test.py
│ │ │ ├── configurator_reverter_test.py
│ │ │ ├── configurator_test.py
│ │ │ ├── conftest.py
│ │ │ ├── debian_test.py
│ │ │ ├── display_ops_test.py
│ │ │ ├── dualnode_test.py
│ │ │ ├── entrypoint_test.py
│ │ │ ├── fedora_test.py
│ │ │ ├── gentoo_test.py
│ │ │ ├── http_01_test.py
│ │ │ ├── obj_test.py
│ │ │ ├── parser_test.py
│ │ │ ├── parsernode_configurator_test.py
│ │ │ ├── parsernode_test.py
│ │ │ ├── parsernode_util_test.py
│ │ │ ├── testdata/
│ │ │ │ ├── centos7_apache/
│ │ │ │ │ └── apache/
│ │ │ │ │ ├── httpd/
│ │ │ │ │ │ ├── conf/
│ │ │ │ │ │ │ ├── httpd.conf
│ │ │ │ │ │ │ └── magic
│ │ │ │ │ │ ├── conf.d/
│ │ │ │ │ │ │ ├── README
│ │ │ │ │ │ │ ├── autoindex.conf
│ │ │ │ │ │ │ ├── centos.example.com.conf
│ │ │ │ │ │ │ ├── ssl.conf
│ │ │ │ │ │ │ ├── userdir.conf
│ │ │ │ │ │ │ └── welcome.conf
│ │ │ │ │ │ └── conf.modules.d/
│ │ │ │ │ │ ├── 00-base.conf
│ │ │ │ │ │ ├── 00-dav.conf
│ │ │ │ │ │ ├── 00-lua.conf
│ │ │ │ │ │ ├── 00-mpm.conf
│ │ │ │ │ │ ├── 00-proxy.conf
│ │ │ │ │ │ ├── 00-ssl.conf
│ │ │ │ │ │ ├── 00-systemd.conf
│ │ │ │ │ │ └── 01-cgi.conf
│ │ │ │ │ ├── sites
│ │ │ │ │ └── sysconfig/
│ │ │ │ │ └── httpd
│ │ │ │ ├── complex_parsing/
│ │ │ │ │ ├── apache2.conf
│ │ │ │ │ ├── conf-enabled/
│ │ │ │ │ │ └── dummy.conf
│ │ │ │ │ ├── test_fnmatch.conf
│ │ │ │ │ └── test_variables.conf
│ │ │ │ ├── debian_apache_2_4/
│ │ │ │ │ ├── augeas_vhosts/
│ │ │ │ │ │ ├── apache2/
│ │ │ │ │ │ │ ├── apache2.conf
│ │ │ │ │ │ │ ├── conf-available/
│ │ │ │ │ │ │ │ ├── bad_conf_file.conf
│ │ │ │ │ │ │ │ ├── other-vhosts-access-log.conf
│ │ │ │ │ │ │ │ ├── security.conf
│ │ │ │ │ │ │ │ └── serve-cgi-bin.conf
│ │ │ │ │ │ │ ├── envvars
│ │ │ │ │ │ │ ├── mods-available/
│ │ │ │ │ │ │ │ ├── authz_svn.load
│ │ │ │ │ │ │ │ ├── dav.load
│ │ │ │ │ │ │ │ ├── dav_svn.conf
│ │ │ │ │ │ │ │ ├── dav_svn.load
│ │ │ │ │ │ │ │ ├── rewrite.load
│ │ │ │ │ │ │ │ ├── ssl.conf
│ │ │ │ │ │ │ │ └── ssl.load
│ │ │ │ │ │ │ ├── ports.conf
│ │ │ │ │ │ │ └── sites-available/
│ │ │ │ │ │ │ ├── another_wildcard.conf
│ │ │ │ │ │ │ ├── old-and-default.conf
│ │ │ │ │ │ │ └── wildcard.conf
│ │ │ │ │ │ └── sites
│ │ │ │ │ ├── default_vhost/
│ │ │ │ │ │ ├── apache2/
│ │ │ │ │ │ │ ├── apache2.conf
│ │ │ │ │ │ │ ├── conf-available/
│ │ │ │ │ │ │ │ ├── other-vhosts-access-log.conf
│ │ │ │ │ │ │ │ ├── security.conf
│ │ │ │ │ │ │ │ └── serve-cgi-bin.conf
│ │ │ │ │ │ │ ├── envvars
│ │ │ │ │ │ │ ├── mods-available/
│ │ │ │ │ │ │ │ ├── ssl.conf
│ │ │ │ │ │ │ │ └── ssl.load
│ │ │ │ │ │ │ ├── ports.conf
│ │ │ │ │ │ │ └── sites-available/
│ │ │ │ │ │ │ ├── 000-default.conf
│ │ │ │ │ │ │ └── default-ssl.conf
│ │ │ │ │ │ └── sites
│ │ │ │ │ ├── multi_vhosts/
│ │ │ │ │ │ └── apache2/
│ │ │ │ │ │ ├── apache2.conf
│ │ │ │ │ │ ├── envvars
│ │ │ │ │ │ ├── ports.conf
│ │ │ │ │ │ └── sites-available/
│ │ │ │ │ │ ├── default.conf
│ │ │ │ │ │ └── multi-vhost.conf
│ │ │ │ │ └── multiple_vhosts/
│ │ │ │ │ ├── apache2/
│ │ │ │ │ │ ├── apache2.conf
│ │ │ │ │ │ ├── conf-available/
│ │ │ │ │ │ │ ├── bad_conf_file.conf
│ │ │ │ │ │ │ ├── other-vhosts-access-log.conf
│ │ │ │ │ │ │ ├── security.conf
│ │ │ │ │ │ │ └── serve-cgi-bin.conf
│ │ │ │ │ │ ├── envvars
│ │ │ │ │ │ ├── mods-available/
│ │ │ │ │ │ │ ├── authz_svn.load
│ │ │ │ │ │ │ ├── dav.load
│ │ │ │ │ │ │ ├── dav_svn.conf
│ │ │ │ │ │ │ ├── dav_svn.load
│ │ │ │ │ │ │ ├── rewrite.load
│ │ │ │ │ │ │ ├── ssl.conf
│ │ │ │ │ │ │ └── ssl.load
│ │ │ │ │ │ ├── ports.conf
│ │ │ │ │ │ ├── sites-available/
│ │ │ │ │ │ │ ├── 000-default.conf
│ │ │ │ │ │ │ ├── certbot.conf
│ │ │ │ │ │ │ ├── default-ssl-port-only.conf
│ │ │ │ │ │ │ ├── default-ssl.conf
│ │ │ │ │ │ │ ├── duplicatehttp.conf
│ │ │ │ │ │ │ ├── duplicatehttps.conf
│ │ │ │ │ │ │ ├── empty.conf
│ │ │ │ │ │ │ ├── encryption-example.conf
│ │ │ │ │ │ │ ├── mod_macro-example.conf
│ │ │ │ │ │ │ ├── no-directives.conf
│ │ │ │ │ │ │ ├── ocsp-ssl.conf
│ │ │ │ │ │ │ └── wildcard.conf
│ │ │ │ │ │ └── sites-enabled/
│ │ │ │ │ │ └── non-symlink.conf
│ │ │ │ │ └── sites
│ │ │ │ └── gentoo_apache/
│ │ │ │ └── apache/
│ │ │ │ ├── apache2/
│ │ │ │ │ ├── httpd.conf
│ │ │ │ │ ├── magic
│ │ │ │ │ ├── modules.d/
│ │ │ │ │ │ ├── 00_default_settings.conf
│ │ │ │ │ │ ├── 00_error_documents.conf
│ │ │ │ │ │ ├── 00_languages.conf
│ │ │ │ │ │ ├── 00_mod_autoindex.conf
│ │ │ │ │ │ ├── 00_mod_info.conf
│ │ │ │ │ │ ├── 00_mod_log_config.conf
│ │ │ │ │ │ ├── 00_mod_mime.conf
│ │ │ │ │ │ ├── 00_mod_status.conf
│ │ │ │ │ │ ├── 00_mod_userdir.conf
│ │ │ │ │ │ ├── 00_mpm.conf
│ │ │ │ │ │ ├── 10_mod_mem_cache.conf
│ │ │ │ │ │ ├── 40_mod_ssl.conf
│ │ │ │ │ │ ├── 41_mod_http2.conf
│ │ │ │ │ │ ├── 45_mod_dav.conf
│ │ │ │ │ │ └── 46_mod_ldap.conf
│ │ │ │ │ └── vhosts.d/
│ │ │ │ │ ├── 00_default_ssl_vhost.conf
│ │ │ │ │ ├── 00_default_vhost.conf
│ │ │ │ │ ├── default_vhost.include
│ │ │ │ │ └── gentoo.example.com.conf
│ │ │ │ ├── conf.d/
│ │ │ │ │ └── apache2
│ │ │ │ └── sites
│ │ │ └── util.py
│ │ └── tls_configs/
│ │ ├── current-options-ssl-apache.conf
│ │ └── old-options-ssl-apache.conf
│ └── py.typed
├── certbot-ci/
│ ├── MANIFEST.in
│ ├── pyproject.toml
│ ├── setup.py
│ └── src/
│ ├── certbot_integration_tests/
│ │ ├── .coveragerc
│ │ ├── __init__.py
│ │ ├── assets/
│ │ │ ├── bind-config/
│ │ │ │ ├── conf/
│ │ │ │ │ └── named.conf
│ │ │ │ ├── rfc2136-credentials-default.ini.tpl
│ │ │ │ └── zones/
│ │ │ │ ├── db.example.com
│ │ │ │ ├── db.sub.example.com
│ │ │ │ └── rpz.mock-recursion
│ │ │ ├── cert.pem
│ │ │ ├── hook.py
│ │ │ ├── key.pem
│ │ │ └── sample-config/
│ │ │ ├── accounts/
│ │ │ │ └── acme-staging.api.letsencrypt.org/
│ │ │ │ └── directory/
│ │ │ │ └── 48d6b9e8d767eccf7e4d877d6ffa81e3/
│ │ │ │ ├── meta.json
│ │ │ │ ├── private_key.json
│ │ │ │ └── regr.json
│ │ │ ├── archive/
│ │ │ │ ├── a.encryption-example.com/
│ │ │ │ │ ├── cert1.pem
│ │ │ │ │ ├── chain1.pem
│ │ │ │ │ ├── fullchain1.pem
│ │ │ │ │ └── privkey1.pem
│ │ │ │ ├── b.encryption-example.com/
│ │ │ │ │ ├── cert1.pem
│ │ │ │ │ ├── chain1.pem
│ │ │ │ │ ├── fullchain1.pem
│ │ │ │ │ └── privkey1.pem
│ │ │ │ └── c.encryption-example.com/
│ │ │ │ ├── README
│ │ │ │ ├── cert.pem
│ │ │ │ ├── chain.pem
│ │ │ │ ├── fullchain.pem
│ │ │ │ └── privkey.pem
│ │ │ ├── csr/
│ │ │ │ ├── 0000_csr-certbot.pem
│ │ │ │ ├── 0001_csr-certbot.pem
│ │ │ │ ├── 0002_csr-certbot.pem
│ │ │ │ └── 0003_csr-certbot.pem
│ │ │ ├── keys/
│ │ │ │ ├── 0000_key-certbot.pem
│ │ │ │ ├── 0001_key-certbot.pem
│ │ │ │ ├── 0002_key-certbot.pem
│ │ │ │ └── 0003_key-certbot.pem
│ │ │ ├── live/
│ │ │ │ ├── a.encryption-example.com/
│ │ │ │ │ └── README
│ │ │ │ ├── b.encryption-example.com/
│ │ │ │ │ └── README
│ │ │ │ └── c.encryption-example.com/
│ │ │ │ └── README
│ │ │ ├── options-ssl-apache.conf
│ │ │ └── renewal/
│ │ │ ├── a.encryption-example.com.conf
│ │ │ ├── b.encryption-example.com.conf
│ │ │ └── c.encryption-example.com.conf
│ │ ├── certbot_tests/
│ │ │ ├── __init__.py
│ │ │ ├── assertions.py
│ │ │ ├── context.py
│ │ │ └── test_main.py
│ │ ├── conftest.py
│ │ ├── nginx_tests/
│ │ │ ├── __init__.py
│ │ │ ├── context.py
│ │ │ ├── nginx_config.py
│ │ │ └── test_main.py
│ │ ├── py.typed
│ │ ├── rfc2136_tests/
│ │ │ ├── __init__.py
│ │ │ ├── context.py
│ │ │ └── test_main.py
│ │ └── utils/
│ │ ├── __init__.py
│ │ ├── acme_server.py
│ │ ├── certbot_call.py
│ │ ├── constants.py
│ │ ├── dns_server.py
│ │ ├── misc.py
│ │ ├── pebble_artifacts.py
│ │ ├── pebble_ocsp_server.py
│ │ └── proxy.py
│ └── snap_integration_tests/
│ ├── __init__.py
│ ├── conftest.py
│ ├── dns_tests/
│ │ ├── __init__.py
│ │ └── test_main.py
│ └── py.typed
├── certbot-compatibility-test/
│ ├── Dockerfile
│ ├── Dockerfile-apache
│ ├── Dockerfile-nginx
│ ├── LICENSE.txt
│ ├── MANIFEST.in
│ ├── README.rst
│ ├── nginx/
│ │ ├── README
│ │ ├── nginx-roundtrip-testdata/
│ │ │ ├── 79-configs/
│ │ │ │ ├── site-10033
│ │ │ │ ├── site-10571
│ │ │ │ ├── site-10591
│ │ │ │ ├── site-10920
│ │ │ │ ├── site-10947
│ │ │ │ ├── site-11018
│ │ │ │ ├── site-11046
│ │ │ │ ├── site-11382
│ │ │ │ ├── site-1167
│ │ │ │ ├── site-11849
│ │ │ │ ├── site-12027
│ │ │ │ ├── site-12235
│ │ │ │ ├── site-12649
│ │ │ │ ├── site-13577
│ │ │ │ ├── site-14402
│ │ │ │ ├── site-14430
│ │ │ │ ├── site-15141
│ │ │ │ ├── site-15270
│ │ │ │ ├── site-15291
│ │ │ │ ├── site-15456
│ │ │ │ ├── site-15497
│ │ │ │ ├── site-15852
│ │ │ │ ├── site-16345
│ │ │ │ ├── site-17175
│ │ │ │ ├── site-17832
│ │ │ │ ├── site-17942
│ │ │ │ ├── site-18018
│ │ │ │ ├── site-18069
│ │ │ │ ├── site-19334
│ │ │ │ ├── site-19639
│ │ │ │ ├── site-1966
│ │ │ │ ├── site-19791
│ │ │ │ ├── site-19955
│ │ │ │ ├── site-21369
│ │ │ │ ├── site-21549
│ │ │ │ ├── site-230
│ │ │ │ ├── site-23325
│ │ │ │ ├── site-23470
│ │ │ │ ├── site-23791
│ │ │ │ ├── site-23803
│ │ │ │ ├── site-23838
│ │ │ │ ├── site-24125
│ │ │ │ ├── site-24193
│ │ │ │ ├── site-24213
│ │ │ │ ├── site-25480
│ │ │ │ ├── site-26195
│ │ │ │ ├── site-26221
│ │ │ │ ├── site-26637
│ │ │ │ ├── site-26758
│ │ │ │ ├── site-27646
│ │ │ │ ├── site-27728
│ │ │ │ ├── site-27736
│ │ │ │ ├── site-27812
│ │ │ │ ├── site-28050
│ │ │ │ ├── site-28690
│ │ │ │ ├── site-29159
│ │ │ │ ├── site-2951
│ │ │ │ ├── site-30011
│ │ │ │ ├── site-30571
│ │ │ │ ├── site-31900
│ │ │ │ ├── site-32190
│ │ │ │ ├── site-32279
│ │ │ │ ├── site-32317
│ │ │ │ ├── site-32438
│ │ │ │ ├── site-3483
│ │ │ │ ├── site-3507
│ │ │ │ ├── site-3874
│ │ │ │ ├── site-4035
│ │ │ │ ├── site-4143
│ │ │ │ ├── site-4264
│ │ │ │ ├── site-5826
│ │ │ │ ├── site-5872
│ │ │ │ ├── site-6228
│ │ │ │ ├── site-7895
│ │ │ │ ├── site-8343
│ │ │ │ ├── site-8422
│ │ │ │ ├── site-8637
│ │ │ │ ├── site-8662
│ │ │ │ └── site-9426
│ │ │ ├── activecolab/
│ │ │ │ └── www.example.com.vhost
│ │ │ ├── anothermapcase/
│ │ │ │ └── nginx.conf
│ │ │ ├── chive/
│ │ │ │ └── chive-nginx-master/
│ │ │ │ ├── fastcgi.conf
│ │ │ │ ├── fastcgi_params
│ │ │ │ ├── koi-utf
│ │ │ │ ├── koi-win
│ │ │ │ ├── map_https_fcgi.conf
│ │ │ │ ├── mime.types
│ │ │ │ ├── nginx.conf
│ │ │ │ ├── reverse_proxy.conf
│ │ │ │ ├── sites-available/
│ │ │ │ │ ├── 000-default
│ │ │ │ │ ├── chive.example.com.conf
│ │ │ │ │ └── secure.chive.example.com.conf
│ │ │ │ ├── upstream_phpapache.conf
│ │ │ │ ├── upstream_phpcgi.conf
│ │ │ │ └── win-utf
│ │ │ ├── cms-made-simple/
│ │ │ │ └── nginx.conf
│ │ │ ├── codeigniter/
│ │ │ │ ├── nginx-alt.conf
│ │ │ │ └── nginx.conf
│ │ │ ├── contao/
│ │ │ │ └── sites-available/
│ │ │ │ └── example.com.vhost
│ │ │ ├── cs-cart/
│ │ │ │ └── sites-available/
│ │ │ │ └── example.com.vhost
│ │ │ ├── djangofastcgi/
│ │ │ │ ├── large.conf
│ │ │ │ └── nginx.conf
│ │ │ ├── dokuwiki/
│ │ │ │ ├── dokuwiki.conf
│ │ │ │ ├── drop.conf
│ │ │ │ ├── full.conf
│ │ │ │ ├── nginx-no-ssl.conf
│ │ │ │ └── nginx.conf
│ │ │ ├── drupal/
│ │ │ │ └── nginx.conf
│ │ │ ├── dynamic_ssi/
│ │ │ │ └── nginx.conf
│ │ │ ├── elgg/
│ │ │ │ └── nginx.conf
│ │ │ ├── embeddedperlminifyjs/
│ │ │ │ └── nginx.conf
│ │ │ ├── embeddedperlsitemapsproxy/
│ │ │ │ └── nginx.conf
│ │ │ ├── expressionengine/
│ │ │ │ ├── bad.conf
│ │ │ │ ├── better.conf
│ │ │ │ └── yourpath.conf
│ │ │ ├── fastcgiexample/
│ │ │ │ ├── fastcgi.conf
│ │ │ │ └── nginx.conf
│ │ │ ├── fengoffice/
│ │ │ │ └── sites-available/
│ │ │ │ └── www.example.com.vhost
│ │ │ ├── full-example/
│ │ │ │ ├── fastcgi.conf
│ │ │ │ ├── mime.types
│ │ │ │ ├── nginx.conf
│ │ │ │ └── proxy.conf
│ │ │ ├── fullexample2/
│ │ │ │ └── nginx.conf
│ │ │ ├── geoip/
│ │ │ │ └── nginx.conf
│ │ │ ├── guide-to-nginx-ssl-spdy-hsts/
│ │ │ │ └── nginx.conf
│ │ │ ├── hardwarelberrors/
│ │ │ │ └── nginx.conf
│ │ │ ├── icinga/
│ │ │ │ └── sites-available/
│ │ │ │ └── www.example.com.vhost
│ │ │ ├── imapauthenticatewithapacheperlscript/
│ │ │ │ └── nginx.conf
│ │ │ ├── imapauthenticatewithapachephpscript/
│ │ │ │ └── nginx.conf
│ │ │ ├── imapproxyexample/
│ │ │ │ ├── nginx.conf
│ │ │ │ └── proxy-example.conf
│ │ │ ├── iphone-website-with-nginx/
│ │ │ │ ├── mobile.conf
│ │ │ │ └── nginx.conf
│ │ │ ├── iredmail/
│ │ │ │ ├── iredadmin.conf
│ │ │ │ └── nginx.conf
│ │ │ ├── javaservers/
│ │ │ │ └── nginx.conf
│ │ │ ├── joomla/
│ │ │ │ └── nginx.conf
│ │ │ ├── likeapache/
│ │ │ │ └── nginx.conf
│ │ │ ├── loadbalanceexample/
│ │ │ │ └── nginx.conf
│ │ │ ├── mailman/
│ │ │ │ └── nginx.conf
│ │ │ ├── mediawiki/
│ │ │ │ └── nginx.conf
│ │ │ ├── memcachepreload/
│ │ │ │ └── sites-available/
│ │ │ │ └── default
│ │ │ ├── minio/
│ │ │ │ └── sites-enabled/
│ │ │ │ └── nginx.conf
│ │ │ ├── mono/
│ │ │ │ └── nginx.conf
│ │ │ ├── mybb/
│ │ │ │ └── nginx.conf
│ │ │ ├── nonrootwebpath/
│ │ │ │ └── nginx.conf
│ │ │ ├── omeka/
│ │ │ │ └── nginx.conf
│ │ │ ├── oscommerce/
│ │ │ │ └── nginx.conf
│ │ │ ├── osticket/
│ │ │ │ └── nginx.conf
│ │ │ ├── owncloud/
│ │ │ │ └── sites-available/
│ │ │ │ └── www.example.com.vhost
│ │ │ ├── oxid-eshop/
│ │ │ │ └── sites-available/
│ │ │ │ └── www.example.com.vhost
│ │ │ ├── php-fpm/
│ │ │ │ └── default.conf
│ │ │ ├── phpbb/
│ │ │ │ └── nginx.sample.conf
│ │ │ ├── phpfastcgionwindows/
│ │ │ │ └── nginx.conf
│ │ │ ├── phpfcgi/
│ │ │ │ ├── fastcgi_params
│ │ │ │ └── nginx.conf
│ │ │ ├── phplist/
│ │ │ │ └── nginx.conf
│ │ │ ├── piwik/
│ │ │ │ └── nginx.conf
│ │ │ ├── pmwiki/
│ │ │ │ └── nginx.conf
│ │ │ ├── prestashop/
│ │ │ │ └── sites-available/
│ │ │ │ └── www.example.com.vhost
│ │ │ ├── processwire/
│ │ │ │ └── sites-available/
│ │ │ │ └── www.example.com.vhost
│ │ │ ├── pylons/
│ │ │ │ └── nginx.vhost.conf
│ │ │ ├── pyrocms/
│ │ │ │ ├── drop.conf
│ │ │ │ ├── fastcgi_params
│ │ │ │ └── nginx.conf
│ │ │ ├── qwebric/
│ │ │ │ ├── redirect.conf
│ │ │ │ └── reverse-proxy.conf
│ │ │ ├── redaxo/
│ │ │ │ └── sites-available/
│ │ │ │ └── www.example.com.vhost
│ │ │ ├── redmine/
│ │ │ │ └── nginx.conf
│ │ │ ├── reverseproxycachingexample/
│ │ │ │ └── nginx.conf
│ │ │ ├── roundcube/
│ │ │ │ └── sites-available/
│ │ │ │ └── example.com.vhost.conf
│ │ │ ├── separateerrorloggingpervirtualhost/
│ │ │ │ └── nginx.conf
│ │ │ ├── server_blocks/
│ │ │ │ ├── catchall.conf
│ │ │ │ ├── two.conf
│ │ │ │ └── wildcard-subdomains.conf
│ │ │ ├── shopware/
│ │ │ │ └── sites-available/
│ │ │ │ └── www.example.com.vhost
│ │ │ ├── shopware4/
│ │ │ │ └── sites-available/
│ │ │ │ └── www.example.com.vhost
│ │ │ ├── silverstripe/
│ │ │ │ └── nginx.conf
│ │ │ ├── simplecgi/
│ │ │ │ └── nginx.conf
│ │ │ ├── simplegroupware/
│ │ │ │ └── sites-available/
│ │ │ │ └── www.example.com.vhost
│ │ │ ├── simplepythonfcgi/
│ │ │ │ ├── fastcgi.conf
│ │ │ │ ├── nginx.conf
│ │ │ │ └── weird-spacing.conf
│ │ │ ├── simplerubyfcgi/
│ │ │ │ └── nginx.conf
│ │ │ ├── spip/
│ │ │ │ └── nginx.conf
│ │ │ ├── sugarcrm/
│ │ │ │ └── sites-available/
│ │ │ │ └── www.example.com.vhost
│ │ │ ├── symfony/
│ │ │ │ ├── nginx.conf
│ │ │ │ ├── old.conf
│ │ │ │ └── oldold.conf
│ │ │ ├── typo3-4.6/
│ │ │ │ └── sites-available/
│ │ │ │ └── www.example.com.vhost
│ │ │ ├── typo3-6.2/
│ │ │ │ └── sites-available/
│ │ │ │ └── www.example.com.vhost
│ │ │ ├── upstream-issue-17/
│ │ │ │ └── nginx.conf
│ │ │ ├── upstream-issue-19/
│ │ │ │ └── nginx.conf
│ │ │ ├── wordpress/
│ │ │ │ ├── multisite-subdir.conf
│ │ │ │ ├── multisite-subdomain.conf
│ │ │ │ └── nginx.conf
│ │ │ ├── wordpress-caching/
│ │ │ │ ├── no-cache.conf
│ │ │ │ ├── supercache.conf
│ │ │ │ ├── total-cache.conf
│ │ │ │ └── totalcache-enhanced.conf
│ │ │ ├── xenforo/
│ │ │ │ └── nginx.conf
│ │ │ ├── yii/
│ │ │ │ └── nginx.conf
│ │ │ ├── zend/
│ │ │ │ └── nginx.conf
│ │ │ ├── zenphoto/
│ │ │ │ └── nginx.conf
│ │ │ └── zope/
│ │ │ └── nginx.conf
│ │ └── roundtrip.py
│ ├── pyproject.toml
│ ├── setup.py
│ └── src/
│ └── certbot_compatibility_test/
│ ├── __init__.py
│ ├── configurators/
│ │ ├── __init__.py
│ │ ├── apache/
│ │ │ ├── __init__.py
│ │ │ └── common.py
│ │ ├── common.py
│ │ └── nginx/
│ │ ├── __init__.py
│ │ └── common.py
│ ├── errors.py
│ ├── interfaces.py
│ ├── test_driver.py
│ ├── testdata/
│ │ └── empty_cert.pem
│ ├── util.py
│ └── validator.py
├── certbot-dns-cloudflare/
│ ├── .readthedocs.yaml
│ ├── LICENSE.txt
│ ├── MANIFEST.in
│ ├── README.rst
│ ├── docs/
│ │ ├── .gitignore
│ │ ├── Makefile
│ │ ├── api.rst
│ │ ├── conf.py
│ │ ├── index.rst
│ │ └── make.bat
│ ├── pyproject.toml
│ ├── readthedocs.org.requirements.txt
│ ├── setup.py
│ └── src/
│ └── certbot_dns_cloudflare/
│ ├── __init__.py
│ ├── _internal/
│ │ ├── __init__.py
│ │ ├── dns_cloudflare.py
│ │ └── tests/
│ │ ├── __init__.py
│ │ └── dns_cloudflare_test.py
│ └── py.typed
├── certbot-dns-digitalocean/
│ ├── .readthedocs.yaml
│ ├── LICENSE.txt
│ ├── MANIFEST.in
│ ├── README.rst
│ ├── docs/
│ │ ├── .gitignore
│ │ ├── Makefile
│ │ ├── api.rst
│ │ ├── conf.py
│ │ ├── index.rst
│ │ └── make.bat
│ ├── pyproject.toml
│ ├── readthedocs.org.requirements.txt
│ ├── setup.py
│ └── src/
│ └── certbot_dns_digitalocean/
│ ├── __init__.py
│ ├── _internal/
│ │ ├── __init__.py
│ │ ├── dns_digitalocean.py
│ │ └── tests/
│ │ ├── __init__.py
│ │ └── dns_digitalocean_test.py
│ └── py.typed
├── certbot-dns-dnsimple/
│ ├── .readthedocs.yaml
│ ├── LICENSE.txt
│ ├── MANIFEST.in
│ ├── README.rst
│ ├── docs/
│ │ ├── .gitignore
│ │ ├── Makefile
│ │ ├── api.rst
│ │ ├── conf.py
│ │ ├── index.rst
│ │ └── make.bat
│ ├── pyproject.toml
│ ├── readthedocs.org.requirements.txt
│ ├── setup.py
│ └── src/
│ └── certbot_dns_dnsimple/
│ ├── __init__.py
│ ├── _internal/
│ │ ├── __init__.py
│ │ ├── dns_dnsimple.py
│ │ └── tests/
│ │ ├── __init__.py
│ │ └── dns_dnsimple_test.py
│ └── py.typed
├── certbot-dns-dnsmadeeasy/
│ ├── .readthedocs.yaml
│ ├── LICENSE.txt
│ ├── MANIFEST.in
│ ├── README.rst
│ ├── docs/
│ │ ├── .gitignore
│ │ ├── Makefile
│ │ ├── api.rst
│ │ ├── conf.py
│ │ ├── index.rst
│ │ └── make.bat
│ ├── pyproject.toml
│ ├── readthedocs.org.requirements.txt
│ ├── setup.py
│ └── src/
│ └── certbot_dns_dnsmadeeasy/
│ ├── __init__.py
│ ├── _internal/
│ │ ├── __init__.py
│ │ ├── dns_dnsmadeeasy.py
│ │ └── tests/
│ │ ├── __init__.py
│ │ └── dns_dnsmadeeasy_test.py
│ └── py.typed
├── certbot-dns-gehirn/
│ ├── .readthedocs.yaml
│ ├── LICENSE.txt
│ ├── MANIFEST.in
│ ├── README.rst
│ ├── docs/
│ │ ├── .gitignore
│ │ ├── Makefile
│ │ ├── api.rst
│ │ ├── conf.py
│ │ ├── index.rst
│ │ └── make.bat
│ ├── pyproject.toml
│ ├── readthedocs.org.requirements.txt
│ ├── setup.py
│ └── src/
│ └── certbot_dns_gehirn/
│ ├── __init__.py
│ ├── _internal/
│ │ ├── __init__.py
│ │ ├── dns_gehirn.py
│ │ └── tests/
│ │ ├── __init__.py
│ │ └── dns_gehirn_test.py
│ └── py.typed
├── certbot-dns-google/
│ ├── .readthedocs.yaml
│ ├── LICENSE.txt
│ ├── MANIFEST.in
│ ├── README.rst
│ ├── docs/
│ │ ├── .gitignore
│ │ ├── Makefile
│ │ ├── api.rst
│ │ ├── conf.py
│ │ ├── index.rst
│ │ └── make.bat
│ ├── pyproject.toml
│ ├── readthedocs.org.requirements.txt
│ ├── setup.py
│ └── src/
│ └── certbot_dns_google/
│ ├── __init__.py
│ ├── _internal/
│ │ ├── __init__.py
│ │ ├── dns_google.py
│ │ └── tests/
│ │ ├── __init__.py
│ │ ├── dns_google_test.py
│ │ └── testdata/
│ │ └── discovery.json
│ └── py.typed
├── certbot-dns-linode/
│ ├── .readthedocs.yaml
│ ├── LICENSE.txt
│ ├── MANIFEST.in
│ ├── README.rst
│ ├── docs/
│ │ ├── .gitignore
│ │ ├── Makefile
│ │ ├── api.rst
│ │ ├── conf.py
│ │ ├── index.rst
│ │ └── make.bat
│ ├── pyproject.toml
│ ├── readthedocs.org.requirements.txt
│ ├── setup.py
│ └── src/
│ └── certbot_dns_linode/
│ ├── __init__.py
│ ├── _internal/
│ │ ├── __init__.py
│ │ ├── dns_linode.py
│ │ └── tests/
│ │ ├── __init__.py
│ │ └── dns_linode_test.py
│ └── py.typed
├── certbot-dns-luadns/
│ ├── .readthedocs.yaml
│ ├── LICENSE.txt
│ ├── MANIFEST.in
│ ├── README.rst
│ ├── docs/
│ │ ├── .gitignore
│ │ ├── Makefile
│ │ ├── api.rst
│ │ ├── conf.py
│ │ ├── index.rst
│ │ └── make.bat
│ ├── pyproject.toml
│ ├── readthedocs.org.requirements.txt
│ ├── setup.py
│ └── src/
│ └── certbot_dns_luadns/
│ ├── __init__.py
│ ├── _internal/
│ │ ├── __init__.py
│ │ ├── dns_luadns.py
│ │ └── tests/
│ │ ├── __init__.py
│ │ └── dns_luadns_test.py
│ └── py.typed
├── certbot-dns-nsone/
│ ├── .readthedocs.yaml
│ ├── LICENSE.txt
│ ├── MANIFEST.in
│ ├── README.rst
│ ├── docs/
│ │ ├── .gitignore
│ │ ├── Makefile
│ │ ├── api.rst
│ │ ├── conf.py
│ │ ├── index.rst
│ │ └── make.bat
│ ├── pyproject.toml
│ ├── readthedocs.org.requirements.txt
│ ├── setup.py
│ └── src/
│ └── certbot_dns_nsone/
│ ├── __init__.py
│ ├── _internal/
│ │ ├── __init__.py
│ │ ├── dns_nsone.py
│ │ └── tests/
│ │ ├── __init__.py
│ │ └── dns_nsone_test.py
│ └── py.typed
├── certbot-dns-ovh/
│ ├── .readthedocs.yaml
│ ├── LICENSE.txt
│ ├── MANIFEST.in
│ ├── README.rst
│ ├── docs/
│ │ ├── .gitignore
│ │ ├── Makefile
│ │ ├── api.rst
│ │ ├── conf.py
│ │ ├── index.rst
│ │ └── make.bat
│ ├── pyproject.toml
│ ├── readthedocs.org.requirements.txt
│ ├── setup.py
│ └── src/
│ └── certbot_dns_ovh/
│ ├── __init__.py
│ ├── _internal/
│ │ ├── __init__.py
│ │ ├── dns_ovh.py
│ │ └── tests/
│ │ ├── __init__.py
│ │ └── dns_ovh_test.py
│ └── py.typed
├── certbot-dns-rfc2136/
│ ├── .readthedocs.yaml
│ ├── LICENSE.txt
│ ├── MANIFEST.in
│ ├── README.rst
│ ├── docs/
│ │ ├── .gitignore
│ │ ├── Makefile
│ │ ├── api.rst
│ │ ├── conf.py
│ │ ├── index.rst
│ │ └── make.bat
│ ├── pyproject.toml
│ ├── readthedocs.org.requirements.txt
│ ├── setup.py
│ └── src/
│ └── certbot_dns_rfc2136/
│ ├── __init__.py
│ ├── _internal/
│ │ ├── __init__.py
│ │ ├── dns_rfc2136.py
│ │ └── tests/
│ │ ├── __init__.py
│ │ └── dns_rfc2136_test.py
│ └── py.typed
├── certbot-dns-route53/
│ ├── .readthedocs.yaml
│ ├── LICENSE.txt
│ ├── MANIFEST.in
│ ├── README.rst
│ ├── docs/
│ │ ├── .gitignore
│ │ ├── Makefile
│ │ ├── api.rst
│ │ ├── conf.py
│ │ ├── index.rst
│ │ └── make.bat
│ ├── examples/
│ │ └── sample-aws-policy.json
│ ├── pyproject.toml
│ ├── readthedocs.org.requirements.txt
│ ├── setup.py
│ └── src/
│ └── certbot_dns_route53/
│ ├── __init__.py
│ ├── _internal/
│ │ ├── __init__.py
│ │ ├── dns_route53.py
│ │ └── tests/
│ │ ├── __init__.py
│ │ ├── conftest.py
│ │ └── dns_route53_test.py
│ └── py.typed
├── certbot-dns-sakuracloud/
│ ├── .readthedocs.yaml
│ ├── LICENSE.txt
│ ├── MANIFEST.in
│ ├── README.rst
│ ├── docs/
│ │ ├── .gitignore
│ │ ├── Makefile
│ │ ├── api.rst
│ │ ├── conf.py
│ │ ├── index.rst
│ │ └── make.bat
│ ├── pyproject.toml
│ ├── readthedocs.org.requirements.txt
│ ├── setup.py
│ └── src/
│ └── certbot_dns_sakuracloud/
│ ├── __init__.py
│ ├── _internal/
│ │ ├── __init__.py
│ │ ├── dns_sakuracloud.py
│ │ └── tests/
│ │ ├── __init__.py
│ │ └── dns_sakuracloud_test.py
│ └── py.typed
├── certbot-nginx/
│ ├── LICENSE.txt
│ ├── MANIFEST.in
│ ├── README.rst
│ ├── pyproject.toml
│ ├── setup.py
│ └── src/
│ └── certbot_nginx/
│ ├── __init__.py
│ ├── _internal/
│ │ ├── __init__.py
│ │ ├── configurator.py
│ │ ├── constants.py
│ │ ├── display_ops.py
│ │ ├── http_01.py
│ │ ├── nginxparser.py
│ │ ├── obj.py
│ │ ├── parser.py
│ │ ├── parser_obj.py
│ │ ├── tests/
│ │ │ ├── __init__.py
│ │ │ ├── configurator_test.py
│ │ │ ├── display_ops_test.py
│ │ │ ├── http_01_test.py
│ │ │ ├── nginxparser_test.py
│ │ │ ├── obj_test.py
│ │ │ ├── parser_obj_test.py
│ │ │ ├── parser_test.py
│ │ │ ├── test_util.py
│ │ │ └── testdata/
│ │ │ └── etc_nginx/
│ │ │ ├── broken.conf
│ │ │ ├── comment_in_file.conf
│ │ │ ├── edge_cases.conf
│ │ │ ├── foo.conf
│ │ │ ├── invalid_unicode_comments.conf
│ │ │ ├── mime.types
│ │ │ ├── minimalistic_comments.conf
│ │ │ ├── multiline_quotes.conf
│ │ │ ├── nginx-include.conf
│ │ │ ├── nginx.conf
│ │ │ ├── server.conf
│ │ │ ├── sites-enabled/
│ │ │ │ ├── addr-80.com
│ │ │ │ ├── both.com
│ │ │ │ ├── default
│ │ │ │ ├── example.com
│ │ │ │ ├── example.net
│ │ │ │ ├── globalssl.com
│ │ │ │ ├── headers.com
│ │ │ │ ├── ipv6.com
│ │ │ │ ├── ipv6ssl.com
│ │ │ │ ├── migration.com
│ │ │ │ ├── no-listens.com
│ │ │ │ └── sslon.com
│ │ │ ├── ubuntu_nginx_1_4_6/
│ │ │ │ └── default_vhost/
│ │ │ │ └── nginx/
│ │ │ │ ├── fastcgi_params
│ │ │ │ ├── koi-utf
│ │ │ │ ├── koi-win
│ │ │ │ ├── mime.types
│ │ │ │ ├── naxsi-ui.conf.1.4.1
│ │ │ │ ├── naxsi.rules
│ │ │ │ ├── naxsi_core.rules
│ │ │ │ ├── nginx.conf
│ │ │ │ ├── proxy_params
│ │ │ │ ├── scgi_params
│ │ │ │ ├── sites-available/
│ │ │ │ │ └── default
│ │ │ │ ├── uwsgi_params
│ │ │ │ └── win-utf
│ │ │ └── valid_unicode_comments.conf
│ │ └── tls_configs/
│ │ ├── options-ssl-nginx-old.conf
│ │ ├── options-ssl-nginx-tls12-only.conf
│ │ ├── options-ssl-nginx-tls13-session-tix-on.conf
│ │ └── options-ssl-nginx.conf
│ └── py.typed
├── letsencrypt-auto-source/
│ ├── README.md
│ ├── letsencrypt-auto
│ └── letsencrypt-auto.sig
├── letstest/
│ ├── README.md
│ ├── letstest/
│ │ ├── __init__.py
│ │ └── multitester.py
│ ├── pyproject.toml
│ ├── scripts/
│ │ ├── bootstrap_os_packages.sh
│ │ ├── test_apache2.sh
│ │ └── version.py
│ ├── setup.py
│ └── targets/
│ └── targets.yaml
├── linter_plugin.py
├── mypy.ini
├── newsfragments/
│ ├── .gitignore
│ └── 10584.changed
├── pytest.ini
├── ruff.toml
├── snap/
│ ├── hooks/
│ │ ├── configure
│ │ └── prepare-plug-plugin
│ └── snapcraft.yaml
├── tests/
│ └── modification-check.py
├── tools/
│ ├── _release.sh
│ ├── docker/
│ │ ├── Dockerfile
│ │ ├── README.md
│ │ ├── build.sh
│ │ ├── deploy_images.sh
│ │ ├── deploy_manifests.sh
│ │ ├── lib/
│ │ │ └── common
│ │ └── test.sh
│ ├── extract_changelog.py
│ ├── finish_release.py
│ ├── oldest_constraints.txt
│ ├── pinning/
│ │ ├── DESIGN.md
│ │ ├── common/
│ │ │ └── export-pinned-dependencies.sh
│ │ ├── current/
│ │ │ ├── pyproject.toml
│ │ │ └── repin.sh
│ │ └── oldest/
│ │ ├── pyproject.toml
│ │ └── repin.sh
│ ├── pip_install.py
│ ├── pipstrap.py
│ ├── release.sh
│ ├── requirements.txt
│ ├── retry.sh
│ ├── snap/
│ │ ├── README.md
│ │ ├── build_remote.py
│ │ ├── generate_dnsplugins_all.sh
│ │ ├── generate_dnsplugins_postrefreshhook.sh
│ │ └── generate_dnsplugins_snapcraft.sh
│ ├── sphinx-quickstart.sh
│ └── venv.py
├── towncrier.toml
└── tox.ini
================================================
FILE CONTENTS
================================================
================================================
FILE: .azure-pipelines/INSTALL.md
================================================
# 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 main, and pushes to main,
* `.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 main.
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 main, 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 targeted github repo)
- The Visibility is public, to profit from 10 parallel jobs
```
!!! ACCESS !!!
Azure Pipelines needs access to the GitHub account (in term of being able to check it is valid), and the Resources shared between the GitHub account and Azure Pipelines.
```
_Done. We can move to pipelines configuration._
## 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, main 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 main 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)
```
To set up a variable that is shared between pipelines, follow the instructions
at
https://docs.microsoft.com/en-us/azure/devops/pipelines/library/variable-groups.
When adding variables to a group, don't forget to tick "Keep this value secret"
if it shouldn't be shared publcily.
================================================
FILE: .azure-pipelines/advanced-test.yml
================================================
# Advanced pipeline for running our full test suite on demand.
trigger:
# When changing these triggers, please ensure the documentation under
# "Running tests in CI" is still correct.
- test-*
pr: none
variables:
# We don't publish our Docker images in this pipeline, but when building them
# for testing, let's use the nightly tag.
dockerTag: nightly
snapBuildTimeout: 5400
stages:
- template: templates/stages/test-and-package-stage.yml
================================================
FILE: .azure-pipelines/main.yml
================================================
# We run the test suite on commits to main so codecov gets coverage data
# about the main branch and can use it to track coverage changes.
trigger:
- main
pr:
- main
- '*.x'
variables:
# We set this here to avoid coverage data being uploaded from things like our
# nightly pipeline. This is done because codecov (helpfully) keeps track of
# the number of coverage uploads for a commit and displays a warning when
# comparing two commits with an unequal number of uploads. Only uploading
# coverage here should keep the number of uploads it sees consistent.
uploadCoverage: true
jobs:
- template: templates/jobs/standard-tests-jobs.yml
================================================
FILE: .azure-pipelines/nightly.yml
================================================
# Nightly pipeline running each day for main.
trigger: none
pr: none
schedules:
- cron: "30 4 * * *"
displayName: Nightly build
branches:
include:
- main
always: true
variables:
dockerTag: nightly
snapBuildTimeout: 19800
stages:
- template: templates/stages/test-and-package-stage.yml
- template: templates/stages/changelog-stage.yml
- template: templates/stages/nightly-deploy-stage.yml
================================================
FILE: .azure-pipelines/release.yml
================================================
# Release pipeline to run our full test suite, build artifacts, and deploy them
# for GitHub release tags.
trigger:
tags:
include:
- v*
pr: none
variables:
dockerTag: ${{variables['Build.SourceBranchName']}}
snapBuildTimeout: 19800
stages:
- template: templates/stages/test-and-package-stage.yml
- template: templates/stages/changelog-stage.yml
- template: templates/stages/release-deploy-stage.yml
================================================
FILE: .azure-pipelines/templates/jobs/common-deploy-jobs.yml
================================================
# As (somewhat) described at
# https://docs.microsoft.com/en-us/azure/devops/pipelines/process/templates?view=azure-devops#context,
# each template only has access to the parameters passed into it. To help make
# use of this design, we define snapReleaseChannel without a default value
# which requires the user of this template to define it as described at
# https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema/parameters-name?view=azure-pipelines#remarks.
# This makes the user of this template be explicit while allowing them to
# define their own parameters with defaults that make sense for that context.
parameters:
- name: snapReleaseChannel
type: string
values:
- edge
- beta
jobs:
# This job relies on credentials used to publish the Certbot snaps. This
# credential file was created by running:
#
# snapcraft logout
# snapcraft export-login --channels=beta,edge snapcraft.cfg
# (provide the shared snapcraft credentials when prompted)
#
# Then the file was added as a secure file in Azure pipelines
# with the name snapcraft.cfg by following the instructions at
# https://docs.microsoft.com/en-us/azure/devops/pipelines/library/secure-files?view=azure-devops
# including authorizing the file for use in the "nightly" and "release"
# pipelines as described at
# https://docs.microsoft.com/en-us/azure/devops/pipelines/library/secure-files?view=azure-devops#q-how-do-i-authorize-a-secure-file-for-use-in-a-specific-pipeline.
#
# This file has a maximum lifetime of one year. Revoking these credentials
# can be done by changing the password of the account used to generate the
# credentials. See
# https://forum.snapcraft.io/t/revoking-exported-credentials/19031 for more
# info.
- job: publish_snap
pool:
vmImage: ubuntu-22.04
variables:
- group: certbot-common
strategy:
matrix:
amd64:
SNAP_ARCH: amd64
arm32v6:
SNAP_ARCH: armhf
arm64v8:
SNAP_ARCH: arm64
steps:
- bash: |
set -e
sudo apt-get update
sudo apt-get install -y --no-install-recommends snapd
sudo snap install --classic snapcraft
displayName: Install dependencies
- task: DownloadPipelineArtifact@2
inputs:
artifact: snaps_$(SNAP_ARCH)
path: $(Build.SourcesDirectory)/snap
displayName: Retrieve Certbot snaps
- task: DownloadSecureFile@1
name: snapcraftCfg
inputs:
secureFile: snapcraft.cfg
- bash: |
set -e
export SNAPCRAFT_STORE_CREDENTIALS=$(cat "$(snapcraftCfg.secureFilePath)")
for SNAP_FILE in snap/*.snap; do
tools/retry.sh eval snapcraft upload --release=${{ parameters.snapReleaseChannel }} "${SNAP_FILE}"
done
displayName: Publish to Snap store
# The credentials used in the following jobs are for the shared
# certbotbot account on Docker Hub. The credentials are stored
# in a service account which was created by following the
# instructions at
# https://docs.microsoft.com/en-us/azure/devops/pipelines/library/service-endpoints?view=azure-devops&tabs=yaml#sep-docreg.
# The name given to this service account must match the value
# given to containerRegistry below. The authentication used when
# creating this service account was a personal access token
# rather than a password to bypass 2FA. When Brad set this up,
# Azure Pipelines failed to verify the credentials with an error
# like "access is forbidden with a JWT issued from a personal
# access token", but after saving them without verification, the
# access token worked when the pipeline actually ran. "Grant
# access to all pipelines" should also be checked on the service
# account. The access token can be deleted on Docker Hub if
# these credentials need to be revoked.
- job: publish_docker_by_arch
pool:
vmImage: ubuntu-22.04
strategy:
matrix:
arm32v6:
DOCKER_ARCH: arm32v6
arm64v8:
DOCKER_ARCH: arm64v8
amd64:
DOCKER_ARCH: amd64
steps:
- task: DownloadPipelineArtifact@2
inputs:
artifact: docker_$(DOCKER_ARCH)
path: $(Build.SourcesDirectory)
displayName: Retrieve Docker images
- bash: set -e && docker load --input $(Build.SourcesDirectory)/images.tar
displayName: Load Docker images
- task: Docker@2
inputs:
command: login
containerRegistry: docker-hub
displayName: Login to Docker Hub
- bash: set -e && tools/docker/deploy_images.sh $(dockerTag) $DOCKER_ARCH
displayName: Deploy the Docker images by architecture
- job: publish_docker_multiarch
dependsOn: publish_docker_by_arch
pool:
vmImage: ubuntu-22.04
steps:
- task: Docker@2
inputs:
command: login
containerRegistry: docker-hub
displayName: Login to Docker Hub
- bash: set -e && tools/docker/deploy_manifests.sh $(dockerTag) all
displayName: Deploy the Docker multiarch manifests
================================================
FILE: .azure-pipelines/templates/jobs/extended-tests-jobs.yml
================================================
jobs:
- job: extended_test
variables:
- name: IMAGE_NAME
value: ubuntu-22.04
- name: PYTHON_VERSION
value: 3.14
- group: certbot-common
strategy:
matrix:
linux-py311:
PYTHON_VERSION: 3.11
TOXENV: py311
linux-py312:
PYTHON_VERSION: 3.12
TOXENV: py312
linux-py313:
PYTHON_VERSION: 3.13
TOXENV: py313
linux-isolated:
TOXENV: 'isolated-acme,isolated-certbot,isolated-apache,isolated-cloudflare,isolated-digitalocean,isolated-dnsimple,isolated-dnsmadeeasy,isolated-gehirn,isolated-google,isolated-linode,isolated-luadns,isolated-nsone,isolated-ovh,isolated-rfc2136,isolated-route53,isolated-sakuracloud,isolated-nginx'
linux-integration-certbot-oldest:
PYTHON_VERSION: 3.10
TOXENV: integration-certbot-oldest
linux-integration-nginx-oldest:
PYTHON_VERSION: 3.10
TOXENV: integration-nginx-oldest
linux-py310-integration:
PYTHON_VERSION: 3.10
TOXENV: integration
linux-py311-integration:
PYTHON_VERSION: 3.11
TOXENV: integration
linux-py312-integration:
PYTHON_VERSION: 3.12
TOXENV: integration
linux-py313-integration:
PYTHON_VERSION: 3.13
TOXENV: integration
# python 3.14 integration tests are not run here because they're run as
# part of the standard test suite
nginx-compat:
TOXENV: nginx_compat
linux-integration-rfc2136:
IMAGE_NAME: ubuntu-22.04
PYTHON_VERSION: 3.12
TOXENV: integration-dns-rfc2136
le-modification:
IMAGE_NAME: ubuntu-22.04
TOXENV: modification
farmtest-apache2:
PYTHON_VERSION: 3.12
TOXENV: test-farm-apache2
pool:
vmImage: $(IMAGE_NAME)
steps:
- template: ../steps/tox-steps.yml
================================================
FILE: .azure-pipelines/templates/jobs/packaging-jobs.yml
================================================
jobs:
- job: docker_build
pool:
vmImage: ubuntu-24.04
strategy:
matrix:
arm32v6:
DOCKER_ARCH: arm32v6
arm64v8:
DOCKER_ARCH: arm64v8
amd64:
DOCKER_ARCH: amd64
# The default timeout of 60 minutes is a little low for compiling
# cryptography on ARM architectures.
timeoutInMinutes: 180
steps:
- bash: set -e && tools/docker/build.sh $(dockerTag) $DOCKER_ARCH
displayName: Build the Docker images
# We don't filter for the Docker Hub organization to continue to allow
# easy testing of these scripts on forks.
- bash: |
set -e
DOCKER_IMAGES=$(docker images --filter reference='*/certbot' --filter reference='*/dns-*' --format '{{.Repository}}')
docker save --output images.tar $DOCKER_IMAGES
displayName: Save the Docker images
# If the name of the tar file or artifact changes, the deploy stage will
# also need to be updated.
- bash: set -e && mv images.tar $(Build.ArtifactStagingDirectory)
displayName: Prepare Docker artifact
- task: PublishPipelineArtifact@1
inputs:
path: $(Build.ArtifactStagingDirectory)
artifact: docker_$(DOCKER_ARCH)
displayName: Store Docker artifact
- job: docker_test
dependsOn: docker_build
pool:
vmImage: ubuntu-22.04
strategy:
matrix:
arm32v6:
DOCKER_ARCH: arm32v6
arm64v8:
DOCKER_ARCH: arm64v8
amd64:
DOCKER_ARCH: amd64
steps:
- task: DownloadPipelineArtifact@2
inputs:
artifact: docker_$(DOCKER_ARCH)
path: $(Build.SourcesDirectory)
displayName: Retrieve Docker images
- bash: set -e && docker load --input $(Build.SourcesDirectory)/images.tar
displayName: Load Docker images
- bash: |
set -e && tools/docker/test.sh $(dockerTag) $DOCKER_ARCH
displayName: Run integration tests for Docker images
- job: snaps_build
pool:
vmImage: ubuntu-22.04
strategy:
matrix:
amd64:
SNAP_ARCH: amd64
armhf:
SNAP_ARCH: armhf
arm64:
SNAP_ARCH: arm64
timeoutInMinutes: 0
steps:
- script: |
set -e
sudo apt-get update
sudo apt-get install -y --no-install-recommends snapd
sudo snap install --classic snapcraft
displayName: Install dependencies
- task: UsePythonVersion@0
inputs:
versionSpec: 3.12
addToPath: true
- task: DownloadSecureFile@1
name: credentials
inputs:
secureFile: launchpad-credentials
- script: |
set -e
git config --global user.email "$(Build.RequestedForEmail)"
git config --global user.name "$(Build.RequestedFor)"
mkdir -p ~/.local/share/snapcraft/provider/launchpad
cp $(credentials.secureFilePath) ~/.local/share/snapcraft/provider/launchpad/credentials
python3 tools/snap/build_remote.py ALL --archs ${SNAP_ARCH} --timeout $(snapBuildTimeout)
displayName: Build snaps
- script: |
set -e
mv *.snap $(Build.ArtifactStagingDirectory)
mv certbot-dns-*/*.snap $(Build.ArtifactStagingDirectory)
displayName: Prepare artifacts
- task: PublishPipelineArtifact@1
inputs:
path: $(Build.ArtifactStagingDirectory)
artifact: snaps_$(SNAP_ARCH)
displayName: Store snaps artifacts
- job: snap_run
dependsOn: snaps_build
pool:
vmImage: ubuntu-22.04
steps:
- task: UsePythonVersion@0
inputs:
versionSpec: 3.12
addToPath: true
- script: |
set -e
sudo apt-get update
sudo apt-get install -y --no-install-recommends nginx-light snapd
python3 -m venv venv
venv/bin/python tools/pip_install.py -U tox
displayName: Install dependencies
- task: DownloadPipelineArtifact@2
inputs:
artifact: snaps_amd64
path: $(Build.SourcesDirectory)/snap
displayName: Retrieve Certbot snaps
- script: |
set -e
sudo snap install --dangerous --classic snap/certbot_*.snap
displayName: Install Certbot snap
- script: |
set -e
venv/bin/python -m tox run -e integration-external,apacheconftest-external-with-pebble
displayName: Run tox
- job: snap_dns_run
dependsOn: snaps_build
pool:
vmImage: ubuntu-22.04
steps:
- script: |
set -e
sudo apt-get update
sudo apt-get install -y --no-install-recommends snapd
displayName: Install dependencies
- task: UsePythonVersion@0
inputs:
versionSpec: 3.12
addToPath: true
- task: DownloadPipelineArtifact@2
inputs:
artifact: snaps_amd64
path: $(Build.SourcesDirectory)/snap
displayName: Retrieve Certbot snaps
- script: |
set -e
python3 -m venv venv
venv/bin/python tools/pip_install.py -e certbot-ci
displayName: Prepare Certbot-CI
- script: |
set -e
sudo -E venv/bin/pytest certbot-ci/src/snap_integration_tests/dns_tests --allow-persistent-changes --snap-folder $(Build.SourcesDirectory)/snap --snap-arch amd64
displayName: Test DNS plugins snaps
================================================
FILE: .azure-pipelines/templates/jobs/standard-tests-jobs.yml
================================================
jobs:
- job: test
variables:
PYTHON_VERSION: 3.14
strategy:
matrix:
macos-cover:
IMAGE_NAME: macOS-15
TOXENV: cover
# As of pip 23.1.0, builds started failing on macOS unless this flag was set.
# See https://github.com/certbot/certbot/pull/9717#issuecomment-1610861794.
PIP_USE_PEP517: "true"
linux-oldest:
IMAGE_NAME: ubuntu-22.04
PYTHON_VERSION: 3.10
TOXENV: oldest
linux-py310:
# linux unit tests with the oldest python we support
IMAGE_NAME: ubuntu-22.04
PYTHON_VERSION: 3.10
TOXENV: py310
linux-cover:
# linux unit+cover tests with the newest python we support
IMAGE_NAME: ubuntu-22.04
TOXENV: cover
linux-lint:
IMAGE_NAME: ubuntu-22.04
TOXENV: lint-posix
linux-mypy:
IMAGE_NAME: ubuntu-22.04
TOXENV: mypy
linux-integration:
IMAGE_NAME: ubuntu-22.04
TOXENV: integration
apache-compat:
IMAGE_NAME: ubuntu-22.04
TOXENV: apache_compat
apacheconftest:
IMAGE_NAME: ubuntu-22.04
TOXENV: apacheconftest-with-pebble
nginxroundtrip:
IMAGE_NAME: ubuntu-22.04
TOXENV: nginxroundtrip
validate-changelog:
IMAGE_NAME: ubuntu-22.04
TOXENV: validate-changelog
pool:
vmImage: $(IMAGE_NAME)
steps:
- template: ../steps/tox-steps.yml
- job: test_sphinx_builds
pool:
vmImage: ubuntu-22.04
steps:
- template: ../steps/sphinx-steps.yml
================================================
FILE: .azure-pipelines/templates/stages/changelog-stage.yml
================================================
stages:
- stage: Changelog
jobs:
- job: prepare
pool:
vmImage: ubuntu-latest
steps:
# If we change the output filename from `release_notes.md`, it should also be changed in tools/create_github_release.py
- bash: |
set -e
CERTBOT_VERSION="$(cd certbot/src && python -c "import certbot; print(certbot.__version__)" && cd ~-)"
"${BUILD_REPOSITORY_LOCALPATH}/tools/extract_changelog.py" "${CERTBOT_VERSION}" >> "${BUILD_ARTIFACTSTAGINGDIRECTORY}/release_notes.md"
displayName: Prepare changelog
- task: PublishPipelineArtifact@1
inputs:
path: $(Build.ArtifactStagingDirectory)
# If we change the artifact's name, it should also be changed in tools/create_github_release.py
artifact: changelog
displayName: Publish changelog
================================================
FILE: .azure-pipelines/templates/stages/nightly-deploy-stage.yml
================================================
stages:
- stage: Deploy
jobs:
- template: ../jobs/common-deploy-jobs.yml
parameters:
snapReleaseChannel: edge
================================================
FILE: .azure-pipelines/templates/stages/release-deploy-stage.yml
================================================
stages:
- stage: Deploy
jobs:
- template: ../jobs/common-deploy-jobs.yml
parameters:
snapReleaseChannel: beta
- job: create_github_release
pool:
vmImage: ubuntu-22.04
steps:
- task: DownloadPipelineArtifact@2
inputs:
artifact: changelog
path: '$(Pipeline.Workspace)'
- task: GitHubRelease@1
inputs:
# this "github-releases" credential is what azure pipelines calls a
# "service connection". it needs to be recreated annually. instructions
# to do so and further information about the token are available at
# https://github.com/EFForg/certbot-misc/wiki/Azure-Pipelines-setup#regenerating-github-release-credentials-for-use-on-azure
#
# as of writing this, the current token will expire on Wed, Feb 25 2026.
gitHubConnection: github-releases
title: ${{ format('Certbot {0}', replace(variables['Build.SourceBranchName'], 'v', '')) }}
releaseNotesFilePath: '$(Pipeline.Workspace)/release_notes.md'
assets: '$(Build.SourcesDirectory)/packages/{*.tar.gz,SHA256SUMS*}'
addChangeLog: false
================================================
FILE: .azure-pipelines/templates/stages/test-and-package-stage.yml
================================================
stages:
- stage: TestAndPackage
jobs:
- template: ../jobs/standard-tests-jobs.yml
- template: ../jobs/extended-tests-jobs.yml
- template: ../jobs/packaging-jobs.yml
================================================
FILE: .azure-pipelines/templates/steps/sphinx-steps.yml
================================================
steps:
- bash: |
set -e
sudo apt-get update
sudo apt-get install -y --no-install-recommends libaugeas-dev
FINAL_STATUS=0
declare -a FAILED_BUILDS
tools/venv.py
source venv/bin/activate
for doc_path in */docs
do
echo ""
echo "##[group]Building $doc_path"
if ! sphinx-build -W --keep-going -b html $doc_path $doc_path/_build/html; then
FINAL_STATUS=1
FAILED_BUILDS[${#FAILED_BUILDS[@]}]="${doc_path%/docs}"
fi
echo "##[endgroup]"
done
if [[ $FINAL_STATUS -ne 0 ]]; then
echo "##[error]The following builds failed: ${FAILED_BUILDS[*]}"
exit 1
fi
displayName: Build Sphinx Documentation
================================================
FILE: .azure-pipelines/templates/steps/tox-steps.yml
================================================
# This does not include the dependencies needed to build cryptography. See
# https://cryptography.io/en/latest/installation/
steps:
# We run brew update because we've seen attempts to install an older version
# of a package fail. See
# https://github.com/actions/virtual-environments/issues/3165.
#
# We untap homebrew/core and homebrew/cask and unset HOMEBREW_NO_INSTALL_FROM_API (which
# is set by the CI macOS env) because GitHub has been having issues, making these jobs
# fail on git clones: https://github.com/orgs/Homebrew/discussions/4612.
- bash: |
set -e
unset HOMEBREW_NO_INSTALL_FROM_API
brew untap homebrew/core homebrew/cask
brew update
brew install augeas
condition: startswith(variables['IMAGE_NAME'], 'macOS')
displayName: Install MacOS dependencies
- bash: |
set -e
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
libaugeas-dev \
nginx-light
sudo systemctl stop nginx
sudo sysctl net.ipv4.ip_unprivileged_port_start=0
condition: startswith(variables['IMAGE_NAME'], 'ubuntu')
displayName: Install Linux dependencies
- task: UsePythonVersion@0
inputs:
versionSpec: $(PYTHON_VERSION)
addToPath: true
- bash: |
set -e
python3 tools/pip_install.py tox
displayName: Install runtime dependencies
- task: DownloadSecureFile@1
name: testFarmPem
inputs:
secureFile: azure-test-farm.pem
condition: contains(variables['TOXENV'], 'test-farm')
- bash: |
set -e
export TARGET_BRANCH="`echo "${BUILD_SOURCEBRANCH}" | sed -E 's!refs/(heads|tags)/!!g'`"
[ -z "${SYSTEM_PULLREQUEST_TARGETBRANCH}" ] || export TARGET_BRANCH="${SYSTEM_PULLREQUEST_TARGETBRANCH}"
env
python3 -m tox run
env:
AWS_ACCESS_KEY_ID: $(AWS_ACCESS_KEY_ID)
AWS_SECRET_ACCESS_KEY: $(AWS_SECRET_ACCESS_KEY)
AWS_EC2_PEM_FILE: $(testFarmPem.secureFilePath)
displayName: Run tox
# For now, let's omit `set -e` and avoid the script exiting with a nonzero
# status code to prevent problems here from causing build failures. If
# this turns out to work well, we can change this.
- bash: |
python3 tools/pip_install.py -I coverage
case "$AGENT_OS" in
Darwin)
CODECOV_URL="https://uploader.codecov.io/latest/macos/codecov"
;;
Linux)
CODECOV_URL="https://uploader.codecov.io/latest/linux/codecov"
;;
Windows_NT)
CODECOV_URL="https://uploader.codecov.io/latest/windows/codecov.exe"
;;
*)
echo "Unexpected OS"
exit 0
esac
curl --retry 3 -o codecov "$CODECOV_URL"
chmod +x codecov
coverage xml
./codecov || echo "Uploading coverage data failed"
condition: and(eq(variables['uploadCoverage'], true), or(startsWith(variables['TOXENV'], 'cover'), startsWith(variables['TOXENV'], 'integration')))
displayName: Upload coverage data
================================================
FILE: .coveragerc
================================================
[run]
omit = */setup.py
source =
acme
certbot
certbot-apache
certbot-dns-cloudflare
certbot-dns-digitalocean
certbot-dns-dnsimple
certbot-dns-dnsmadeeasy
certbot-dns-gehirn
certbot-dns-google
certbot-dns-linode
certbot-dns-luadns
certbot-dns-nsone
certbot-dns-ovh
certbot-dns-rfc2136
certbot-dns-route53
certbot-dns-sakuracloud
certbot-nginx
[report]
omit = */setup.py
show_missing = True
================================================
FILE: .dockerignore
================================================
# this file uses slightly different syntax than .gitignore,
# e.g. ".tox/" will not ignore .tox directory
# well, official docker build should be done on clean git checkout
# anyway, so .tox should be empty... But I'm sure people will try to
# test docker on their git working directories.
.git
.tox
venv
docs
================================================
FILE: .editorconfig
================================================
# https://editorconfig.org/
root = true
[*]
insert_final_newline = true
trim_trailing_whitespace = true
end_of_line = lf
[*.py]
indent_style = space
indent_size = 4
charset = utf-8
max_line_length = 100
[*.yaml]
indent_style = space
indent_size = 2
================================================
FILE: .gitattributes
================================================
#Default, normalize CRLF into LF in non-binary files
# Files identified as binary by Git are not changed
* crlf=auto
# special files
*.sh crlf=input
*.py crlf=input
*.bat text eol=crlf
*.der binary
*.gz binary
*.jpeg binary
*.jpg binary
*.png binary
*.gz binary
================================================
FILE: .github/CODEOWNERS
================================================
* @certbot/eff-devs
================================================
FILE: .github/FUNDING.yml
================================================
custom: https://supporters.eff.org/donate/support-work-on-certbot
================================================
FILE: .github/ISSUE_TEMPLATE/bug.yaml
================================================
name: Bug Report
description: File a bug report.
title: "[Bug]: "
type: Bug
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report! If you're
having trouble using Certbot and aren't sure you've found a bug,
please first try asking for help at https://community.letsencrypt.org/.
There is a much larger community there of people familiar with the
project who will be able to more quickly answer your questions.
- type: input
attributes:
label: OS
description: |
Describe your Operating System. Examples: Ubuntu 18.04, CentOS 8 Stream
placeholder: Ubuntu 24.04
validations:
required: true
- type: input
attributes:
label: Installation method
description: |
How did you install Certbot? Examples: snap, pip, apt, yum
placeholder: snap
validations:
required: true
- type: input
attributes:
label: Certbot Version
description: |
If you're not sure, you can find this by running `certbot --version`.
placeholder: 1.0.0
validations:
required: true
- type: textarea
id: what-happened
attributes:
label: What happened?
description: |
I ran this command and it produced this output. Example:
```
$ sudo certbot certonly -d adfsfasdf.asdfasdf --staging
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx
Requesting a certificate for example.com
An unexpected error occurred:
Invalid identifiers requested :: Cannot issue for "adfsfasdf.asdfasdf": Domain name does not end with a valid public suffix (TLD)
Ask for help or search for solutions at https://community.letsencrypt.org. See the logfile /var/log/letsencrypt/letsencrypt.log or re-run Certbot with -v for more details.
```
placeholder: Tell us what you see!
validations:
required: true
- type: textarea
id: expected
attributes:
label: Expected behavior
description: Certbot's behavior differed from what I expected because.
placeholder: "What was expected?"
validations:
required: true
- type: textarea
id: logs
attributes:
label: Relevant log output
description: Here is a Certbot log showing the issue (if available). Logs are stored in `/var/log/letsencrypt` by default. Feel free to redact domains, e-mail and IP addresses as you see fit.
render: shell
================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
contact_links:
- name: Let's Encrypt Community Support
url: https://community.letsencrypt.org/
about: If you're having trouble using Certbot and aren't sure you've found a bug or request for a new feature, please first try asking for help here. There is a much larger community there of people familiar with the project who will be able to more quickly answer your questions.
- name: Certbot Security Policy
url: https://github.com/certbot/certbot/security/advisories/new
about: Please report security vulnerabilities here.
================================================
FILE: .github/ISSUE_TEMPLATE/feature.yaml
================================================
name: Feature Request
description: Suggest a new feature or improvement to Certbot
title: "[Feature Request]: "
type: Feature
body:
- type: textarea
id: problem
attributes:
label: What problem does this feature solve or what does it enhance?
description: Explain what this feature addresses, or the benefit it provides.
placeholder: For example, "Currently, users have to manually do X, which is time-consuming."
validations:
required: true
- type: textarea
id: solution
attributes:
label: Proposed Solution
description: Describe the solution you'd like to see implemented.
placeholder: For example, "Implement a new button that automatically does X."
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: Alternatives Considered
description: Have you considered any alternative solutions?
placeholder: For example, "We considered Y, but Z is a better approach because..."
================================================
FILE: .github/ISSUE_TEMPLATE/task.yaml
================================================
name: Task
description: A codebase upkeep task such as managing deprecations and refactoring
title: "[Task]: "
type: Task
body:
- type: textarea
id: problem
attributes:
label: Task description
description: Describe the work that needs to happen, and why.
placeholder: >
For example, "In issue [link here], we noted that we cannot update [dependency] until
[something happens]. That thing has happened, so now we should update [dependency]."
validations:
required: true
================================================
FILE: .github/codecov.yml
================================================
# This disables all reporting from codecov. Let's just set it up to collect
# data for now and then we can play with the settings here.
comment: false
coverage:
status:
project: off
patch: off
================================================
FILE: .github/pull_request_template.md
================================================
## Pull Request Checklist
- [ ] The Certbot team has recently expressed interest in reviewing a PR for this. If not, this PR may be closed due our limited resources and need to prioritize how we spend them.
- [ ] If you used AI to create this PR, you have done a self-review of all AI-generated code and disclosed that your contribution was AI-generated per [EFF's AI-generated contribution policy](https://www.eff.org/about/opportunities/volunteer/coding-with-eff). You assert you have thoroughly understood, reviewed, and tested your entire submission.
- [ ] If the change being made is to a [distributed component](https://certbot.eff.org/docs/contributing.html#code-components-and-layout), add a description of your change to the `newsfragments` directory. This should be a file called `<title>.<type>`, where `<title>` is either a GitHub issue number or some other unique name starting with `+`, and `<type>` is either `changed`, `fixed`, or `added`.
* For example, if you fixed a bug for issue number 42, create a file called `42.fixed` and put a description of your change in that file.
- [ ] Add or update any documentation as needed to support the changes in this PR.
- [ ] Include your name in `AUTHORS.md` if you like.
================================================
FILE: .github/workflows/assigned.yaml
================================================
name: Issue Assigned
on:
issues:
types: [assigned]
permissions: {} # let's not use any permissions we don't need here
jobs:
send-mattermost-message:
runs-on: ubuntu-latest
steps:
# issue triggers in github actions can be dangerous like
# pull_request_target because they run with additional privileges in an
# environment containing values that can be controlled by an attacker.
# because of this, please take extra caution when modifying the steps taken
# by this workflow. for additional information, see
# https://github.com/certbot/certbot/pull/10490
#
# we pin this action to a version tested and audited by certbot's
# maintainers for extra security. the full hash is used as doing so is
# recommended by zizmor
- uses: mattermost/action-mattermost-notify@b7d118e440bf2749cd18a4a8c88e7092e696257a
with:
MATTERMOST_WEBHOOK_URL: ${{ secrets.MATTERMOST_ASSIGN_WEBHOOK }}
TEXT: >
${{ github.event.assignee.login }} assigned to "${{ github.event.issue.title }}": ${{ github.event.issue.html_url }}
================================================
FILE: .github/workflows/merged.yaml
================================================
name: Merge Event
on:
pull_request_target:
types:
- closed
permissions: {} # let's not use any permissions we don't need here
jobs:
if_merged:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
steps:
# github actions workflows triggered by pull_request_target can be
# dangerous because they run with additional privileges in an environment
# containing values that can be controlled by an attacker. because of
# this, please take extra caution when modifying the steps taken by this
# workflow. for additional information, see
# https://github.com/certbot/certbot/pull/10490
#
# we pin this action to a version tested and audited by certbot's
# maintainers for extra security. the full hash is used as doing so is
# recommended by zizmor
- uses: mattermost/action-mattermost-notify@b7d118e440bf2749cd18a4a8c88e7092e696257a
with:
MATTERMOST_WEBHOOK_URL: ${{ secrets.MATTERMOST_MERGE_WEBHOOK }}
TEXT: >
[${{ github.repository }}] |
[${{ github.event.pull_request.title }}
#${{ github.event.number }}](https://github.com/${{ github.repository }}/pull/${{ github.event.number }})
was merged into ${{ github.event.pull_request.base.ref }} by ${{ github.actor }}
================================================
FILE: .github/workflows/notify_weekly.yaml
================================================
name: Weekly Github Update
on:
schedule:
# Every week on Thursday @ 10:00
- cron: "0 10 * * 4"
workflow_dispatch:
permissions: {} # let's not use any permissions we don't need here
jobs:
send-mattermost-message:
runs-on: ubuntu-latest
steps:
- name: Create Mattermost Message
run: |
DATE=$(date --date="7 days ago" +"%Y-%m-%d")
echo "ASSIGNED_PRS=https://github.com/pulls?q=is%3Apr+is%3Aopen+updated%3A%3E%3D${DATE}+assignee%3A*+user%3Acertbot" >> $GITHUB_ENV
echo "UPDATED_URL=https://github.com/issues?q=is%3Aissue+is%3Aopen+sort%3Acomments-desc+updated%3A%3E%3D${DATE}+user%3Acertbot" >> $GITHUB_ENV
# we pin this action to a version tested and audited by certbot's
# maintainers for extra security. the full hash is used as doing so is
# recommended by zizmor
- uses: mattermost/action-mattermost-notify@b7d118e440bf2749cd18a4a8c88e7092e696257a
with:
MATTERMOST_WEBHOOK_URL: ${{ secrets.MATTERMOST_WEBHOOK_URL }}
MATTERMOST_CHANNEL: private-certbot
TEXT: |
## Updates In the Past Week
- Most commented in the last week: [link](${{ env.UPDATED_URL }})
- Updated (assigned) PRs in the last week: [link](${{ env.ASSIGNED_PRS }})
================================================
FILE: .github/workflows/review_requested.yaml
================================================
name: Review Requested
on:
pull_request_target:
types: [review_requested]
permissions: {}
jobs:
send-mattermost-message:
# Don't notify for the interim step of certbot/eff-devs being assigned
if: ${{ github.event.requested_reviewer.login != ''}}
runs-on: ubuntu-latest
steps:
# github actions workflows triggered by pull_request_target can be
# dangerous because they run with additional privileges in an environment
# containing values that can be controlled by an attacker. because of
# this, please take extra caution when modifying the steps taken by this
# workflow. for additional information, see
# https://github.com/certbot/certbot/pull/10490
#
# we pin this action to a version tested and audited by certbot's
# maintainers for extra security. the full hash is used as doing so is
# recommended by zizmor
- uses: mattermost/action-mattermost-notify@b7d118e440bf2749cd18a4a8c88e7092e696257a
with:
MATTERMOST_WEBHOOK_URL: ${{ secrets.MATTERMOST_ASSIGN_WEBHOOK }}
TEXT: >
Review requested from ${{ github.event.requested_reviewer.login }} for "${{ github.event.pull_request.title }}": ${{ github.event.pull_request.html_url }}
================================================
FILE: .github/workflows/stale.yml
================================================
name: Update Stale Issues
on:
schedule:
# Run 1:24AM every night
- cron: '24 1 * * *'
workflow_dispatch:
permissions:
issues: write
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v6
with:
# Idle number of days before marking issues stale
days-before-issue-stale: 365
# Never mark PRs as stale
days-before-pr-stale: -1
# Idle number of days before closing stale issues
days-before-issue-close: 30
# Never close PRs
days-before-pr-close: -1
# Ignore issues with an assignee
exempt-all-issue-assignees: true
# Label to use when marking as stale
stale-issue-label: stale-needs-update
# Label to use when issue is automatically closed
close-issue-label: auto-closed
stale-issue-message: >
We've made a lot of changes to Certbot since this issue was opened. If you
still have this issue with an up-to-date version of Certbot, can you please
add a comment letting us know? This helps us to better see what issues are
still affecting our users. If there is no activity in the next 30 days, this
issue will be automatically closed.
close-issue-message: >
This issue has been closed due to lack of activity, but if you think it
should be reopened, please open a new issue with a link to this one and we'll
take a look.
# Limit the number of actions per run. As of writing this, GitHub's
# rate limit is 1000 requests per hour so we're still a ways off. See
# https://docs.github.com/en/rest/overview/resources-in-the-rest-api?apiVersion=2022-11-28#rate-limits-for-requests-from-github-actions.
operations-per-run: 180
================================================
FILE: .gitignore
================================================
*.pyc
*.egg-info/
.eggs/
build/
dist*/
/venv*/
/.tox/
/releases*/
/log*
letsencrypt.log
certbot.log
poetry.lock
# coverage
.coverage
.coverage.*
/htmlcov/
/.vagrant
tags
# editor temporary files
*~
*.sw?
\#*#
.idea
.ropeproject
.vscode
*.sublime-project
*.sublime-workspace
# auth --cert-path --chain-path
/*.pem
.venv
# pytest cache
.cache
.mypy_cache/
.pytest_cache/
# docker files
.docker
# certbot tests
.certbot_test_workspace
**/assets/pebble*
**/assets/challtestsrv*
# snap files
.snapcraft
parts
prime
stage
*.snap
snap-constraints.txt
qemu-*
certbot-dns*/certbot-dns*_amd64*.txt
certbot-dns*/certbot-dns*_arm*.txt
/certbot_amd64*.txt
/certbot_arm*.txt
certbot-dns*/snap
snapcraft.cfg
# pyenv files
.python-version
# macOS files
.DS_Store
================================================
FILE: .isort.cfg
================================================
[settings]
skip_glob=venv*
force_sort_within_sections=True
force_single_line=True
order_by_type=False
line_length=400
src_paths=acme/src,acme/tests,certbot*/tests,certbot/src,certbot*/src/certbot*
================================================
FILE: .pylintrc
================================================
[MAIN]
# Analyse import fallback blocks. This can be used to support both Python 2 and
# 3 compatible code, which means that the block might have code that exists
# only in one or another interpreter, leading to false positives when analysed.
analyse-fallback-blocks=no
# Load and enable all available extensions. Use --list-extensions to see a list
# all available extensions.
#enable-all-extensions=
# In error mode, messages with a category besides ERROR or FATAL are
# suppressed, and no reports are done by default. Error mode is compatible with
# disabling specific errors.
#errors-only=
# Always return a 0 (non-error) status code, even if lint errors are found.
# This is primarily useful in continuous integration scripts.
#exit-zero=
# A comma-separated list of package or module names from where C extensions may
# be loaded. Extensions are loading into the active Python interpreter and may
# run arbitrary code.
extension-pkg-allow-list=
# A comma-separated list of package or module names from where C extensions may
# be loaded. Extensions are loading into the active Python interpreter and may
# run arbitrary code. (This is an alternative name to extension-pkg-allow-list
# for backward compatibility.)
extension-pkg-whitelist=pywintypes,win32api,win32file,win32security
# Return non-zero exit code if any of these messages/categories are detected,
# even if score is above --fail-under value. Syntax same as enable. Messages
# specified are enabled, while categories only check already-enabled messages.
fail-on=
# Specify a score threshold under which the program will exit with error.
fail-under=10
# Interpret the stdin as a python script, whose filename needs to be passed as
# the module_or_package argument.
#from-stdin=
# Files or directories to be skipped. They should be base names, not paths.
ignore=CVS
# Add files or directories matching the regular expressions patterns to the
# ignore-list. The regex matches against paths and can be in Posix or Windows
# format. Because '\' represents the directory delimiter on Windows systems, it
# can't be used as an escape character.
# CERTBOT COMMENT
# Changing this line back to the default of `ignore-paths=` is being tracked by
# https://github.com/certbot/certbot/issues/7908.
ignore-paths=.*/_internal/tests/
# Files or directories matching the regular expression patterns are skipped.
# The regex matches against base names, not paths. The default value ignores
# Emacs file locks
ignore-patterns=^\.#
# List of module names for which member attributes should not be checked
# (useful for modules/projects where namespaces are manipulated during runtime
# and thus existing member attributes cannot be deduced by static analysis). It
# supports qualified module names, as well as Unix pattern matching.
ignored-modules=
# Python code to execute, usually for sys.path manipulation such as
# pygtk.require().
# CERTBOT COMMENT
# This is needed for pylint to import linter_plugin.py since
# https://github.com/PyCQA/pylint/pull/3396.
init-hook="import pylint.config, os, sys; sys.path.append(os.path.dirname(next(pylint.config.find_default_config_files())))"
# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the
# number of processors available to use, and will cap the count on Windows to
# avoid hangs.
jobs=0
# Control the amount of potential inferred values when inferring a single
# object. This can help the performance when dealing with large functions or
# complex, nested conditions.
limit-inference-results=100
# List of plugins (as comma separated values of python module names) to load,
# usually to register additional checkers.
load-plugins=linter_plugin
# Pickle collected data for later comparisons.
persistent=yes
# Minimum Python version to use for version dependent checks. Will default to
# the version used to run pylint.
py-version=3.10
# Discover python modules and packages in the file system subtree.
recursive=no
# When enabled, pylint would attempt to guess common misconfiguration and emit
# user-friendly hints instead of false-positive error messages.
suggestion-mode=yes
# Allow loading of arbitrary C extensions. Extensions are imported into the
# active Python interpreter and may run arbitrary code.
unsafe-load-any-extension=no
# In verbose mode, extra non-checker-related info will be displayed.
#verbose=
[BASIC]
# Naming style matching correct argument names.
argument-naming-style=snake_case
# Regular expression matching correct argument names. Overrides argument-
# naming-style. If left empty, argument names will be checked with the set
# naming style.
#argument-rgx=
# Naming style matching correct attribute names.
attr-naming-style=snake_case
# Regular expression matching correct attribute names. Overrides attr-naming-
# style. If left empty, attribute names will be checked with the set naming
# style.
#attr-rgx=
# Bad variable names which should always be refused, separated by a comma.
bad-names=foo,
bar,
baz,
toto,
tutu,
tata
# Bad variable names regexes, separated by a comma. If names match any regex,
# they will always be refused
bad-names-rgxs=
# Naming style matching correct class attribute names.
class-attribute-naming-style=any
# Regular expression matching correct class attribute names. Overrides class-
# attribute-naming-style. If left empty, class attribute names will be checked
# with the set naming style.
#class-attribute-rgx=
# Naming style matching correct class constant names.
class-const-naming-style=UPPER_CASE
# Regular expression matching correct class constant names. Overrides class-
# const-naming-style. If left empty, class constant names will be checked with
# the set naming style.
#class-const-rgx=
# Naming style matching correct class names.
class-naming-style=PascalCase
# Regular expression matching correct class names. Overrides class-naming-
# style. If left empty, class names will be checked with the set naming style.
#class-rgx=
# Naming style matching correct constant names.
const-naming-style=UPPER_CASE
# Regular expression matching correct constant names. Overrides const-naming-
# style. If left empty, constant names will be checked with the set naming
# style.
#const-rgx=
# Minimum line length for functions/classes that require docstrings, shorter
# ones are exempt.
docstring-min-length=-1
# Naming style matching correct function names.
function-naming-style=snake_case
# Regular expression matching correct function names. Overrides function-
# naming-style. If left empty, function names will be checked with the set
# naming style.
function-rgx=[a-z_][a-z0-9_]{2,40}$
# Good variable names which should always be accepted, separated by a comma.
good-names=i,
j,
k,
ex,
Run,
_,
fd,
logger
# Good variable names regexes, separated by a comma. If names match any regex,
# they will always be accepted
good-names-rgxs=
# Include a hint for the correct naming format with invalid-name.
include-naming-hint=no
# Naming style matching correct inline iteration names.
inlinevar-naming-style=any
# Regular expression matching correct inline iteration names. Overrides
# inlinevar-naming-style. If left empty, inline iteration names will be checked
# with the set naming style.
#inlinevar-rgx=
# Naming style matching correct method names.
method-naming-style=snake_case
# Regular expression matching correct method names. Overrides method-naming-
# style. If left empty, method names will be checked with the set naming style.
method-rgx=[a-z_][a-z0-9_]{2,50}$
# Naming style matching correct module names.
module-naming-style=snake_case
# Regular expression matching correct module names. Overrides module-naming-
# style. If left empty, module names will be checked with the set naming style.
#module-rgx=
# Colon-delimited sets of names that determine each other's naming style when
# the name regexes allow several styles.
name-group=
# Regular expression which should only match function or class names that do
# not require a docstring.
no-docstring-rgx=(__.*__)|(test_[A-Za-z0-9_]*)|(_.*)|(.*Test$)
# List of decorators that produce properties, such as abc.abstractproperty. Add
# to this list to register other decorators that produce valid properties.
# These decorators are taken in consideration only for invalid-name.
property-classes=abc.abstractproperty
# Regular expression matching correct type variable names. If left empty, type
# variable names will be checked with the set naming style.
#typevar-rgx=
# Naming style matching correct variable names.
variable-naming-style=snake_case
# Regular expression matching correct variable names. Overrides variable-
# naming-style. If left empty, variable names will be checked with the set
# naming style.
variable-rgx=[a-z_][a-z0-9_]{1,30}$
[CLASSES]
# Warn about protected attribute access inside special methods
check-protected-access-in-special-methods=no
# List of method names used to declare (i.e. assign) instance attributes.
defining-attr-methods=__init__,
__new__,
setUp,
__post_init__
# List of valid names for the first argument in a class method.
valid-classmethod-first-arg=cls
# List of valid names for the first argument in a metaclass class method.
valid-metaclass-classmethod-first-arg=cls
[EXCEPTIONS]
# Exceptions that will emit a warning when caught.
overgeneral-exceptions=builtins.BaseException,
builtins.Exception
[FORMAT]
# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
expected-line-ending-format=
# Regexp for a line that is allowed to be longer than the limit.
ignore-long-lines=^\s*(# )?<?https?://\S+>?$
# Number of spaces of indent required inside a hanging or continued line.
# git history told me that "This does something silly/broken..."
#indent-after-paren=4
# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
# tab).
indent-string=' '
# Maximum number of characters on a single line.
max-line-length=100
# Maximum number of lines in a module.
max-module-lines=1250
# Allow the body of a class to be on the same line as the declaration if body
# contains single statement.
single-line-class-stmt=no
# Allow the body of an if to be on the same line as the test if there is no
# else.
single-line-if-stmt=no
[IMPORTS]
# List of modules that can be imported at any level, not just the top level
# one.
allow-any-import-level=
# Allow wildcard imports from modules that define __all__.
allow-wildcard-with-all=no
# Deprecated modules which should not be used, separated by a comma.
deprecated-modules=
# Output a graph (.gv or any supported image format) of external dependencies
# to the given file (report RP0402 must not be disabled).
ext-import-graph=
# Output a graph (.gv or any supported image format) of all (i.e. internal and
# external) dependencies to the given file (report RP0402 must not be
# disabled).
import-graph=
# Output a graph (.gv or any supported image format) of internal dependencies
# to the given file (report RP0402 must not be disabled).
int-import-graph=
# Force import order to recognize a module as part of the standard
# compatibility libraries.
known-standard-library=
# Force import order to recognize a module as part of a third party library.
known-third-party=enchant
# Couples of modules and preferred modules, separated by a comma.
preferred-modules=
[LOGGING]
# The type of string formatting that logging methods do. `old` means using %
# formatting, `new` is for `{}` formatting.
logging-format-style=old
# Logging modules to check that the string format arguments are in logging
# function parameter format.
logging-modules=logging,logger
[MESSAGES CONTROL]
# Only show warnings with the listed confidence levels. Leave empty to show
# all. Valid levels: HIGH, CONTROL_FLOW, INFERENCE, INFERENCE_FAILURE,
# UNDEFINED.
confidence=HIGH,
CONTROL_FLOW,
INFERENCE,
INFERENCE_FAILURE,
UNDEFINED
# Disable the message, report, category or checker with the given id(s). You
# can either give multiple identifiers separated by comma (,) or put this
# option multiple times (only on the command line, not in the configuration
# file where it should appear only once). You can also use "--disable=all" to
# disable everything first and then re-enable specific checks. For example, if
# you want to run only the similarities checker, you can use "--disable=all
# --enable=similarities". If you want to run only the classes checker, but have
# no Warning level messages displayed, use "--disable=all --enable=classes
# --disable=W".
# CERTBOT COMMENT
# 1) Once certbot codebase is claimed to be compatible exclusively with Python 3,
# the useless-object-inheritance check can be enabled again, and code fixed accordingly.
# 2) Check unsubscriptable-object tends to create a lot of false positives. Let's disable it.
# See https://github.com/PyCQA/pylint/issues/1498.
# 3) Same as point 2 for no-value-for-parameter.
# See https://github.com/PyCQA/pylint/issues/2820.
# 4) raise-missing-from makes it an error to raise an exception from except
# block without using explicit exception chaining. While explicit exception
# chaining results in a slightly more informative traceback, I don't think
# it's beneficial enough for us to change all of our current instances and
# give Certbot developers errors about this when they're working on new code
# in the future. You can read more about exception chaining and this pylint
# check at
# https://blog.ram.rachum.com/post/621791438475296768/improving-python-exception-chaining-with.
# 5) wrong-import-order generates false positives and a pylint developer
# suggests that people using isort should disable this check at
# https://github.com/PyCQA/pylint/issues/3817#issuecomment-687892090.
# 6) unspecified-encoding generates errors when encoding is not specified in
# in a call to the built-in open function. This relates more to a design decision
# (unspecified encoding makes the open function use the default encoding of the system)
# than a clear flaw on which a check should be enforced. Anyway the project does
# not need to enforce encoding on files so we disable this check.
# 7) consider-using-f-string is "suggesting" to move to f-string when possible with an error. This
# clearly relates to code design and not to potential defects in the code, let's just ignore that.
disable=fixme,locally-disabled,invalid-name,cyclic-import,duplicate-code,design,import-outside-toplevel,useless-object-inheritance,unsubscriptable-object,no-value-for-parameter,no-else-return,no-else-raise,no-else-break,no-else-continue,raise-missing-from,wrong-import-order,unspecified-encoding,consider-using-f-string,raw-checker-failed,bad-inline-option,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,use-symbolic-message-instead
# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option
# multiple time (only on the command line, not in the configuration file where
# it should appear only once). See also the "--disable" option for examples.
enable=c-extension-no-member
[METHOD_ARGS]
# List of qualified names (i.e., library.method) which require a timeout
# parameter e.g. 'requests.api.get,requests.api.post'
timeout-methods=requests.api.delete,requests.api.get,requests.api.head,requests.api.options,requests.api.patch,requests.api.post,requests.api.put,requests.api.request
[MISCELLANEOUS]
# List of note tags to take in consideration, separated by a comma.
notes=FIXME,
XXX,
TODO
# Regular expression of note tags to take in consideration.
notes-rgx=
[REFACTORING]
# Maximum number of nested blocks for function / method body
max-nested-blocks=5
# Complete name of functions that never returns. When checking for
# inconsistent-return-statements if a never returning function is called then
# it will be considered as an explicit return statement and no message will be
# printed.
never-returning-functions=sys.exit,argparse.parse_error
[REPORTS]
# Python expression which should return a score less than or equal to 10. You
# have access to the variables 'fatal', 'error', 'warning', 'refactor',
# 'convention', and 'info' which contain the number of messages in each
# category, as well as 'statement' which is the total number of statements
# analyzed. This score is used by the global evaluation report (RP0004).
evaluation=max(0, 0 if fatal else 10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10))
# Template used to display messages. This is a python new-style format string
# used to format the message information. See doc for all details.
msg-template=
# Set the output format. Available formats are text, parseable, colorized, json
# and msvs (visual studio). You can also give a reporter class, e.g.
# mypackage.mymodule.MyReporterClass.
#output-format=
# Tells whether to display a full report or only the messages.
reports=no
# Activate the evaluation score.
score=yes
[SIMILARITIES]
# Comments are removed from the similarity computation
ignore-comments=yes
# Docstrings are removed from the similarity computation
ignore-docstrings=yes
# Imports are removed from the similarity computation
ignore-imports=yes
# Signatures are removed from the similarity computation
ignore-signatures=yes
# Minimum lines number of a similarity.
min-similarity-lines=6
[STRING]
# This flag controls whether inconsistent-quotes generates a warning when the
# character used as a quote delimiter is used inconsistently within a module.
check-quote-consistency=no
# This flag controls whether the implicit-str-concat should generate a warning
# on implicit string concatenation in sequences defined over several lines.
check-str-concat-over-line-jumps=no
[TYPECHECK]
# List of decorators that produce context managers, such as
# contextlib.contextmanager. Add to this list to register other decorators that
# produce valid context managers.
contextmanager-decorators=contextlib.contextmanager
# List of members which are set dynamically and missed by pylint inference
# system, and so shouldn't trigger E1101 when accessed. Python regular
# expressions are accepted.
generated-members=
# Tells whether to warn about missing members when the owner of the attribute
# is inferred to be None.
ignore-none=yes
# This flag controls whether pylint should warn about no-member and similar
# checks whenever an opaque object is returned when inferring. The inference
# can return multiple potential results while evaluating a Python object, but
# some branches might not be evaluated, which results in partial inference. In
# that case, it might be useful to still emit no-member and other checks for
# the rest of the inferred objects.
ignore-on-opaque-inference=yes
# List of symbolic message names to ignore for Mixin members.
ignored-checks-for-mixins=no-member,
not-async-context-manager,
not-context-manager,
attribute-defined-outside-init
# List of class names for which member attributes should not be checked (useful
# for classes with dynamically set attributes). This supports the use of
# qualified names.
ignored-classes=optparse.Values,thread._local,_thread._local,argparse.Namespace,Field,Header,JWS,closing
# List of module names for which member attributes should not be checked
# (useful for modules/projects where namespaces are manipulated during runtime
# and thus existing member attributes cannot be deduced by static analysis
ignored-modules=confargparse,argparse
# Show a hint with possible names when a member name was not found. The aspect
# of finding the hint is based on edit distance.
missing-member-hint=yes
# The minimum edit distance a name should have in order to be considered a
# similar match for a missing member name.
missing-member-hint-distance=1
# The total number of similar names that should be taken in consideration when
# showing a hint for a missing member.
missing-member-max-choices=1
# Regex pattern to define which classes are considered mixins.
mixin-class-rgx=.*[Mm]ixin
# List of decorators that change the signature of a decorated function.
signature-mutators=
[VARIABLES]
# List of additional names supposed to be defined in builtins. Remember that
# you should avoid defining new builtins when possible.
additional-builtins=
# Tells whether unused global variables should be treated as a violation.
allow-global-unused-variables=yes
# List of names allowed to shadow builtins
allowed-redefined-builtins=
# List of strings which can identify a callback function by name. A callback
# name must start or end with one of those strings.
callbacks=cb_,
_cb
# A regular expression matching the name of dummy variables (i.e. expected to
# not be used).
dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_
# Argument names that match this expression will be ignored.
ignored-argument-names=_.*|^ignored_|^unused_
# Tells whether we should check for unused import in __init__ files.
init-import=no
# List of qualified module names which can have objects that can redefine
# builtins.
redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io
================================================
FILE: AUTHORS.md
================================================
Authors
=======
* [Aaron Gable](https://github.com/aarongable)
* [Aaron Zirbes](https://github.com/aaronzirbes)
* Aaron Zuehlke
* Ada Lovelace
* [Adam Woodbeck](https://github.com/awoodbeck)
* [Adrien Ferrand](https://github.com/adferrand)
* [Aidin Gharibnavaz](https://github.com/aidin36)
* [AJ ONeal](https://github.com/coolaj86)
* [Alcaro](https://github.com/Alcaro)
* [Alexander Mankuta](https://github.com/pointlessone)
* [Alex Bowers](https://github.com/alexbowers)
* [Alex Conlin](https://github.com/alexconlin)
* [Alex Gaynor](https://github.com/alex)
* [Alex Halderman](https://github.com/jhalderm)
* [Alex Jordan](https://github.com/strugee)
* [Alex Zorin](https://github.com/alexzorin)
* [Alexis Hancock](https://github.com/zoracon)
* [Amir Omidi](https://github.com/aaomidi)
* [Amjad Mashaal](https://github.com/TheNavigat)
* [amplifi](https://github.com/amplifi)
* [Andrew Murray](https://github.com/radarhere)
* [Andrzej Górski](https://github.com/andrzej3393)
* [Anna Glasgall](https://github.com/aglasgall)
* [Anselm Levskaya](https://github.com/levskaya)
* [Antoine Jacoutot](https://github.com/ajacoutot)
* [April King](https://github.com/april)
* [asaph](https://github.com/asaph)
* [Axel Beckert](https://github.com/xtaran)
* [Bas](https://github.com/Mechazawa)
* [benbankes](https://github.com/benbankes)
* [Ben Irving](https://github.com/benileo)
* [Benjamin Kerensa](https://github.com/bkerensa)
* [Benjamin Neff](https://github.com/SuperTux88)
* [Benjamin Piouffle](https://github.com/Betree)
* [Ben Ubois](https://github.com/benubois)
* [Ben Wolfe](https://github.com/bwolfe)
* [Bigfish](https://github.com/bwolfe)
* [Blake Griffith](https://github.com/cowlicks)
* [Brad Warren](https://github.com/bmw)
* [Brandon Kraft](https://github.com/kraftbj)
* [Brandon Kreisel](https://github.com/BKreisel)
* [Brian Heim](https://github.com/brianlheim)
* [Cameron Steel](https://github.com/Tugzrida)
* [Ceesjan Luiten](https://github.com/quinox)
* [Chad Whitacre](https://github.com/whit537)
* [Chhatoi Pritam Baral](https://github.com/pritambaral)
* [Chris Johns](https://github.com/ter0)
* [Chris Lamb](https://github.com/lamby)
* [chrismarget](https://github.com/chrismarget)
* [Christian Gärtner](https://github.com/ChristianGaertner)
* [Christian Rosentreter](https://github.com/the-real-tokai)
* [Christopher Brown](https://github.com/chbrown)
* [Christopher Manning](https://github.com/christophermanning)
* [Christoph Kisfeld](https://github.com/chk1)
* [Clif Houck](https://github.com/ClifHouck)
* [Cooper Quintin](https://github.com/cooperq)
* [Corey Farwell](https://github.com/frewsxcv)
* [Craig Smith](https://github.com/dashaxiong)
* [Damian Poddebniak](https://github.com/duesee)
* [Damien Nozay](https://github.com/dnozay)
* [Damien Tournoud](https://github.com/damz)
* [DanCld](https://github.com/DanCld)
* [Daniel Albers](https://github.com/AID)
* [Daniel Aleksandersen](https://github.com/da2x)
* [Daniel Almasi](https://github.com/almasen)
* [Daniel Convissor](https://github.com/convissor)
* [Daniel "Drex" Drexler](https://github.com/aeturnum)
* [Daniel Huang](https://github.com/dhuang)
* [Daniel McMahon] (https://github.com/igloodan)
* [Dave Guarino](https://github.com/daguar)
* [David cz](https://github.com/dave-cz)
* [David Dworken](https://github.com/ddworken)
* [David Kreitschmann](https://kreitschmann.de)
* [David Xia](https://github.com/davidxia)
* [Devin Howard](https://github.com/devvmh)
* [dokazaki](https://github.com/dokazaki)
* [Dominic Cleal](https://github.com/domcleal)
* [Dominic Lüchinger](https://github.com/dol)
* [Douglas José](https://github.com/douglasjose)
* [Erica Portnoy](https://github.com/ohemorange)
* [Eric Engestrom](https://github.com/1ace)
* [Eric Rescorla](https://github.com/ekr)
* [Eric Wustrow](https://github.com/ewust)
* [Erik Rose](https://github.com/erikrose)
* [Eugene Kazakov](https://github.com/xgin)
* [Fabian](https://github.com/faerbit)
* [Faidon Liambotis](https://github.com/paravoid)
* [Fan Jiang](https://github.com/tcz001)
* [Felix Lechner](https://github.com/lechner)
* [Felix Schwarz](https://github.com/FelixSchwarz)
* [Felix Yan](https://github.com/felixonmars)
* [Filip Ochnik](https://github.com/filipochnik)
* [Florian Klink](https://github.com/flokli)
* [Francesco Colista](https://github.com/fcolista)
* [Francois Marier](https://github.com/fmarier)
* [Frank](https://github.com/Frankkkkk)
* [Frederic BLANC](https://github.com/fblanc)
* [Garrett Robinson](https://github.com/garrettr)
* [Gene Wood](https://github.com/gene1wood)
* [Geoffroy Doucet](https://www.geoffroydoucet.com)
* [Gian Carlo Pace](https://github.com/gicappa)
* [Gilles Pietri](https://github.com/gilou)
* [Giovanni Pellerano](https://github.com/evilaliv3)
* [Giovanni Toraldo](https://github.com/gionn)
* [Gordin](https://github.com/Gordin)
* [Gregor Dschung](https://github.com/chkpnt)
* [Gregory L. Dietsche](https://github.com/farmergreg)
* [Greg Osuri](https://github.com/gosuri)
* [Guillaume Boudreau](https://github.com/gboudreau)
* [Harlan Lieberman-Berg](https://github.com/hlieberman)
* [Henri Salo](https://github.com/fgeek)
* [Henry Chen](https://github.com/henrychen95)
* [Hugo van Kemenade](https://github.com/hugovk)
* [Ingolf Becker](https://github.com/watercrossing)
* [Ivan Nejgebauer](https://github.com/inejge)
* [Jaap Eldering](https://github.com/eldering)
* [Jacob Hoffman-Andrews](https://github.com/jsha)
* [Jacob Sachs](https://github.com/jsachs)
* [Jairo Llopis](https://github.com/Yajo)
* [Jakub Warmuz](https://github.com/kuba)
* [James Balazs](https://github.com/jamesbalazs)
* [James Kasten](https://github.com/jdkasten)
* [Jason Grinblat](https://github.com/ptychomancer)
* [Jason Owen](https://github.com/jasonaowen)
* [Jawshua](https://github.com/jawshua)
* [Jay Faulkner](https://github.com/jayofdoom)
* [J.C. Jones](https://github.com/jcjones)
* [Jeff Hodges](https://github.com/jmhodges)
* [Jeremy Gillula](https://github.com/jgillula)
* [Jeroen Ketelaar](https://github.com/JKetelaar)
* [Jeroen Pluimers](https://github.com/jpluimers)
* [j](https://github.com/bit)
* [Jim Tittsler](https://github.com/jimt)
* [Joe Ranweiler](https://github.com/ranweiler)
* [Joerg Sonnenberger](https://github.com/jsonn)
* [John Leach](https://github.com/johnl)
* [John Reed](https://github.com/leerspace)
* [Jonas Berlin](https://github.com/xkr47)
* [Jonathan Herlin](https://github.com/Jonher937)
* [Jonathan Vanasco](https://github.com/jvanasco)
* [Jon Walsh](https://github.com/code-tree)
* [Joona Hoikkala](https://github.com/joohoi)
* [Josh McCullough](https://github.com/JoshMcCullough)
* [Josh Soref](https://github.com/jsoref)
* [Joubin Jabbari](https://github.com/joubin)
* [Juho Juopperi](https://github.com/jkjuopperi)
* [Kane York](https://github.com/riking)
* [Katsuyoshi Ozaki](https://github.com/moratori)
* [Kenichi Maehashi](https://github.com/kmaehashi)
* [Kenneth Skovhede](https://github.com/kenkendk)
* [Kevin Burke](https://github.com/kevinburke)
* [Kevin London](https://github.com/kevinlondon)
* [Kubilay Kocak](https://github.com/koobs)
* [LeCoyote](https://github.com/LeCoyote)
* [Lee Watson](https://github.com/TheReverend403)
* [Leo Famulari](https://github.com/lfam)
* [Leon G](https://github.com/LeonGr)
* [lf](https://github.com/lf-)
* [Liam Marshall](https://github.com/liamim)
* [Lior Sabag](https://github.com/liorsbg)
* [Lipis](https://github.com/lipis)
* [lord63](https://github.com/lord63)
* [Lorenzo Fundaró](https://github.com/lfundaro)
* [Luca Beltrame](https://github.com/lbeltrame)
* [Luca Ebach](https://github.com/lucebac)
* [Luca Olivetti](https://github.com/olivluca)
* [Luke Rogers](https://github.com/lukeroge)
* [Lukhnos Liu](https://github.com/lukhnos)
* [Maarten](https://github.com/mrtndwrd)
* [Mads Jensen](https://github.com/atombrella)
* [Maikel Martens](https://github.com/krukas)
* [Malte Janduda](https://github.com/MalteJ)
* [Mantas Mikulėnas](https://github.com/grawity)
* [Marcel Krüger](https://github.com/zauguin)
* [Marcos Caceres](https://github.com/marcoscaceres)
* [Marek Viger](https://github.com/freezy-sk)
* [Mario Villaplana](https://github.com/supermari0)
* [Marius Gedminas](https://github.com/mgedmin)
* [Martey Dodoo](https://github.com/martey)
* [Martijn Bastiaan](https://github.com/martijnbastiaan)
* [Martijn Braam](https://github.com/MartijnBraam)
* [Martin Brugger](https://github.com/mbrugger)
* [Mathieu Leduc-Hamel](https://github.com/mlhamel)
* [Matt Bostock](https://github.com/mattbostock)
* [Matthew Ames](https://github.com/SuperMatt)
* [Matthew W. Thomas](https://github.com/mwt)
* [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)
* [Mickaël Schoentgen](https://github.com/BoboTiG)
* [Minn Soe](https://github.com/MinnSoe)
* [Min RK](https://github.com/minrk)
* [Miquel Ruiz](https://github.com/miquelruiz)
* [Môshe van der Sterre](https://github.com/moshevds)
* [mrstanwell](https://github.com/mrstanwell)
* [Nav Aulakh](https://github.com/Nav)
* [Nelson Elhage](https://github.com/nelhage)
* [Nick Fong](https://github.com/nickfong)
* [Nick Le Mouton](https://github.com/NoodlesNZ)
* [Nikos Roussos](https://github.com/comzeradd)
* [Noah Swartz](https://github.com/swartzcr)
* [Ola Bini](https://github.com/olabini)
* [Ondřej Súkup](https://github.com/mimi1vx)
* [Ondřej Surý](https://github.com/oerdnj)
* [osirisinferi](https://github.com/osirisinferi)
* Patrick Figel
* [Patrick Heppler](https://github.com/PatrickHeppler)
* [Paul Buonopane](https://github.com/Zenexer)
* [Paul Feitzinger](https://github.com/pfeyz)
* [Paulo Dias](https://github.com/paulojmdias)
* [Pavan Gupta](https://github.com/pavgup)
* [Pavel Pavlov](https://github.com/ghost355)
* [Peter Conrad](https://github.com/pconrad-fb)
* [Peter Eckersley](https://github.com/pde)
* [Peter Mosmans](https://github.com/PeterMosmans)
* [Phil Martin](https://github.com/frillip)
* [Philippe Langlois](https://github.com/langloisjp)
* [Philipp Spitzer](https://github.com/spitza)
* [Piero Steinger](https://github.com/Jadaw1n)
* [Pierre Jaury](https://github.com/kaiyou)
* [Piotr Kasprzyk](https://github.com/kwadrat)
* [Prayag Verma](https://github.com/pra85)
* [Preston Locke](https://github.com/Preston12321)
* [Q Misell][https://magicalcodewit.ch]
* [Rasesh Patel](https://github.com/raspat1)
* [Reinaldo de Souza Jr](https://github.com/juniorz)
* [Remi Rampin](https://github.com/remram44)
* [Rémy HUBSCHER](https://github.com/Natim)
* [Rémy Léone](https://github.com/sieben)
* [Richard Barnes](https://github.com/r-barnes)
* [Richard Harman](https://github.com/warewolf)
* [Richard Panek](https://github.com/kernelpanek)
* [Robert Buchholz](https://github.com/rbu)
* [Robert Dailey](https://github.com/pahrohfit)
* [Robert Habermann](https://github.com/frennkie)
* [Robert Xiao](https://github.com/nneonneo)
* [Roland Shoemaker](https://github.com/rolandshoemaker)
* [Roy Wellington Ⅳ](https://github.com/thanatos)
* [rugk](https://github.com/rugk)
* [seeg](https://github.com/s33g)
* [Sachi King](https://github.com/nakato)
* [Sagi Kedmi](https://github.com/sagi)
* [Sam Lanning](https://github.com/samlanning)
* [sapics](https://github.com/sapics)
* [SATOH Fumiyasu](https://github.com/fumiyas)
* [Scott Barr](https://github.com/scottjbarr)
* [Scott Merrill](https://github.com/skpy)
* [Sebastian Bögl](https://github.com/TheBoegl)
* [Sebastian Wagner](https://github.com/sebix)
* [sedrubal](https://github.com/sedrubal)
* [Seppe Stas](https://github.com/seppestas)
* [Sergey Nuzdhin](https://github.com/lwolf)
* [Seth Schoen](https://github.com/schoen)
* [Sharif Nassar](https://github.com/mrwacky42)
* [Shaun Cummiskey](https://github.com/ampersign)
* [Shiloh Heurich](https://github.com/sheurich)
* [silverwind](https://github.com/silverwind)
* [Sorvani](https://github.com/sorvani)
* [Spencer Bliven](https://github.com/sbliven)
* [Stacey Sheldon](https://github.com/solidgoldbomb)
* [Stavros Korokithakis](https://github.com/skorokithakis)
* [Ștefan Talpalaru](https://github.com/stefantalpalaru)
* [Stefan Weil](https://github.com/stweil)
* [Steve Desmond](https://github.com/stevedesmond-ca)
* [sydneyli](https://github.com/sydneyli)
* [taixx046](https://github.com/taixx046)
* [Tan Jay Jun](https://github.com/jayjun)
* [Tapple Gao](https://github.com/tapple)
* [Telepenin Nikolay](https://github.com/telepenin)
* [Thomas Cottier](https://github.com/tcottier-enalean)
* [Thomas Mayer](https://github.com/thomaszbz)
* [Thomas Waldmann](https://github.com/ThomasWaldmann)
* [Thom Wiggers](https://github.com/thomwiggers)
* [Till Maas](https://github.com/tyll)
* [Timothy Guan-tin Chien](https://github.com/timdream)
* [Torsten Bögershausen](https://github.com/tboegi)
* [Travis Raines](https://github.com/rainest)
* [Trung Ngo](https://github.com/Ngo-The-Trung)
* [Valentin](https://github.com/e00E)
* [venyii](https://github.com/venyii)
* [Viktor Szakats](https://github.com/vszakats)
* [Ville Skyttä](https://github.com/scop)
* [Vinney Cavallo](https://github.com/vcavallo)
* [Vladimir Rutsky](https://github.com/rutsky)
* [Wang Yu](https://github.com/wyhitcs)
* [Ward Vandewege](https://github.com/cure)
* [Whyfoo](https://github.com/whyfoo)
* [Wilfried Teiken](https://github.com/wteiken)
* [Willem Fibbe](https://github.com/fibbers)
* [William Budington](https://github.com/Hainish)
* [Will Greenberg](https://github.com/wgreenberg)
* [Will Newby](https://github.com/willnewby)
* [Will Oller](https://github.com/willoller)
* [Yan](https://github.com/diracdeltas)
* [Yen Chi Hsuan](https://github.com/yan12125)
* [Yomna](https://github.com/ynasser)
* [Yoni Jah](https://github.com/yonjah)
* [YourDaddyIsHere](https://github.com/YourDaddyIsHere)
* [Yuseong Cho](https://github.com/g6123)
* [Zach Shepherd](https://github.com/zjs)
* [陈三](https://github.com/chenxsan)
* [Shahar Naveh](https://github.com/ShaharNaveh)
================================================
FILE: CODE_OF_CONDUCT.md
================================================
This project is governed by [EFF's Public Projects Code of Conduct](https://www.eff.org/pages/eppcode).
================================================
FILE: CONTRIBUTING.md
================================================
<!---
zoracon: (This is an old comment below, not sure how accurate this is anymore.
Since Github seems to lean more towards Markdown these days, it's still probably accurate)
This file serves as an entry point for GitHub's Contributing
Guidelines [1] only.
GitHub doesn't render rST very well, especially in respect to internal
hyperlink targets and cross-references [2]. People also tend to
confuse rST and Markdown syntax. Therefore, instead of keeping the
contents here (and including from rST documentation under doc/), link
to the Sphinx generated docs is provided below.
[1] https://github.com/blog/1184-contributing-guidelines
[2] https://docutils.sourceforge.io/docs/user/rst/quickref.html#hyperlink-targets
-->
# Certbot Contributing Guide
Hi! Welcome to the Certbot project. We look forward to collaborating with you.
If you're reporting a bug in Certbot. Please open an issue: https://github.com/certbot/certbot/issues/new/choose.
If you're having trouble using Certbot and aren't sure you've found a bug, please first try asking for help at https://community.letsencrypt.org/. There is a much larger community there of people familiar with the project who will be able to more quickly answer your questions.
If you're a developer, we have some helpful information in our
[Developer's Guide](https://certbot.eff.org/docs/contributing.html) to get you
started. In particular, we recommend you read these sections:
- [EFF's Public Projects Code of Conduct](https://www.eff.org/pages/eppcode)
- [Finding issues to work on](https://certbot.eff.org/docs/contributing.html#find-issues-to-work-on)
- [Coding style](https://certbot.eff.org/docs/contributing.html#coding-style)
- [Submitting a pull request](https://certbot.eff.org/docs/contributing.html#submitting-a-pull-request)
================================================
FILE: LICENSE.txt
================================================
Certbot ACME Client
Copyright (c) Electronic Frontier Foundation and others
Licensed Apache Version 2.0
The nginx plugin incorporates code from nginxparser
Copyright (c) 2014 Fatih Erikli
Licensed MIT
Text of Apache License
======================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
Text of MIT License
===================
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
================================================
FILE: SECURITY.md
================================================
# Security Policy
## Supported Versions
Explanation on supported versions [here](https://github.com/certbot/certbot/wiki/Architectural-Decision-Records#-update-to-certbots-version-policy-and-end-of-life-support-on-previous-major-versions)
| Major Version | Support Level |
| ------- | ------------------ |
| >= 5.0 | Full Support |
| 4.x | Discretionary Backports |
| <=3.x | None |
## Reporting a Vulnerability
Security vulnerabilities can be reported using GitHub's [private vulnerability reporting tool](https://github.com/certbot/certbot/security/advisories/new).
================================================
FILE: acme/.readthedocs.yaml
================================================
# Read the Docs configuration file for Sphinx projects
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
# Set the OS, Python version and other tools you might need
build:
os: ubuntu-22.04
tools:
python: "3.11"
# You can also specify other tool versions:
# Build documentation in the "docs/" directory with Sphinx
sphinx:
configuration: acme/docs/conf.py
# You can configure Sphinx to use a different builder, for instance use the dirhtml builder for simpler URLs
# builder: "dirhtml"
# Fail on all warnings to avoid broken references
fail_on_warning: true
# Optionally build your docs in additional formats such as PDF and ePub
formats:
- pdf
- epub
# Optional but recommended, declare the Python requirements required
# to build your documentation
# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
python:
install:
- requirements: acme/readthedocs.org.requirements.txt
================================================
FILE: acme/LICENSE.txt
================================================
Copyright 2015 Electronic Frontier Foundation and others
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
================================================
FILE: acme/MANIFEST.in
================================================
include LICENSE.txt
include README.rst
recursive-include docs *
recursive-include examples *
recursive-include src/acme/_internal/tests/testdata *
include src/acme/py.typed
global-exclude __pycache__
global-exclude *.py[cod]
================================================
FILE: acme/README.rst
================================================
ACME protocol implementation in Python
================================================
FILE: acme/docs/.gitignore
================================================
/_build/
================================================
FILE: acme/docs/Makefile
================================================
# Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = _build
# User-friendly check for sphinx-build
ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from https://www.sphinx-doc.org/)
endif
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " applehelp to make an Apple Help Book"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " texinfo to make Texinfo files"
@echo " info to make Texinfo files and run them through makeinfo"
@echo " gettext to make PO message catalogs"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " xml to make Docutils-native XML files"
@echo " pseudoxml to make pseudoxml-XML files for display purposes"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
@echo " coverage to run coverage check of the documentation (if enabled)"
clean:
rm -rf $(BUILDDIR)/*
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/acme-python.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/acme-python.qhc"
applehelp:
$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
@echo
@echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
@echo "N.B. You won't be able to view it unless you put it in" \
"~/Library/Documentation/Help or install it in your application" \
"bundle."
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/acme-python"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/acme-python"
@echo "# devhelp"
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)."
latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
latexpdfja:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through platex and dvipdfmx..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
texinfo:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
@echo "Run \`make' in that directory to run these through makeinfo" \
"(use \`make info' here to do that automatically)."
info:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo "Running Texinfo files through makeinfo..."
make -C $(BUILDDIR)/texinfo info
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
gettext:
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
@echo
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."
coverage:
$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
@echo "Testing of coverage in the sources finished, look at the " \
"results in $(BUILDDIR)/coverage/python.txt."
xml:
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
@echo
@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
pseudoxml:
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
@echo
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
================================================
FILE: acme/docs/_static/.gitignore
================================================
================================================
FILE: acme/docs/_templates/.gitignore
================================================
================================================
FILE: acme/docs/api/challenges.rst
================================================
Challenges
----------
.. automodule:: acme.challenges
:members:
================================================
FILE: acme/docs/api/client.rst
================================================
Client
------
.. automodule:: acme.client
:members:
================================================
FILE: acme/docs/api/crypto_util.rst
================================================
Crypto_util
-----------
.. automodule:: acme.crypto_util
:members:
================================================
FILE: acme/docs/api/errors.rst
================================================
Errors
------
.. automodule:: acme.errors
:members:
================================================
FILE: acme/docs/api/fields.rst
================================================
Fields
------
.. automodule:: acme.fields
:members:
================================================
FILE: acme/docs/api/jose.rst
================================================
JOSE
----
The ``acme.jose`` module was moved to its own package "josepy_".
Please refer to its documentation there.
.. _josepy: https://josepy.readthedocs.io/
================================================
FILE: acme/docs/api/jws.rst
================================================
JWS
---
.. automodule:: acme.jws
:members:
================================================
FILE: acme/docs/api/messages.rst
================================================
Messages
--------
.. automodule:: acme.messages
:members:
================================================
FILE: acme/docs/api/standalone.rst
================================================
Standalone
----------
.. automodule:: acme.standalone
:members:
================================================
FILE: acme/docs/api/util.rst
================================================
Util
----
.. automodule:: acme.util
:members:
================================================
FILE: acme/docs/api.rst
================================================
=================
API Documentation
=================
.. toctree::
:glob:
api/*
================================================
FILE: acme/docs/conf.py
================================================
# -*- coding: utf-8 -*-
#
# acme-python documentation build configuration file, created by
# sphinx-quickstart on Sun Oct 18 13:38:06 2015.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import os
import sys
here = os.path.abspath(os.path.dirname(__file__))
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
sys.path.insert(0, os.path.abspath(os.path.join(here, '..')))
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.intersphinx',
'sphinx.ext.todo',
'sphinx.ext.coverage',
'sphinx.ext.viewcode',
'sphinx_rtd_theme',
]
autodoc_member_order = 'bysource'
autodoc_default_flags = ['show-inheritance']
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
# source_suffix = ['.rst', '.md']
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'acme-python'
copyright = u'2015, Let\'s Encrypt Project'
author = u'Let\'s Encrypt Project'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '0'
# The full version, including alpha/beta/rc tags.
release = '0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = 'en'
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = [
'_build',
]
# The reST default role (used for this markup: `text`) to use for all
# documents.
default_role = 'py:obj'
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# If true, keep warnings as "system message" paragraphs in the built documents.
#keep_warnings = False
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = False
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
html_theme = 'sphinx_rtd_theme'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
# directly to the root of the documentation.
#html_extra_path = []
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_domain_indices = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None
# Language to be used for generating the HTML full-text search index.
# Sphinx supports the following languages:
# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'
#html_search_language = 'en'
# A dictionary with options for the search language support, empty by default.
# Now only 'ja' uses this config value
#html_search_options = {'type': 'default'}
# The name of a javascript file (relative to the configuration directory) that
# implements a search results scorer. If empty, the default will be used.
#html_search_scorer = 'scorer.js'
# Output file base name for HTML help builder.
htmlhelp_basename = 'acme-pythondoc'
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#'preamble': '',
# Latex figure (float) alignment
#'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'acme-python.tex', u'acme-python Documentation',
u'Let\'s Encrypt Project', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# If true, show page references after internal links.
#latex_show_pagerefs = False
# If true, show URL addresses after external links.
#latex_show_urls = False
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_domain_indices = True
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'acme-python', u'acme-python Documentation',
[author], 1),
('man/jws', 'jws', u'jws script documentation', [project], 1),
]
# If true, show URL addresses after external links.
#man_show_urls = False
# -- Options for Texinfo output -------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'acme-python', u'acme-python Documentation',
author, 'acme-python', 'One line description of project.',
'Miscellaneous'),
]
# Documents to append as an appendix to all manuals.
#texinfo_appendices = []
# If false, no module index is generated.
#texinfo_domain_indices = True
# How to display URL addresses: 'footnote', 'no', or 'inline'.
#texinfo_show_urls = 'footnote'
# If true, do not generate a @detailmenu in the "Top" node's menu.
#texinfo_no_detailmenu = False
intersphinx_mapping = {
'python': ('https://docs.python.org/', None),
'josepy': ('https://josepy.readthedocs.io/en/latest/', None),
}
================================================
FILE: acme/docs/index.rst
================================================
.. acme-python documentation master file, created by
sphinx-quickstart on Sun Oct 18 13:38:06 2015.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to acme-python's documentation!
=======================================
Contents:
.. toctree::
:maxdepth: 2
api
.. automodule:: acme
:members:
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
================================================
FILE: acme/docs/jws-help.txt
================================================
usage: jws [-h] [--compact] {sign,verify} ...
positional arguments:
{sign,verify}
options:
-h, --help show this help message and exit
--compact
================================================
FILE: acme/docs/make.bat
================================================
@ECHO OFF
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set BUILDDIR=_build
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
set I18NSPHINXOPTS=%SPHINXOPTS% .
if NOT "%PAPER%" == "" (
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
)
if "%1" == "" goto help
if "%1" == "help" (
:help
echo.Please use `make ^<target^>` where ^<target^> is one of
echo. html to make standalone HTML files
echo. dirhtml to make HTML files named index.html in directories
echo. singlehtml to make a single large HTML file
echo. pickle to make pickle files
echo. json to make JSON files
echo. htmlhelp to make HTML files and a HTML help project
echo. qthelp to make HTML files and a qthelp project
echo. devhelp to make HTML files and a Devhelp project
echo. epub to make an epub
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
echo. text to make text files
echo. man to make manual pages
echo. texinfo to make Texinfo files
echo. gettext to make PO message catalogs
echo. changes to make an overview over all changed/added/deprecated items
echo. xml to make Docutils-native XML files
echo. pseudoxml to make pseudoxml-XML files for display purposes
echo. linkcheck to check all external links for integrity
echo. doctest to run all doctests embedded in the documentation if enabled
echo. coverage to run coverage check of the documentation if enabled
goto end
)
if "%1" == "clean" (
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
del /q /s %BUILDDIR%\*
goto end
)
REM Check if sphinx-build is available and fallback to Python version if any
%SPHINXBUILD% 2> nul
if errorlevel 9009 goto sphinx_python
goto sphinx_ok
:sphinx_python
set SPHINXBUILD=python -m sphinx.__init__
%SPHINXBUILD% 2> nul
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.https://www.sphinx-doc.org/
exit /b 1
)
:sphinx_ok
if "%1" == "html" (
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
goto end
)
if "%1" == "dirhtml" (
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
goto end
)
if "%1" == "singlehtml" (
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
goto end
)
if "%1" == "pickle" (
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the pickle files.
goto end
)
if "%1" == "json" (
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the JSON files.
goto end
)
if "%1" == "htmlhelp" (
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run HTML Help Workshop with the ^
.hhp project file in %BUILDDIR%/htmlhelp.
goto end
)
if "%1" == "qthelp" (
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run "qcollectiongenerator" with the ^
.qhcp project file in %BUILDDIR%/qthelp, like this:
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\acme-python.qhcp
echo.To view the help file:
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\acme-python.ghc
goto end
)
if "%1" == "devhelp" (
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished.
goto end
)
if "%1" == "epub" (
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The epub file is in %BUILDDIR%/epub.
goto end
)
if "%1" == "latex" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
if errorlevel 1 exit /b 1
echo.
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "latexpdf" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
cd %BUILDDIR%/latex
make all-pdf
cd %~dp0
echo.
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "latexpdfja" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
cd %BUILDDIR%/latex
make all-pdf-ja
cd %~dp0
echo.
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "text" (
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The text files are in %BUILDDIR%/text.
goto end
)
if "%1" == "man" (
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The manual pages are in %BUILDDIR%/man.
goto end
)
if "%1" == "texinfo" (
%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
goto end
)
if "%1" == "gettext" (
%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
goto end
)
if "%1" == "changes" (
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
if errorlevel 1 exit /b 1
echo.
echo.The overview file is in %BUILDDIR%/changes.
goto end
)
if "%1" == "linkcheck" (
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
if errorlevel 1 exit /b 1
echo.
echo.Link check complete; look for any errors in the above output ^
or in %BUILDDIR%/linkcheck/output.txt.
goto end
)
if "%1" == "doctest" (
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
if errorlevel 1 exit /b 1
echo.
echo.Testing of doctests in the sources finished, look at the ^
results in %BUILDDIR%/doctest/output.txt.
goto end
)
if "%1" == "coverage" (
%SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage
if errorlevel 1 exit /b 1
echo.
echo.Testing of coverage in the sources finished, look at the ^
results in %BUILDDIR%/coverage/python.txt.
goto end
)
if "%1" == "xml" (
%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The XML files are in %BUILDDIR%/xml.
goto end
)
if "%1" == "pseudoxml" (
%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
goto end
)
:end
================================================
FILE: acme/docs/man/jws.rst
================================================
:orphan:
.. literalinclude:: ../jws-help.txt
================================================
FILE: acme/examples/http01_example.py
================================================
"""Example ACME-V2 API for HTTP-01 challenge.
Brief:
This a complete usage example of the python-acme API.
Limitations of this example:
- Works for only one Domain name
- Performs only HTTP-01 challenge
- Uses ACME-v2
Workflow:
(Account creation)
- Create account key
- Register account and accept TOS
(Certificate actions)
- Select HTTP-01 within offered challenges by the CA server
- Set up http challenge resource
- Set up standalone web server
- Create domain private key and CSR
- Issue certificate
- Renew certificate
- Revoke certificate
(Account update actions)
- Change contact information
- Deactivate Account
"""
from contextlib import contextmanager
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
import josepy as jose
from acme import challenges
from acme import client
from acme import crypto_util
from acme import errors
from acme import messages
from acme import standalone
# Constants:
# This is the staging point for ACME-V2 within Let's Encrypt.
DIRECTORY_URL = 'https://acme-staging-v02.api.letsencrypt.org/directory'
USER_AGENT = 'python-acme-example'
# Account key size
ACC_KEY_BITS = 2048
# Certificate private key size
CERT_PKEY_BITS = 2048
# Domain name for the certificate.
DOMAIN = 'client.example.com'
# If you are running Boulder locally, it is possible to configure any port
# number to execute the challenge, but real CA servers will always use port
# 80, as described in the ACME specification.
PORT = 80
# Useful methods and classes:
def new_csr_comp(domain_name, pkey_pem=None):
"""Create certificate signing request."""
if pkey_pem is None:
# Create private key.
pkey = rsa.generate_private_key(public_exponent=65537, key_size=CERT_PKEY_BITS)
pkey_pem = pkey.private_bytes(encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption())
csr_pem = crypto_util.make_csr(pkey_pem, [domain_name])
return pkey_pem, csr_pem
def select_http01_chall(orderr):
"""Extract authorization resource from within order resource."""
# Authorization Resource: authz.
# This object holds the offered challenges by the server and their status.
authz_list = orderr.authorizations
for authz in authz_list:
# Choosing challenge.
# authz.body.challenges is a set of ChallengeBody objects.
for i in authz.body.challenges:
# Find the supported challenge.
if isinstance(i.chall, challenges.HTTP01):
return i
raise Exception('HTTP-01 challenge was not offered by the CA server.')
@contextmanager
def challenge_server(http_01_resources):
"""Manage standalone server set up and shutdown."""
# Setting up a fake server that binds at PORT and any address.
address = ('', PORT)
try:
servers = standalone.HTTP01DualNetworkedServers(address,
http_01_resources)
# Start client standalone web server.
servers.serve_forever()
yield servers
finally:
# Shutdown client web server and unbind from PORT
servers.shutdown_and_server_close()
def perform_http01(client_acme, challb, orderr):
"""Set up standalone webserver and perform HTTP-01 challenge."""
response, validation = challb.response_and_validation(client_acme.net.key)
resource = standalone.HTTP01RequestHandler.HTTP01Resource(
chall=challb.chall, response=response, validation=validation)
with challenge_server({resource}):
# Let the CA server know that we are ready for the challenge.
client_acme.answer_challenge(challb, response)
# Wait for challenge status and then issue a certificate.
# It is possible to set a deadline time.
finalized_orderr = client_acme.poll_and_finalize(orderr)
return finalized_orderr.fullchain_pem
# Main examples:
def example_http():
"""This example executes the whole process of fulfilling a HTTP-01
challenge for one specific domain.
The workflow consists of:
(Account creation)
- Create account key
- Register account and accept TOS
(Certificate actions)
- Select HTTP-01 within offered challenges by the CA server
- Set up http challenge resource
- Set up standalone web server
- Create domain private key and CSR
- Issue certificate
- Renew certificate
- Revoke certificate
(Account update actions)
- Change contact information
- Deactivate Account
"""
# Create account key
acc_key = jose.JWKRSA(
key=rsa.generate_private_key(public_exponent=65537,
key_size=ACC_KEY_BITS,
backend=default_backend()))
# Register account and accept TOS
net = client.ClientNetwork(acc_key, user_agent=USER_AGENT)
directory = client.ClientV2.get_directory(DIRECTORY_URL, net)
client_acme = client.ClientV2(directory, net=net)
# Terms of Service URL is in client_acme.directory.meta.terms_of_service
# Registration Resource: regr
regr = client_acme.new_account(
messages.NewRegistration.from_data(terms_of_service_agreed=True))
# Create domain private key and CSR
pkey_pem, csr_pem = new_csr_comp(DOMAIN)
# Issue certificate
orderr = client_acme.new_order(csr_pem)
# Select HTTP-01 within offered challenges by the CA server
challb = select_http01_chall(orderr)
# The certificate is ready to be used in the variable "fullchain_pem".
fullchain_pem = perform_http01(client_acme, challb, orderr)
# Renew certificate
_, csr_pem = new_csr_comp(DOMAIN, pkey_pem)
orderr = client_acme.new_order(csr_pem)
challb = select_http01_chall(orderr)
# Performing challenge
fullchain_pem = perform_http01(client_acme, challb, orderr)
# Revoke certificate
fullchain_com = x509.load_pem_x509_certificate(fullchain_pem.encode())
try:
client_acme.revoke(fullchain_com, 0) # revocation reason = 0
except errors.ConflictError:
# Certificate already revoked.
pass
# Query registration status.
client_acme.net.account = regr
try:
regr = client_acme.query_registration(regr)
except errors.Error as err:
if err.typ == messages.ERROR_PREFIX + 'unauthorized':
# Status is deactivated.
pass
raise
# Change contact information
email = 'newfake@example.com'
regr = client_acme.update_registration(
regr.update(
body=regr.body.update(
contact=('mailto:' + email,)
)
)
)
# Deactivate account/registration
regr = client_acme.deactivate_registration(regr)
if __name__ == "__main__":
example_http()
================================================
FILE: acme/pyproject.toml
================================================
[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"
[project]
name = "acme"
dynamic = ["version"]
description = "ACME protocol implementation in Python"
readme = "README.rst"
license = "Apache-2.0"
requires-python = ">=3.10"
authors = [
{ name = "Certbot Project" },
]
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.14",
"Topic :: Internet :: WWW/HTTP",
"Topic :: Security",
]
dependencies = [
"cryptography>=43.0.0",
"josepy>=2.0.0",
# PyOpenSSL>=25.0.0 is just needed to satisfy mypy right now so this dependency can probably be
# relaxed to >=24.0.0 if needed.
"PyOpenSSL>=25.0.0",
"pyrfc3339",
"requests>=2.25.1",
]
[project.optional-dependencies]
docs = [
"Sphinx>=1.0", # autodoc_member_order = 'bysource', autodoc_default_flags
"sphinx_rtd_theme",
]
test = [
"pytest",
"pytest-xdist",
"typing-extensions",
]
[project.urls]
Homepage = "https://github.com/certbot/certbot"
[tool.setuptools]
package-dir = {"" = "src"}
[tool.setuptools.packages.find]
where = ["src"]
================================================
FILE: acme/readthedocs.org.requirements.txt
================================================
# readthedocs.org gives no way to change the install command to "pip
# install -e acme[docs]" (that would in turn install documentation
# dependencies), but it allows to specify a requirements.txt file at
# https://readthedocs.org/dashboard/letsencrypt/advanced/ (c.f. #259)
# Although ReadTheDocs certainly doesn't need to install the project
# in --editable mode (-e), just "pip install acme[docs]" does not work as
# expected and "pip install -e acme[docs]" must be used instead
# We also pin our dependencies for increased stability.
-c ../tools/requirements.txt
-e acme[docs]
================================================
FILE: acme/setup.py
================================================
from setuptools import setup
version = '5.5.0.dev0'
setup(
version=version,
)
================================================
FILE: acme/src/acme/__init__.py
================================================
"""ACME protocol implementation.
This module is an implementation of the `ACME protocol`_.
.. _`ACME protocol`: https://datatracker.ietf.org/doc/html/rfc8555
"""
import sys
# This code exists to keep backwards compatibility with people using acme.jose
# before it became the standalone josepy package.
#
# It is based on
# https://github.com/requests/requests/blob/1278ecdf71a312dc2268f3bfc0aabfab3c006dcf/requests/packages.py
import josepy as jose # noqa: F401
for mod in list(sys.modules):
# This traversal is apparently necessary such that the identities are
# preserved (acme.jose.* is josepy.*)
if mod == 'josepy' or mod.startswith('josepy.'):
sys.modules['acme.' + mod.replace('josepy', 'jose', 1)] = sys.modules[mod]
================================================
FILE: acme/src/acme/_internal/__init__.py
================================================
"""acme's internal implementation"""
================================================
FILE: acme/src/acme/_internal/tests/__init__.py
================================================
"""acme tests"""
================================================
FILE: acme/src/acme/_internal/tests/challenges_test.py
================================================
"""Tests for acme.challenges."""
import sys
from typing import TYPE_CHECKING
import unittest
from unittest import mock
import urllib.parse as urllib_parse
import josepy as jose
from josepy.jwk import JWKEC
import pytest
import requests
from acme._internal.tests import test_util
CERT = test_util.load_cert('cert.pem')
KEY = jose.JWKRSA(key=test_util.load_rsa_private_key('rsa512_key.pem'))
class ChallengeTest(unittest.TestCase):
def test_from_json_unrecognized(self):
from acme.challenges import Challenge
from acme.challenges import UnrecognizedChallenge
chall = UnrecognizedChallenge({"type": "foo"})
assert chall == Challenge.from_json(chall.jobj)
class UnrecognizedChallengeTest(unittest.TestCase):
def setUp(self):
from acme.challenges import UnrecognizedChallenge
self.jobj = {"type": "foo"}
self.chall = UnrecognizedChallenge(self.jobj)
def test_to_partial_json(self):
assert self.jobj == self.chall.to_partial_json()
def test_from_json(self):
from acme.challenges import UnrecognizedChallenge
assert self.chall == UnrecognizedChallenge.from_json(self.jobj)
class KeyAuthorizationChallengeResponseTest(unittest.TestCase):
def setUp(self):
def _encode(name):
assert name == "token"
return "foo"
self.chall = mock.Mock()
self.chall.encode.side_effect = _encode
def test_verify_ok(self):
from acme.challenges import KeyAuthorizationChallengeResponse
response = KeyAuthorizationChallengeResponse(
key_authorization='foo.oKGqedy-b-acd5eoybm2f-NVFxvyOoET5CNy3xnv8WY')
assert response.verify(self.chall, KEY.public_key())
def test_verify_wrong_token(self):
from acme.challenges import KeyAuthorizationChallengeResponse
response = KeyAuthorizationChallengeResponse(
key_authorization='bar.oKGqedy-b-acd5eoybm2f-NVFxvyOoET5CNy3xnv8WY')
assert not response.verify(self.chall, KEY.public_key())
def test_verify_wrong_thumbprint(self):
from acme.challenges import KeyAuthorizationChallengeResponse
response = KeyAuthorizationChallengeResponse(
key_authorization='foo.oKGqedy-b-acd5eoybm2f-NVFxv')
assert not response.verify(self.chall, KEY.public_key())
def test_verify_wrong_form(self):
from acme.challenges import KeyAuthorizationChallengeResponse
response = KeyAuthorizationChallengeResponse(
key_authorization='.foo.oKGqedy-b-acd5eoybm2f-'
'NVFxvyOoET5CNy3xnv8WY')
assert not response.verify(self.chall, KEY.public_key())
class DNS01ResponseTest(unittest.TestCase):
def setUp(self):
from acme.challenges import DNS01Response
self.msg = DNS01Response(key_authorization=u'foo')
self.jmsg = {
'resource': 'challenge',
'type': 'dns-01',
'keyAuthorization': u'foo',
}
from acme.challenges import DNS01
self.chall = DNS01(token=(b'x' * 16))
self.response = self.chall.response(KEY)
def test_to_partial_json(self):
assert {} == self.msg.to_partial_json()
def test_from_json(self):
from acme.challenges import DNS01Response
assert self.msg == DNS01Response.from_json(self.jmsg)
def test_from_json_hashable(self):
from acme.challenges import DNS01Response
hash(DNS01Response.from_json(self.jmsg))
def test_simple_verify_failure(self):
key2 = jose.JWKRSA.load(test_util.load_vector('rsa256_key.pem'))
public_key = key2.public_key()
verified = self.response.simple_verify(self.chall, "local", public_key)
assert not verified
def test_simple_verify_success(self):
public_key = KEY.public_key()
verified = self.response.simple_verify(self.chall, "local", public_key)
assert verified
class DNS01Test(unittest.TestCase):
def setUp(self):
from acme.challenges import DNS01
self.msg = DNS01(token=jose.decode_b64jose(
'evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ+PCt92wr+oA'))
self.jmsg = {
'type': 'dns-01',
'token': 'evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ-PCt92wr-oA',
}
def test_validation_domain_name(self):
assert '_acme-challenge.www.example.com' == \
self.msg.validation_domain_name('www.example.com')
def test_validation(self):
assert "rAa7iIg4K2y63fvUhCfy8dP1Xl7wEhmQq0oChTcE3Zk" == \
self.msg.validation(KEY)
def test_to_partial_json(self):
assert self.jmsg == self.msg.to_partial_json()
def test_from_json(self):
from acme.challenges import DNS01
assert self.msg == DNS01.from_json(self.jmsg)
def test_from_json_hashable(self):
from acme.challenges import DNS01
hash(DNS01.from_json(self.jmsg))
class HTTP01ResponseTest(unittest.TestCase):
def setUp(self):
from acme.challenges import HTTP01Response
self.msg = HTTP01Response(key_authorization=u'foo')
self.jmsg = {
'resource': 'challenge',
'type': 'http-01',
'keyAuthorization': u'foo',
}
from acme.challenges import HTTP01
self.chall = HTTP01(token=(b'x' * 16))
self.response = self.chall.response(KEY)
def test_to_partial_json(self):
assert {} == self.msg.to_partial_json()
def test_from_json(self):
from acme.challenges import HTTP01Response
assert self.msg == HTTP01Response.from_json(self.jmsg)
def test_from_json_hashable(self):
from acme.challenges import HTTP01Response
hash(HTTP01Response.from_json(self.jmsg))
def test_simple_verify_bad_key_authorization(self):
key2 = jose.JWKRSA.load(test_util.load_vector('rsa256_key.pem'))
self.response.simple_verify(self.chall, "local", key2.public_key())
@mock.patch("acme.challenges.requests.get")
def test_simple_verify_good_validation(self, mock_get):
validation = self.chall.validation(KEY)
mock_get.return_value = mock.MagicMock(text=validation)
assert self.response.simple_verify(
self.chall, "local", KEY.public_key())
mock_get.assert_called_once_with(self.chall.uri("local"), verify=False,
timeout=mock.ANY)
@mock.patch("acme.challenges.requests.get")
def test_simple_verify_bad_validation(self, mock_get):
mock_get.return_value = mock.MagicMock(text="!")
assert not self.response.simple_verify(
self.chall, "local", KEY.public_key())
@mock.patch("acme.challenges.requests.get")
def test_simple_verify_whitespace_validation(self, mock_get):
from acme.challenges import HTTP01Response
mock_get.return_value = mock.MagicMock(
text=(self.chall.validation(KEY) +
HTTP01Response.WHITESPACE_CUTSET))
assert self.response.simple_verify(
self.chall, "local", KEY.public_key())
mock_get.assert_called_once_with(self.chall.uri("local"), verify=False,
timeout=mock.ANY)
@mock.patch("acme.challenges.requests.get")
def test_simple_verify_connection_error(self, mock_get):
mock_get.side_effect = requests.exceptions.RequestException
assert not self.response.simple_verify(
self.chall, "local", KEY.public_key())
@mock.patch("acme.challenges.requests.get")
def test_simple_verify_port(self, mock_get):
self.response.simple_verify(
self.chall, domain="local",
account_public_key=KEY.public_key(), port=8080)
assert "local:8080" == urllib_parse.urlparse(
mock_get.mock_calls[0][1][0]).netloc
@mock.patch("acme.challenges.requests.get")
def test_simple_verify_timeout(self, mock_get):
self.response.simple_verify(self.chall, "local", KEY.public_key())
mock_get.assert_called_once_with(self.chall.uri("local"), verify=False,
timeout=30)
mock_get.reset_mock()
self.response.simple_verify(self.chall, "local", KEY.public_key(), timeout=1234)
mock_get.assert_called_once_with(self.chall.uri("local"), verify=False,
timeout=1234)
class HTTP01Test(unittest.TestCase):
def setUp(self):
from acme.challenges import HTTP01
self.msg = HTTP01(
token=jose.decode_b64jose(
'evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ+PCt92wr+oA'))
self.jmsg = {
'type': 'http-01',
'token': 'evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ-PCt92wr-oA',
}
def test_path(self):
assert self.msg.path == '/.well-known/acme-challenge/' \
'evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ-PCt92wr-oA'
def test_uri(self):
assert 'http://example.com/.well-known/acme-challenge/' \
'evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ-PCt92wr-oA' == \
self.msg.uri('example.com')
assert 'http://1.2.3.4/.well-known/acme-challenge/' \
'evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ-PCt92wr-oA' == \
self.msg.uri('1.2.3.4')
assert 'http://[::1]/.well-known/acme-challenge/' \
'evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ-PCt92wr-oA' == \
self.msg.uri('::1')
def test_to_partial_json(self):
assert self.jmsg == self.msg.to_partial_json()
def test_from_json(self):
from acme.challenges import HTTP01
assert self.msg == HTTP01.from_json(self.jmsg)
def test_from_json_hashable(self):
from acme.challenges import HTTP01
hash(HTTP01.from_json(self.jmsg))
def test_good_token(self):
assert self.msg.good_token
assert not self.msg.update(token=b'..').good_token
class TestDNS:
if TYPE_CHECKING:
from acme.challenges import DNS
@pytest.fixture
def jmsg(self) -> dict:
jmsg = {
'type': 'dns',
'token': 'evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ-PCt92wr-oA',
}
return jmsg
@pytest.fixture
def msg(self) -> 'DNS':
from acme.challenges import DNS
msg = DNS(token=jose.b64decode(
b'evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ-PCt92wr-oA'))
return msg
def test_to_partial_json(self, msg: 'DNS', jmsg: dict):
assert jmsg == msg.to_partial_json()
def test_from_json(self, msg: 'DNS', jmsg: dict):
from acme.challenges import DNS
assert msg == DNS.from_json(jmsg)
def test_from_json_hashable(self, jmsg: dict):
from acme.challenges import DNS
hash(DNS.from_json(jmsg))
# Using fixtures in parametrize is an open issue
# https://github.com/pytest-dev/pytest/issues/349
@pytest.mark.parametrize("key, alg", [
(KEY, jose.RS256),
(JWKEC(key=test_util.load_ecdsa_private_key('ec_secp384r1_key.pem')), jose.ES384)])
def test_gen_check_validation(self, key, alg, msg: 'DNS'):
assert msg.check_validation(
msg.gen_validation(key, alg=alg), key.public_key())
def test_gen_check_validation_wrong_key(self, msg: 'DNS'):
key2 = jose.JWKRSA.load(test_util.load_vector('rsa1024_key.pem'))
assert not msg.check_validation(
msg.gen_validation(KEY), key2.public_key())
def test_check_validation_wrong_payload(self, msg: 'DNS'):
validations = tuple(
jose.JWS.sign(payload=payload, alg=jose.RS256, key=KEY)
for payload in (b'', b'{}')
)
for validation in validations:
assert not msg.check_validation(
validation, KEY.public_key())
def test_check_validation_wrong_fields(self, msg: 'DNS'):
bad_validation = jose.JWS.sign(
payload=msg.update(
token=b'x' * 20).json_dumps().encode('utf-8'),
alg=jose.RS256, key=KEY)
assert not msg.check_validation(bad_validation, KEY.public_key())
def test_gen_response(self, msg: 'DNS'):
with mock.patch('acme.challenges.DNS.gen_validation') as mock_gen:
mock_gen.return_value = mock.sentinel.validation
response = msg.gen_response(KEY)
from acme.challenges import DNSResponse
assert isinstance(response, DNSResponse)
assert response.validation == mock.sentinel.validation
def test_validation_domain_name(self, msg: 'DNS'):
assert '_acme-challenge.le.wtf' == msg.validation_domain_name('le.wtf')
def test_validation_domain_name_ecdsa(self, msg: 'DNS'):
ec_key_secp384r1 = JWKEC(key=test_util.load_ecdsa_private_key('ec_secp384r1_key.pem'))
assert msg.check_validation(
msg.gen_validation(ec_key_secp384r1, alg=jose.ES384),
ec_key_secp384r1.public_key()) is True
class DNSResponseTest(unittest.TestCase):
def setUp(self):
from acme.challenges import DNS
self.chall = DNS(token=jose.b64decode(
b"evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ-PCt92wr-oA"))
self.validation = jose.JWS.sign(
payload=self.chall.json_dumps(sort_keys=True).encode(),
key=KEY, alg=jose.RS256)
from acme.challenges import DNSResponse
self.msg = DNSResponse(validation=self.validation)
self.jmsg_to = {
'validation': self.validation,
}
self.jmsg_from = {
'resource': 'challenge',
'type': 'dns',
'validation': self.validation.to_json(),
}
def test_to_partial_json(self):
assert self.jmsg_to == self.msg.to_partial_json()
def test_from_json(self):
from acme.challenges import DNSResponse
assert self.msg == DNSResponse.from_json(self.jmsg_from)
def test_from_json_hashable(self):
from acme.challenges import DNSResponse
hash(DNSResponse.from_json(self.jmsg_from))
def test_check_validation(self):
assert self.msg.check_validation(self.chall, KEY.public_key())
class JWSPayloadRFC8555Compliant(unittest.TestCase):
"""Test for RFC8555 compliance of JWS generated from resources/challenges"""
def test_challenge_payload(self):
from acme.challenges import HTTP01Response
challenge_body = HTTP01Response()
jobj = challenge_body.json_dumps(indent=2).encode()
# RFC8555 states that challenge responses must have an empty payload.
assert jobj == b'{}'
if __name__ == '__main__':
sys.exit(pytest.main(sys.argv[1:] + [__file__])) # pragma: no cover
================================================
FILE: acme/src/acme/_internal/tests/client_test.py
================================================
"""Tests for acme.client."""
# pylint: disable=too-many-lines
import copy
import datetime
import http.client as http_client
import json
import sys
import unittest
from unittest import mock
from cryptography import x509
import josepy as jose
import pytest
import requests
from acme import challenges
from acme import errors
from acme import jws as acme_jws
from acme import messages
from acme._internal.tests import messages_test
from acme._internal.tests import test_util
from acme.client import ClientNetwork
from acme.client import ClientV2
CERT_SAN_PEM = test_util.load_vector('cert-san.pem')
CSR_MIXED_PEM = test_util.load_vector('csr-mixed.pem')
CSR_NO_SANS_PEM = test_util.load_vector('csr-nosans.pem')
KEY = jose.JWKRSA.load(test_util.load_vector('rsa512_key.pem'))
DIRECTORY_V2 = messages.Directory({
'newAccount': 'https://www.letsencrypt-demo.org/acme/new-account',
'newNonce': 'https://www.letsencrypt-demo.org/acme/new-nonce',
'newOrder': 'https://www.letsencrypt-demo.org/acme/new-order',
'revokeCert': 'https://www.letsencrypt-demo.org/acme/revoke-cert',
'meta': messages.Directory.Meta(),
})
class ClientV2Test(unittest.TestCase):
"""Tests for acme.client.ClientV2."""
def setUp(self):
self.response = mock.MagicMock(
ok=True, status_code=http_client.OK, headers={}, links={})
self.net = mock.MagicMock()
self.net.post.return_value = self.response
self.net.get.return_value = self.response
self.identifier = messages.Identifier(
typ=messages.IDENTIFIER_FQDN, value='example.com')
# Registration
self.contact = ('mailto:cert-admin@example.com', 'tel:+12025551212')
reg = messages.Registration(
contact=self.contact, key=KEY.public_key())
the_arg: dict = dict(reg)
self.new_reg = messages.NewRegistration(**the_arg)
self.regr = messages.RegistrationResource(
body=reg, uri='https://www.letsencrypt-demo.org/acme/reg/1')
# Authorization
authzr_uri = 'https://www.letsencrypt-demo.org/acme/authz/1'
challb = messages.ChallengeBody(
uri=(authzr_uri + '/1'), status=messages.STATUS_VALID,
chall=challenges.DNS(token=jose.b64decode(
'evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ-PCt92wr-oA')))
self.challr = messages.ChallengeResource(
body=challb, authzr_uri=authzr_uri)
self.authz = messages.Authorization(
identifier=messages.Identifier(
typ=messages.IDENTIFIER_FQDN, value='example.com'),
challenges=(challb,))
self.authzr = messages.AuthorizationResource(
body=self.authz, uri=authzr_uri)
# Reason code for revocation
self.rsn = 1
self.directory = DIRECTORY_V2
self.client = ClientV2(self.directory, self.net)
self.new_reg = self.new_reg.update(terms_of_service_agreed=True)
self.authzr_uri2 = 'https://www.letsencrypt-demo.org/acme/authz/2'
self.authz2 = self.authz.update(identifier=messages.Identifier(
typ=messages.IDENTIFIER_FQDN, value='www.example.com'),
status=messages.STATUS_PENDING)
self.authzr2 = messages.AuthorizationResource(
body=self.authz2, uri=self.authzr_uri2)
self.order = messages.Order(
identifiers=(self.authz.identifier, self.authz2.identifier),
status=messages.STATUS_PENDING,
authorizations=(self.authzr.uri, self.authzr_uri2),
finalize='https://www.letsencrypt-demo.org/acme/acct/1/order/1/finalize')
self.orderr = messages.OrderResource(
body=self.order,
uri='https://www.letsencrypt-demo.org/acme/acct/1/order/1',
authorizations=[self.authzr, self.authzr2], csr_pem=CSR_MIXED_PEM)
self.orderr2 = messages.OrderResource(
body=self.order,
uri='https://www.letsencrypt-demo.org/acme/acct/1/order/1',
authorizations=[self.authzr, self.authzr2], csr_pem=CSR_NO_SANS_PEM)
def test_new_account(self):
self.response.status_code = http_client.CREATED
self.response.json.return_value = self.regr.body.to_json()
self.response.headers['Location'] = self.regr.uri
assert self.regr == self.client.new_account(self.new_reg)
def test_new_account_tos_link(self):
self.response.status_code = http_client.CREATED
self.response.json.return_value = self.regr.body.to_json()
self.response.headers['Location'] = self.regr.uri
self.response.links.update({
'terms-of-service': {'url': 'https://www.letsencrypt-demo.org/tos'},
})
assert self.client.new_account(self.new_reg).terms_of_service == \
'https://www.letsencrypt-demo.org/tos'
def test_new_account_conflict(self):
self.response.status_code = http_client.OK
self.response.headers['Location'] = self.regr.uri
with pytest.raises(errors.ConflictError):
self.client.new_account(self.new_reg)
def test_deactivate_account(self):
deactivated_regr = self.regr.update(
body=self.regr.body.update(status='deactivated'))
self.response.json.return_value = deactivated_regr.body.to_json()
self.response.status_code = http_client.OK
self.response.headers['Location'] = self.regr.uri
assert self.client.deactivate_registration(self.regr) == deactivated_regr
def test_deactivate_authorization(self):
deactivated_authz = self.authzr.update(
body=self.authzr.body.update(status=messages.STATUS_DEACTIVATED))
self.response.json.return_value = deactivated_authz.body.to_json()
authzr = self.client.deactivate_authorization(self.authzr)
assert deactivated_authz.body == authzr.body
assert self.client.net.post.call_count == 1
assert self.authzr.uri in self.net.post.call_args_list[0][0]
def test_new_order(self):
order_response = copy.deepcopy(self.response)
order_response.status_code = http_client.CREATED
order_response.json.return_value = self.order.to_json()
order_response.headers['Location'] = self.orderr.uri
self.net.post.return_value = order_response
authz_response = copy.deepcopy(self.response)
authz_response.json.return_value = self.authz.to_json()
authz_response.headers['Location'] = self.authzr.uri
authz_response2 = self.response
authz_response2.json.return_value = self.authz2.to_json()
authz_response2.headers['Location'] = self.authzr2.uri
with mock.patch('acme.client.ClientV2._post_as_get') as mock_post_as_get:
mock_post_as_get.side_effect = (authz_response, authz_response2)
assert self.client.new_order(CSR_MIXED_PEM) == self.orderr
with mock.patch('acme.client.ClientV2._post_as_get') as mock_post_as_get:
mock_post_as_get.side_effect = (authz_response, authz_response2)
assert self.client.new_order(CSR_NO_SANS_PEM) == self.orderr2
def test_answer_challege(self):
self.response.links['up'] = {'url': self.challr.authzr_uri}
self.response.json.return_value = self.challr.body.to_json()
chall_response = challenges.DNSResponse(validation=None)
self.client.answer_challenge(self.challr.body, chall_response)
with pytest.raises(errors.UnexpectedUpdate):
self.client.answer_challenge(self.challr.body.update(uri='foo'), chall_response)
def test_answer_challenge_missing_next(self):
with pytest.raises(errors.ClientError):
self.client.answer_challenge(self.challr.body, challenges.DNSResponse(validation=None))
@mock.patch('acme.client.datetime')
def test_poll_and_finalize(self, mock_datetime):
mock_datetime.datetime.now.return_value = datetime.datetime(2018, 2, 15)
mock_datetime.timedelta = datetime.timedelta
expected_deadline = mock_datetime.datetime.now() + datetime.timedelta(seconds=90)
self.client.poll_authorizations = mock.Mock(return_value=self.orderr)
self.client.finalize_order = mock.Mock(return_value=self.orderr)
assert self.client.poll_and_finalize(self.orderr) == self.orderr
self.client.poll_authorizations.assert_called_once_with(self.orderr, expected_deadline)
self.client.finalize_order.assert_called_once_with(self.orderr, expected_deadline)
@mock.patch('acme.client.datetime')
def test_poll_authorizations_timeout(self, mock_datetime):
now_side_effect = [datetime.datetime(2018, 2, 15),
datetime.datetime(2018, 2, 16),
datetime.datetime(2018, 2, 17)]
mock_datetime.datetime.now.side_effect = now_side_effect
self.response.json.side_effect = [
self.authz.to_json(), self.authz2.to_json(), self.authz2.to_json()]
with pytest.raises(errors.TimeoutError):
self.client.poll_authorizations(self.orderr, now_side_effect[1])
def test_poll_authorizations_failure(self):
deadline = datetime.datetime(9999, 9, 9)
challb = self.challr.body.update(status=messages.STATUS_INVALID,
error=messages.Error.with_code('unauthorized'))
authz = self.authz.update(status=messages.STATUS_INVALID, challenges=(challb,))
self.response.json.return_value = authz.to_json()
with pytest.raises(errors.ValidationError):
self.client.poll_authorizations(self.orderr, deadline)
def test_poll_authorizations_success(self):
deadline = datetime.datetime(9999, 9, 9)
updated_authz2 = self.authz2.update(status=messages.STATUS_VALID)
updated_authzr2 = messages.AuthorizationResource(
body=updated_authz2, uri=self.authzr_uri2)
updated_orderr = self.orderr.update(authorizations=[self.authzr, updated_authzr2])
self.response.json.side_effect = (
self.authz.to_json(), self.authz2.to_json(), updated_authz2.to_json())
assert self.client.poll_authorizations(self.orderr, deadline) == updated_orderr
def test_poll_unexpected_update(self):
updated_authz = self.authz.update(identifier=self.identifier.update(value='foo'))
self.response.json.return_value = updated_authz.to_json()
with pytest.raises(errors.UnexpectedUpdate):
self.client.poll(self.authzr)
def test_finalize_order_success(self):
updated_order = self.order.update(
certificate='https://www.letsencrypt-demo.org/acme/cert/',
status=messages.STATUS_VALID)
updated_orderr = self.orderr.update(body=updated_order, fullchain_pem=CERT_SAN_PEM)
self.response.json.return_value = updated_order.to_json()
self.response.text = CERT_SAN_PEM
deadline = datetime.datetime(9999, 9, 9)
assert self.client.finalize_order(self.orderr, deadline) == updated_orderr
def test_finalize_order_error(self):
updated_order = self.order.update(
error=messages.Error.with_code('unauthorized'),
status=messages.STATUS_INVALID)
self.response.json.return_value = updated_order.to_json()
deadline = datetime.datetime(9999, 9, 9)
with pytest.raises(errors.IssuanceError):
self.client.finalize_order(self.orderr, deadline)
@mock.patch('acme.client.ClientV2.begin_finalization')
def test_finalize_order_ready(self, mock_begin):
# https://github.com/certbot/certbot/issues/9766
updated_order_ready = self.order.update(status=messages.STATUS_READY)
updated_order_valid = self.order.update(
certificate='https://www.letsencrypt-demo.org/acme/cert/',
status=messages.STATUS_VALID)
updated_orderr = self.orderr.update(body=updated_order_valid, fullchain_pem=CERT_SAN_PEM)
self.response.text = CERT_SAN_PEM
self.response.json.side_effect = [updated_order_ready.to_json(),
updated_order_valid.to_json()]
deadline = datetime.datetime(9999, 9, 9)
assert self.client.finalize_order(self.orderr, deadline) == updated_orderr
assert self.response.json.call_count == 2
assert mock_begin.call_count == 2
def test_finalize_order_invalid_status(self):
# https://github.com/certbot/certbot/issues/9296
order = self.order.update(error=None, status=messages.STATUS_INVALID)
self.response.json.return_value = order.to_json()
with pytest.raises(errors.Error, match="The certificate order failed"):
self.client.finalize_order(self.orderr, datetime.datetime(9999, 9, 9))
@mock.patch('acme.client.time.sleep')
@mock.patch('acme.client.datetime')
def test_finalize_order_orderNotReady(self, dt_mock, mock_sleep):
# https://github.com/certbot/certbot/issues/9766
updated_order_processing = self.order.update(status=messages.STATUS_PROCESSING)
updated_order_ready = self.order.update(status=messages.STATUS_READY)
updated_order_valid = self.order.update(
certificate='https://www.letsencrypt-demo.org/acme/cert/',
status=messages.STATUS_VALID)
self.orderr.update(body=updated_order_valid, fullchain_pem=CERT_SAN_PEM)
self.response.text = CERT_SAN_PEM
self.response.json.side_effect = [updated_order_processing.to_json(),
updated_order_ready.to_json(),
updated_order_valid.to_json()]
dt_mock.datetime.now.return_value = datetime.datetime(2015, 3, 27)
dt_mock.timedelta = datetime.timedelta
self.response.headers['Retry-After'] = '50'
post = mock.MagicMock()
post.side_effect = [messages.Error.with_code('orderNotReady'), # first begin_finalization
# sleep 1
self.response, # first poll_finalization poll --> returns processing
# retry-after sleep here
self.response, # second poll_finalization poll --> returns ready
mock.MagicMock(), # second begin_finalization
# sleep 1
self.response, # third poll_finalization poll --> returns valid
self.response # fetch cert
]
self.net.post = post
self.client.finalize_order(self.orderr, datetime.datetime(9999, 9, 9))
assert self.net.post.call_count == 6
assert mock_sleep.call_args_list == [((1,),), ((50,),), ((1,),)]
def test_finalize_order_otherErrorCode(self):
post = mock.MagicMock()
post.side_effect = [messages.Error.with_code('serverInternal')]
self.net.post = post
with pytest.raises(messages.Error):
self.client.finalize_order(self.orderr, datetime.datetime(9999, 9, 9))
def test_finalize_order_timeout(self):
deadline = datetime.datetime.now() - datetime.timedelta(seconds=60)
with pytest.raises(errors.TimeoutError):
self.client.finalize_order(self.orderr, deadline)
def test_finalize_order_alt_chains(self):
updated_order = self.order.update(
certificate='https://www.letsencrypt-demo.org/acme/cert/',
status=messages.STATUS_VALID
)
updated_orderr = self.orderr.update(body=updated_order,
fullchain_pem=CERT_SAN_PEM,
alternative_fullchains_pem=[CERT_SAN_PEM,
CERT_SAN_PEM])
self.response.json.return_value = updated_order.to_json()
self.response.text = CERT_SAN_PEM
self.response.headers['Link'] ='<https://example.com/acme/cert/1>;rel="alternate", ' + \
'<https://example.com/dir>;rel="index", ' + \
'<https://example.com/acme/cert/2>;title="foo";rel="alternate"'
deadline = datetime.datetime(9999, 9, 9)
resp = self.client.finalize_order(self.orderr, deadline, fetch_alternative_chains=True)
self.net.post.assert_any_call('https://example.com/acme/cert/1',
mock.ANY, new_nonce_url=mock.ANY)
self.net.post.assert_any_call('https://example.com/acme/cert/2',
mock.ANY, new_nonce_url=mock.ANY)
assert resp == updated_orderr
del self.response.headers['Link']
resp = self.client.finalize_order(self.orderr, deadline, fetch_alternative_chains=True)
assert resp == updated_orderr.update(alternative_fullchains_pem=[])
def test_revoke(self):
self.client.revoke(messages_test.CERT, self.rsn)
self.net.post.assert_called_once_with(
self.directory["revokeCert"], mock.ANY, new_nonce_url=DIRECTORY_V2['newNonce'])
def test_revoke_bad_status_raises_error(self):
self.response.status_code = http_client.METHOD_NOT_ALLOWED
with pytest.raises(errors.ClientError):
self.client.revoke(messages_test.CERT,
self.rsn)
def test_update_registration(self):
# "Instance of 'Field' has no to_json/update member" bug:
self.response.headers['Location'] = self.regr.uri
self.response.json.return_value = self.regr.body.to_json()
assert self.regr == self.client.update_registration(self.regr)
assert self.client.net.account is not None
assert self.client.net.post.call_count == 2
assert DIRECTORY_V2.newAccount in self.net.post.call_args_list[0][0]
self.response.json.return_value = self.regr.body.update(
contact=()).to_json()
def test_external_account_required_true(self):
self.client.directory = messages.Directory({
'meta': messages.Directory.Meta(external_account_required=True)
})
assert self.client.external_account_required()
def test_external_account_required_false(self):
self.client.directory = messages.Directory({
'meta': messages.Directory.Meta(external_account_required=False)
})
assert not self.client.external_account_required()
def test_external_account_required_default(self):
assert not self.client.external_account_required()
def test_query_registration_client(self):
self.response.json.return_value = self.regr.body.to_json()
self.response.headers['Location'] = 'https://www.letsencrypt-demo.org/acme/reg/1'
assert self.regr == self.client.query_registration(self.regr)
def test_post_as_get(self):
with mock.patch('acme.client.ClientV2._authzr_from_response') as mock_client:
mock_client.return_value = self.authzr2
self.client.poll(self.authzr2)
self.client.net.post.assert_called_once_with(
self.authzr2.uri, None,
new_nonce_url='https://www.letsencrypt-demo.org/acme/new-nonce')
self.client.net.get.assert_not_called()
def test_retry_after_date(self):
self.response.headers['Retry-After'] = 'Fri, 31 Dec 1999 23:59:59 GMT'
assert datetime.datetime(1999, 12, 31, 23, 59, 59) == \
self.client.retry_after(response=self.response, default=10)
@mock.patch('acme.client.datetime')
def test_retry_after_invalid(self, dt_mock):
dt_mock.datetime.now.return_value = datetime.datetime(2015, 3, 27)
dt_mock.timedelta = datetime.timedelta
self.response.headers['Retry-After'] = 'foooo'
assert datetime.datetime(2015, 3, 27, 0, 0, 10) == \
self.client.retry_after(response=self.response, default=10)
@mock.patch('acme.client.datetime')
def test_retry_after_overflow(self, dt_mock):
dt_mock.datetime.now.return_value = datetime.datetime(2015, 3, 27)
dt_mock.timedelta = datetime.timedelta
dt_mock.datetime.side_effect = datetime.datetime
self.response.headers['Retry-After'] = "Tue, 116 Feb 2016 11:50:00 MST"
assert datetime.datetime(2015, 3, 27, 0, 0, 10) == \
self.client.retry_after(response=self.response, default=10)
@mock.patch('acme.client.datetime')
def test_retry_after_seconds(self, dt_mock):
dt_mock.datetime.now.return_value = datetime.datetime(2015, 3, 27)
dt_mock.timedelta = datetime.timedelta
self.response.headers['Retry-After'] = '50'
assert datetime.datetime(2015, 3, 27, 0, 0, 50) == \
self.client.retry_after(response=self.response, default=10)
@mock.patch('acme.client.datetime')
def test_retry_after_missing(self, dt_mock):
dt_mock.datetime.now.return_value = datetime.datetime(2015, 3, 27)
dt_mock.timedelta = datetime.timedelta
assert datetime.datetime(2015, 3, 27, 0, 0, 10) == \
self.client.retry_after(response=self.response, default=10)
def test_get_directory(self):
self.response.json.return_value = DIRECTORY_V2.to_json()
assert DIRECTORY_V2.to_partial_json() == \
ClientV2.get_directory('https://example.com/dir', self.net).to_partial_json()
@mock.patch('acme.client.datetime')
def test_renewal_time_expired_cert(self, dt_mock):
utc_now = datetime.datetime(2026, 1, 1, tzinfo=datetime.timezone.utc)
dt_mock.datetime.now.return_value = utc_now
cert_pem = make_cert_for_renewal(
not_before=datetime.datetime(2025, 3, 12, 00, 00, 00),
not_after=datetime.datetime(2025, 3, 20, 00, 00, 00),
)
cert = x509.load_pem_x509_certificate(cert_pem)
t, _ = self.client.renewal_time(cert_pem)
assert t == cert.not_valid_after_utc
@mock.patch('acme.client.datetime')
def test_renewal_time_no_renewal_info(self, dt_mock):
utc_now = datetime.datetime(2025, 3, 15, tzinfo=datetime.timezone.utc)
dt_mock.datetime.now.return_value = utc_now
# A directory with no 'renewalInfo' should result in None.
self.client.directory = messages.Directory({})
cert_pem = make_cert_for_renewal(
not_before=datetime.datetime(2025, 3, 12, 00, 00, 00),
not_after=datetime.datetime(2025, 3, 20, 00, 00, 00),
)
t, _ = self.client.renewal_time(cert_pem)
assert t is None
cert_pem = make_cert_for_renewal(
not_before=datetime.datetime(2025, 3, 12, 00, 00, 00),
not_after=datetime.datetime(2025, 3, 30, 00, 00, 00),
)
t, _ = self.client.renewal_time(cert_pem)
assert t is None
@mock.patch('acme.client.datetime')
def test_renewal_time_with_renewal_info(self, dt_mock):
from cryptography import x509
from acme.client import _renewal_info_path_component
utc_now = datetime.datetime(2025, 3, 15, tzinfo=datetime.timezone.utc)
dt_mock.datetime.now.return_value = utc_now
dt_mock.timedelta = datetime.timedelta
cert_pem = make_cert_for_renewal(
not_before=datetime.datetime(2025, 3, 12, 00, 00, 00),
not_after=datetime.datetime(2025, 3, 20, 00, 00, 00),
)
self.client.directory = messages.Directory({
'renewalInfo': 'https://www.letsencrypt-demo.org/acme/renewal-info',
})
self.response.json.return_value = {
"suggestedWindow": {
"start": "2025-03-14T01:01:01Z",
"end": "2025-03-14T01:01:01Z",
},
"message": "Keep those certs fresh"
}
t, _ = self.client.renewal_time(cert_pem)
cert_parsed = x509.load_pem_x509_certificate(cert_pem)
ari_path_component = _renewal_info_path_component(cert_parsed)
self.net.get.assert_called_once_with("https://www.letsencrypt-demo.org/acme/renewal-info/" +
ari_path_component,
content_type='application/json')
assert t == datetime.datetime(2025, 3, 14, 1, 1, 1, tzinfo=datetime.timezone.utc)
self.net.reset_mock()
self.response.json.return_value = {
"suggestedWindow": {
"start": "2025-03-16T01:01:01Z",
"end": "2025-03-17T01:01:01Z",
},
"message": "Keep those certs fresh"
}
t, _ = self.client.renewal_time(cert_pem)
self.net.get.assert_called_once_with("https://www.letsencrypt-demo.org/acme/renewal-info/" +
ari_path_component,
content_type='application/json')
assert t >= datetime.datetime(2025, 3, 16, 1, 1, 1, tzinfo=datetime.timezone.utc)
assert t <= datetime.datetime(2025, 3, 17, 1, 1, 1, tzinfo=datetime.timezone.utc)
@mock.patch('acme.client.datetime')
def test_renewal_time_renewal_info_errors(self, dt_mock):
def now(tzinfo=None):
return datetime.datetime(2025, 3, 15, tzinfo=tzinfo)
dt_mock.datetime.now.side_effect = now
dt_mock.timedelta = datetime.timedelta
dt_mock.timezone = datetime.timezone
self.client.directory = messages.Directory({
'renewalInfo': 'https://www.letsencrypt-demo.org/acme/renewal-info',
})
# Failure to fetch the 'renewalInfo' URL should raise an ARIError with the exception raised
# by self.net.get as the __cause__ and a Retry-After 6 hours in the future
expected_cause = requests.exceptions.RequestException
expected_retry_after = now() + datetime.timedelta(seconds=6 * 60 * 60)
self.net.get.side_effect = expected_cause
cert_pem = make_cert_for_renewal(
not_before=datetime.datetime(2025, 3, 12, 00, 00, 00),
not_after=datetime.datetime(2025, 3, 20, 00, 00, 00),
)
with pytest.raises(errors.ARIError) as exception_info:
self.client.renewal_time(cert_pem)
assert isinstance(exception_info.value.__cause__, expected_cause)
assert exception_info.value.retry_after == expected_retry_after
cert_pem = make_cert_for_renewal(
not_before=datetime.datetime(2025, 3, 12, 00, 00, 00),
not_after=datetime.datetime(2025, 3, 30, 00, 00, 00),
)
with pytest.raises(errors.ARIError) as exception_info:
self.client.renewal_time(cert_pem)
assert isinstance(exception_info.value.__cause__, expected_cause)
assert exception_info.value.retry_after == expected_retry_after
@mock.patch('acme.client.datetime')
def test_renewal_time_returns_retry_after(self, dt_mock):
def now(tzinfo=None):
return datetime.datetime(2025, 3, 15, tzinfo=tzinfo)
dt_mock.datetime.now.side_effect = now
dt_mock.timedelta = datetime.timedelta
dt_mock.timezone = datetime.timezone
self.client.directory = messages.Directory({
'renewalInfo': 'https://www.letsencrypt-demo.org/acme/renewal-info',
})
cert_pem = make_cert_for_renewal(
not_before=datetime.datetime(2025, 3, 12, 00, 00, 00),
not_after=datetime.datetime(2025, 3, 20, 00, 00, 00),
)
self.response.json.return_value = {
"suggestedWindow": {
"start": "2025-03-14T01:01:01Z",
"end": "2025-03-14T01:01:01Z",
},
"message": "Keep those certs fresh"
}
# With no explicit Retry-After in header, default to six hours
_, retry_after = self.client.renewal_time(cert_pem)
assert retry_after == datetime.datetime(2025, 3, 15, 6, 0, 0)
# With an explicit Retry-After in header, use that
self.response.headers['Retry-After'] = '100'
_, retry_after = self.client.renewal_time(cert_pem)
assert retry_after == datetime.datetime(2025, 3, 15, 00, 1, 40)
def test_renewal_info_path_component():
from cryptography import x509
from acme.client import _renewal_info_path_component
cert = x509.load_pem_x509_certificate(test_util.load_vector('rsa2048_cert.pem'))
assert _renewal_info_path_component(cert) == "fL5sRirC8VS5AtOQh9DfoAzYNCI.ALVG_VbBb5U7"
# From https://www.ietf.org/archive/id/draft-ietf-acme-ari-08.html appendix A.
ARI_TEST_CERT = b"""
-----BEGIN CERTIFICATE-----
MIIBQzCB66ADAgECAgUAh2VDITAKBggqhkjOPQQDAjAVMRMwEQYDVQQDEwpFeGFt
cGxlIENBMCIYDzAwMDEwMTAxMDAwMDAwWhgPMDAwMTAxMDEwMDAwMDBaMBYxFDAS
BgNVBAMTC2V4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEeBZu
7cbpAYNXZLbbh8rNIzuOoqOOtmxA1v7cRm//AwyMwWxyHz4zfwmBhcSrf47NUAFf
qzLQ2PPQxdTXREYEnKMjMCEwHwYDVR0jBBgwFoAUaYhba4dGQEHhs3uEe6CuLN4B
yNQwCgYIKoZIzj0EAwIDRwAwRAIge09+S5TZAlw5tgtiVvuERV6cT4mfutXIlwTb
+FYN/8oCIClDsqBklhB9KAelFiYt9+6FDj3z4KGVelYM5MdsO3pK
-----END CERTIFICATE-----
"""
cert = x509.load_pem_x509_certificate(ARI_TEST_CERT)
assert _renewal_info_path_component(cert) == "aYhba4dGQEHhs3uEe6CuLN4ByNQ.AIdlQyE"
if __name__ == '__main__':
sys.exit(pytest.main(sys.argv[1:] + [__file__])) # pragma: no cover
def make_cert_for_renewal(not_before, not_after) -> bytes:
"""
Return a PEM-encoded, self-signed certificate with the given dates.
"""
from cryptography import x509
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives import serialization, hashes
# AKID and serial are the inputs to constructing the renewalInfo URL
akid = x509.AuthorityKeyIdentifier(b"1234", None, None)
serial = 56789
key = ec.generate_private_key(ec.SECP256R1())
cert = x509.CertificateBuilder(
issuer_name=x509.Name([x509.NameAttribute(x509.oid.NameOID.COMMON_NAME, "Some Issuer")]),
subject_name=x509.Name([]),
public_key=key.public_key(),
serial_number=serial,
not_valid_before=not_before,
not_valid_after=not_after,
).add_extension(
x509.SubjectAlternativeName([x509.DNSName('example.com')]),
critical=False,
).add_extension(
akid,
critical=False,
).sign(
private_key=key,
algorithm=hashes.SHA256(),
)
return cert.public_bytes(serialization.Encoding.PEM)
class MockJSONDeSerializable(jose.JSONDeSerializable):
# pylint: disable=missing-docstring
def __init__(self, value):
self.value = value
def to_partial_json(self):
return {'foo': self.value}
@classmethod
def from_json(cls, jobj):
pass # pragma: no cover
class ClientNetworkTest(unittest.TestCase):
"""Tests for acme.client.ClientNetwork."""
def setUp(self):
self.verify_ssl = mock.MagicMock()
self.wrap_in_jws = mock.MagicMock(return_value=mock.sentinel.wrapped)
self.net = ClientNetwork(
key=KEY, alg=jose.RS256, verify_ssl=self.verify_ssl,
user_agent='acme-python-test')
self.response = mock.MagicMock(ok=True, status_code=http_client.OK)
self.response.headers = {}
self.response.links = {}
def test_init(self):
assert self.net.verify_ssl is self.verify_ssl
def test_wrap_in_jws(self):
# pylint: disable=protected-access
jws_dump = self.net._wrap_in_jws(
MockJSONDeSerializable('foo'), nonce=b'Tg', url="url")
jws = acme_jws.JWS.json_loads(jws_dump)
assert json.loads(jws.payload.decode()) == {'foo': 'foo'}
assert jws.signature.combined.nonce == b'Tg'
def test_wrap_in_jws_v2(self):
self.net.account = {'uri': 'acct-uri'}
# pylint: disable=protected-access
jws_dump = self.net._wrap_in_jws(
MockJSONDeSerializable('foo'), nonce=b'Tg', url="url")
jws = acme_jws.JWS.json_loads(jws_dump)
assert json.loads(jws.payload.decode()) == {'foo': 'foo'}
assert jws.signature.combined.nonce == b'Tg'
assert jws.signature.combined.kid == u'acct-uri'
assert jws.signature.combined.url == u'url'
def test_check_response_not_ok_jobj_no_error(self):
self.response.ok = False
self.response.json.return_value = {}
with mock.patch('acme.client.messages.Error.from_json') as from_json:
from_json.side_effect = jose.DeserializationError
# pylint: disable=protected-access
with pytest.raises(errors.ClientError):
self.net._check_response(self.response)
def test_check_response_not_ok_jobj_error(self):
self.response.ok = False
self.response.json.return_value = messages.Error.with_code(
'serverInternal', detail='foo', title='some title').to_json()
# pylint: disable=protected-access
with pytest.raises(messages.Error):
self.net._check_response(self.response)
def test_check_response_not_ok_no_jobj(self):
self.response.ok = False
self.response.json.side_effect = ValueError
# pylint: disable=protected-access
with pytest.raises(errors.ClientError):
self.net._check_response(self.response)
def test_check_response_ok_no_jobj_ct_required(self):
self.response.json.side_effect = ValueError
for response_ct in [self.net.JSON_CONTENT_TYPE, 'foo']:
self.response.headers['Content-Type'] = response_ct
# pylint: disable=protected-access
with pytest.raises(errors.ClientError):
self.net._check_response(self.response,
content_type=self.net.JSON_CONTENT_TYPE)
def test_check_response_ok_no_jobj_no_ct(self):
self.response.json.side_effect = ValueError
for response_ct in [self.net.JSON_CONTENT_TYPE, 'foo']:
self.response.headers['Content-Type'] = response_ct
# pylint: disable=protected-access
assert self.response == self.net._check_response(self.response)
@mock.patch('acme.client.logger')
def test_check_response_ok_ct_with_charset(self, mock_logger):
self.response.json.return_value = {}
self.response.headers['Content-Type'] = 'application/json; charset=utf-8'
# pylint: disable=protected-access
assert self.response == self.
gitextract_6brtvsg5/ ├── .azure-pipelines/ │ ├── INSTALL.md │ ├── advanced-test.yml │ ├── main.yml │ ├── nightly.yml │ ├── release.yml │ └── templates/ │ ├── jobs/ │ │ ├── common-deploy-jobs.yml │ │ ├── extended-tests-jobs.yml │ │ ├── packaging-jobs.yml │ │ └── standard-tests-jobs.yml │ ├── stages/ │ │ ├── changelog-stage.yml │ │ ├── nightly-deploy-stage.yml │ │ ├── release-deploy-stage.yml │ │ └── test-and-package-stage.yml │ └── steps/ │ ├── sphinx-steps.yml │ └── tox-steps.yml ├── .coveragerc ├── .dockerignore ├── .editorconfig ├── .gitattributes ├── .github/ │ ├── CODEOWNERS │ ├── FUNDING.yml │ ├── ISSUE_TEMPLATE/ │ │ ├── bug.yaml │ │ ├── config.yml │ │ ├── feature.yaml │ │ └── task.yaml │ ├── codecov.yml │ ├── pull_request_template.md │ └── workflows/ │ ├── assigned.yaml │ ├── merged.yaml │ ├── notify_weekly.yaml │ ├── review_requested.yaml │ └── stale.yml ├── .gitignore ├── .isort.cfg ├── .pylintrc ├── AUTHORS.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE.txt ├── SECURITY.md ├── acme/ │ ├── .readthedocs.yaml │ ├── LICENSE.txt │ ├── MANIFEST.in │ ├── README.rst │ ├── docs/ │ │ ├── .gitignore │ │ ├── Makefile │ │ ├── _static/ │ │ │ └── .gitignore │ │ ├── _templates/ │ │ │ └── .gitignore │ │ ├── api/ │ │ │ ├── challenges.rst │ │ │ ├── client.rst │ │ │ ├── crypto_util.rst │ │ │ ├── errors.rst │ │ │ ├── fields.rst │ │ │ ├── jose.rst │ │ │ ├── jws.rst │ │ │ ├── messages.rst │ │ │ ├── standalone.rst │ │ │ └── util.rst │ │ ├── api.rst │ │ ├── conf.py │ │ ├── index.rst │ │ ├── jws-help.txt │ │ ├── make.bat │ │ └── man/ │ │ └── jws.rst │ ├── examples/ │ │ └── http01_example.py │ ├── pyproject.toml │ ├── readthedocs.org.requirements.txt │ ├── setup.py │ └── src/ │ └── acme/ │ ├── __init__.py │ ├── _internal/ │ │ ├── __init__.py │ │ └── tests/ │ │ ├── __init__.py │ │ ├── challenges_test.py │ │ ├── client_test.py │ │ ├── conftest.py │ │ ├── crypto_util_test.py │ │ ├── errors_test.py │ │ ├── fields_test.py │ │ ├── jose_test.py │ │ ├── jws_test.py │ │ ├── messages_test.py │ │ ├── standalone_test.py │ │ ├── test_util.py │ │ ├── testdata/ │ │ │ ├── README │ │ │ ├── cert-100sans.pem │ │ │ ├── cert-idnsans.pem │ │ │ ├── cert-ipsans.pem │ │ │ ├── cert-ipv6sans.pem │ │ │ ├── cert-nocn.der │ │ │ ├── cert-san.pem │ │ │ ├── cert.der │ │ │ ├── cert.pem │ │ │ ├── critical-san.pem │ │ │ ├── csr-100sans.pem │ │ │ ├── csr-6sans.pem │ │ │ ├── csr-idnsans.pem │ │ │ ├── csr-ipsans.pem │ │ │ ├── csr-ipv6sans.pem │ │ │ ├── csr-mixed.pem │ │ │ ├── csr-nosans.pem │ │ │ ├── csr-san.pem │ │ │ ├── csr.der │ │ │ ├── csr.pem │ │ │ ├── dsa512_key.pem │ │ │ ├── ec_secp384r1_key.pem │ │ │ ├── rsa1024_cert.pem │ │ │ ├── rsa1024_key.pem │ │ │ ├── rsa2048_cert.pem │ │ │ ├── rsa2048_key.pem │ │ │ ├── rsa256_key.pem │ │ │ ├── rsa4096_cert.pem │ │ │ ├── rsa4096_key.pem │ │ │ └── rsa512_key.pem │ │ └── util_test.py │ ├── challenges.py │ ├── client.py │ ├── crypto_util.py │ ├── errors.py │ ├── fields.py │ ├── jws.py │ ├── messages.py │ ├── py.typed │ ├── standalone.py │ └── util.py ├── certbot/ │ ├── .readthedocs.yaml │ ├── CHANGELOG.md │ ├── LICENSE.txt │ ├── MANIFEST.in │ ├── README.rst │ ├── docs/ │ │ ├── .gitignore │ │ ├── Makefile │ │ ├── _static/ │ │ │ └── .gitignore │ │ ├── _templates/ │ │ │ └── footer.html │ │ ├── api/ │ │ │ ├── certbot.achallenges.rst │ │ │ ├── certbot.compat.filesystem.rst │ │ │ ├── certbot.compat.misc.rst │ │ │ ├── certbot.compat.os.rst │ │ │ ├── certbot.compat.rst │ │ │ ├── certbot.crypto_util.rst │ │ │ ├── certbot.display.ops.rst │ │ │ ├── certbot.display.rst │ │ │ ├── certbot.display.util.rst │ │ │ ├── certbot.errors.rst │ │ │ ├── certbot.interfaces.rst │ │ │ ├── certbot.main.rst │ │ │ ├── certbot.plugins.common.rst │ │ │ ├── certbot.plugins.dns_common.rst │ │ │ ├── certbot.plugins.dns_common_lexicon.rst │ │ │ ├── certbot.plugins.dns_test_common.rst │ │ │ ├── certbot.plugins.dns_test_common_lexicon.rst │ │ │ ├── certbot.plugins.enhancements.rst │ │ │ ├── certbot.plugins.rst │ │ │ ├── certbot.plugins.storage.rst │ │ │ ├── certbot.plugins.util.rst │ │ │ ├── certbot.reverter.rst │ │ │ ├── certbot.rst │ │ │ ├── certbot.tests.acme_util.rst │ │ │ ├── certbot.tests.rst │ │ │ ├── certbot.tests.util.rst │ │ │ └── certbot.util.rst │ │ ├── api.rst │ │ ├── challenges.rst │ │ ├── ciphers.rst │ │ ├── cli-help.txt │ │ ├── compatibility.rst │ │ ├── conf.py │ │ ├── contributing.rst │ │ ├── index.rst │ │ ├── install.rst │ │ ├── intro.rst │ │ ├── make.bat │ │ ├── man/ │ │ │ └── certbot.rst │ │ ├── packaging.rst │ │ ├── resources.rst │ │ ├── using.rst │ │ └── what.rst │ ├── examples/ │ │ ├── .gitignore │ │ ├── cli.ini │ │ ├── dev-cli.ini │ │ ├── generate-csr.sh │ │ ├── openssl.cnf │ │ └── plugins/ │ │ ├── certbot_example_plugins.py │ │ └── setup.py │ ├── pyproject.toml │ ├── readthedocs.org.requirements.txt │ ├── setup.py │ └── src/ │ └── certbot/ │ ├── __init__.py │ ├── _internal/ │ │ ├── __init__.py │ │ ├── account.py │ │ ├── auth_handler.py │ │ ├── cert_manager.py │ │ ├── cli/ │ │ │ ├── __init__.py │ │ │ ├── cli_constants.py │ │ │ ├── cli_utils.py │ │ │ ├── group_adder.py │ │ │ ├── helpful.py │ │ │ ├── paths_parser.py │ │ │ ├── plugins_parsing.py │ │ │ ├── subparsers.py │ │ │ └── verb_help.py │ │ ├── client.py │ │ ├── constants.py │ │ ├── display/ │ │ │ ├── __init__.py │ │ │ ├── completer.py │ │ │ ├── dummy_readline.py │ │ │ ├── obj.py │ │ │ └── util.py │ │ ├── eff.py │ │ ├── error_handler.py │ │ ├── hooks.py │ │ ├── lock.py │ │ ├── log.py │ │ ├── main.py │ │ ├── ocsp.py │ │ ├── plugins/ │ │ │ ├── __init__.py │ │ │ ├── disco.py │ │ │ ├── manual.py │ │ │ ├── null.py │ │ │ ├── selection.py │ │ │ ├── standalone.py │ │ │ └── webroot.py │ │ ├── renewal.py │ │ ├── san.py │ │ ├── snap_config.py │ │ ├── storage.py │ │ ├── tests/ │ │ │ ├── __init__.py │ │ │ ├── account_test.py │ │ │ ├── auth_handler_test.py │ │ │ ├── cert_manager_test.py │ │ │ ├── cli_test.py │ │ │ ├── client_test.py │ │ │ ├── compat/ │ │ │ │ ├── __init__.py │ │ │ │ ├── filesystem_test.py │ │ │ │ ├── misc_test.py │ │ │ │ └── os_test.py │ │ │ ├── configuration_test.py │ │ │ ├── conftest.py │ │ │ ├── crypto_util_test.py │ │ │ ├── display/ │ │ │ │ ├── __init__.py │ │ │ │ ├── completer_test.py │ │ │ │ ├── internal_util_test.py │ │ │ │ ├── obj_test.py │ │ │ │ ├── ops_test.py │ │ │ │ └── util_test.py │ │ │ ├── eff_test.py │ │ │ ├── error_handler_test.py │ │ │ ├── errors_test.py │ │ │ ├── helpful_test.py │ │ │ ├── hook_test.py │ │ │ ├── lock_test.py │ │ │ ├── log_test.py │ │ │ ├── main_test.py │ │ │ ├── ocsp_test.py │ │ │ ├── plugins/ │ │ │ │ ├── __init__.py │ │ │ │ ├── common_test.py │ │ │ │ ├── disco_test.py │ │ │ │ ├── dns_common_test.py │ │ │ │ ├── enhancements_test.py │ │ │ │ ├── manual_test.py │ │ │ │ ├── null_test.py │ │ │ │ ├── selection_test.py │ │ │ │ ├── standalone_test.py │ │ │ │ ├── storage_test.py │ │ │ │ ├── util_test.py │ │ │ │ └── webroot_test.py │ │ │ ├── renewal_test.py │ │ │ ├── renewupdater_test.py │ │ │ ├── reverter_test.py │ │ │ ├── san_test.py │ │ │ ├── storage_test.py │ │ │ └── util_test.py │ │ └── updater.py │ ├── achallenges.py │ ├── compat/ │ │ ├── __init__.py │ │ ├── _path.py │ │ ├── filesystem.py │ │ ├── misc.py │ │ └── os.py │ ├── configuration.py │ ├── crypto_util.py │ ├── display/ │ │ ├── __init__.py │ │ ├── ops.py │ │ └── util.py │ ├── errors.py │ ├── interfaces.py │ ├── main.py │ ├── ocsp.py │ ├── plugins/ │ │ ├── __init__.py │ │ ├── common.py │ │ ├── dns_common.py │ │ ├── dns_common_lexicon.py │ │ ├── dns_test_common.py │ │ ├── dns_test_common_lexicon.py │ │ ├── enhancements.py │ │ ├── storage.py │ │ └── util.py │ ├── py.typed │ ├── reverter.py │ ├── ssl-dhparams.pem │ ├── tests/ │ │ ├── __init__.py │ │ ├── acme_util.py │ │ ├── testdata/ │ │ │ ├── README │ │ │ ├── cert-5sans_512.pem │ │ │ ├── cert-nosans_nistp256.pem │ │ │ ├── cert-san_512.pem │ │ │ ├── cert_2048.pem │ │ │ ├── cert_512.pem │ │ │ ├── cert_512_bad.pem │ │ │ ├── cert_fullchain_2048.pem │ │ │ ├── cert_intermediate_1.pem │ │ │ ├── cert_intermediate_2.pem │ │ │ ├── cert_leaf.pem │ │ │ ├── cli.ini │ │ │ ├── csr-6sans_512.conf │ │ │ ├── csr-6sans_512.pem │ │ │ ├── csr-nonames_512.pem │ │ │ ├── csr-nosans_512.conf │ │ │ ├── csr-nosans_512.pem │ │ │ ├── csr-nosans_nistp256.pem │ │ │ ├── csr-san_512.pem │ │ │ ├── csr_512.der │ │ │ ├── csr_512.pem │ │ │ ├── ec_prime256v1_key.pem │ │ │ ├── ec_secp384r1_key.pem │ │ │ ├── ec_secp521r1_key.pem │ │ │ ├── nistp256_key.pem │ │ │ ├── ocsp_certificate.pem │ │ │ ├── ocsp_issuer_certificate.pem │ │ │ ├── ocsp_responder_certificate.pem │ │ │ ├── os-release │ │ │ ├── rsa2048_key.pem │ │ │ ├── rsa512_key.pem │ │ │ ├── sample-archive/ │ │ │ │ ├── cert1.pem │ │ │ │ ├── chain1.pem │ │ │ │ ├── fullchain1.pem │ │ │ │ └── privkey1.pem │ │ │ ├── sample-archive-ec/ │ │ │ │ ├── cert1.pem │ │ │ │ ├── chain1.pem │ │ │ │ ├── fullchain1.pem │ │ │ │ └── privkey1.pem │ │ │ ├── sample-renewal-ancient.conf │ │ │ ├── sample-renewal-deprecated-option.conf │ │ │ ├── sample-renewal-ec.conf │ │ │ ├── sample-renewal.conf │ │ │ └── webrootconftest.ini │ │ └── util.py │ └── util.py ├── certbot-apache/ │ ├── LICENSE.txt │ ├── MANIFEST.in │ ├── README.rst │ ├── pyproject.toml │ ├── setup.py │ └── src/ │ └── certbot_apache/ │ ├── __init__.py │ ├── _internal/ │ │ ├── __init__.py │ │ ├── apache_util.py │ │ ├── apacheparser.py │ │ ├── assertions.py │ │ ├── augeas_lens/ │ │ │ ├── README │ │ │ └── httpd.aug │ │ ├── augeasparser.py │ │ ├── configurator.py │ │ ├── constants.py │ │ ├── display_ops.py │ │ ├── dualparser.py │ │ ├── entrypoint.py │ │ ├── http_01.py │ │ ├── interfaces.py │ │ ├── obj.py │ │ ├── override_alpine.py │ │ ├── override_arch.py │ │ ├── override_centos.py │ │ ├── override_darwin.py │ │ ├── override_debian.py │ │ ├── override_fedora.py │ │ ├── override_gentoo.py │ │ ├── override_suse.py │ │ ├── override_void.py │ │ ├── parser.py │ │ ├── parsernode_util.py │ │ ├── tests/ │ │ │ ├── __init__.py │ │ │ ├── apache-conf-files/ │ │ │ │ ├── NEEDED.txt │ │ │ │ ├── apache-conf-test │ │ │ │ ├── apache-conf-test-pebble.py │ │ │ │ ├── failing/ │ │ │ │ │ ├── missing-double-quote-1724.conf │ │ │ │ │ ├── multivhost-1093.conf │ │ │ │ │ └── multivhost-1093b.conf │ │ │ │ └── passing/ │ │ │ │ ├── 1626-1531.conf │ │ │ │ ├── README.modules │ │ │ │ ├── anarcat-1531.conf │ │ │ │ ├── comment-continuations-2050.conf │ │ │ │ ├── drupal-errordocument-arg-1724.conf │ │ │ │ ├── drupal-htaccess-1531.conf │ │ │ │ ├── escaped-space-arguments-2735.conf │ │ │ │ ├── example-1755.conf │ │ │ │ ├── example-ssl.conf │ │ │ │ ├── example.conf │ │ │ │ ├── finalize-1243.apache2.conf.txt │ │ │ │ ├── finalize-1243.conf │ │ │ │ ├── graphite-quote-1934.conf │ │ │ │ ├── ipv6-1143.conf │ │ │ │ ├── ipv6-1143b.conf │ │ │ │ ├── ipv6-1143c.conf │ │ │ │ ├── ipv6-1143d.conf │ │ │ │ ├── missing-quote-1724.conf │ │ │ │ ├── modmacro-1385.conf │ │ │ │ ├── owncloud-1264.conf │ │ │ │ ├── rewrite-quote-1960.conf │ │ │ │ ├── roundcube-1222.conf │ │ │ │ ├── section-continuations-2525.conf │ │ │ │ ├── section-empty-continuations-2731.conf │ │ │ │ ├── semacode-1598.conf │ │ │ │ ├── sslrequire-wordlist-1827.htaccess │ │ │ │ └── two-blocks-one-line-1693.conf │ │ │ ├── augeasnode_test.py │ │ │ ├── autohsts_test.py │ │ │ ├── centos_test.py │ │ │ ├── complex_parsing_test.py │ │ │ ├── configurator_reverter_test.py │ │ │ ├── configurator_test.py │ │ │ ├── conftest.py │ │ │ ├── debian_test.py │ │ │ ├── display_ops_test.py │ │ │ ├── dualnode_test.py │ │ │ ├── entrypoint_test.py │ │ │ ├── fedora_test.py │ │ │ ├── gentoo_test.py │ │ │ ├── http_01_test.py │ │ │ ├── obj_test.py │ │ │ ├── parser_test.py │ │ │ ├── parsernode_configurator_test.py │ │ │ ├── parsernode_test.py │ │ │ ├── parsernode_util_test.py │ │ │ ├── testdata/ │ │ │ │ ├── centos7_apache/ │ │ │ │ │ └── apache/ │ │ │ │ │ ├── httpd/ │ │ │ │ │ │ ├── conf/ │ │ │ │ │ │ │ ├── httpd.conf │ │ │ │ │ │ │ └── magic │ │ │ │ │ │ ├── conf.d/ │ │ │ │ │ │ │ ├── README │ │ │ │ │ │ │ ├── autoindex.conf │ │ │ │ │ │ │ ├── centos.example.com.conf │ │ │ │ │ │ │ ├── ssl.conf │ │ │ │ │ │ │ ├── userdir.conf │ │ │ │ │ │ │ └── welcome.conf │ │ │ │ │ │ └── conf.modules.d/ │ │ │ │ │ │ ├── 00-base.conf │ │ │ │ │ │ ├── 00-dav.conf │ │ │ │ │ │ ├── 00-lua.conf │ │ │ │ │ │ ├── 00-mpm.conf │ │ │ │ │ │ ├── 00-proxy.conf │ │ │ │ │ │ ├── 00-ssl.conf │ │ │ │ │ │ ├── 00-systemd.conf │ │ │ │ │ │ └── 01-cgi.conf │ │ │ │ │ ├── sites │ │ │ │ │ └── sysconfig/ │ │ │ │ │ └── httpd │ │ │ │ ├── complex_parsing/ │ │ │ │ │ ├── apache2.conf │ │ │ │ │ ├── conf-enabled/ │ │ │ │ │ │ └── dummy.conf │ │ │ │ │ ├── test_fnmatch.conf │ │ │ │ │ └── test_variables.conf │ │ │ │ ├── debian_apache_2_4/ │ │ │ │ │ ├── augeas_vhosts/ │ │ │ │ │ │ ├── apache2/ │ │ │ │ │ │ │ ├── apache2.conf │ │ │ │ │ │ │ ├── conf-available/ │ │ │ │ │ │ │ │ ├── bad_conf_file.conf │ │ │ │ │ │ │ │ ├── other-vhosts-access-log.conf │ │ │ │ │ │ │ │ ├── security.conf │ │ │ │ │ │ │ │ └── serve-cgi-bin.conf │ │ │ │ │ │ │ ├── envvars │ │ │ │ │ │ │ ├── mods-available/ │ │ │ │ │ │ │ │ ├── authz_svn.load │ │ │ │ │ │ │ │ ├── dav.load │ │ │ │ │ │ │ │ ├── dav_svn.conf │ │ │ │ │ │ │ │ ├── dav_svn.load │ │ │ │ │ │ │ │ ├── rewrite.load │ │ │ │ │ │ │ │ ├── ssl.conf │ │ │ │ │ │ │ │ └── ssl.load │ │ │ │ │ │ │ ├── ports.conf │ │ │ │ │ │ │ └── sites-available/ │ │ │ │ │ │ │ ├── another_wildcard.conf │ │ │ │ │ │ │ ├── old-and-default.conf │ │ │ │ │ │ │ └── wildcard.conf │ │ │ │ │ │ └── sites │ │ │ │ │ ├── default_vhost/ │ │ │ │ │ │ ├── apache2/ │ │ │ │ │ │ │ ├── apache2.conf │ │ │ │ │ │ │ ├── conf-available/ │ │ │ │ │ │ │ │ ├── other-vhosts-access-log.conf │ │ │ │ │ │ │ │ ├── security.conf │ │ │ │ │ │ │ │ └── serve-cgi-bin.conf │ │ │ │ │ │ │ ├── envvars │ │ │ │ │ │ │ ├── mods-available/ │ │ │ │ │ │ │ │ ├── ssl.conf │ │ │ │ │ │ │ │ └── ssl.load │ │ │ │ │ │ │ ├── ports.conf │ │ │ │ │ │ │ └── sites-available/ │ │ │ │ │ │ │ ├── 000-default.conf │ │ │ │ │ │ │ └── default-ssl.conf │ │ │ │ │ │ └── sites │ │ │ │ │ ├── multi_vhosts/ │ │ │ │ │ │ └── apache2/ │ │ │ │ │ │ ├── apache2.conf │ │ │ │ │ │ ├── envvars │ │ │ │ │ │ ├── ports.conf │ │ │ │ │ │ └── sites-available/ │ │ │ │ │ │ ├── default.conf │ │ │ │ │ │ └── multi-vhost.conf │ │ │ │ │ └── multiple_vhosts/ │ │ │ │ │ ├── apache2/ │ │ │ │ │ │ ├── apache2.conf │ │ │ │ │ │ ├── conf-available/ │ │ │ │ │ │ │ ├── bad_conf_file.conf │ │ │ │ │ │ │ ├── other-vhosts-access-log.conf │ │ │ │ │ │ │ ├── security.conf │ │ │ │ │ │ │ └── serve-cgi-bin.conf │ │ │ │ │ │ ├── envvars │ │ │ │ │ │ ├── mods-available/ │ │ │ │ │ │ │ ├── authz_svn.load │ │ │ │ │ │ │ ├── dav.load │ │ │ │ │ │ │ ├── dav_svn.conf │ │ │ │ │ │ │ ├── dav_svn.load │ │ │ │ │ │ │ ├── rewrite.load │ │ │ │ │ │ │ ├── ssl.conf │ │ │ │ │ │ │ └── ssl.load │ │ │ │ │ │ ├── ports.conf │ │ │ │ │ │ ├── sites-available/ │ │ │ │ │ │ │ ├── 000-default.conf │ │ │ │ │ │ │ ├── certbot.conf │ │ │ │ │ │ │ ├── default-ssl-port-only.conf │ │ │ │ │ │ │ ├── default-ssl.conf │ │ │ │ │ │ │ ├── duplicatehttp.conf │ │ │ │ │ │ │ ├── duplicatehttps.conf │ │ │ │ │ │ │ ├── empty.conf │ │ │ │ │ │ │ ├── encryption-example.conf │ │ │ │ │ │ │ ├── mod_macro-example.conf │ │ │ │ │ │ │ ├── no-directives.conf │ │ │ │ │ │ │ ├── ocsp-ssl.conf │ │ │ │ │ │ │ └── wildcard.conf │ │ │ │ │ │ └── sites-enabled/ │ │ │ │ │ │ └── non-symlink.conf │ │ │ │ │ └── sites │ │ │ │ └── gentoo_apache/ │ │ │ │ └── apache/ │ │ │ │ ├── apache2/ │ │ │ │ │ ├── httpd.conf │ │ │ │ │ ├── magic │ │ │ │ │ ├── modules.d/ │ │ │ │ │ │ ├── 00_default_settings.conf │ │ │ │ │ │ ├── 00_error_documents.conf │ │ │ │ │ │ ├── 00_languages.conf │ │ │ │ │ │ ├── 00_mod_autoindex.conf │ │ │ │ │ │ ├── 00_mod_info.conf │ │ │ │ │ │ ├── 00_mod_log_config.conf │ │ │ │ │ │ ├── 00_mod_mime.conf │ │ │ │ │ │ ├── 00_mod_status.conf │ │ │ │ │ │ ├── 00_mod_userdir.conf │ │ │ │ │ │ ├── 00_mpm.conf │ │ │ │ │ │ ├── 10_mod_mem_cache.conf │ │ │ │ │ │ ├── 40_mod_ssl.conf │ │ │ │ │ │ ├── 41_mod_http2.conf │ │ │ │ │ │ ├── 45_mod_dav.conf │ │ │ │ │ │ └── 46_mod_ldap.conf │ │ │ │ │ └── vhosts.d/ │ │ │ │ │ ├── 00_default_ssl_vhost.conf │ │ │ │ │ ├── 00_default_vhost.conf │ │ │ │ │ ├── default_vhost.include │ │ │ │ │ └── gentoo.example.com.conf │ │ │ │ ├── conf.d/ │ │ │ │ │ └── apache2 │ │ │ │ └── sites │ │ │ └── util.py │ │ └── tls_configs/ │ │ ├── current-options-ssl-apache.conf │ │ └── old-options-ssl-apache.conf │ └── py.typed ├── certbot-ci/ │ ├── MANIFEST.in │ ├── pyproject.toml │ ├── setup.py │ └── src/ │ ├── certbot_integration_tests/ │ │ ├── .coveragerc │ │ ├── __init__.py │ │ ├── assets/ │ │ │ ├── bind-config/ │ │ │ │ ├── conf/ │ │ │ │ │ └── named.conf │ │ │ │ ├── rfc2136-credentials-default.ini.tpl │ │ │ │ └── zones/ │ │ │ │ ├── db.example.com │ │ │ │ ├── db.sub.example.com │ │ │ │ └── rpz.mock-recursion │ │ │ ├── cert.pem │ │ │ ├── hook.py │ │ │ ├── key.pem │ │ │ └── sample-config/ │ │ │ ├── accounts/ │ │ │ │ └── acme-staging.api.letsencrypt.org/ │ │ │ │ └── directory/ │ │ │ │ └── 48d6b9e8d767eccf7e4d877d6ffa81e3/ │ │ │ │ ├── meta.json │ │ │ │ ├── private_key.json │ │ │ │ └── regr.json │ │ │ ├── archive/ │ │ │ │ ├── a.encryption-example.com/ │ │ │ │ │ ├── cert1.pem │ │ │ │ │ ├── chain1.pem │ │ │ │ │ ├── fullchain1.pem │ │ │ │ │ └── privkey1.pem │ │ │ │ ├── b.encryption-example.com/ │ │ │ │ │ ├── cert1.pem │ │ │ │ │ ├── chain1.pem │ │ │ │ │ ├── fullchain1.pem │ │ │ │ │ └── privkey1.pem │ │ │ │ └── c.encryption-example.com/ │ │ │ │ ├── README │ │ │ │ ├── cert.pem │ │ │ │ ├── chain.pem │ │ │ │ ├── fullchain.pem │ │ │ │ └── privkey.pem │ │ │ ├── csr/ │ │ │ │ ├── 0000_csr-certbot.pem │ │ │ │ ├── 0001_csr-certbot.pem │ │ │ │ ├── 0002_csr-certbot.pem │ │ │ │ └── 0003_csr-certbot.pem │ │ │ ├── keys/ │ │ │ │ ├── 0000_key-certbot.pem │ │ │ │ ├── 0001_key-certbot.pem │ │ │ │ ├── 0002_key-certbot.pem │ │ │ │ └── 0003_key-certbot.pem │ │ │ ├── live/ │ │ │ │ ├── a.encryption-example.com/ │ │ │ │ │ └── README │ │ │ │ ├── b.encryption-example.com/ │ │ │ │ │ └── README │ │ │ │ └── c.encryption-example.com/ │ │ │ │ └── README │ │ │ ├── options-ssl-apache.conf │ │ │ └── renewal/ │ │ │ ├── a.encryption-example.com.conf │ │ │ ├── b.encryption-example.com.conf │ │ │ └── c.encryption-example.com.conf │ │ ├── certbot_tests/ │ │ │ ├── __init__.py │ │ │ ├── assertions.py │ │ │ ├── context.py │ │ │ └── test_main.py │ │ ├── conftest.py │ │ ├── nginx_tests/ │ │ │ ├── __init__.py │ │ │ ├── context.py │ │ │ ├── nginx_config.py │ │ │ └── test_main.py │ │ ├── py.typed │ │ ├── rfc2136_tests/ │ │ │ ├── __init__.py │ │ │ ├── context.py │ │ │ └── test_main.py │ │ └── utils/ │ │ ├── __init__.py │ │ ├── acme_server.py │ │ ├── certbot_call.py │ │ ├── constants.py │ │ ├── dns_server.py │ │ ├── misc.py │ │ ├── pebble_artifacts.py │ │ ├── pebble_ocsp_server.py │ │ └── proxy.py │ └── snap_integration_tests/ │ ├── __init__.py │ ├── conftest.py │ ├── dns_tests/ │ │ ├── __init__.py │ │ └── test_main.py │ └── py.typed ├── certbot-compatibility-test/ │ ├── Dockerfile │ ├── Dockerfile-apache │ ├── Dockerfile-nginx │ ├── LICENSE.txt │ ├── MANIFEST.in │ ├── README.rst │ ├── nginx/ │ │ ├── README │ │ ├── nginx-roundtrip-testdata/ │ │ │ ├── 79-configs/ │ │ │ │ ├── site-10033 │ │ │ │ ├── site-10571 │ │ │ │ ├── site-10591 │ │ │ │ ├── site-10920 │ │ │ │ ├── site-10947 │ │ │ │ ├── site-11018 │ │ │ │ ├── site-11046 │ │ │ │ ├── site-11382 │ │ │ │ ├── site-1167 │ │ │ │ ├── site-11849 │ │ │ │ ├── site-12027 │ │ │ │ ├── site-12235 │ │ │ │ ├── site-12649 │ │ │ │ ├── site-13577 │ │ │ │ ├── site-14402 │ │ │ │ ├── site-14430 │ │ │ │ ├── site-15141 │ │ │ │ ├── site-15270 │ │ │ │ ├── site-15291 │ │ │ │ ├── site-15456 │ │ │ │ ├── site-15497 │ │ │ │ ├── site-15852 │ │ │ │ ├── site-16345 │ │ │ │ ├── site-17175 │ │ │ │ ├── site-17832 │ │ │ │ ├── site-17942 │ │ │ │ ├── site-18018 │ │ │ │ ├── site-18069 │ │ │ │ ├── site-19334 │ │ │ │ ├── site-19639 │ │ │ │ ├── site-1966 │ │ │ │ ├── site-19791 │ │ │ │ ├── site-19955 │ │ │ │ ├── site-21369 │ │ │ │ ├── site-21549 │ │ │ │ ├── site-230 │ │ │ │ ├── site-23325 │ │ │ │ ├── site-23470 │ │ │ │ ├── site-23791 │ │ │ │ ├── site-23803 │ │ │ │ ├── site-23838 │ │ │ │ ├── site-24125 │ │ │ │ ├── site-24193 │ │ │ │ ├── site-24213 │ │ │ │ ├── site-25480 │ │ │ │ ├── site-26195 │ │ │ │ ├── site-26221 │ │ │ │ ├── site-26637 │ │ │ │ ├── site-26758 │ │ │ │ ├── site-27646 │ │ │ │ ├── site-27728 │ │ │ │ ├── site-27736 │ │ │ │ ├── site-27812 │ │ │ │ ├── site-28050 │ │ │ │ ├── site-28690 │ │ │ │ ├── site-29159 │ │ │ │ ├── site-2951 │ │ │ │ ├── site-30011 │ │ │ │ ├── site-30571 │ │ │ │ ├── site-31900 │ │ │ │ ├── site-32190 │ │ │ │ ├── site-32279 │ │ │ │ ├── site-32317 │ │ │ │ ├── site-32438 │ │ │ │ ├── site-3483 │ │ │ │ ├── site-3507 │ │ │ │ ├── site-3874 │ │ │ │ ├── site-4035 │ │ │ │ ├── site-4143 │ │ │ │ ├── site-4264 │ │ │ │ ├── site-5826 │ │ │ │ ├── site-5872 │ │ │ │ ├── site-6228 │ │ │ │ ├── site-7895 │ │ │ │ ├── site-8343 │ │ │ │ ├── site-8422 │ │ │ │ ├── site-8637 │ │ │ │ ├── site-8662 │ │ │ │ └── site-9426 │ │ │ ├── activecolab/ │ │ │ │ └── www.example.com.vhost │ │ │ ├── anothermapcase/ │ │ │ │ └── nginx.conf │ │ │ ├── chive/ │ │ │ │ └── chive-nginx-master/ │ │ │ │ ├── fastcgi.conf │ │ │ │ ├── fastcgi_params │ │ │ │ ├── koi-utf │ │ │ │ ├── koi-win │ │ │ │ ├── map_https_fcgi.conf │ │ │ │ ├── mime.types │ │ │ │ ├── nginx.conf │ │ │ │ ├── reverse_proxy.conf │ │ │ │ ├── sites-available/ │ │ │ │ │ ├── 000-default │ │ │ │ │ ├── chive.example.com.conf │ │ │ │ │ └── secure.chive.example.com.conf │ │ │ │ ├── upstream_phpapache.conf │ │ │ │ ├── upstream_phpcgi.conf │ │ │ │ └── win-utf │ │ │ ├── cms-made-simple/ │ │ │ │ └── nginx.conf │ │ │ ├── codeigniter/ │ │ │ │ ├── nginx-alt.conf │ │ │ │ └── nginx.conf │ │ │ ├── contao/ │ │ │ │ └── sites-available/ │ │ │ │ └── example.com.vhost │ │ │ ├── cs-cart/ │ │ │ │ └── sites-available/ │ │ │ │ └── example.com.vhost │ │ │ ├── djangofastcgi/ │ │ │ │ ├── large.conf │ │ │ │ └── nginx.conf │ │ │ ├── dokuwiki/ │ │ │ │ ├── dokuwiki.conf │ │ │ │ ├── drop.conf │ │ │ │ ├── full.conf │ │ │ │ ├── nginx-no-ssl.conf │ │ │ │ └── nginx.conf │ │ │ ├── drupal/ │ │ │ │ └── nginx.conf │ │ │ ├── dynamic_ssi/ │ │ │ │ └── nginx.conf │ │ │ ├── elgg/ │ │ │ │ └── nginx.conf │ │ │ ├── embeddedperlminifyjs/ │ │ │ │ └── nginx.conf │ │ │ ├── embeddedperlsitemapsproxy/ │ │ │ │ └── nginx.conf │ │ │ ├── expressionengine/ │ │ │ │ ├── bad.conf │ │ │ │ ├── better.conf │ │ │ │ └── yourpath.conf │ │ │ ├── fastcgiexample/ │ │ │ │ ├── fastcgi.conf │ │ │ │ └── nginx.conf │ │ │ ├── fengoffice/ │ │ │ │ └── sites-available/ │ │ │ │ └── www.example.com.vhost │ │ │ ├── full-example/ │ │ │ │ ├── fastcgi.conf │ │ │ │ ├── mime.types │ │ │ │ ├── nginx.conf │ │ │ │ └── proxy.conf │ │ │ ├── fullexample2/ │ │ │ │ └── nginx.conf │ │ │ ├── geoip/ │ │ │ │ └── nginx.conf │ │ │ ├── guide-to-nginx-ssl-spdy-hsts/ │ │ │ │ └── nginx.conf │ │ │ ├── hardwarelberrors/ │ │ │ │ └── nginx.conf │ │ │ ├── icinga/ │ │ │ │ └── sites-available/ │ │ │ │ └── www.example.com.vhost │ │ │ ├── imapauthenticatewithapacheperlscript/ │ │ │ │ └── nginx.conf │ │ │ ├── imapauthenticatewithapachephpscript/ │ │ │ │ └── nginx.conf │ │ │ ├── imapproxyexample/ │ │ │ │ ├── nginx.conf │ │ │ │ └── proxy-example.conf │ │ │ ├── iphone-website-with-nginx/ │ │ │ │ ├── mobile.conf │ │ │ │ └── nginx.conf │ │ │ ├── iredmail/ │ │ │ │ ├── iredadmin.conf │ │ │ │ └── nginx.conf │ │ │ ├── javaservers/ │ │ │ │ └── nginx.conf │ │ │ ├── joomla/ │ │ │ │ └── nginx.conf │ │ │ ├── likeapache/ │ │ │ │ └── nginx.conf │ │ │ ├── loadbalanceexample/ │ │ │ │ └── nginx.conf │ │ │ ├── mailman/ │ │ │ │ └── nginx.conf │ │ │ ├── mediawiki/ │ │ │ │ └── nginx.conf │ │ │ ├── memcachepreload/ │ │ │ │ └── sites-available/ │ │ │ │ └── default │ │ │ ├── minio/ │ │ │ │ └── sites-enabled/ │ │ │ │ └── nginx.conf │ │ │ ├── mono/ │ │ │ │ └── nginx.conf │ │ │ ├── mybb/ │ │ │ │ └── nginx.conf │ │ │ ├── nonrootwebpath/ │ │ │ │ └── nginx.conf │ │ │ ├── omeka/ │ │ │ │ └── nginx.conf │ │ │ ├── oscommerce/ │ │ │ │ └── nginx.conf │ │ │ ├── osticket/ │ │ │ │ └── nginx.conf │ │ │ ├── owncloud/ │ │ │ │ └── sites-available/ │ │ │ │ └── www.example.com.vhost │ │ │ ├── oxid-eshop/ │ │ │ │ └── sites-available/ │ │ │ │ └── www.example.com.vhost │ │ │ ├── php-fpm/ │ │ │ │ └── default.conf │ │ │ ├── phpbb/ │ │ │ │ └── nginx.sample.conf │ │ │ ├── phpfastcgionwindows/ │ │ │ │ └── nginx.conf │ │ │ ├── phpfcgi/ │ │ │ │ ├── fastcgi_params │ │ │ │ └── nginx.conf │ │ │ ├── phplist/ │ │ │ │ └── nginx.conf │ │ │ ├── piwik/ │ │ │ │ └── nginx.conf │ │ │ ├── pmwiki/ │ │ │ │ └── nginx.conf │ │ │ ├── prestashop/ │ │ │ │ └── sites-available/ │ │ │ │ └── www.example.com.vhost │ │ │ ├── processwire/ │ │ │ │ └── sites-available/ │ │ │ │ └── www.example.com.vhost │ │ │ ├── pylons/ │ │ │ │ └── nginx.vhost.conf │ │ │ ├── pyrocms/ │ │ │ │ ├── drop.conf │ │ │ │ ├── fastcgi_params │ │ │ │ └── nginx.conf │ │ │ ├── qwebric/ │ │ │ │ ├── redirect.conf │ │ │ │ └── reverse-proxy.conf │ │ │ ├── redaxo/ │ │ │ │ └── sites-available/ │ │ │ │ └── www.example.com.vhost │ │ │ ├── redmine/ │ │ │ │ └── nginx.conf │ │ │ ├── reverseproxycachingexample/ │ │ │ │ └── nginx.conf │ │ │ ├── roundcube/ │ │ │ │ └── sites-available/ │ │ │ │ └── example.com.vhost.conf │ │ │ ├── separateerrorloggingpervirtualhost/ │ │ │ │ └── nginx.conf │ │ │ ├── server_blocks/ │ │ │ │ ├── catchall.conf │ │ │ │ ├── two.conf │ │ │ │ └── wildcard-subdomains.conf │ │ │ ├── shopware/ │ │ │ │ └── sites-available/ │ │ │ │ └── www.example.com.vhost │ │ │ ├── shopware4/ │ │ │ │ └── sites-available/ │ │ │ │ └── www.example.com.vhost │ │ │ ├── silverstripe/ │ │ │ │ └── nginx.conf │ │ │ ├── simplecgi/ │ │ │ │ └── nginx.conf │ │ │ ├── simplegroupware/ │ │ │ │ └── sites-available/ │ │ │ │ └── www.example.com.vhost │ │ │ ├── simplepythonfcgi/ │ │ │ │ ├── fastcgi.conf │ │ │ │ ├── nginx.conf │ │ │ │ └── weird-spacing.conf │ │ │ ├── simplerubyfcgi/ │ │ │ │ └── nginx.conf │ │ │ ├── spip/ │ │ │ │ └── nginx.conf │ │ │ ├── sugarcrm/ │ │ │ │ └── sites-available/ │ │ │ │ └── www.example.com.vhost │ │ │ ├── symfony/ │ │ │ │ ├── nginx.conf │ │ │ │ ├── old.conf │ │ │ │ └── oldold.conf │ │ │ ├── typo3-4.6/ │ │ │ │ └── sites-available/ │ │ │ │ └── www.example.com.vhost │ │ │ ├── typo3-6.2/ │ │ │ │ └── sites-available/ │ │ │ │ └── www.example.com.vhost │ │ │ ├── upstream-issue-17/ │ │ │ │ └── nginx.conf │ │ │ ├── upstream-issue-19/ │ │ │ │ └── nginx.conf │ │ │ ├── wordpress/ │ │ │ │ ├── multisite-subdir.conf │ │ │ │ ├── multisite-subdomain.conf │ │ │ │ └── nginx.conf │ │ │ ├── wordpress-caching/ │ │ │ │ ├── no-cache.conf │ │ │ │ ├── supercache.conf │ │ │ │ ├── total-cache.conf │ │ │ │ └── totalcache-enhanced.conf │ │ │ ├── xenforo/ │ │ │ │ └── nginx.conf │ │ │ ├── yii/ │ │ │ │ └── nginx.conf │ │ │ ├── zend/ │ │ │ │ └── nginx.conf │ │ │ ├── zenphoto/ │ │ │ │ └── nginx.conf │ │ │ └── zope/ │ │ │ └── nginx.conf │ │ └── roundtrip.py │ ├── pyproject.toml │ ├── setup.py │ └── src/ │ └── certbot_compatibility_test/ │ ├── __init__.py │ ├── configurators/ │ │ ├── __init__.py │ │ ├── apache/ │ │ │ ├── __init__.py │ │ │ └── common.py │ │ ├── common.py │ │ └── nginx/ │ │ ├── __init__.py │ │ └── common.py │ ├── errors.py │ ├── interfaces.py │ ├── test_driver.py │ ├── testdata/ │ │ └── empty_cert.pem │ ├── util.py │ └── validator.py ├── certbot-dns-cloudflare/ │ ├── .readthedocs.yaml │ ├── LICENSE.txt │ ├── MANIFEST.in │ ├── README.rst │ ├── docs/ │ │ ├── .gitignore │ │ ├── Makefile │ │ ├── api.rst │ │ ├── conf.py │ │ ├── index.rst │ │ └── make.bat │ ├── pyproject.toml │ ├── readthedocs.org.requirements.txt │ ├── setup.py │ └── src/ │ └── certbot_dns_cloudflare/ │ ├── __init__.py │ ├── _internal/ │ │ ├── __init__.py │ │ ├── dns_cloudflare.py │ │ └── tests/ │ │ ├── __init__.py │ │ └── dns_cloudflare_test.py │ └── py.typed ├── certbot-dns-digitalocean/ │ ├── .readthedocs.yaml │ ├── LICENSE.txt │ ├── MANIFEST.in │ ├── README.rst │ ├── docs/ │ │ ├── .gitignore │ │ ├── Makefile │ │ ├── api.rst │ │ ├── conf.py │ │ ├── index.rst │ │ └── make.bat │ ├── pyproject.toml │ ├── readthedocs.org.requirements.txt │ ├── setup.py │ └── src/ │ └── certbot_dns_digitalocean/ │ ├── __init__.py │ ├── _internal/ │ │ ├── __init__.py │ │ ├── dns_digitalocean.py │ │ └── tests/ │ │ ├── __init__.py │ │ └── dns_digitalocean_test.py │ └── py.typed ├── certbot-dns-dnsimple/ │ ├── .readthedocs.yaml │ ├── LICENSE.txt │ ├── MANIFEST.in │ ├── README.rst │ ├── docs/ │ │ ├── .gitignore │ │ ├── Makefile │ │ ├── api.rst │ │ ├── conf.py │ │ ├── index.rst │ │ └── make.bat │ ├── pyproject.toml │ ├── readthedocs.org.requirements.txt │ ├── setup.py │ └── src/ │ └── certbot_dns_dnsimple/ │ ├── __init__.py │ ├── _internal/ │ │ ├── __init__.py │ │ ├── dns_dnsimple.py │ │ └── tests/ │ │ ├── __init__.py │ │ └── dns_dnsimple_test.py │ └── py.typed ├── certbot-dns-dnsmadeeasy/ │ ├── .readthedocs.yaml │ ├── LICENSE.txt │ ├── MANIFEST.in │ ├── README.rst │ ├── docs/ │ │ ├── .gitignore │ │ ├── Makefile │ │ ├── api.rst │ │ ├── conf.py │ │ ├── index.rst │ │ └── make.bat │ ├── pyproject.toml │ ├── readthedocs.org.requirements.txt │ ├── setup.py │ └── src/ │ └── certbot_dns_dnsmadeeasy/ │ ├── __init__.py │ ├── _internal/ │ │ ├── __init__.py │ │ ├── dns_dnsmadeeasy.py │ │ └── tests/ │ │ ├── __init__.py │ │ └── dns_dnsmadeeasy_test.py │ └── py.typed ├── certbot-dns-gehirn/ │ ├── .readthedocs.yaml │ ├── LICENSE.txt │ ├── MANIFEST.in │ ├── README.rst │ ├── docs/ │ │ ├── .gitignore │ │ ├── Makefile │ │ ├── api.rst │ │ ├── conf.py │ │ ├── index.rst │ │ └── make.bat │ ├── pyproject.toml │ ├── readthedocs.org.requirements.txt │ ├── setup.py │ └── src/ │ └── certbot_dns_gehirn/ │ ├── __init__.py │ ├── _internal/ │ │ ├── __init__.py │ │ ├── dns_gehirn.py │ │ └── tests/ │ │ ├── __init__.py │ │ └── dns_gehirn_test.py │ └── py.typed ├── certbot-dns-google/ │ ├── .readthedocs.yaml │ ├── LICENSE.txt │ ├── MANIFEST.in │ ├── README.rst │ ├── docs/ │ │ ├── .gitignore │ │ ├── Makefile │ │ ├── api.rst │ │ ├── conf.py │ │ ├── index.rst │ │ └── make.bat │ ├── pyproject.toml │ ├── readthedocs.org.requirements.txt │ ├── setup.py │ └── src/ │ └── certbot_dns_google/ │ ├── __init__.py │ ├── _internal/ │ │ ├── __init__.py │ │ ├── dns_google.py │ │ └── tests/ │ │ ├── __init__.py │ │ ├── dns_google_test.py │ │ └── testdata/ │ │ └── discovery.json │ └── py.typed ├── certbot-dns-linode/ │ ├── .readthedocs.yaml │ ├── LICENSE.txt │ ├── MANIFEST.in │ ├── README.rst │ ├── docs/ │ │ ├── .gitignore │ │ ├── Makefile │ │ ├── api.rst │ │ ├── conf.py │ │ ├── index.rst │ │ └── make.bat │ ├── pyproject.toml │ ├── readthedocs.org.requirements.txt │ ├── setup.py │ └── src/ │ └── certbot_dns_linode/ │ ├── __init__.py │ ├── _internal/ │ │ ├── __init__.py │ │ ├── dns_linode.py │ │ └── tests/ │ │ ├── __init__.py │ │ └── dns_linode_test.py │ └── py.typed ├── certbot-dns-luadns/ │ ├── .readthedocs.yaml │ ├── LICENSE.txt │ ├── MANIFEST.in │ ├── README.rst │ ├── docs/ │ │ ├── .gitignore │ │ ├── Makefile │ │ ├── api.rst │ │ ├── conf.py │ │ ├── index.rst │ │ └── make.bat │ ├── pyproject.toml │ ├── readthedocs.org.requirements.txt │ ├── setup.py │ └── src/ │ └── certbot_dns_luadns/ │ ├── __init__.py │ ├── _internal/ │ │ ├── __init__.py │ │ ├── dns_luadns.py │ │ └── tests/ │ │ ├── __init__.py │ │ └── dns_luadns_test.py │ └── py.typed ├── certbot-dns-nsone/ │ ├── .readthedocs.yaml │ ├── LICENSE.txt │ ├── MANIFEST.in │ ├── README.rst │ ├── docs/ │ │ ├── .gitignore │ │ ├── Makefile │ │ ├── api.rst │ │ ├── conf.py │ │ ├── index.rst │ │ └── make.bat │ ├── pyproject.toml │ ├── readthedocs.org.requirements.txt │ ├── setup.py │ └── src/ │ └── certbot_dns_nsone/ │ ├── __init__.py │ ├── _internal/ │ │ ├── __init__.py │ │ ├── dns_nsone.py │ │ └── tests/ │ │ ├── __init__.py │ │ └── dns_nsone_test.py │ └── py.typed ├── certbot-dns-ovh/ │ ├── .readthedocs.yaml │ ├── LICENSE.txt │ ├── MANIFEST.in │ ├── README.rst │ ├── docs/ │ │ ├── .gitignore │ │ ├── Makefile │ │ ├── api.rst │ │ ├── conf.py │ │ ├── index.rst │ │ └── make.bat │ ├── pyproject.toml │ ├── readthedocs.org.requirements.txt │ ├── setup.py │ └── src/ │ └── certbot_dns_ovh/ │ ├── __init__.py │ ├── _internal/ │ │ ├── __init__.py │ │ ├── dns_ovh.py │ │ └── tests/ │ │ ├── __init__.py │ │ └── dns_ovh_test.py │ └── py.typed ├── certbot-dns-rfc2136/ │ ├── .readthedocs.yaml │ ├── LICENSE.txt │ ├── MANIFEST.in │ ├── README.rst │ ├── docs/ │ │ ├── .gitignore │ │ ├── Makefile │ │ ├── api.rst │ │ ├── conf.py │ │ ├── index.rst │ │ └── make.bat │ ├── pyproject.toml │ ├── readthedocs.org.requirements.txt │ ├── setup.py │ └── src/ │ └── certbot_dns_rfc2136/ │ ├── __init__.py │ ├── _internal/ │ │ ├── __init__.py │ │ ├── dns_rfc2136.py │ │ └── tests/ │ │ ├── __init__.py │ │ └── dns_rfc2136_test.py │ └── py.typed ├── certbot-dns-route53/ │ ├── .readthedocs.yaml │ ├── LICENSE.txt │ ├── MANIFEST.in │ ├── README.rst │ ├── docs/ │ │ ├── .gitignore │ │ ├── Makefile │ │ ├── api.rst │ │ ├── conf.py │ │ ├── index.rst │ │ └── make.bat │ ├── examples/ │ │ └── sample-aws-policy.json │ ├── pyproject.toml │ ├── readthedocs.org.requirements.txt │ ├── setup.py │ └── src/ │ └── certbot_dns_route53/ │ ├── __init__.py │ ├── _internal/ │ │ ├── __init__.py │ │ ├── dns_route53.py │ │ └── tests/ │ │ ├── __init__.py │ │ ├── conftest.py │ │ └── dns_route53_test.py │ └── py.typed ├── certbot-dns-sakuracloud/ │ ├── .readthedocs.yaml │ ├── LICENSE.txt │ ├── MANIFEST.in │ ├── README.rst │ ├── docs/ │ │ ├── .gitignore │ │ ├── Makefile │ │ ├── api.rst │ │ ├── conf.py │ │ ├── index.rst │ │ └── make.bat │ ├── pyproject.toml │ ├── readthedocs.org.requirements.txt │ ├── setup.py │ └── src/ │ └── certbot_dns_sakuracloud/ │ ├── __init__.py │ ├── _internal/ │ │ ├── __init__.py │ │ ├── dns_sakuracloud.py │ │ └── tests/ │ │ ├── __init__.py │ │ └── dns_sakuracloud_test.py │ └── py.typed ├── certbot-nginx/ │ ├── LICENSE.txt │ ├── MANIFEST.in │ ├── README.rst │ ├── pyproject.toml │ ├── setup.py │ └── src/ │ └── certbot_nginx/ │ ├── __init__.py │ ├── _internal/ │ │ ├── __init__.py │ │ ├── configurator.py │ │ ├── constants.py │ │ ├── display_ops.py │ │ ├── http_01.py │ │ ├── nginxparser.py │ │ ├── obj.py │ │ ├── parser.py │ │ ├── parser_obj.py │ │ ├── tests/ │ │ │ ├── __init__.py │ │ │ ├── configurator_test.py │ │ │ ├── display_ops_test.py │ │ │ ├── http_01_test.py │ │ │ ├── nginxparser_test.py │ │ │ ├── obj_test.py │ │ │ ├── parser_obj_test.py │ │ │ ├── parser_test.py │ │ │ ├── test_util.py │ │ │ └── testdata/ │ │ │ └── etc_nginx/ │ │ │ ├── broken.conf │ │ │ ├── comment_in_file.conf │ │ │ ├── edge_cases.conf │ │ │ ├── foo.conf │ │ │ ├── invalid_unicode_comments.conf │ │ │ ├── mime.types │ │ │ ├── minimalistic_comments.conf │ │ │ ├── multiline_quotes.conf │ │ │ ├── nginx-include.conf │ │ │ ├── nginx.conf │ │ │ ├── server.conf │ │ │ ├── sites-enabled/ │ │ │ │ ├── addr-80.com │ │ │ │ ├── both.com │ │ │ │ ├── default │ │ │ │ ├── example.com │ │ │ │ ├── example.net │ │ │ │ ├── globalssl.com │ │ │ │ ├── headers.com │ │ │ │ ├── ipv6.com │ │ │ │ ├── ipv6ssl.com │ │ │ │ ├── migration.com │ │ │ │ ├── no-listens.com │ │ │ │ └── sslon.com │ │ │ ├── ubuntu_nginx_1_4_6/ │ │ │ │ └── default_vhost/ │ │ │ │ └── nginx/ │ │ │ │ ├── fastcgi_params │ │ │ │ ├── koi-utf │ │ │ │ ├── koi-win │ │ │ │ ├── mime.types │ │ │ │ ├── naxsi-ui.conf.1.4.1 │ │ │ │ ├── naxsi.rules │ │ │ │ ├── naxsi_core.rules │ │ │ │ ├── nginx.conf │ │ │ │ ├── proxy_params │ │ │ │ ├── scgi_params │ │ │ │ ├── sites-available/ │ │ │ │ │ └── default │ │ │ │ ├── uwsgi_params │ │ │ │ └── win-utf │ │ │ └── valid_unicode_comments.conf │ │ └── tls_configs/ │ │ ├── options-ssl-nginx-old.conf │ │ ├── options-ssl-nginx-tls12-only.conf │ │ ├── options-ssl-nginx-tls13-session-tix-on.conf │ │ └── options-ssl-nginx.conf │ └── py.typed ├── letsencrypt-auto-source/ │ ├── README.md │ ├── letsencrypt-auto │ └── letsencrypt-auto.sig ├── letstest/ │ ├── README.md │ ├── letstest/ │ │ ├── __init__.py │ │ └── multitester.py │ ├── pyproject.toml │ ├── scripts/ │ │ ├── bootstrap_os_packages.sh │ │ ├── test_apache2.sh │ │ └── version.py │ ├── setup.py │ └── targets/ │ └── targets.yaml ├── linter_plugin.py ├── mypy.ini ├── newsfragments/ │ ├── .gitignore │ └── 10584.changed ├── pytest.ini ├── ruff.toml ├── snap/ │ ├── hooks/ │ │ ├── configure │ │ └── prepare-plug-plugin │ └── snapcraft.yaml ├── tests/ │ └── modification-check.py ├── tools/ │ ├── _release.sh │ ├── docker/ │ │ ├── Dockerfile │ │ ├── README.md │ │ ├── build.sh │ │ ├── deploy_images.sh │ │ ├── deploy_manifests.sh │ │ ├── lib/ │ │ │ └── common │ │ └── test.sh │ ├── extract_changelog.py │ ├── finish_release.py │ ├── oldest_constraints.txt │ ├── pinning/ │ │ ├── DESIGN.md │ │ ├── common/ │ │ │ └── export-pinned-dependencies.sh │ │ ├── current/ │ │ │ ├── pyproject.toml │ │ │ └── repin.sh │ │ └── oldest/ │ │ ├── pyproject.toml │ │ └── repin.sh │ ├── pip_install.py │ ├── pipstrap.py │ ├── release.sh │ ├── requirements.txt │ ├── retry.sh │ ├── snap/ │ │ ├── README.md │ │ ├── build_remote.py │ │ ├── generate_dnsplugins_all.sh │ │ ├── generate_dnsplugins_postrefreshhook.sh │ │ └── generate_dnsplugins_snapcraft.sh │ ├── sphinx-quickstart.sh │ └── venv.py ├── towncrier.toml └── tox.ini
Showing preview only (446K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (4908 symbols across 248 files)
FILE: acme/examples/http01_example.py
function new_csr_comp (line 68) | def new_csr_comp(domain_name, pkey_pem=None):
function select_http01_chall (line 81) | def select_http01_chall(orderr):
function challenge_server (line 99) | def challenge_server(http_01_resources):
function perform_http01 (line 115) | def perform_http01(client_acme, challb, orderr):
function example_http (line 137) | def example_http():
FILE: acme/src/acme/_internal/tests/challenges_test.py
class ChallengeTest (line 19) | class ChallengeTest(unittest.TestCase):
method test_from_json_unrecognized (line 21) | def test_from_json_unrecognized(self):
class UnrecognizedChallengeTest (line 28) | class UnrecognizedChallengeTest(unittest.TestCase):
method setUp (line 30) | def setUp(self):
method test_to_partial_json (line 35) | def test_to_partial_json(self):
method test_from_json (line 38) | def test_from_json(self):
class KeyAuthorizationChallengeResponseTest (line 43) | class KeyAuthorizationChallengeResponseTest(unittest.TestCase):
method setUp (line 45) | def setUp(self):
method test_verify_ok (line 52) | def test_verify_ok(self):
method test_verify_wrong_token (line 58) | def test_verify_wrong_token(self):
method test_verify_wrong_thumbprint (line 64) | def test_verify_wrong_thumbprint(self):
method test_verify_wrong_form (line 70) | def test_verify_wrong_form(self):
class DNS01ResponseTest (line 78) | class DNS01ResponseTest(unittest.TestCase):
method setUp (line 80) | def setUp(self):
method test_to_partial_json (line 93) | def test_to_partial_json(self):
method test_from_json (line 96) | def test_from_json(self):
method test_from_json_hashable (line 100) | def test_from_json_hashable(self):
method test_simple_verify_failure (line 104) | def test_simple_verify_failure(self):
method test_simple_verify_success (line 110) | def test_simple_verify_success(self):
class DNS01Test (line 116) | class DNS01Test(unittest.TestCase):
method setUp (line 118) | def setUp(self):
method test_validation_domain_name (line 127) | def test_validation_domain_name(self):
method test_validation (line 131) | def test_validation(self):
method test_to_partial_json (line 135) | def test_to_partial_json(self):
method test_from_json (line 138) | def test_from_json(self):
method test_from_json_hashable (line 142) | def test_from_json_hashable(self):
class HTTP01ResponseTest (line 147) | class HTTP01ResponseTest(unittest.TestCase):
method setUp (line 149) | def setUp(self):
method test_to_partial_json (line 162) | def test_to_partial_json(self):
method test_from_json (line 165) | def test_from_json(self):
method test_from_json_hashable (line 169) | def test_from_json_hashable(self):
method test_simple_verify_bad_key_authorization (line 173) | def test_simple_verify_bad_key_authorization(self):
method test_simple_verify_good_validation (line 178) | def test_simple_verify_good_validation(self, mock_get):
method test_simple_verify_bad_validation (line 187) | def test_simple_verify_bad_validation(self, mock_get):
method test_simple_verify_whitespace_validation (line 193) | def test_simple_verify_whitespace_validation(self, mock_get):
method test_simple_verify_connection_error (line 204) | def test_simple_verify_connection_error(self, mock_get):
method test_simple_verify_port (line 210) | def test_simple_verify_port(self, mock_get):
method test_simple_verify_timeout (line 218) | def test_simple_verify_timeout(self, mock_get):
class HTTP01Test (line 228) | class HTTP01Test(unittest.TestCase):
method setUp (line 230) | def setUp(self):
method test_path (line 240) | def test_path(self):
method test_uri (line 244) | def test_uri(self):
method test_to_partial_json (line 255) | def test_to_partial_json(self):
method test_from_json (line 258) | def test_from_json(self):
method test_from_json_hashable (line 262) | def test_from_json_hashable(self):
method test_good_token (line 266) | def test_good_token(self):
class TestDNS (line 271) | class TestDNS:
method jmsg (line 277) | def jmsg(self) -> dict:
method msg (line 285) | def msg(self) -> 'DNS':
method test_to_partial_json (line 291) | def test_to_partial_json(self, msg: 'DNS', jmsg: dict):
method test_from_json (line 294) | def test_from_json(self, msg: 'DNS', jmsg: dict):
method test_from_json_hashable (line 298) | def test_from_json_hashable(self, jmsg: dict):
method test_gen_check_validation (line 307) | def test_gen_check_validation(self, key, alg, msg: 'DNS'):
method test_gen_check_validation_wrong_key (line 311) | def test_gen_check_validation_wrong_key(self, msg: 'DNS'):
method test_check_validation_wrong_payload (line 316) | def test_check_validation_wrong_payload(self, msg: 'DNS'):
method test_check_validation_wrong_fields (line 325) | def test_check_validation_wrong_fields(self, msg: 'DNS'):
method test_gen_response (line 332) | def test_gen_response(self, msg: 'DNS'):
method test_validation_domain_name (line 340) | def test_validation_domain_name(self, msg: 'DNS'):
method test_validation_domain_name_ecdsa (line 343) | def test_validation_domain_name_ecdsa(self, msg: 'DNS'):
class DNSResponseTest (line 350) | class DNSResponseTest(unittest.TestCase):
method setUp (line 352) | def setUp(self):
method test_to_partial_json (line 371) | def test_to_partial_json(self):
method test_from_json (line 374) | def test_from_json(self):
method test_from_json_hashable (line 378) | def test_from_json_hashable(self):
method test_check_validation (line 382) | def test_check_validation(self):
class JWSPayloadRFC8555Compliant (line 386) | class JWSPayloadRFC8555Compliant(unittest.TestCase):
method test_challenge_payload (line 388) | def test_challenge_payload(self):
FILE: acme/src/acme/_internal/tests/client_test.py
class ClientV2Test (line 40) | class ClientV2Test(unittest.TestCase):
method setUp (line 43) | def setUp(self):
method test_new_account (line 107) | def test_new_account(self):
method test_new_account_tos_link (line 114) | def test_new_account_tos_link(self):
method test_new_account_conflict (line 126) | def test_new_account_conflict(self):
method test_deactivate_account (line 132) | def test_deactivate_account(self):
method test_deactivate_authorization (line 140) | def test_deactivate_authorization(self):
method test_new_order (line 149) | def test_new_order(self):
method test_answer_challege (line 171) | def test_answer_challege(self):
method test_answer_challenge_missing_next (line 180) | def test_answer_challenge_missing_next(self):
method test_poll_and_finalize (line 185) | def test_poll_and_finalize(self, mock_datetime):
method test_poll_authorizations_timeout (line 198) | def test_poll_authorizations_timeout(self, mock_datetime):
method test_poll_authorizations_failure (line 209) | def test_poll_authorizations_failure(self):
method test_poll_authorizations_success (line 219) | def test_poll_authorizations_success(self):
method test_poll_unexpected_update (line 230) | def test_poll_unexpected_update(self):
method test_finalize_order_success (line 236) | def test_finalize_order_success(self):
method test_finalize_order_error (line 248) | def test_finalize_order_error(self):
method test_finalize_order_ready (line 259) | def test_finalize_order_ready(self, mock_begin):
method test_finalize_order_invalid_status (line 278) | def test_finalize_order_invalid_status(self):
method test_finalize_order_orderNotReady (line 287) | def test_finalize_order_orderNotReady(self, dt_mock, mock_sleep):
method test_finalize_order_otherErrorCode (line 324) | def test_finalize_order_otherErrorCode(self):
method test_finalize_order_timeout (line 332) | def test_finalize_order_timeout(self):
method test_finalize_order_alt_chains (line 337) | def test_finalize_order_alt_chains(self):
method test_revoke (line 364) | def test_revoke(self):
method test_revoke_bad_status_raises_error (line 369) | def test_revoke_bad_status_raises_error(self):
method test_update_registration (line 375) | def test_update_registration(self):
method test_external_account_required_true (line 387) | def test_external_account_required_true(self):
method test_external_account_required_false (line 394) | def test_external_account_required_false(self):
method test_external_account_required_default (line 401) | def test_external_account_required_default(self):
method test_query_registration_client (line 404) | def test_query_registration_client(self):
method test_post_as_get (line 409) | def test_post_as_get(self):
method test_retry_after_date (line 420) | def test_retry_after_date(self):
method test_retry_after_invalid (line 426) | def test_retry_after_invalid(self, dt_mock):
method test_retry_after_overflow (line 435) | def test_retry_after_overflow(self, dt_mock):
method test_retry_after_seconds (line 445) | def test_retry_after_seconds(self, dt_mock):
method test_retry_after_missing (line 454) | def test_retry_after_missing(self, dt_mock):
method test_get_directory (line 461) | def test_get_directory(self):
method test_renewal_time_expired_cert (line 467) | def test_renewal_time_expired_cert(self, dt_mock):
method test_renewal_time_no_renewal_info (line 481) | def test_renewal_time_no_renewal_info(self, dt_mock):
method test_renewal_time_with_renewal_info (line 501) | def test_renewal_time_with_renewal_info(self, dt_mock):
method test_renewal_time_renewal_info_errors (line 549) | def test_renewal_time_renewal_info_errors(self, dt_mock):
method test_renewal_time_returns_retry_after (line 584) | def test_renewal_time_returns_retry_after(self, dt_mock):
function test_renewal_info_path_component (line 615) | def test_renewal_info_path_component():
function make_cert_for_renewal (line 642) | def make_cert_for_renewal(not_before, not_after) -> bytes:
class MockJSONDeSerializable (line 672) | class MockJSONDeSerializable(jose.JSONDeSerializable):
method __init__ (line 674) | def __init__(self, value):
method to_partial_json (line 677) | def to_partial_json(self):
method from_json (line 681) | def from_json(cls, jobj):
class ClientNetworkTest (line 685) | class ClientNetworkTest(unittest.TestCase):
method setUp (line 688) | def setUp(self):
method test_init (line 700) | def test_init(self):
method test_wrap_in_jws (line 703) | def test_wrap_in_jws(self):
method test_wrap_in_jws_v2 (line 711) | def test_wrap_in_jws_v2(self):
method test_check_response_not_ok_jobj_no_error (line 722) | def test_check_response_not_ok_jobj_no_error(self):
method test_check_response_not_ok_jobj_error (line 731) | def test_check_response_not_ok_jobj_error(self):
method test_check_response_not_ok_no_jobj (line 739) | def test_check_response_not_ok_no_jobj(self):
method test_check_response_ok_no_jobj_ct_required (line 746) | def test_check_response_ok_no_jobj_ct_required(self):
method test_check_response_ok_no_jobj_no_ct (line 755) | def test_check_response_ok_no_jobj_no_ct(self):
method test_check_response_ok_ct_with_charset (line 763) | def test_check_response_ok_ct_with_charset(self, mock_logger):
method test_check_response_ok_bad_ct (line 780) | def test_check_response_ok_bad_ct(self, mock_logger):
method test_check_response_conflict (line 791) | def test_check_response_conflict(self):
method test_check_response_jobj (line 798) | def test_check_response_jobj(self):
method test_send_request (line 805) | def test_send_request(self):
method test_send_request_get_der (line 816) | def test_send_request_get_der(self, mock_logger):
method test_send_request_post (line 828) | def test_send_request_post(self):
method test_send_request_verify_ssl (line 838) | def test_send_request_verify_ssl(self):
method test_send_request_user_agent (line 851) | def test_send_request_user_agent(self):
method test_send_request_timeout (line 867) | def test_send_request_timeout(self):
method test_del (line 876) | def test_del(self, close_exception=None):
method test_del_error (line 886) | def test_del_error(self):
method test_requests_error_passthrough (line 890) | def test_requests_error_passthrough(self, mock_requests):
class ClientNetworkWithMockedResponseTest (line 898) | class ClientNetworkWithMockedResponseTest(unittest.TestCase):
method setUp (line 901) | def setUp(self):
method check_response (line 944) | def check_response(self, response, content_type):
method test_head (line 952) | def test_head(self):
method test_head_v2 (line 958) | def test_head_v2(self):
method test_get (line 964) | def test_get(self):
method test_post_no_content_type (line 971) | def test_post_no_content_type(self):
method test_post (line 976) | def test_post(self):
method test_post_wrong_initial_nonce (line 989) | def test_post_wrong_initial_nonce(self): # HEAD
method test_post_wrong_post_response_nonce (line 995) | def test_post_wrong_post_response_nonce(self):
method test_post_failed_retry (line 1001) | def test_post_failed_retry(self):
method test_post_not_retried (line 1010) | def test_post_not_retried(self):
method test_post_successful_retry (line 1020) | def test_post_successful_retry(self):
method test_head_get_post_error_passthrough (line 1028) | def test_head_get_post_error_passthrough(self):
method test_post_bad_nonce_head (line 1036) | def test_post_bad_nonce_head(self):
method test_new_nonce_uri_removed (line 1051) | def test_new_nonce_uri_removed(self):
method test_no_key_error (line 1055) | def test_no_key_error(self):
FILE: acme/src/acme/_internal/tests/conftest.py
function mock_getfqdn (line 9) | def mock_getfqdn():
function mock_sleep (line 14) | def mock_sleep():
FILE: acme/src/acme/_internal/tests/crypto_util_test.py
class FormatTest (line 17) | class FormatTest(unittest.TestCase):
method test_to_cryptography_encoding (line 18) | def test_to_cryptography_encoding(self):
class MiscTests (line 25) | class MiscTests(unittest.TestCase):
method test_dump_cryptography_chain (line 27) | def test_dump_cryptography_chain(self):
class CryptographyCertOrReqSANTest (line 40) | class CryptographyCertOrReqSANTest(unittest.TestCase):
method _call (line 44) | def _call(cls, loader, name):
method _get_idn_names (line 50) | def _get_idn_names(cls):
method _call_cert (line 58) | def _call_cert(self, name):
method _call_csr (line 61) | def _call_csr(self, name):
method test_cert_no_sans (line 64) | def test_cert_no_sans(self):
method test_cert_two_sans (line 67) | def test_cert_two_sans(self):
method test_cert_hundred_sans (line 71) | def test_cert_hundred_sans(self):
method test_cert_idn_sans (line 75) | def test_cert_idn_sans(self):
method test_csr_no_sans (line 79) | def test_csr_no_sans(self):
method test_csr_one_san (line 82) | def test_csr_one_san(self):
method test_csr_two_sans (line 85) | def test_csr_two_sans(self):
method test_csr_six_sans (line 89) | def test_csr_six_sans(self):
method test_csr_hundred_sans (line 95) | def test_csr_hundred_sans(self):
method test_csr_idn_sans (line 99) | def test_csr_idn_sans(self):
method test_critical_san (line 103) | def test_critical_san(self):
class GenMakeSelfSignedCertTest (line 108) | class GenMakeSelfSignedCertTest(unittest.TestCase):
method setUp (line 111) | def setUp(self):
method _call (line 117) | def _call(cls, *args, **kwargs):
method test_sn_collisions (line 122) | def test_sn_collisions(self):
method test_no_ips (line 129) | def test_no_ips(self):
method test_expiry_times (line 133) | def test_expiry_times(self, mock_now):
method test_no_name (line 175) | def test_no_name(self):
method test_extensions (line 180) | def test_extensions(self):
class MakeCSRTest (line 195) | class MakeCSRTest(unittest.TestCase):
method _call_with_key (line 199) | def _call_with_key(cls, *args, **kwargs):
method test_make_csr (line 210) | def test_make_csr(self):
method test_make_csr_ip (line 224) | def test_make_csr_ip(self):
method test_make_csr_must_staple (line 244) | def test_make_csr_must_staple(self):
method test_make_csr_without_hostname (line 253) | def test_make_csr_without_hostname(self):
method test_make_csr_invalid_key_type (line 257) | def test_make_csr_invalid_key_type(self):
FILE: acme/src/acme/_internal/tests/errors_test.py
class BadNonceTest (line 9) | class BadNonceTest(unittest.TestCase):
method setUp (line 12) | def setUp(self):
method test_str (line 16) | def test_str(self):
class MissingNonceTest (line 20) | class MissingNonceTest(unittest.TestCase):
method setUp (line 23) | def setUp(self):
method test_str (line 29) | def test_str(self):
class PollErrorTest (line 34) | class PollErrorTest(unittest.TestCase):
method setUp (line 37) | def setUp(self):
method test_timeout (line 45) | def test_timeout(self):
method test_repr (line 49) | def test_repr(self):
class ValidationErrorTest (line 54) | class ValidationErrorTest(unittest.TestCase):
method setUp (line 57) | def setUp(self):
method test_repr (line 78) | def test_repr(self):
FILE: acme/src/acme/_internal/tests/fields_test.py
class FixedTest (line 10) | class FixedTest(unittest.TestCase):
method setUp (line 13) | def setUp(self):
method test_decode (line 17) | def test_decode(self):
method test_decode_bad (line 20) | def test_decode_bad(self):
method test_encode (line 24) | def test_encode(self):
method test_encode_override (line 27) | def test_encode_override(self):
class RFC3339FieldTest (line 31) | class RFC3339FieldTest(unittest.TestCase):
method setUp (line 34) | def setUp(self):
method test_default_encoder (line 38) | def test_default_encoder(self):
method test_default_encoder_naive_fails (line 42) | def test_default_encoder_naive_fails(self):
method test_default_decoder (line 47) | def test_default_decoder(self):
method test_default_decoder_raises_deserialization_error (line 51) | def test_default_decoder_raises_deserialization_error(self):
FILE: acme/src/acme/_internal/tests/jose_test.py
function _test_it (line 8) | def _test_it(submodule, attribute):
function test_top_level (line 31) | def test_top_level():
function test_submodules (line 34) | def test_submodules():
FILE: acme/src/acme/_internal/tests/jws_test.py
class HeaderTest (line 13) | class HeaderTest(unittest.TestCase):
method test_nonce_decoder (line 26) | def test_nonce_decoder(self):
class JWSTest (line 35) | class JWSTest(unittest.TestCase):
method setUp (line 38) | def setUp(self):
method test_kid_serialize (line 45) | def test_kid_serialize(self):
method test_jwk_serialize (line 58) | def test_jwk_serialize(self):
FILE: acme/src/acme/_internal/tests/messages_test.py
class ErrorTest (line 18) | class ErrorTest(unittest.TestCase):
method setUp (line 21) | def setUp(self):
method test_default_typ (line 38) | def test_default_typ(self):
method test_from_json_empty (line 42) | def test_from_json_empty(self):
method test_from_json_hashable (line 46) | def test_from_json_hashable(self):
method test_from_json_with_subproblems (line 50) | def test_from_json_with_subproblems(self):
method test_description (line 58) | def test_description(self):
method test_code (line 62) | def test_code(self):
method test_is_acme_error (line 68) | def test_is_acme_error(self):
method test_unicode_error (line 77) | def test_unicode_error(self):
method test_with_code (line 84) | def test_with_code(self):
method test_str (line 91) | def test_str(self):
method test_setting_traceback (line 102) | def test_setting_traceback(self):
class ConstantTest (line 113) | class ConstantTest(unittest.TestCase):
method setUp (line 116) | def setUp(self):
method test_to_partial_json (line 126) | def test_to_partial_json(self):
method test_from_json (line 130) | def test_from_json(self):
method test_from_json_hashable (line 135) | def test_from_json_hashable(self):
method test_repr (line 138) | def test_repr(self):
method test_equality (line 142) | def test_equality(self):
class DirectoryTest (line 151) | class DirectoryTest(unittest.TestCase):
method setUp (line 154) | def setUp(self):
method test_init_wrong_key_value_success (line 170) | def test_init_wrong_key_value_success(self): # pylint: disable=no-sel...
method test_getitem (line 174) | def test_getitem(self):
method test_getitem_fails_with_key_error (line 177) | def test_getitem_fails_with_key_error(self):
method test_getattr (line 181) | def test_getattr(self):
method test_getattr_fails_with_attribute_error (line 184) | def test_getattr_fails_with_attribute_error(self):
method test_to_json (line 188) | def test_to_json(self):
method test_from_json_deserialization_unknown_key_success (line 203) | def test_from_json_deserialization_unknown_key_success(self): # pylin...
method test_iter_meta (line 207) | def test_iter_meta(self):
class ExternalAccountBindingTest (line 215) | class ExternalAccountBindingTest(unittest.TestCase):
method setUp (line 216) | def setUp(self):
method test_from_data (line 226) | def test_from_data(self):
method test_from_data_invalid_hmac_alg (line 233) | def test_from_data_invalid_hmac_alg(self):
method test_from_data_default_hmac_alg (line 241) | def test_from_data_default_hmac_alg(self):
class RegistrationTest (line 259) | class RegistrationTest(unittest.TestCase):
method setUp (line 262) | def setUp(self):
method test_from_data (line 282) | def test_from_data(self):
method test_new_registration_from_data_with_eab (line 290) | def test_new_registration_from_data_with_eab(self):
method test_phones (line 309) | def test_phones(self):
method test_emails (line 312) | def test_emails(self):
method test_to_partial_json (line 315) | def test_to_partial_json(self):
method test_from_json (line 318) | def test_from_json(self):
method test_from_json_hashable (line 322) | def test_from_json_hashable(self):
method test_default_not_transmitted (line 326) | def test_default_not_transmitted(self):
class UpdateRegistrationTest (line 340) | class UpdateRegistrationTest(unittest.TestCase):
method test_empty (line 343) | def test_empty(self):
class RegistrationResourceTest (line 350) | class RegistrationResourceTest(unittest.TestCase):
method setUp (line 353) | def setUp(self):
method test_to_partial_json (line 359) | def test_to_partial_json(self):
class ChallengeResourceTest (line 367) | class ChallengeResourceTest(unittest.TestCase):
method test_uri (line 370) | def test_uri(self):
class ChallengeBodyTest (line 376) | class ChallengeBodyTest(unittest.TestCase):
method setUp (line 379) | def setUp(self):
method test_encode (line 406) | def test_encode(self):
method test_to_partial_json (line 409) | def test_to_partial_json(self):
method test_from_json (line 412) | def test_from_json(self):
method test_from_json_hashable (line 416) | def test_from_json_hashable(self):
method test_proxy (line 420) | def test_proxy(self):
class AuthorizationTest (line 425) | class AuthorizationTest(unittest.TestCase):
method setUp (line 428) | def setUp(self):
method test_from_json (line 453) | def test_from_json(self):
method test_from_json_hashable (line 457) | def test_from_json_hashable(self):
class AuthorizationResourceTest (line 462) | class AuthorizationResourceTest(unittest.TestCase):
method test_json_de_serializable (line 465) | def test_json_de_serializable(self):
class CertificateRequestTest (line 473) | class CertificateRequestTest(unittest.TestCase):
method setUp (line 476) | def setUp(self):
method test_json_de_serializable (line 480) | def test_json_de_serializable(self):
class CertificateResourceTest (line 486) | class CertificateResourceTest(unittest.TestCase):
method setUp (line 489) | def setUp(self):
method test_json_de_serializable (line 495) | def test_json_de_serializable(self):
class RevocationTest (line 501) | class RevocationTest(unittest.TestCase):
method setUp (line 504) | def setUp(self):
method test_from_json_hashable (line 508) | def test_from_json_hashable(self):
class OrderResourceTest (line 513) | class OrderResourceTest(unittest.TestCase):
method setUp (line 516) | def setUp(self):
method test_to_partial_json (line 521) | def test_to_partial_json(self):
method test_json_de_serializable (line 528) | def test_json_de_serializable(self):
class NewOrderTest (line 559) | class NewOrderTest(unittest.TestCase):
method setUp (line 562) | def setUp(self):
method test_to_partial_json (line 567) | def test_to_partial_json(self):
method test_default_profile_empty (line 572) | def test_default_profile_empty(self):
method test_non_empty_profile (line 575) | def test_non_empty_profile(self):
class JWSPayloadRFC8555Compliant (line 584) | class JWSPayloadRFC8555Compliant(unittest.TestCase):
method test_message_payload (line 586) | def test_message_payload(self):
FILE: acme/src/acme/_internal/tests/standalone_test.py
class HTTP01ServerTest (line 18) | class HTTP01ServerTest(unittest.TestCase):
method setUp (line 22) | def setUp(self):
method tearDown (line 34) | def tearDown(self):
method test_index (line 39) | def test_index(self):
method test_404 (line 45) | def test_404(self):
method _test_http01 (line 50) | def _test_http01(self, add):
method test_http01_found (line 63) | def test_http01_found(self):
method test_http01_not_found (line 66) | def test_http01_not_found(self):
method test_timely_shutdown (line 69) | def test_timely_shutdown(self):
class BaseDualNetworkedServersTest (line 92) | class BaseDualNetworkedServersTest(unittest.TestCase):
class SingleProtocolServer (line 95) | class SingleProtocolServer(socketserver.TCPServer):
method __init__ (line 97) | def __init__(self, *args, **kwargs):
method test_fail_to_bind (line 118) | def test_fail_to_bind(self, mock_bind):
method test_ports_equal (line 132) | def test_ports_equal(self):
class HTTP01DualNetworkedServersTest (line 150) | class HTTP01DualNetworkedServersTest(unittest.TestCase):
method setUp (line 153) | def setUp(self):
method tearDown (line 164) | def tearDown(self):
method test_index (line 167) | def test_index(self):
method test_404 (line 173) | def test_404(self):
method _test_http01 (line 178) | def _test_http01(self, add):
method test_http01_found (line 191) | def test_http01_found(self):
method test_http01_not_found (line 194) | def test_http01_not_found(self):
FILE: acme/src/acme/_internal/tests/test_util.py
function load_vector (line 17) | def load_vector(*names):
function _guess_loader (line 24) | def _guess_loader(filename: str, loader_pem: Callable, loader_der: Calla...
function load_cert (line 34) | def load_cert(*names: str) -> x509.Certificate:
function load_csr (line 42) | def load_csr(*names: str) -> x509.CertificateSigningRequest:
function load_rsa_private_key (line 48) | def load_rsa_private_key(*names):
function load_ecdsa_private_key (line 56) | def load_ecdsa_private_key(*names):
FILE: acme/src/acme/_internal/tests/util_test.py
function test_it (line 7) | def test_it():
FILE: acme/src/acme/challenges.py
class Challenge (line 23) | class Challenge(jose.TypedJSONObjectWithFields):
method from_json (line 29) | def from_json(cls: type[GenericChallenge],
class ChallengeResponse (line 38) | class ChallengeResponse(jose.TypedJSONObjectWithFields):
method to_partial_json (line 43) | def to_partial_json(self) -> dict[str, Any]:
class UnrecognizedChallenge (line 51) | class UnrecognizedChallenge(Challenge):
method __init__ (line 65) | def __init__(self, jobj: Mapping[str, Any]) -> None:
method to_partial_json (line 69) | def to_partial_json(self) -> dict[str, Any]:
method from_json (line 73) | def from_json(cls, jobj: Mapping[str, Any]) -> 'UnrecognizedChallenge':
class _TokenChallenge (line 77) | class _TokenChallenge(Challenge):
method good_token (line 93) | def good_token(self) -> bool: # XXX: @token.decoder
class KeyAuthorizationChallengeResponse (line 107) | class KeyAuthorizationChallengeResponse(ChallengeResponse):
method verify (line 116) | def verify(self, chall: 'KeyAuthorizationChallenge', account_public_ke...
method to_partial_json (line 148) | def to_partial_json(self) -> dict[str, Any]:
class KeyAuthorizationChallenge (line 157) | class KeyAuthorizationChallenge(_TokenChallenge, metaclass=abc.ABCMeta):
method key_authorization (line 169) | def key_authorization(self, account_key: jose.JWK) -> str:
method response (line 180) | def response(self, account_key: jose.JWK) -> KeyAuthorizationChallenge...
method validation (line 193) | def validation(self, account_key: jose.JWK, **kwargs: Any) -> Any:
method response_and_validation (line 207) | def response_and_validation(self, account_key: jose.JWK, *args: Any, *...
class DNS01Response (line 223) | class DNS01Response(KeyAuthorizationChallengeResponse):
method simple_verify (line 227) | def simple_verify(self, chall: 'DNS01', domain: str, account_public_ke...
class DNS01 (line 250) | class DNS01(KeyAuthorizationChallenge):
method validation (line 258) | def validation(self, account_key: jose.JWK, **unused_kwargs: Any) -> str:
method validation_domain_name (line 268) | def validation_domain_name(self, name: str) -> str:
class HTTP01Response (line 279) | class HTTP01Response(KeyAuthorizationChallengeResponse):
method simple_verify (line 294) | def simple_verify(self, chall: 'HTTP01', domain: str, account_public_k...
class HTTP01 (line 352) | class HTTP01(KeyAuthorizationChallenge):
method path (line 361) | def path(self) -> str:
method uri (line 369) | def uri(self, identifier: str) -> str:
method validation (line 388) | def validation(self, account_key: jose.JWK, **unused_kwargs: Any) -> str:
class DNS (line 399) | class DNS(_TokenChallenge):
method gen_validation (line 406) | def gen_validation(self, account_key: jose.JWK, alg: jose.JWASignature...
method check_validation (line 421) | def check_validation(self, validation: jose.JWS, account_public_key: j...
method gen_response (line 438) | def gen_response(self, account_key: jose.JWK, **kwargs: Any) -> 'DNSRe...
method validation_domain_name (line 449) | def validation_domain_name(self, name: str) -> str:
class DNSResponse (line 459) | class DNSResponse(ChallengeResponse):
method check_validation (line 469) | def check_validation(self, chall: 'DNS', account_public_key: jose.JWK)...
FILE: acme/src/acme/client.py
class ClientV2 (line 34) | class ClientV2:
method __init__ (line 41) | def __init__(self, directory: messages.Directory, net: 'ClientNetwork'...
method new_account (line 50) | def new_account(self, new_account: messages.NewRegistration) -> messag...
method query_registration (line 69) | def query_registration(self, regr: messages.RegistrationResource
method update_registration (line 81) | def update_registration(self, regr: messages.RegistrationResource,
method _get_v2_account (line 103) | def _get_v2_account(self, regr: messages.RegistrationResource, update_...
method new_order (line 115) | def new_order(self, csr_pem: bytes, profile: Optional[str] = None) -> ...
method poll (line 149) | def poll(self, authzr: messages.AuthorizationResource
method poll_and_finalize (line 166) | def poll_and_finalize(self, orderr: messages.OrderResource,
method poll_authorizations (line 185) | def poll_authorizations(self, orderr: messages.OrderResource, deadline...
method begin_finalization (line 210) | def begin_finalization(self, orderr: messages.OrderResource
method poll_finalization (line 231) | def poll_finalization(self, orderr: messages.OrderResource,
method finalize_order (line 287) | def finalize_order(self, orderr: messages.OrderResource, deadline: dat...
method renewal_time (line 307) | def renewal_time(self, cert_pem: bytes
method revoke (line 374) | def revoke(self, cert: x509.Certificate, rsn: int) -> None:
method external_account_required (line 386) | def external_account_required(self) -> bool:
method _post_as_get (line 392) | def _post_as_get(self, *args: Any, **kwargs: Any) -> requests.Response:
method _get_links (line 402) | def _get_links(self, response: requests.Response, relation_type: str) ...
method get_directory (line 417) | def get_directory(cls, url: str, net: 'ClientNetwork') -> messages.Dir...
method _regr_from_response (line 429) | def _regr_from_response(cls, response: requests.Response, uri: Optiona...
method _send_recv_regr (line 440) | def _send_recv_regr(self, regr: messages.RegistrationResource,
method _post (line 454) | def _post(self, *args: Any, **kwargs: Any) -> requests.Response:
method deactivate_registration (line 463) | def deactivate_registration(self, regr: messages.RegistrationResource
method deactivate_authorization (line 477) | def deactivate_authorization(self,
method _authzr_from_response (line 494) | def _authzr_from_response(self, response: requests.Response,
method answer_challenge (line 504) | def answer_challenge(self, challb: messages.ChallengeBody,
method retry_after (line 534) | def retry_after(cls, response: requests.Response, default: int) -> dat...
method _revoke (line 565) | def _revoke(self, cert: x509.Certificate, rsn: int, url: str) -> None:
class ClientNetwork (line 586) | class ClientNetwork:
method __init__ (line 607) | def __init__(self, key: Optional[jose.JWK] = None,
method __del__ (line 624) | def __del__(self) -> None:
method _wrap_in_jws (line 632) | def _wrap_in_jws(self, obj: jose.JSONDeSerializable, nonce: str, url: ...
method _check_response (line 659) | def _check_response(cls, response: requests.Response,
method _send_request (line 717) | def _send_request(self, method: str, url: str, *args: Any, **kwargs: A...
method head (line 765) | def head(self, *args: Any, **kwargs: Any) -> requests.Response:
method get (line 775) | def get(self, url: str, content_type: str = JSON_CONTENT_TYPE,
method _add_nonce (line 781) | def _add_nonce(self, response: requests.Response) -> None:
method _get_nonce (line 793) | def _get_nonce(self, url: str, new_nonce_url: str) -> str:
method post (line 804) | def post(self, *args: Any, **kwargs: Any) -> requests.Response:
method _post_once (line 819) | def _post_once(self, url: str, obj: jose.JSONDeSerializable,
function _renewal_info_path_component (line 831) | def _renewal_info_path_component(cert: x509.Certificate) -> str:
FILE: acme/src/acme/crypto_util.py
class _ClientDeprecationModule (line 25) | class _ClientDeprecationModule(ModuleType):
method __init__ (line 30) | def __init__(self, module: ModuleType) -> None:
method __getattr__ (line 34) | def __getattr__(self, attr: str) -> Any:
method __setattr__ (line 40) | def __setattr__(self, attr: str, value: Any) -> None: # pragma: no cover
method __delattr__ (line 43) | def __delattr__(self, attr: str) -> None: # pragma: no cover
method __dir__ (line 46) | def __dir__(self) -> list[str]: # pragma: no cover
class Format (line 54) | class Format(enum.IntEnum):
method to_cryptography_encoding (line 63) | def to_cryptography_encoding(self) -> Encoding:
function make_csr (line 89) | def make_csr(
function get_names_from_subject_and_extensions (line 145) | def get_names_from_subject_and_extensions(
function get_identifiers_from_x509 (line 162) | def get_identifiers_from_x509(
function _cryptography_cert_or_req_san (line 199) | def _cryptography_cert_or_req_san(
function _now (line 227) | def _now() -> datetime:
function make_self_signed_cert (line 231) | def make_self_signed_cert(private_key: types.CertificateIssuerPrivateKey...
function dump_cryptography_chain (line 308) | def dump_cryptography_chain(
FILE: acme/src/acme/errors.py
class Error (line 16) | class Error(Exception):
class DependencyError (line 20) | class DependencyError(Error):
class SchemaValidationError (line 24) | class SchemaValidationError(jose_errors.DeserializationError):
class ClientError (line 28) | class ClientError(Error):
class UnexpectedUpdate (line 32) | class UnexpectedUpdate(ClientError):
class NonceError (line 36) | class NonceError(ClientError):
class BadNonce (line 40) | class BadNonce(NonceError):
method __init__ (line 42) | def __init__(self, nonce: str, error: Exception, *args: Any) -> None:
method __str__ (line 47) | def __str__(self) -> str:
class MissingNonce (line 51) | class MissingNonce(NonceError):
method __init__ (line 61) | def __init__(self, response: requests.Response, *args: Any) -> None:
method __str__ (line 65) | def __str__(self) -> str:
class PollError (line 71) | class PollError(ClientError):
method __init__ (line 83) | def __init__(self, exhausted: set['messages.AuthorizationResource'],
method timeout (line 92) | def timeout(self) -> bool:
method __repr__ (line 96) | def __repr__(self) -> str:
class ValidationError (line 101) | class ValidationError(Error):
method __init__ (line 105) | def __init__(self, failed_authzrs: list['messages.AuthorizationResourc...
method __str__ (line 109) | def __str__(self) -> str:
class TimeoutError (line 120) | class TimeoutError(Error): # pylint: disable=redefined-builtin
class IssuanceError (line 124) | class IssuanceError(Error):
method __init__ (line 127) | def __init__(self, error: 'messages.Error') -> None:
class ConflictError (line 136) | class ConflictError(ClientError):
method __init__ (line 144) | def __init__(self, location: str) -> None:
class WildcardUnsupportedError (line 149) | class WildcardUnsupportedError(Error):
class ARIError (line 153) | class ARIError(ClientError):
method __init__ (line 155) | def __init__(self, message: str, retry_after: datetime.datetime) -> None:
FILE: acme/src/acme/fields.py
class Fixed (line 12) | class Fixed(jose.Field):
method __init__ (line 15) | def __init__(self, json_name: str, value: Any) -> None:
method decode (line 20) | def decode(self, value: Any) -> Any:
method encode (line 25) | def encode(self, value: Any) -> Any:
class RFC3339Field (line 32) | class RFC3339Field(jose.Field):
method default_encoder (line 42) | def default_encoder(cls, value: datetime.datetime) -> str:
method default_decoder (line 46) | def default_decoder(cls, value: str) -> datetime.datetime:
function fixed (line 53) | def fixed(json_name: str, value: Any) -> Any:
function rfc3339 (line 58) | def rfc3339(json_name: str, omitempty: bool = False) -> Any:
FILE: acme/src/acme/jws.py
class Header (line 12) | class Header(jose.Header):
method nonce (line 22) | def nonce(value: str) -> bytes: # type: ignore[misc] # pylint: disab...
class Signature (line 30) | class Signature(jose.Signature):
class JWS (line 44) | class JWS(jose.JWS):
method sign (line 51) | def sign(cls, payload: bytes, key: jose.JWK, alg: jose.JWASignature, n...
FILE: acme/src/acme/messages.py
function is_acme_error (line 62) | def is_acme_error(err: BaseException) -> bool:
class _Constant (line 69) | class _Constant(jose.JSONDeSerializable, Hashable):
method __init__ (line 74) | def __init__(self, name: str) -> None:
method to_partial_json (line 79) | def to_partial_json(self) -> str:
method from_json (line 83) | def from_json(cls, jobj: str) -> '_Constant':
method __repr__ (line 88) | def __repr__(self) -> str:
method __eq__ (line 91) | def __eq__(self, other: Any) -> bool:
method __hash__ (line 94) | def __hash__(self) -> int:
class IdentifierType (line 98) | class IdentifierType(_Constant):
class Identifier (line 107) | class Identifier(jose.JSONObjectWithFields):
class Error (line 118) | class Error(jose.JSONObjectWithFields, errors.Error):
method subproblems (line 144) | def subproblems(value: list[dict[str, Any]]) -> tuple['Error', ...]: ...
method with_code (line 148) | def with_code(cls, code: str, **kwargs: Any) -> 'Error':
method description (line 164) | def description(self) -> Optional[str]:
method code (line 174) | def code(self) -> Optional[str]:
method __setattr__ (line 189) | def __setattr__(self, name: str, value: Any) -> None:
method __str__ (line 192) | def __str__(self) -> str:
class Status (line 205) | class Status(_Constant):
class Directory (line 220) | class Directory(jose.JSONDeSerializable):
class Meta (line 226) | class Meta(jose.JSONObjectWithFields):
method __init__ (line 234) | def __init__(self, **kwargs: Any) -> None:
method terms_of_service (line 239) | def terms_of_service(self) -> str:
method __iter__ (line 243) | def __iter__(self) -> Iterator[str]:
method _internal_name (line 249) | def _internal_name(self, name: str) -> str:
method __init__ (line 252) | def __init__(self, jobj: Mapping[str, Any]) -> None:
method __getattr__ (line 255) | def __getattr__(self, name: str) -> Any:
method __getitem__ (line 261) | def __getitem__(self, name: str) -> Any:
method to_partial_json (line 267) | def to_partial_json(self) -> dict[str, Any]:
method from_json (line 271) | def from_json(cls, jobj: MutableMapping[str, Any]) -> 'Directory':
class Resource (line 276) | class Resource(jose.JSONObjectWithFields):
class ResourceWithURI (line 285) | class ResourceWithURI(Resource):
class ResourceBody (line 294) | class ResourceBody(jose.JSONObjectWithFields):
class ExternalAccountBinding (line 298) | class ExternalAccountBinding:
method from_data (line 302) | def from_data(cls, account_public_key: jose.JWK, kid: str, hmac_key: str,
class Registration (line 331) | class Registration(ResourceBody):
method from_data (line 358) | def from_data(cls: type[GenericRegistration], phone: Optional[str] = N...
method __init__ (line 390) | def __init__(self, **kwargs: Any) -> None:
method _filter_contact (line 397) | def _filter_contact(self, prefix: str) -> tuple[str, ...]:
method _add_contact_if_appropriate (line 402) | def _add_contact_if_appropriate(self, jobj: dict[str, Any]) -> dict[st...
method to_partial_json (line 419) | def to_partial_json(self) -> dict[str, Any]:
method fields_to_partial_json (line 424) | def fields_to_partial_json(self) -> dict[str, Any]:
method phones (line 430) | def phones(self) -> tuple[str, ...]:
method emails (line 435) | def emails(self) -> tuple[str, ...]:
class NewRegistration (line 440) | class NewRegistration(Registration):
class UpdateRegistration (line 444) | class UpdateRegistration(Registration):
class RegistrationResource (line 448) | class RegistrationResource(ResourceWithURI):
class ChallengeBody (line 461) | class ChallengeBody(ResourceBody):
method __init__ (line 490) | def __init__(self, **kwargs: Any) -> None:
method encode (line 494) | def encode(self, name: str) -> Any:
method to_partial_json (line 497) | def to_partial_json(self) -> dict[str, Any]:
method fields_from_json (line 503) | def fields_from_json(cls, jobj: Mapping[str, Any]) -> dict[str, Any]:
method uri (line 509) | def uri(self) -> str:
method __getattr__ (line 513) | def __getattr__(self, name: str) -> Any:
method __iter__ (line 516) | def __iter__(self) -> Iterator[str]:
method _internal_name (line 522) | def _internal_name(self, name: str) -> str:
class ChallengeResource (line 526) | class ChallengeResource(Resource):
method uri (line 537) | def uri(self) -> str:
class Authorization (line 542) | class Authorization(ResourceBody):
method challenges (line 565) | def challenges(value: list[dict[str, Any]]) -> tuple[ChallengeBody, .....
class NewAuthorization (line 569) | class NewAuthorization(Authorization):
class UpdateAuthorization (line 573) | class UpdateAuthorization(Authorization):
class AuthorizationResource (line 577) | class AuthorizationResource(ResourceWithURI):
class CertificateRequest (line 588) | class CertificateRequest(jose.JSONObjectWithFields):
class CertificateResource (line 598) | class CertificateResource(ResourceWithURI):
class Revocation (line 610) | class Revocation(jose.JSONObjectWithFields):
class Order (line 621) | class Order(ResourceBody):
method identifiers (line 650) | def identifiers(value: list[dict[str, Any]]) -> tuple[Identifier, ...]...
class OrderResource (line 654) | class OrderResource(ResourceWithURI):
method authorizations (line 688) | def authorizations(value: list[dict[str, Any]]) -> tuple[Authorization...
class NewOrder (line 692) | class NewOrder(Order):
class RenewalInfo (line 696) | class RenewalInfo(ResourceBody):
class SuggestedWindow (line 700) | class SuggestedWindow(jose.JSONObjectWithFields):
FILE: acme/src/acme/standalone.py
class ACMEServerMixin (line 20) | class ACMEServerMixin:
class BaseDualNetworkedServers (line 27) | class BaseDualNetworkedServers:
method __init__ (line 35) | def __init__(self, ServerClass: type[socketserver.TCPServer], server_a...
method serve_forever (line 85) | def serve_forever(self) -> None:
method getsocknames (line 93) | def getsocknames(self) -> list[tuple[str, int]]:
method shutdown_and_server_close (line 97) | def shutdown_and_server_close(self) -> None:
class HTTPServer (line 108) | class HTTPServer(BaseHTTPServer.HTTPServer):
method __init__ (line 111) | def __init__(self, *args: Any, **kwargs: Any) -> None:
class HTTP01Server (line 120) | class HTTP01Server(HTTPServer, ACMEServerMixin):
method __init__ (line 123) | def __init__(self, server_address: tuple[str, int],
class HTTP01DualNetworkedServers (line 131) | class HTTP01DualNetworkedServers(BaseDualNetworkedServers):
method __init__ (line 135) | def __init__(self, *args: Any, **kwargs: Any) -> None:
class HTTP01RequestHandler (line 139) | class HTTP01RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
method __init__ (line 151) | def __init__(self, *args: Any, **kwargs: Any) -> None:
method timeout (line 164) | def timeout(self) -> int: # type: ignore[override]
method log_message (line 172) | def log_message(self, format: str, *args: Any) -> None: # pylint: dis...
method handle (line 176) | def handle(self) -> None:
method do_GET (line 181) | def do_GET(self) -> None: # pylint: disable=invalid-name,missing-func...
method handle_index (line 189) | def handle_index(self) -> None:
method handle_404 (line 196) | def handle_404(self) -> None:
method handle_simple_http_resource (line 203) | def handle_simple_http_resource(self) -> None:
method partial_init (line 219) | def partial_init(cls, simple_http_resources: set[HTTP01RequestHandler....
FILE: acme/src/acme/util.py
function map_keys (line 7) | def map_keys(dikt: Mapping[Any, Any], func: Callable[[Any], Any]) -> dic...
FILE: certbot-apache/src/certbot_apache/_internal/apache_util.py
function get_mod_deps (line 20) | def get_mod_deps(mod_name: str) -> list[str]:
function get_file_path (line 39) | def get_file_path(vhost_path: str) -> Optional[str]:
function get_internal_aug_path (line 56) | def get_internal_aug_path(vhost_path: str) -> str:
function _split_aug_path (line 68) | def _split_aug_path(vhost_path: str) -> tuple[str, str]:
function parse_define_file (line 92) | def parse_define_file(filepath: str, varname: str) -> dict[str, str]:
function unique_id (line 117) | def unique_id() -> str:
function included_in_paths (line 122) | def included_in_paths(filepath: str, paths: Iterable[str]) -> bool:
function parse_defines (line 137) | def parse_defines(define_cmd: list[str]) -> dict[str, str]:
function parse_includes (line 164) | def parse_includes(inc_cmd: list[str]) -> list[str]:
function parse_modules (line 178) | def parse_modules(mod_cmd: list[str]) -> list[str]:
function parse_from_subprocess (line 192) | def parse_from_subprocess(command: list[str], regexp: str) -> list[str]:
function _get_runtime_cfg (line 206) | def _get_runtime_cfg(command: list[str]) -> str:
function find_ssl_apache_conf (line 242) | def find_ssl_apache_conf(prefix: str) -> str:
FILE: certbot-apache/src/certbot_apache/_internal/apacheparser.py
class ApacheParserNode (line 12) | class ApacheParserNode(interfaces.ParserNode):
method __init__ (line 19) | def __init__(self, **kwargs: Any) -> None:
method save (line 29) | def save(self, msg: str) -> None:
method find_ancestors (line 32) | def find_ancestors(self, name: str) -> list["ApacheParserNode"]: # py...
class ApacheCommentNode (line 41) | class ApacheCommentNode(ApacheParserNode):
method __init__ (line 44) | def __init__(self, **kwargs: Any) -> None:
method __eq__ (line 49) | def __eq__(self, other: Any) -> bool:
class ApacheDirectiveNode (line 59) | class ApacheDirectiveNode(ApacheParserNode):
method __init__ (line 62) | def __init__(self, **kwargs: Any) -> None:
method __eq__ (line 70) | def __eq__(self, other: Any) -> bool:
method set_parameters (line 81) | def set_parameters(self, _parameters: Iterable[str]) -> None:
class ApacheBlockNode (line 86) | class ApacheBlockNode(ApacheDirectiveNode):
method __init__ (line 89) | def __init__(self, **kwargs: Any) -> None:
method __eq__ (line 93) | def __eq__(self, other: Any) -> bool:
method add_child_block (line 106) | def add_child_block(self, name: str, parameters: Optional[list[str]] =...
method add_child_directive (line 118) | def add_child_directive(self, name: str, parameters: Optional[list[str...
method add_child_comment (line 131) | def add_child_comment(
method find_blocks (line 143) | def find_blocks(self, name: str, exclude: bool = True) -> list["Apache...
method find_directives (line 151) | def find_directives(self, name: str, exclude: bool = True) -> list[Apa...
method find_comments (line 160) | def find_comments(self, comment: str, exact: bool = False) -> list[Apa...
method delete_child (line 167) | def delete_child(self, child: ParserNode) -> None:
method unsaved_files (line 171) | def unsaved_files(self) -> list[str]:
method parsed_paths (line 175) | def parsed_paths(self) -> list[str]:
FILE: certbot-apache/src/certbot_apache/_internal/assertions.py
function assertEqual (line 17) | def assertEqual(first: ParserNode, second: ParserNode) -> None:
function assertEqualComment (line 41) | def assertEqualComment(first: ParserNode, second: ParserNode) -> None: ...
function _assertEqualDirectiveComponents (line 51) | def _assertEqualDirectiveComponents(first: ParserNode, # pragma: no cover
function assertEqualDirective (line 68) | def assertEqualDirective(first: ParserNode, second: ParserNode) -> None:
function isPass (line 76) | def isPass(value: Any) -> bool: # pragma: no cover
function isPassDirective (line 83) | def isPassDirective(block: DirectiveNode) -> bool:
function isPassComment (line 95) | def isPassComment(comment: CommentNode) -> bool:
function isPassNodeList (line 105) | def isPassNodeList(nodelist: list[Union[DirectiveNode, CommentNode]]) ->...
function assertEqualSimple (line 125) | def assertEqualSimple(first: Any, second: Any) -> None:
function isEqualVirtualHost (line 131) | def isEqualVirtualHost(first: VirtualHost, second: VirtualHost) -> bool:
function assertEqualPathsList (line 152) | def assertEqualPathsList(first: Iterable[str], second: Iterable[str]) ->...
FILE: certbot-apache/src/certbot_apache/_internal/augeasparser.py
class AugeasParserNode (line 82) | class AugeasParserNode(interfaces.ParserNode):
method __init__ (line 85) | def __init__(self, **kwargs: Any) -> None:
method save (line 105) | def save(self, msg: Iterable[str]) -> None:
method find_ancestors (line 108) | def find_ancestors(self, name: str) -> list["AugeasParserNode"]:
method _create_blocknode (line 133) | def _create_blocknode(self, path: str) -> "AugeasBlockNode":
method _aug_get_name (line 159) | def _aug_get_name(self, path: str) -> str:
class AugeasCommentNode (line 176) | class AugeasCommentNode(AugeasParserNode):
method __init__ (line 179) | def __init__(self, **kwargs: Any) -> None:
method __eq__ (line 184) | def __eq__(self, other: Any) -> bool:
class AugeasDirectiveNode (line 194) | class AugeasDirectiveNode(AugeasParserNode):
method __init__ (line 197) | def __init__(self, **kwargs: Any) -> None:
method __eq__ (line 205) | def __eq__(self, other: Any) -> bool:
method set_parameters (line 216) | def set_parameters(self, parameters: Iterable[str]) -> None:
method parameters (line 235) | def parameters(self) -> tuple[str, ...]:
method _aug_get_params (line 245) | def _aug_get_params(self, path: str) -> list[str]:
class AugeasBlockNode (line 253) | class AugeasBlockNode(AugeasDirectiveNode):
method __init__ (line 256) | def __init__(self, **kwargs: Any) -> None:
method __eq__ (line 260) | def __eq__(self, other: Any) -> bool:
method add_child_block (line 273) | def add_child_block(self, name: str, # pragma: no cover
method add_child_directive (line 303) | def add_child_directive(self, name: str, # pragma: no cover
method add_child_comment (line 336) | def add_child_comment(
method find_blocks (line 361) | def find_blocks(self, name: str, exclude: bool = True) -> list["Augeas...
method find_directives (line 373) | def find_directives(self, name: str, exclude: bool = True) -> list["Au...
method find_comments (line 392) | def find_comments(self, comment: str) -> list["AugeasCommentNode"]:
method delete_child (line 408) | def delete_child(self, child: "AugeasParserNode") -> None:
method unsaved_files (line 421) | def unsaved_files(self) -> set[str]:
method parsed_paths (line 425) | def parsed_paths(self) -> list[str]:
method _create_commentnode (line 445) | def _create_commentnode(self, path: str) -> "AugeasCommentNode":
method _create_directivenode (line 458) | def _create_directivenode(self, path: str) -> "AugeasDirectiveNode":
method _aug_find_blocks (line 476) | def _aug_find_blocks(self, name: str) -> set[str]:
method _aug_resolve_child_position (line 490) | def _aug_resolve_child_position(
FILE: certbot-apache/src/certbot_apache/_internal/configurator.py
class OsOptions (line 49) | class OsOptions:
method __init__ (line 54) | def __init__(self,
class ApacheConfigurator (line 122) | class ApacheConfigurator(common.Configurator):
method pick_apache_config (line 148) | def pick_apache_config(self, warn_on_no_mod_ssl: bool = True) -> str:
method _override_cmds (line 174) | def _override_cmds(self) -> None:
method _prepare_options (line 185) | def _prepare_options(self) -> None:
method add_parser_arguments (line 203) | def add_parser_arguments(cls, add: Callable[..., None]) -> None:
method __init__ (line 241) | def __init__(self, *args: Any, **kwargs: Any) -> None:
method mod_ssl_conf (line 286) | def mod_ssl_conf(self) -> str:
method updated_mod_ssl_conf_digest (line 291) | def updated_mod_ssl_conf_digest(self) -> str:
method _open_module_file (line 295) | def _open_module_file(self, ssl_module_location: str) -> Optional[bytes]:
method openssl_version (line 305) | def openssl_version(self, warn_on_no_mod_ssl: bool = True) -> Optional...
method prepare (line 348) | def prepare(self) -> None:
method save (line 413) | def save(self, title: Optional[str] = None, temporary: bool = False) -...
method recovery_routine (line 438) | def recovery_routine(self) -> None:
method revert_challenge_config (line 453) | def revert_challenge_config(self) -> None:
method rollback_checkpoints (line 462) | def rollback_checkpoints(self, rollback: int = 1) -> None:
method _verify_exe_availability (line 474) | def _verify_exe_availability(self, exe: str) -> None:
method get_parser (line 481) | def get_parser(self) -> parser.ApacheParser:
method get_parsernode_root (line 487) | def get_parsernode_root(self, metadata: dict[str, Any]) -> dualparser....
method deploy_cert (line 510) | def deploy_cert(
method choose_vhosts (line 536) | def choose_vhosts(self, domain: str, create_if_no_ssl: bool = True) ->...
method _vhosts_for_wildcard (line 558) | def _vhosts_for_wildcard(self, domain: str) -> list[obj.VirtualHost]:
method _generate_no_suitable_vhost_error (line 573) | def _generate_no_suitable_vhost_error(self, target_name: str) -> error...
method _in_wildcard_scope (line 587) | def _in_wildcard_scope(self, name: str, domain: str) -> Optional[bool]:
method _choose_vhosts_wildcard (line 599) | def _choose_vhosts_wildcard(self, domain: str, create_ssl: bool = True
method _deploy_cert (line 639) | def _deploy_cert(
method choose_vhost (line 708) | def choose_vhost(self, target_name: str, create_if_no_ssl: bool = True...
method _choose_vhost_from_list (line 748) | def _choose_vhost_from_list(self, target_name: str,
method domain_in_names (line 773) | def domain_in_names(self, names: Iterable[str], target_name: str) -> b...
method find_best_http_vhost (line 796) | def find_best_http_vhost(
method _find_best_vhost (line 815) | def _find_best_vhost(
method _non_default_vhosts (line 879) | def _non_default_vhosts(self, vhosts: list[obj.VirtualHost]) -> list[o...
method get_all_names (line 885) | def get_all_names(self) -> set[str]:
method get_name_from_ip (line 918) | def get_name_from_ip(self, addr: obj.Addr) -> str:
method _get_vhost_names (line 938) | def _get_vhost_names(self, path: Optional[str]) -> tuple[Optional[str]...
method _add_servernames (line 964) | def _add_servernames(self, host: obj.VirtualHost) -> None:
method _create_vhost (line 981) | def _create_vhost(self, path: str) -> Optional[obj.VirtualHost]:
method get_virtual_hosts (line 1027) | def get_virtual_hosts(self) -> list[obj.VirtualHost]:
method get_virtual_hosts_v1 (line 1050) | def get_virtual_hosts_v1(self) -> list[obj.VirtualHost]:
method get_virtual_hosts_v2 (line 1103) | def get_virtual_hosts_v2(self) -> list[obj.VirtualHost]:
method _create_vhost_v2 (line 1120) | def _create_vhost_v2(self, node: ApacheBlockNode) -> obj.VirtualHost:
method _populate_vhost_names_v2 (line 1164) | def _populate_vhost_names_v2(self, vhost: obj.VirtualHost) -> None:
method prepare_server_https (line 1185) | def prepare_server_https(self, port: str, temp: bool = False) -> None:
method ensure_listen (line 1198) | def ensure_listen(self, port: str, https: bool = False) -> None:
method _add_listens_http (line 1248) | def _add_listens_http(self, listens: set[str], listens_orig: list[str]...
method _add_listens_https (line 1273) | def _add_listens_https(self, listens: set[str], listens_orig: list[str...
method _has_port_already (line 1306) | def _has_port_already(self, listens: list[str], port: str) -> Optional...
method prepare_https_modules (line 1324) | def prepare_https_modules(self, temp: bool) -> None:
method make_vhost_ssl (line 1345) | def make_vhost_ssl(self, nonssl_vhost: obj.VirtualHost) -> obj.Virtual...
method _get_new_vh_path (line 1421) | def _get_new_vh_path(self, orig_matches: list[str], new_matches: list[...
method _get_ssl_vhost_path (line 1435) | def _get_ssl_vhost_path(self, non_ssl_vh_fp: str) -> str:
method _sift_rewrite_rule (line 1457) | def _sift_rewrite_rule(self, line: str) -> bool:
method _copy_create_ssl_vhost_skeleton (line 1490) | def _copy_create_ssl_vhost_skeleton(self, vhost: obj.VirtualHost, ssl_...
method _sift_rewrite_rules (line 1537) | def _sift_rewrite_rules(self, contents: Iterable[str]) -> tuple[list[s...
method _get_vhost_block (line 1598) | def _get_vhost_block(self, vhost: obj.VirtualHost) -> list[str]:
method _remove_closing_vhost_tag (line 1621) | def _remove_closing_vhost_tag(self, vh_contents: list[str]) -> None:
method _update_ssl_vhosts_addrs (line 1640) | def _update_ssl_vhosts_addrs(self, vh_path: str) -> set[obj.Addr]:
method _clean_vhost (line 1653) | def _clean_vhost(self, vhost: obj.VirtualHost) -> None:
method _deduplicate_directives (line 1661) | def _deduplicate_directives(self, vh_path: Optional[str], directives: ...
method _remove_directives (line 1669) | def _remove_directives(self, vh_path: Optional[str], directives: list[...
method _add_dummy_ssl_directives (line 1676) | def _add_dummy_ssl_directives(self, vh_path: str) -> None:
method _add_servername_alias (line 1686) | def _add_servername_alias(self, target_name: str, vhost: obj.VirtualHo...
method _has_matching_wildcard (line 1700) | def _has_matching_wildcard(self, vh_path: str, target_name: str) -> bool:
method find_vhost_by_id (line 1716) | def find_vhost_by_id(self, id_str: str) -> obj.VirtualHost:
method _find_vhost_id (line 1735) | def _find_vhost_id(self, vhost: obj.VirtualHost) -> Optional[str]:
method add_vhost_id (line 1756) | def add_vhost_id(self, vhost: obj.VirtualHost) -> Optional[str]:
method _escape (line 1777) | def _escape(self, fp: str) -> str:
method supported_enhancements (line 1791) | def supported_enhancements(self) -> list[str]:
method enhance (line 1795) | def enhance(self, domain: str, enhancement: str,
method _autohsts_increase (line 1837) | def _autohsts_increase(
method _autohsts_write (line 1854) | def _autohsts_write(self, vhost: obj.VirtualHost, nextstep_value: floa...
method _autohsts_fetch_state (line 1885) | def _autohsts_fetch_state(self) -> None:
method _autohsts_save_state (line 1894) | def _autohsts_save_state(self) -> None:
method _autohsts_vhost_in_lineage (line 1901) | def _autohsts_vhost_in_lineage(
method _enable_ocsp_stapling (line 1910) | def _enable_ocsp_stapling(self, ssl_vhost: obj.VirtualHost, unused_opt...
method _set_http_header (line 1962) | def _set_http_header(self, ssl_vhost: obj.VirtualHost, header_substrin...
method _verify_no_matching_http_header (line 1999) | def _verify_no_matching_http_header(
method _enable_redirect (line 2029) | def _enable_redirect(self, ssl_vhost: obj.VirtualHost, unused_options:...
method _set_https_redirection_rewrite_rule (line 2110) | def _set_https_redirection_rewrite_rule(self, vhost: obj.VirtualHost) ...
method _verify_no_certbot_redirect (line 2113) | def _verify_no_certbot_redirect(self, vhost: obj.VirtualHost) -> None:
method _is_rewrite_exists (line 2158) | def _is_rewrite_exists(self, vhost: obj.VirtualHost) -> bool:
method _is_rewrite_engine_on (line 2172) | def _is_rewrite_engine_on(self, vhost: obj.VirtualHost) -> Optional[Un...
method _create_redirect_vhost (line 2188) | def _create_redirect_vhost(self, ssl_vhost: obj.VirtualHost) -> None:
method _get_redirect_config_str (line 2213) | def _get_redirect_config_str(self, ssl_vhost: obj.VirtualHost) -> str:
method _write_out_redirect (line 2237) | def _write_out_redirect(self, ssl_vhost: obj.VirtualHost, text: str) -...
method _get_http_vhost (line 2267) | def _get_http_vhost(self, ssl_vhost: obj.VirtualHost) -> Optional[obj....
method _get_proposed_addrs (line 2287) | def _get_proposed_addrs(self, vhost: obj.VirtualHost, port: str = "80"...
method enable_site (line 2302) | def enable_site(self, vhost: obj.VirtualHost) -> None:
method enable_mod (line 2330) | def enable_mod(self, mod_name: str, temp: bool = False) -> None:
method restart (line 2353) | def restart(self) -> None:
method _reload (line 2363) | def _reload(self) -> None:
method config_test (line 2388) | def config_test(self) -> None:
method get_version (line 2399) | def get_version(self) -> tuple[int, ...]:
method more_info (line 2425) | def more_info(self) -> str:
method auth_hint (line 2435) | def auth_hint(
method get_chall_pref (line 2445) | def get_chall_pref(self, unused_identifier: str) -> Sequence[type[chal...
method perform (line 2449) | def perform(self, achalls: list[achallenges.AnnotatedChallenge]
method _update_responses (line 2486) | def _update_responses(
method cleanup (line 2498) | def cleanup(self, achalls: list[achallenges.AnnotatedChallenge]) -> None:
method install_ssl_options_conf (line 2508) | def install_ssl_options_conf(
method enable_autohsts (line 2524) | def enable_autohsts(self, _unused_lineage: RenewableCert, domains: lis...
method _enable_autohsts_domain (line 2568) | def _enable_autohsts_domain(self, ssl_vhost: obj.VirtualHost) -> None:
method update_autohsts (line 2603) | def update_autohsts(self, _unused_domain: str) -> None:
method deploy_autohsts (line 2649) | def deploy_autohsts(self, lineage: RenewableCert) -> None:
FILE: certbot-apache/src/certbot_apache/_internal/constants.py
function _generate_augeas_lens_dir_static (line 42) | def _generate_augeas_lens_dir_static() -> str:
FILE: certbot-apache/src/certbot_apache/_internal/display_ops.py
function select_vhost_multiple (line 15) | def select_vhost_multiple(vhosts: Optional[list[VirtualHost]]) -> list[V...
function _reversemap_vhosts (line 39) | def _reversemap_vhosts(names: Iterable[str], vhosts: Iterable[VirtualHos...
function select_vhost (line 51) | def select_vhost(domain: str, vhosts: Sequence[VirtualHost]) -> Optional...
function _vhost_menu (line 71) | def _vhost_menu(domain: str, vhosts: Iterable[VirtualHost]) -> tuple[str...
FILE: certbot-apache/src/certbot_apache/_internal/dualparser.py
class DualNodeBase (line 24) | class DualNodeBase(Generic[GenericAugeasParserNode, GenericApacheParserN...
method __init__ (line 29) | def __init__(self, primary: GenericAugeasParserNode,
method save (line 34) | def save(self, msg: str) -> None: # pragma: no cover
method __getattr__ (line 39) | def __getattr__(self, aname: str) -> Any:
method find_ancestors (line 53) | def find_ancestors(self, name: str) -> list["DualBlockNode"]:
method _find_helper (line 57) | def _find_helper(self, nodeclass: type[GenericDualNode], findfunc: str...
class DualCommentNode (line 98) | class DualCommentNode(DualNodeBase[augeasparser.AugeasCommentNode,
method __init__ (line 102) | def __init__(self, **kwargs: Any) -> None:
class DualDirectiveNode (line 130) | class DualDirectiveNode(DualNodeBase[augeasparser.AugeasDirectiveNode,
method __init__ (line 136) | def __init__(self, **kwargs: Any) -> None:
method set_parameters (line 163) | def set_parameters(self, parameters: Iterable[str]) -> None:
class DualBlockNode (line 172) | class DualBlockNode(DualNodeBase[augeasparser.AugeasBlockNode,
method __init__ (line 176) | def __init__(self, **kwargs: Any) -> None:
method add_child_block (line 203) | def add_child_block(self, name: str, parameters: Optional[list[str]] =...
method add_child_directive (line 214) | def add_child_directive(self, name: str, parameters: Optional[list[str...
method add_child_comment (line 225) | def add_child_comment(self, comment: str = "",
method _create_matching_list (line 236) | def _create_matching_list(self, primary_list: Iterable[interfaces.Pars...
method find_blocks (line 265) | def find_blocks(self, name: str, exclude: bool = True) -> list["DualBl...
method find_directives (line 277) | def find_directives(self, name: str, exclude: bool = True) -> list[Dua...
method find_comments (line 289) | def find_comments(self, comment: str) -> list[DualCommentNode]:
method delete_child (line 300) | def delete_child(self, child: "DualBlockNode") -> None:
method unsaved_files (line 308) | def unsaved_files(self) -> set[str]:
method parsed_paths (line 317) | def parsed_paths(self) -> list[str]:
FILE: certbot-apache/src/certbot_apache/_internal/entrypoint.py
function get_configurator (line 44) | def get_configurator() -> type[configurator.ApacheConfigurator]:
FILE: certbot-apache/src/certbot_apache/_internal/http_01.py
class ApacheHttp01 (line 22) | class ApacheHttp01(common.ChallengePerformer):
method __init__ (line 38) | def __init__(self, configurator: "ApacheConfigurator") -> None:
method perform (line 52) | def perform(self) -> list[KeyAuthorizationChallengeResponse]:
method prepare_http01_modules (line 74) | def prepare_http01_modules(self) -> None:
method _mod_config (line 83) | def _mod_config(self) -> None:
method _matching_vhosts (line 125) | def _matching_vhosts(self, domain: str) -> list[VirtualHost]:
method _relevant_vhosts (line 139) | def _relevant_vhosts(self) -> list[VirtualHost]:
method _unnamed_vhosts (line 155) | def _unnamed_vhosts(self) -> list[VirtualHost]:
method _set_up_challenges (line 159) | def _set_up_challenges(self) -> list[KeyAuthorizationChallengeResponse]:
method _set_up_challenge (line 175) | def _set_up_challenge(self, achall: KeyAuthorizationAnnotatedChallenge
method _set_up_include_directives (line 189) | def _set_up_include_directives(self, vhost: VirtualHost) -> None:
FILE: certbot-apache/src/certbot_apache/_internal/interfaces.py
class ParserNode (line 109) | class ParserNode(metaclass=abc.ABCMeta):
method __init__ (line 157) | def __init__(self, **kwargs: Any) -> None:
method save (line 181) | def save(self, msg: str) -> None:
method find_ancestors (line 200) | def find_ancestors(self: GenericParserNode, name: str) -> list[Generic...
class CommentNode (line 212) | class CommentNode(ParserNode, metaclass=abc.ABCMeta):
method __init__ (line 232) | def __init__(self, **kwargs: Any) -> None:
class DirectiveNode (line 258) | class DirectiveNode(ParserNode, metaclass=abc.ABCMeta):
method __init__ (line 289) | def __init__(self, **kwargs: Any) -> None:
method set_parameters (line 327) | def set_parameters(self, parameters: list[str]) -> None:
class BlockNode (line 338) | class BlockNode(DirectiveNode, metaclass=abc.ABCMeta):
method add_child_block (line 381) | def add_child_block(self, name: str, parameters: Optional[list[str]] =...
method add_child_directive (line 402) | def add_child_directive(self, name: str, parameters: Optional[list[str...
method add_child_comment (line 424) | def add_child_comment(self, comment: str = "", position: Optional[int]...
method find_blocks (line 444) | def find_blocks(self, name: str, exclude: bool = True) -> list["BlockN...
method find_directives (line 461) | def find_directives(self, name: str, exclude: bool = True) -> list[Dir...
method find_comments (line 479) | def find_comments(self, comment: str) -> list[CommentNode]:
method delete_child (line 495) | def delete_child(self, child: ParserNode) -> None:
method unsaved_files (line 505) | def unsaved_files(self) -> list[str]:
method parsed_paths (line 518) | def parsed_paths(self) -> list[str]:
FILE: certbot-apache/src/certbot_apache/_internal/obj.py
class Addr (line 14) | class Addr(common.Addr):
method __eq__ (line 17) | def __eq__(self, other: Any) -> bool:
method __repr__ (line 29) | def __repr__(self) -> str:
method __hash__ (line 32) | def __hash__(self) -> int: # pylint: disable=useless-super-delegation
method _addr_less_specific (line 37) | def _addr_less_specific(self, addr: "Addr") -> bool:
method _rank_specific_addr (line 42) | def _rank_specific_addr(self) -> int:
method conflicts (line 55) | def conflicts(self, addr: "Addr") -> bool:
method is_wildcard (line 83) | def is_wildcard(self) -> bool:
method get_sni_addr (line 87) | def get_sni_addr(self, port: str) -> common.Addr:
class VirtualHost (line 104) | class VirtualHost:
method __init__ (line 129) | def __init__(self, filepath: str, path: str, addrs: set["Addr"], ssl: ...
method get_names (line 147) | def get_names(self) -> set[str]:
method __str__ (line 157) | def __str__(self) -> str:
method display_repr (line 169) | def display_repr(self) -> str:
method __eq__ (line 178) | def __eq__(self, other: Any) -> bool:
method __hash__ (line 189) | def __hash__(self) -> int:
method conflicts (line 194) | def conflicts(self, addrs: Iterable[Addr]) -> bool:
method same_server (line 213) | def same_server(self, vhost: "VirtualHost", generic: bool = False) -> ...
FILE: certbot-apache/src/certbot_apache/_internal/override_alpine.py
class AlpineConfigurator (line 6) | class AlpineConfigurator(configurator.ApacheConfigurator):
FILE: certbot-apache/src/certbot_apache/_internal/override_arch.py
class ArchConfigurator (line 6) | class ArchConfigurator(configurator.ApacheConfigurator):
FILE: certbot-apache/src/certbot_apache/_internal/override_centos.py
class CentOSConfigurator (line 15) | class CentOSConfigurator(configurator.ApacheConfigurator):
method config_test (line 32) | def config_test(self) -> None:
method _rhel9_or_newer (line 51) | def _rhel9_or_newer(self) -> bool:
method _override_cmds (line 68) | def _override_cmds(self) -> None:
method _try_restart_fedora (line 87) | def _try_restart_fedora(self) -> None:
method get_parser (line 100) | def get_parser(self) -> "CentOSParser":
class CentOSParser (line 106) | class CentOSParser(parser.ApacheParser):
method __init__ (line 108) | def __init__(self, *args: Any, **kwargs: Any) -> None:
method update_runtime_variables (line 113) | def update_runtime_variables(self) -> None:
method parse_sysconfig_var (line 119) | def parse_sysconfig_var(self) -> None:
FILE: certbot-apache/src/certbot_apache/_internal/override_darwin.py
class DarwinConfigurator (line 6) | class DarwinConfigurator(configurator.ApacheConfigurator):
FILE: certbot-apache/src/certbot_apache/_internal/override_debian.py
class DebianConfigurator (line 16) | class DebianConfigurator(configurator.ApacheConfigurator):
method enable_site (line 26) | def enable_site(self, vhost: VirtualHost) -> None:
method enable_mod (line 71) | def enable_mod(self, mod_name: str, temp: bool = False) -> None:
method _enable_mod_debian (line 117) | def _enable_mod_debian(self, mod_name: str, temp: bool) -> None:
FILE: certbot-apache/src/certbot_apache/_internal/override_fedora.py
class FedoraConfigurator (line 12) | class FedoraConfigurator(configurator.ApacheConfigurator):
method config_test (line 28) | def config_test(self) -> None:
method get_parser (line 40) | def get_parser(self) -> "FedoraParser":
method _try_restart_fedora (line 45) | def _try_restart_fedora(self) -> None:
method _prepare_options (line 57) | def _prepare_options(self) -> None:
class FedoraParser (line 71) | class FedoraParser(parser.ApacheParser):
method __init__ (line 73) | def __init__(self, *args: Any, **kwargs: Any) -> None:
method update_runtime_variables (line 78) | def update_runtime_variables(self) -> None:
method _parse_sysconfig_var (line 84) | def _parse_sysconfig_var(self) -> None:
FILE: certbot-apache/src/certbot_apache/_internal/override_gentoo.py
class GentooConfigurator (line 10) | class GentooConfigurator(configurator.ApacheConfigurator):
method _prepare_options (line 21) | def _prepare_options(self) -> None:
method get_parser (line 31) | def get_parser(self) -> "GentooParser":
class GentooParser (line 37) | class GentooParser(parser.ApacheParser):
method __init__ (line 39) | def __init__(self, *args: Any, **kwargs: Any) -> None:
method update_runtime_variables (line 44) | def update_runtime_variables(self) -> None:
method parse_sysconfig_var (line 49) | def parse_sysconfig_var(self) -> None:
method update_modules (line 56) | def update_modules(self) -> None:
FILE: certbot-apache/src/certbot_apache/_internal/override_suse.py
class OpenSUSEConfigurator (line 6) | class OpenSUSEConfigurator(configurator.ApacheConfigurator):
FILE: certbot-apache/src/certbot_apache/_internal/override_void.py
class VoidConfigurator (line 6) | class VoidConfigurator(configurator.ApacheConfigurator):
FILE: certbot-apache/src/certbot_apache/_internal/parser.py
class ApacheParser (line 29) | class ApacheParser:
method __init__ (line 45) | def __init__(self, root: str, configurator: "ApacheConfigurator",
method check_parsing_errors (line 92) | def check_parsing_errors(self, lens: str) -> None:
method check_aug_version (line 118) | def check_aug_version(self) -> Union[bool, list[str]]:
method unsaved_files (line 133) | def unsaved_files(self) -> set[str]:
method ensure_augeas_state (line 172) | def ensure_augeas_state(self) -> None:
method save (line 182) | def save(self, save_files: Iterable[str]) -> None:
method _log_save_errors (line 207) | def _log_save_errors(self, ex_errs: Iterable[str]) -> None:
method add_include (line 224) | def add_include(self, main_config: str, inc_path: str) -> None:
method add_mod (line 243) | def add_mod(self, mod_name: str) -> None:
method reset_modules (line 250) | def reset_modules(self) -> None:
method parse_modules (line 257) | def parse_modules(self) -> None:
method update_runtime_variables (line 285) | def update_runtime_variables(self) -> None:
method update_defines (line 292) | def update_defines(self) -> None:
method update_includes (line 296) | def update_includes(self) -> None:
method update_modules (line 310) | def update_modules(self) -> None:
method filter_args_num (line 317) | def filter_args_num(self, matches: str, args: int) -> list[str]:
method add_dir_to_ifmodssl (line 348) | def add_dir_to_ifmodssl(self, aug_conf_path: str, directive: str, args...
method get_ifmod (line 374) | def get_ifmod(self, aug_conf_path: str, mod: str) -> str:
method create_ifmod (line 396) | def create_ifmod(self, aug_conf_path: str, mod: str) -> str:
method add_dir (line 414) | def add_dir(
method add_dir_beginning (line 437) | def add_dir_beginning(self, aug_conf_path: Optional[str], dirname: str,
method add_comment (line 460) | def add_comment(self, aug_conf_path: str, comment: str) -> None:
method find_comments (line 469) | def find_comments(self, arg: str, start: Optional[str] = None) -> list...
method find_dir (line 491) | def find_dir(self, directive: str, arg: Optional[str] = None,
method get_arg (line 570) | def get_arg(self, match: str) -> Optional[str]:
method get_root_augpath (line 599) | def get_root_augpath(self) -> str:
method exclude_dirs (line 605) | def exclude_dirs(self, matches: Iterable[str]) -> list[str]:
method _pass_filter (line 619) | def _pass_filter(self, match: str, filter_: tuple[str, Collection[str]...
method standard_path_from_server_root (line 648) | def standard_path_from_server_root(self, arg: str) -> str:
method _get_include_path (line 667) | def _get_include_path(self, arg: Optional[str]) -> Optional[str]:
method fnmatch_to_re (line 713) | def fnmatch_to_re(self, clean_fn_match: str) -> str:
method parse_file (line 730) | def parse_file(self, filepath: str) -> None:
method parsed_in_current (line 757) | def parsed_in_current(self, filep: Optional[str]) -> bool:
method parsed_in_original (line 771) | def parsed_in_original(self, filep: Optional[str]) -> bool:
method _parsed_by_parser_paths (line 785) | def _parsed_by_parser_paths(self, filep: str, paths: Mapping[str, list...
method _check_path_actions (line 794) | def _check_path_actions(self, filepath: str) -> tuple[bool, bool]:
method _remove_httpd_transform (line 819) | def _remove_httpd_transform(self, filepath: str) -> None:
method _add_httpd_transform (line 834) | def _add_httpd_transform(self, incl: str) -> None:
method standardize_excl (line 862) | def standardize_excl(self) -> None:
method _set_locations (line 894) | def _set_locations(self) -> dict[str, str]:
method _find_config_root (line 913) | def _find_config_root(self) -> str:
function case_i (line 922) | def case_i(string: str) -> str:
function get_aug_path (line 938) | def get_aug_path(file_path: str) -> str:
function init_augeas (line 947) | def init_augeas() -> Augeas:
FILE: certbot-apache/src/certbot_apache/_internal/parsernode_util.py
function validate_kwargs (line 9) | def validate_kwargs(kwargs: dict[str, Any], required_names: Iterable[str...
function parsernode_kwargs (line 33) | def parsernode_kwargs(kwargs: dict[str, Any]
function commentnode_kwargs (line 64) | def commentnode_kwargs(kwargs: dict[str, Any]) -> tuple[Optional[str], d...
function directivenode_kwargs (line 99) | def directivenode_kwargs(kwargs: dict[str, Any]
FILE: certbot-apache/src/certbot_apache/_internal/tests/apache-conf-files/apache-conf-test-pebble.py
function main (line 15) | def main() -> int:
FILE: certbot-apache/src/certbot_apache/_internal/tests/augeasnode_test.py
function _get_augeasnode_mock (line 13) | def _get_augeasnode_mock(filepath):
class AugeasParserNodeTest (line 24) | class AugeasParserNodeTest(util.ApacheTest): # pylint: disable=too-many...
method setUp (line 27) | def setUp(self): # pylint: disable=arguments-differ
method test_save (line 42) | def test_save(self):
method test_unsaved_files (line 48) | def test_unsaved_files(self):
method test_get_block_node_name (line 54) | def test_get_block_node_name(self):
method test_find_blocks (line 73) | def test_find_blocks(self):
method test_find_blocks_case_insensitive (line 77) | def test_find_blocks_case_insensitive(self):
method test_find_directive_found (line 82) | def test_find_directive_found(self):
method test_find_directive_notfound (line 88) | def test_find_directive_notfound(self):
method test_find_directive_from_block (line 92) | def test_find_directive_from_block(self):
method test_find_comments (line 102) | def test_find_comments(self):
method test_set_parameters (line 111) | def test_set_parameters(self):
method test_set_parameters_atinit (line 124) | def test_set_parameters_atinit(self):
method test_set_parameters_delete (line 139) | def test_set_parameters_delete(self):
method test_add_child_comment (line 165) | def test_add_child_comment(self):
method test_delete_child (line 173) | def test_delete_child(self):
method test_delete_child_not_found (line 181) | def test_delete_child_not_found(self):
method test_add_child_block (line 188) | def test_add_child_block(self):
method test_add_child_block_beginning (line 198) | def test_add_child_block_beginning(self):
method test_add_child_block_append (line 209) | def test_add_child_block_append(self):
method test_add_child_block_append_alt (line 219) | def test_add_child_block_append_alt(self):
method test_add_child_block_middle (line 230) | def test_add_child_block_middle(self):
method test_add_child_block_existing_name (line 241) | def test_add_child_block_existing_name(self):
method test_node_init_error_bad_augeaspath (line 254) | def test_node_init_error_bad_augeaspath(self):
method test_node_init_error_missing_augeaspath (line 268) | def test_node_init_error_missing_augeaspath(self):
method test_add_child_directive (line 281) | def test_add_child_directive(self):
method test_add_child_directive_exception (line 293) | def test_add_child_directive_exception(self):
method test_parsed_paths (line 297) | def test_parsed_paths(self):
method test_find_ancestors (line 301) | def test_find_ancestors(self):
method test_find_ancestors_bad_path (line 317) | def test_find_ancestors_bad_path(self):
FILE: certbot-apache/src/certbot_apache/_internal/tests/autohsts_test.py
class AutoHSTSTest (line 14) | class AutoHSTSTest(util.ApacheTest):
method setUp (line 18) | def setUp(self): # pylint: disable=arguments-differ
method get_autohsts_value (line 31) | def get_autohsts_value(self, vh_path):
method test_autohsts_enable_headers_mod (line 44) | def test_autohsts_enable_headers_mod(self, mock_enable, _restart):
method test_autohsts_deploy_already_exists (line 51) | def test_autohsts_deploy_already_exists(self, _restart):
method test_autohsts_increase (line 59) | def test_autohsts_increase(self, mock_prepare, _mock_restart):
method test_autohsts_increase_noop (line 78) | def test_autohsts_increase_noop(self, mock_increase, _restart):
method test_autohsts_increase_no_header (line 93) | def test_autohsts_increase_no_header(self, _restart):
method test_autohsts_increase_and_make_permanent (line 105) | def test_autohsts_increase_and_make_permanent(self, _mock_restart):
method test_autohsts_update_noop (line 129) | def test_autohsts_update_noop(self):
method test_autohsts_make_permanent_noop (line 136) | def test_autohsts_make_permanent_noop(self):
method test_autohsts_no_ssl_vhost (line 143) | def test_autohsts_no_ssl_vhost(self, mock_select):
method test_autohsts_dont_enhance_twice (line 152) | def test_autohsts_dont_enhance_twice(self, mock_id, _restart):
method test_autohsts_remove_orphaned (line 157) | def test_autohsts_remove_orphaned(self):
method test_autohsts_make_permanent_vhost_not_found (line 170) | def test_autohsts_make_permanent_vhost_not_found(self):
FILE: certbot-apache/src/certbot_apache/_internal/tests/centos_test.py
function get_vh_truth (line 15) | def get_vh_truth(temp_dir, config_name):
class FedoraRestartTest (line 36) | class FedoraRestartTest(util.ApacheTest):
method setUp (line 39) | def setUp(self): # pylint: disable=arguments-differ
method _run_fedora_test (line 52) | def _run_fedora_test(self):
method test_non_fedora_error (line 58) | def test_non_fedora_error(self):
method test_fedora_restart_error (line 67) | def test_fedora_restart_error(self):
method test_fedora_restart (line 77) | def test_fedora_restart(self):
class UseCorrectApacheExecutableTest (line 89) | class UseCorrectApacheExecutableTest(util.ApacheTest):
method setUp (line 92) | def setUp(self): # pylint: disable=arguments-differ
method test_old_centos_rhel_and_fedora (line 101) | def test_old_centos_rhel_and_fedora(self, mock_get_os_info):
method test_new_rhel_derived (line 118) | def test_new_rhel_derived(self, mock_get_os_info):
class MultipleVhostsTestCentOS (line 135) | class MultipleVhostsTestCentOS(util.ApacheTest):
method setUp (line 139) | def setUp(self, mock_get_os_info): # pylint: disable=arguments-differ
method test_get_parser (line 153) | def test_get_parser(self):
method test_opportunistic_httpd_runtime_parsing (line 157) | def test_opportunistic_httpd_runtime_parsing(self, mock_get):
method test_get_virtual_hosts (line 190) | def test_get_virtual_hosts(self):
method test_get_sysconfig_vars (line 206) | def test_get_sysconfig_vars(self, mock_cfg):
method test_alt_restart_works (line 227) | def test_alt_restart_works(self, mock_run_script):
method test_alt_restart_errors (line 233) | def test_alt_restart_errors(self, mock_run_script):
FILE: certbot-apache/src/certbot_apache/_internal/tests/complex_parsing_test.py
class ComplexParserTest (line 11) | class ComplexParserTest(util.ParserTest):
method setUp (line 14) | def setUp(self): # pylint: disable=arguments-differ
method setup_variables (line 22) | def setup_variables(self):
method test_filter_args_num (line 33) | def test_filter_args_num(self):
method test_basic_variable_parsing (line 41) | def test_basic_variable_parsing(self):
method test_basic_variable_parsing_quotes (line 47) | def test_basic_variable_parsing_quotes(self):
method test_invalid_variable_parsing (line 53) | def test_invalid_variable_parsing(self):
method test_basic_ifdefine (line 60) | def test_basic_ifdefine(self):
method test_basic_ifmodule (line 64) | def test_basic_ifmodule(self):
method test_nested (line 68) | def test_nested(self):
method test_load_modules (line 72) | def test_load_modules(self):
method verify_fnmatch (line 81) | def verify_fnmatch(self, arg, hit=True):
method test_include (line 93) | def test_include(self):
method test_include_complex (line 96) | def test_include_complex(self):
method test_include_fullpath (line 99) | def test_include_fullpath(self):
method test_include_fullpath_trailing_slash (line 103) | def test_include_fullpath_trailing_slash(self):
method test_include_single_quotes (line 106) | def test_include_single_quotes(self):
method test_include_double_quotes (line 109) | def test_include_double_quotes(self):
method test_include_variable (line 112) | def test_include_variable(self):
method test_include_missing (line 115) | def test_include_missing(self):
FILE: certbot-apache/src/certbot_apache/_internal/tests/configurator_reverter_test.py
class ConfiguratorReverterTest (line 11) | class ConfiguratorReverterTest(util.ApacheTest):
method setUp (line 14) | def setUp(self): # pylint: disable=arguments-differ
method test_bad_save_checkpoint (line 22) | def test_bad_save_checkpoint(self):
method test_bad_save_finalize_checkpoint (line 28) | def test_bad_save_finalize_checkpoint(self):
method test_finalize_save (line 34) | def test_finalize_save(self):
method test_revert_challenge_config (line 41) | def test_revert_challenge_config(self):
method test_revert_challenge_config_error (line 48) | def test_revert_challenge_config_error(self):
method test_rollback_checkpoints (line 55) | def test_rollback_checkpoints(self):
method test_rollback_error (line 62) | def test_rollback_error(self):
method test_recovery_routine_reload (line 67) | def test_recovery_routine_reload(self):
FILE: certbot-apache/src/certbot_apache/_internal/tests/configurator_test.py
class MultipleVhostsTest (line 27) | class MultipleVhostsTest(util.ApacheTest):
method setUp (line 30) | def setUp(self): # pylint: disable=arguments-differ
method mock_deploy_cert (line 39) | def mock_deploy_cert(self, config):
method test_prepare_no_install (line 52) | def test_prepare_no_install(self, mock_surgery):
method test_prepare_version (line 62) | def test_prepare_version(self, mock_exe_exists, _):
method test_prepare_locked (line 71) | def test_prepare_locked(self):
method _test_prepare_locked (line 87) | def _test_prepare_locked(self, _node, _exists, _parser):
method test_add_parser_arguments (line 97) | def test_add_parser_arguments(self): # pylint: disable=no-self-use
method test_docs_parser_arguments (line 103) | def test_docs_parser_arguments(self):
method test_add_parser_arguments_all_configurators (line 131) | def test_add_parser_arguments_all_configurators(self): # pylint: disa...
method test_all_configurators_defaults_defined (line 136) | def test_all_configurators_defaults_defined(self):
method test_constant (line 143) | def test_constant(self):
method test_get_all_names (line 147) | def test_get_all_names(self, mock_getutility):
method test_get_all_names_addrs (line 157) | def test_get_all_names_addrs(self, mock_gethost, mock_getutility):
method test_get_bad_path (line 176) | def test_get_bad_path(self):
method test_get_aug_internal_path (line 181) | def test_get_aug_internal_path(self):
method test_bad_servername_alias (line 191) | def test_bad_servername_alias(self):
method test_add_servernames_alias (line 199) | def test_add_servernames_alias(self):
method test_get_virtual_hosts (line 206) | def test_get_virtual_hosts(self):
method test_choose_vhost_none_avail (line 231) | def test_choose_vhost_none_avail(self, mock_select):
method test_choose_vhost_select_vhost_ssl (line 237) | def test_choose_vhost_select_vhost_ssl(self, mock_select):
method test_choose_vhost_select_vhost_non_ssl (line 243) | def test_choose_vhost_select_vhost_non_ssl(self, mock_conf, mock_select):
method test_choose_vhost_and_servername_addition (line 256) | def test_choose_vhost_and_servername_addition(self, mock_add, mock_find):
method test_choose_vhost_select_vhost_with_temp (line 264) | def test_choose_vhost_select_vhost_with_temp(self, mock_select):
method test_choose_vhost_select_vhost_conflicting_non_ssl (line 270) | def test_choose_vhost_select_vhost_conflicting_non_ssl(self, mock_sele...
method test_find_best_http_vhost_default (line 280) | def test_find_best_http_vhost_default(self):
method test_find_best_http_vhost_port (line 286) | def test_find_best_http_vhost_port(self):
method test_findbest_continues_on_short_domain (line 294) | def test_findbest_continues_on_short_domain(self):
method test_findbest_continues_on_long_domain (line 298) | def test_findbest_continues_on_long_domain(self):
method test_find_best_vhost (line 302) | def test_find_best_vhost(self):
method test_find_best_vhost_variety (line 308) | def test_find_best_vhost_variety(self):
method test_find_best_vhost_default (line 317) | def test_find_best_vhost_default(self):
method test_non_default_vhosts (line 330) | def test_non_default_vhosts(self):
method test_deploy_cert_enable_new_vhost (line 336) | def test_deploy_cert_enable_new_vhost(self, unused_mock_notify):
method test_no_duplicate_include (line 349) | def test_no_duplicate_include(self):
method test_deploy_cert (line 375) | def test_deploy_cert(self, unused_mock_notify):
method test_add_listen_80 (line 442) | def test_add_listen_80(self):
method test_add_listen_80_named (line 454) | def test_add_listen_80_named(self):
method test_prepare_server_https (line 484) | def test_prepare_server_https(self, mock_reset):
method test_prepare_server_https_named_listen (line 511) | def test_prepare_server_https_named_listen(self, mock_reset):
method test_prepare_server_https_needed_listen (line 549) | def test_prepare_server_https_needed_listen(self, mock_reset):
method test_prepare_server_https_mixed_listen (line 566) | def test_prepare_server_https_mixed_listen(self, mock_reset):
method test_make_vhost_ssl_with_mock_span (line 585) | def test_make_vhost_ssl_with_mock_span(self):
method test_make_vhost_ssl_with_mock_span2 (line 593) | def test_make_vhost_ssl_with_mock_span2(self):
method test_make_vhost_ssl_nonsymlink (line 601) | def test_make_vhost_ssl_nonsymlink(self):
method test_make_vhost_ssl_nonexistent_vhost_path (line 607) | def test_make_vhost_ssl_nonexistent_vhost_path(self):
method test_make_vhost_ssl (line 612) | def test_make_vhost_ssl(self):
method test_clean_vhost_ssl (line 629) | def test_clean_vhost_ssl(self):
method test_deduplicate_directives (line 657) | def test_deduplicate_directives(self):
method test_remove_directives (line 671) | def test_remove_directives(self):
method test_make_vhost_ssl_bad_write (line 687) | def test_make_vhost_ssl_bad_write(self):
method test_get_ssl_vhost_path (line 696) | def test_get_ssl_vhost_path(self):
method test_perform (line 702) | def test_perform(self, mock_restart, mock_http_perform):
method test_cleanup (line 719) | def test_cleanup(self, mock_cfg, mock_restart):
method test_cleanup_no_errors (line 735) | def test_cleanup_no_errors(self, mock_cfg, mock_restart):
method test_get_version (line 750) | def test_get_version(self, mock_script):
method test_restart (line 775) | def test_restart(self, _):
method test_restart_bad_process (line 779) | def test_restart_bad_process(self, mock_run_script):
method test_config_test (line 786) | def test_config_test(self, _):
method test_config_test_bad_process (line 790) | def test_config_test_bad_process(self, mock_run_script):
method test_more_info (line 796) | def test_more_info(self):
method test_get_chall_pref (line 799) | def test_get_chall_pref(self):
method test_install_ssl_options_conf (line 802) | def test_install_ssl_options_conf(self):
method test_supported_enhancements (line 810) | def test_supported_enhancements(self):
method test_find_http_vhost_without_ancestor (line 813) | def test_find_http_vhost_without_ancestor(self):
method test_enhance_unknown_vhost (line 825) | def test_enhance_unknown_vhost(self, mock_exe, mock_sel_vhost, mock_get):
method test_enhance_unknown_enhancement (line 839) | def test_enhance_unknown_enhancement(self):
method test_enhance_no_ssl_vhost (line 843) | def test_enhance_no_ssl_vhost(self):
method test_ocsp_stapling (line 860) | def test_ocsp_stapling(self, mock_exe):
method test_ocsp_stapling_twice (line 887) | def test_ocsp_stapling_twice(self, mock_exe):
method test_get_http_vhost_third_filter (line 912) | def test_get_http_vhost_third_filter(self):
method test_http_header_hsts (line 925) | def test_http_header_hsts(self, mock_exe, _):
method test_http_header_hsts_twice (line 947) | def test_http_header_hsts_twice(self):
method test_http_header_uir (line 963) | def test_http_header_uir(self, mock_exe, _):
method test_http_header_uir_twice (line 988) | def test_http_header_uir_twice(self):
method test_redirect_well_formed_http (line 1004) | def test_redirect_well_formed_http(self, mock_exe, _):
method test_rewrite_rule_exists (line 1029) | def test_rewrite_rule_exists(self):
method test_rewrite_engine_exists (line 1038) | def test_rewrite_engine_exists(self):
method test_redirect_with_existing_rewrite (line 1049) | def test_redirect_with_existing_rewrite(self, mock_exe, _):
method test_redirect_with_old_https_redirection (line 1083) | def test_redirect_with_old_https_redirection(self, mock_exe, _):
method test_redirect_with_conflict (line 1112) | def test_redirect_with_conflict(self):
method test_redirect_two_domains_one_vhost (line 1124) | def test_redirect_two_domains_one_vhost(self):
method test_redirect_from_previous_run (line 1139) | def test_redirect_from_previous_run(self):
method test_create_own_redirect (line 1152) | def test_create_own_redirect(self):
method test_create_own_redirect_for_old_apache_version (line 1163) | def test_create_own_redirect_for_old_apache_version(self):
method test_sift_rewrite_rule (line 1174) | def test_sift_rewrite_rule(self):
method get_key_and_achalls (line 1188) | def get_key_and_achalls(self):
method test_enable_site_nondebian (line 1213) | def test_enable_site_nondebian(self):
method test_deploy_cert_not_parsed_path (line 1227) | def test_deploy_cert_not_parsed_path(self, unused_mock_notify):
method test_deploy_cert_no_mod_ssl (line 1249) | def test_deploy_cert_no_mod_ssl(self):
method test_choose_vhost_and_servername_addition_parsed (line 1260) | def test_choose_vhost_and_servername_addition_parsed(self, mock_parsed):
method test_enable_mod_unsupported (line 1267) | def test_enable_mod_unsupported(self):
method test_choose_vhosts_wildcard (line 1271) | def test_choose_vhosts_wildcard(self):
method test_choose_vhosts_wildcard_no_ssl (line 1290) | def test_choose_vhosts_wildcard_no_ssl(self, mock_makessl):
method test_choose_vhosts_wildcard_already_ssl (line 1302) | def test_choose_vhosts_wildcard_already_ssl(self, mock_makessl, mock_v...
method test_deploy_cert_wildcard (line 1322) | def test_deploy_cert_wildcard(self, unused_mock_notify):
method test_deploy_cert_wildcard_no_vhosts (line 1336) | def test_deploy_cert_wildcard_no_vhosts(self, mock_dialog):
method test_enhance_wildcard_after_install (line 1344) | def test_enhance_wildcard_after_install(self, mock_choose):
method test_enhance_wildcard_no_install (line 1355) | def test_enhance_wildcard_no_install(self, mock_choose):
method test_add_vhost_id (line 1364) | def test_add_vhost_id(self):
method test_find_vhost_by_id_404 (line 1369) | def test_find_vhost_by_id_404(self):
method test_add_vhost_id_already_exists (line 1373) | def test_add_vhost_id_already_exists(self):
method test_realpath_replaces_symlink (line 1378) | def test_realpath_replaces_symlink(self):
class AugeasVhostsTest (line 1402) | class AugeasVhostsTest(util.ApacheTest):
method setUp (line 1406) | def setUp(self): # pylint: disable=arguments-differ
method test_choosevhost_with_illegal_name (line 1418) | def test_choosevhost_with_illegal_name(self):
method test_choosevhost_works (line 1425) | def test_choosevhost_works(self):
method test_get_vhost_continue (line 1431) | def test_get_vhost_continue(self, mock_vhost):
method test_choose_vhost_with_matching_wildcard (line 1436) | def test_choose_vhost_with_matching_wildcard(self):
method test_choose_vhost_without_matching_wildcard (line 1444) | def test_choose_vhost_without_matching_wildcard(self, mock_conflicts):
method test_choose_vhost_wildcard_not_found (line 1452) | def test_choose_vhost_wildcard_not_found(self, mock_conflicts):
method test_choose_vhost_wildcard_found (line 1465) | def test_choose_vhost_wildcard_found(self):
method test_augeas_span_error (line 1476) | def test_augeas_span_error(self):
class MultiVhostsTest (line 1483) | class MultiVhostsTest(util.ApacheTest):
method setUp (line 1487) | def setUp(self): # pylint: disable=arguments-differ
method test_make_vhost_ssl (line 1499) | def test_make_vhost_ssl(self):
method test_get_new_path (line 1520) | def test_get_new_path(self):
method test_make_vhost_ssl_with_existing_rewrite_rule (line 1531) | def test_make_vhost_ssl_with_existing_rewrite_rule(self, mock_notify):
method test_make_vhost_ssl_with_existing_rewrite_conds (line 1550) | def test_make_vhost_ssl_with_existing_rewrite_conds(self, mock_notify):
class InstallSslOptionsConfTest (line 1579) | class InstallSslOptionsConfTest(util.ApacheTest):
method setUp (line 1582) | def setUp(self): # pylint: disable=arguments-differ
method _call (line 1588) | def _call(self):
method _current_ssl_options_hash (line 1592) | def _current_ssl_options_hash(self):
method _assert_current_file (line 1595) | def _assert_current_file(self):
method test_no_file (line 1600) | def test_no_file(self):
method test_current_file (line 1608) | def test_current_file(self):
method test_prev_file_updates_to_current (line 1613) | def test_prev_file_updates_to_current(self):
method test_manually_modified_current_file_does_not_update (line 1621) | def test_manually_modified_current_file_does_not_update(self):
method test_manually_modified_past_file_warns (line 1634) | def test_manually_modified_past_file_warns(self):
method test_pick_apache_config_versions_and_warnings (line 1654) | def test_pick_apache_config_versions_and_warnings(self, mock_openssl_v...
method test_ssl_config_files_hash_in_all_hashes (line 1696) | def test_ssl_config_files_hash_in_all_hashes(self):
method test_openssl_version (line 1718) | def test_openssl_version(self):
method test_openssl_version_warns (line 1747) | def test_openssl_version_warns(self):
method test_open_module_file (line 1786) | def test_open_module_file(self):
FILE: certbot-apache/src/certbot_apache/_internal/tests/conftest.py
function mock_sleep (line 6) | def mock_sleep():
FILE: certbot-apache/src/certbot_apache/_internal/tests/debian_test.py
class MultipleVhostsTestDebian (line 16) | class MultipleVhostsTestDebian(util.ApacheTest):
method setUp (line 19) | def setUp(self): # pylint: disable=arguments-differ
method mock_deploy_cert (line 28) | def mock_deploy_cert(self, config):
method test_enable_mod_unsupported_dirs (line 42) | def test_enable_mod_unsupported_dirs(self):
method test_enable_mod (line 50) | def test_enable_mod(self, mock_run, mock_exe_exists, mock_run_script):
method test_deploy_cert_enable_new_vhost (line 62) | def test_deploy_cert_enable_new_vhost(self):
method test_enable_site_failure (line 81) | def test_enable_site_failure(self):
method test_deploy_cert_newssl (line 90) | def test_deploy_cert_newssl(self):
method test_deploy_cert_newssl_no_fullchain (line 125) | def test_deploy_cert_newssl_no_fullchain(self):
method test_deploy_cert_old_apache_no_chain (line 140) | def test_deploy_cert_old_apache_no_chain(self):
method test_ocsp_stapling_enable_mod (line 157) | def test_ocsp_stapling_enable_mod(self, mock_exe, _):
method test_ensure_http_header_enable_mod (line 169) | def test_ensure_http_header_enable_mod(self, mock_exe, _):
method test_redirect_enable_mod (line 182) | def test_redirect_enable_mod(self, mock_exe, _):
method test_enable_site_already_enabled (line 191) | def test_enable_site_already_enabled(self):
method test_enable_site_call_parent (line 195) | def test_enable_site_call_parent(self):
method test_enable_mod_no_disable (line 205) | def test_enable_mod_no_disable(self, mock_exe_exists):
FILE: certbot-apache/src/certbot_apache/_internal/tests/display_ops_test.py
class SelectVhostMultiTest (line 16) | class SelectVhostMultiTest(unittest.TestCase):
method setUp (line 19) | def setUp(self):
method test_select_no_input (line 24) | def test_select_no_input(self):
method test_select_correct (line 28) | def test_select_correct(self, mock_util):
method test_select_cancel (line 40) | def test_select_cancel(self, mock_util):
class SelectVhostTest (line 46) | class SelectVhostTest(unittest.TestCase):
method setUp (line 49) | def setUp(self):
method _call (line 55) | def _call(cls, vhosts):
method test_successful_choice (line 60) | def test_successful_choice(self, mock_util):
method test_noninteractive (line 65) | def test_noninteractive(self, mock_util):
method test_more_info_cancel (line 73) | def test_more_info_cancel(self, mock_util):
method test_no_vhosts (line 80) | def test_no_vhosts(self):
method test_small_display (line 85) | def test_small_display(self, mock_logger, mock_display_util):
method test_multiple_names (line 93) | def test_multiple_names(self, mock_util):
FILE: certbot-apache/src/certbot_apache/_internal/tests/dualnode_test.py
class DualParserNodeTest (line 11) | class DualParserNodeTest(unittest.TestCase): # pylint: disable=too-many...
method setUp (line 14) | def setUp(self): # pylint: disable=arguments-differ
method test_create_with_precreated (line 36) | def test_create_with_precreated(self):
method test_set_params (line 60) | def test_set_params(self):
method test_set_parameters (line 68) | def test_set_parameters(self):
method test_delete_child (line 79) | def test_delete_child(self):
method test_unsaved_files (line 88) | def test_unsaved_files(self):
method test_getattr_equality (line 99) | def test_getattr_equality(self):
method test_parsernode_dirty_assert (line 112) | def test_parsernode_dirty_assert(self):
method test_parsernode_filepath_assert (line 124) | def test_parsernode_filepath_assert(self):
method test_add_child_block (line 134) | def test_add_child_block(self):
method test_add_child_directive (line 143) | def test_add_child_directive(self):
method test_add_child_comment (line 152) | def test_add_child_comment(self):
method test_find_comments (line 161) | def test_find_comments(self):
method test_find_blocks_first_passing (line 187) | def test_find_blocks_first_passing(self):
method test_find_blocks_second_passing (line 210) | def test_find_blocks_second_passing(self):
method test_find_dirs_first_passing (line 233) | def test_find_dirs_first_passing(self):
method test_find_dirs_second_passing (line 256) | def test_find_dirs_second_passing(self):
method test_find_coms_first_passing (line 279) | def test_find_coms_first_passing(self):
method test_find_coms_second_passing (line 302) | def test_find_coms_second_passing(self):
method test_find_blocks_no_pass_equal (line 325) | def test_find_blocks_no_pass_equal(self):
method test_find_dirs_no_pass_equal (line 345) | def test_find_dirs_no_pass_equal(self):
method test_find_comments_no_pass_equal (line 365) | def test_find_comments_no_pass_equal(self):
method test_find_blocks_no_pass_notequal (line 385) | def test_find_blocks_no_pass_notequal(self):
method test_parsernode_notequal (line 402) | def test_parsernode_notequal(self):
method test_parsed_paths (line 419) | def test_parsed_paths(self):
method test_parsed_paths_error (line 430) | def test_parsed_paths_error(self):
method test_find_ancestors (line 438) | def test_find_ancestors(self):
FILE: certbot-apache/src/certbot_apache/_internal/tests/entrypoint_test.py
function test_get_configurator (line 11) | def test_get_configurator():
function test_nonexistent_like (line 23) | def test_nonexistent_like():
function test_nonexistent_generic (line 32) | def test_nonexistent_generic():
FILE: certbot-apache/src/certbot_apache/_internal/tests/fedora_test.py
function get_vh_truth (line 15) | def get_vh_truth(temp_dir, config_name):
class FedoraRestartTest (line 38) | class FedoraRestartTest(util.ApacheTest):
method setUp (line 43) | def setUp(self): # pylint: disable=arguments-differ
method _run_fedora_test (line 56) | def _run_fedora_test(self):
method test_fedora_restart_error (line 60) | def test_fedora_restart_error(self):
method test_fedora_restart (line 70) | def test_fedora_restart(self):
class MultipleVhostsTestFedora (line 82) | class MultipleVhostsTestFedora(util.ApacheTest):
method setUp (line 85) | def setUp(self): # pylint: disable=arguments-differ
method test_get_parser (line 99) | def test_get_parser(self):
method test_opportunistic_httpd_runtime_parsing (line 103) | def test_opportunistic_httpd_runtime_parsing(self, mock_get):
method test_get_version (line 137) | def test_get_version(self, mock_run_script):
method test_get_virtual_hosts (line 143) | def test_get_virtual_hosts(self):
method test_get_sysconfig_vars (line 159) | def test_get_sysconfig_vars(self, mock_cfg):
method test_alt_restart_works (line 180) | def test_alt_restart_works(self, mock_run_script):
method test_alt_restart_errors (line 186) | def test_alt_restart_errors(self, mock_run_script):
FILE: certbot-apache/src/certbot_apache/_internal/tests/gentoo_test.py
function get_vh_truth (line 15) | def get_vh_truth(temp_dir, config_name):
class MultipleVhostsTestGentoo (line 42) | class MultipleVhostsTestGentoo(util.ApacheTest):
method setUp (line 45) | def setUp(self): # pylint: disable=arguments-differ
method test_get_parser (line 61) | def test_get_parser(self):
method test_get_virtual_hosts (line 64) | def test_get_virtual_hosts(self):
method test_get_sysconfig_vars (line 79) | def test_get_sysconfig_vars(self):
method test_no_binary_configdump (line 92) | def test_no_binary_configdump(self, mock_subprocess):
method test_opportunistic_httpd_runtime_parsing (line 106) | def test_opportunistic_httpd_runtime_parsing(self, mock_get):
method test_alt_restart_works (line 130) | def test_alt_restart_works(self, mock_run_script):
FILE: certbot-apache/src/certbot_apache/_internal/tests/http_01_test.py
class ApacheHttp01Test (line 20) | class ApacheHttp01Test(util.ApacheTest):
method setUp (line 23) | def setUp(self, *args, **kwargs): # pylint: disable=arguments-differ
method test_empty_perform (line 51) | def test_empty_perform(self):
method test_ip_address_perform (line 54) | def test_ip_address_perform(self):
method test_enable_modules_apache_2_4 (line 65) | def test_enable_modules_apache_2_4(self, mock_enmod):
method common_enable_modules_test (line 72) | def common_enable_modules_test(self, mock_enmod):
method test_same_vhost (line 90) | def test_same_vhost(self):
method test_anonymous_vhost (line 108) | def test_anonymous_vhost(self):
method test_configure_multiple_vhosts (line 119) | def test_configure_multiple_vhosts(self):
method test_configure_name_and_blank (line 131) | def test_configure_name_and_blank(self):
method test_no_vhost (line 144) | def test_no_vhost(self):
method test_perform_1_achall_apache_2_4 (line 151) | def test_perform_1_achall_apache_2_4(self):
method test_perform_2_achall_apache_2_4 (line 154) | def test_perform_2_achall_apache_2_4(self):
method test_perform_3_achall_apache_2_4 (line 157) | def test_perform_3_achall_apache_2_4(self):
method test_activate_disabled_vhost (line 160) | def test_activate_disabled_vhost(self):
method combinations_perform_test (line 176) | def combinations_perform_test(self, num_achalls, minor_version):
method common_perform_test (line 183) | def common_perform_test(self, achalls, vhosts):
method test_failed_makedirs (line 214) | def test_failed_makedirs(self, mock_makedirs):
method _test_challenge_conf (line 220) | def _test_challenge_conf(self):
method _test_challenge_file (line 233) | def _test_challenge_file(self, achall):
FILE: certbot-apache/src/certbot_apache/_internal/tests/obj_test.py
class VirtualHostTest (line 8) | class VirtualHostTest(unittest.TestCase):
method setUp (line 11) | def setUp(self):
method test_repr (line 28) | def test_repr(self):
method test_eq (line 32) | def test_eq(self):
method test_ne (line 38) | def test_ne(self):
method test_conflicts (line 42) | def test_conflicts(self):
method test_same_server (line 59) | def test_same_server(self):
class AddrTest (line 80) | class AddrTest(unittest.TestCase):
method setUp (line 82) | def setUp(self):
method test_wildcard (line 92) | def test_wildcard(self):
method test_get_sni_addr (line 97) | def test_get_sni_addr(self):
method test_conflicts (line 103) | def test_conflicts(self):
method test_equal (line 129) | def test_equal(self):
method test_not_equal (line 134) | def test_not_equal(self):
FILE: certbot-apache/src/certbot_apache/_internal/tests/parser_test.py
class BasicParserTest (line 12) | class BasicParserTest(util.ParserTest):
method test_bad_parse (line 15) | def test_bad_parse(self):
method test_bad_save (line 21) | def test_bad_save(self):
method test_bad_save_errors (line 29) | def test_bad_save_errors(self, mock_logger):
method test_aug_version (line 42) | def test_aug_version(self):
method test_find_config_root_no_root (line 51) | def test_find_config_root_no_root(self):
method test_parse_file (line 57) | def test_parse_file(self):
method test_find_dir (line 75) | def test_find_dir(self):
method test_add_dir (line 83) | def test_add_dir(self):
method test_add_dir_beginning (line 94) | def test_add_dir_beginning(self):
method test_empty_arg (line 114) | def test_empty_arg(self):
method test_add_dir_to_ifmodssl (line 117) | def test_add_dir_to_ifmodssl(self):
method test_add_dir_to_ifmodssl_multiple (line 137) | def test_add_dir_to_ifmodssl_multiple(self):
method test_get_aug_path (line 152) | def test_get_aug_path(self):
method test_set_locations (line 156) | def test_set_locations(self):
method test_parse_modules_bad_syntax (line 169) | def test_parse_modules_bad_syntax(self, mock_arg, mock_find):
method test_update_runtime_variables (line 179) | def test_update_runtime_variables(self, mock_cfg, _):
method test_update_runtime_variables_alt_values (line 290) | def test_update_runtime_variables_alt_values(self, mock_cfg, _):
method test_update_runtime_vars_bad_ctl (line 312) | def test_update_runtime_vars_bad_ctl(self, mock_run):
method test_update_runtime_vars_bad_exit (line 318) | def test_update_runtime_vars_bad_exit(self, mock_run):
method test_add_comment (line 326) | def test_add_comment(self):
class ParserInitTest (line 334) | class ParserInitTest(util.ApacheTest):
method test_prepare_no_augeas (line 337) | def test_prepare_no_augeas(self, mock_init_augeas):
method test_init_old_aug (line 345) | def test_init_old_aug(self):
method test_root_normalized (line 353) | def test_root_normalized(self):
method test_root_absolute (line 366) | def test_root_absolute(self):
method test_root_no_trailing_slash (line 375) | def test_root_no_trailing_slash(self):
FILE: certbot-apache/src/certbot_apache/_internal/tests/parsernode_configurator_test.py
class ConfiguratorParserNodeTest (line 19) | class ConfiguratorParserNodeTest(util.ApacheTest): # pylint: disable=to...
method setUp (line 22) | def setUp(self): # pylint: disable=arguments-differ
method test_parsernode_get_vhosts (line 31) | def test_parsernode_get_vhosts(self):
method test_parsernode_get_vhosts_mismatch (line 37) | def test_parsernode_get_vhosts_mismatch(self):
FILE: certbot-apache/src/certbot_apache/_internal/tests/parsernode_test.py
class DummyParserNode (line 11) | class DummyParserNode(interfaces.ParserNode):
method __init__ (line 14) | def __init__(self, **kwargs):
method save (line 25) | def save(self, msg): # pragma: no cover
method find_ancestors (line 29) | def find_ancestors(self, name): # pragma: no cover
class DummyCommentNode (line 34) | class DummyCommentNode(DummyParserNode):
method __init__ (line 37) | def __init__(self, **kwargs):
class DummyDirectiveNode (line 46) | class DummyDirectiveNode(DummyParserNode):
method __init__ (line 50) | def __init__(self, **kwargs):
method set_parameters (line 61) | def set_parameters(self, parameters): # pragma: no cover
class DummyBlockNode (line 66) | class DummyBlockNode(DummyDirectiveNode):
method add_child_block (line 69) | def add_child_block(self, name, parameters=None, position=None): # pr...
method add_child_directive (line 73) | def add_child_directive(self, name, parameters=None, position=None): ...
method add_child_comment (line 77) | def add_child_comment(self, comment="", position=None): # pragma: no ...
method find_blocks (line 81) | def find_blocks(self, name, exclude=True): # pragma: no cover
method find_directives (line 85) | def find_directives(self, name, exclude=True): # pragma: no cover
method find_comments (line 89) | def find_comments(self, comment, exact=False): # pragma: no cover
method delete_child (line 93) | def delete_child(self, child): # pragma: no cover
method unsaved_files (line 97) | def unsaved_files(self): # pragma: no cover
function test_dummy (line 106) | def test_dummy():
FILE: certbot-apache/src/certbot_apache/_internal/tests/parsernode_util_test.py
function _setup_parsernode (line 9) | def _setup_parsernode():
function _setup_commentnode (line 17) | def _setup_commentnode():
function _setup_directivenode (line 24) | def _setup_directivenode():
function test_unknown_parameter (line 33) | def test_unknown_parameter():
function test_parsernode (line 49) | def test_parsernode():
function test_parsernode_from_metadata (line 59) | def test_parsernode_from_metadata():
function test_commentnode (line 69) | def test_commentnode():
function test_commentnode_from_metadata (line 76) | def test_commentnode_from_metadata():
function test_directivenode (line 84) | def test_directivenode():
function test_directivenode_from_metadata (line 93) | def test_directivenode_from_metadata():
function test_missing_required (line 102) | def test_missing_required():
FILE: certbot-apache/src/certbot_apache/_internal/tests/util.py
class ApacheTest (line 19) | class ApacheTest(unittest.TestCase):
method setUp (line 21) | def setUp(self, test_dir: str = "debian_apache_2_4/multiple_vhosts",
method tearDown (line 56) | def tearDown(self) -> None:
class ParserTest (line 63) | class ParserTest(ApacheTest):
method setUp (line 65) | def setUp(self, test_dir: str = "debian_apache_2_4/multiple_vhosts",
function get_apache_configurator (line 80) | def get_apache_configurator(
function get_vh_truth (line 132) | def get_vh_truth(temp_dir: str, config_name: str) -> Optional[list[obj.V...
FILE: certbot-ci/src/certbot_integration_tests/certbot_tests/assertions.py
function assert_elliptic_key (line 24) | def assert_elliptic_key(key_path: str, curve: type[EllipticCurve]) -> None:
function assert_rsa_key (line 39) | def assert_rsa_key(key_path: str, key_size: Optional[int] = None) -> None:
function assert_hook_execution (line 54) | def assert_hook_execution(probe_path: str, probe_content: str) -> None:
function assert_saved_lineage_option (line 68) | def assert_saved_lineage_option(config_dir: str, lineage: str,
function assert_saved_deploy_hook (line 81) | def assert_saved_deploy_hook(config_dir: str, lineage: str) -> None:
function assert_cert_count_for_lineage (line 90) | def assert_cert_count_for_lineage(config_dir: str, lineage: str, count: ...
function assert_equals_group_permissions (line 103) | def assert_equals_group_permissions(file1: str, file2: str) -> None:
function assert_equals_world_read_permissions (line 117) | def assert_equals_world_read_permissions(file1: str, file2: str) -> None:
function assert_equals_group_owner (line 152) | def assert_equals_group_owner(file1: str, file2: str) -> None:
function assert_world_no_permissions (line 166) | def assert_world_no_permissions(file: str) -> None:
function assert_world_read_permissions (line 186) | def assert_world_read_permissions(file: str) -> None:
FILE: certbot-ci/src/certbot_integration_tests/certbot_tests/context.py
class IntegrationTestsContext (line 13) | class IntegrationTestsContext:
method __init__ (line 15) | def __init__(self, request: pytest.FixtureRequest) -> None:
method cleanup (line 66) | def cleanup(self) -> None:
method certbot (line 70) | def certbot(self, args: Iterable[str], force_renew: bool = True) -> tu...
method get_domain (line 84) | def get_domain(self, subdomain: str = 'le') -> str:
FILE: certbot-ci/src/certbot_integration_tests/certbot_tests/test_main.py
function test_context (line 40) | def test_context(request: pytest.FixtureRequest) -> Generator[Integratio...
function test_basic_commands (line 50) | def test_basic_commands(context: IntegrationTestsContext) -> None:
function test_hook_dirs_creation (line 68) | def test_hook_dirs_creation(context: IntegrationTestsContext) -> None:
function test_registration_override (line 76) | def test_registration_override(context: IntegrationTestsContext) -> None:
function test_prepare_plugins (line 92) | def test_prepare_plugins(context: IntegrationTestsContext) -> None:
function test_http_01 (line 99) | def test_http_01(context: IntegrationTestsContext) -> None:
function test_ipv4_address_standalone (line 117) | def test_ipv4_address_standalone(context: IntegrationTestsContext) -> None:
function test_ipv6_address_standalone (line 136) | def test_ipv6_address_standalone(context: IntegrationTestsContext) -> None:
function test_manual_http_auth (line 168) | def test_manual_http_auth(context: IntegrationTestsContext) -> None:
function test_manual_dns_auth (line 188) | def test_manual_dns_auth(context: IntegrationTestsContext) -> None:
function test_certonly (line 209) | def test_certonly(context: IntegrationTestsContext) -> None:
function test_certonly_webroot (line 216) | def test_certonly_webroot(context: IntegrationTestsContext) -> None:
function test_certonly_webroot_ipv4 (line 227) | def test_certonly_webroot_ipv4(context: IntegrationTestsContext) -> None:
function test_auth_and_install_with_csr (line 243) | def test_auth_and_install_with_csr(context: IntegrationTestsContext) -> ...
function test_renew_files_permissions (line 270) | def test_renew_files_permissions(context: IntegrationTestsContext) -> None:
function test_renew_with_hook_scripts (line 290) | def test_renew_with_hook_scripts(context: IntegrationTestsContext) -> None:
function test_renew_files_propagate_permissions (line 304) | def test_renew_files_propagate_permissions(context: IntegrationTestsCont...
function test_graceful_renew_it_is_not_time (line 347) | def test_graceful_renew_it_is_not_time(context: IntegrationTestsContext)...
function test_graceful_renew_it_is_time (line 362) | def test_graceful_renew_it_is_time(context: IntegrationTestsContext) -> ...
function test_renew_when_ari_says_its_time (line 382) | def test_renew_when_ari_says_its_time(context: IntegrationTestsContext) ...
function test_renew_with_changed_private_key_complexity (line 414) | def test_renew_with_changed_private_key_complexity(context: IntegrationT...
function test_certonly_non_default_key_size_kept (line 434) | def test_certonly_non_default_key_size_kept(context: IntegrationTestsCon...
function test_renew_ignoring_directory_hooks (line 458) | def test_renew_ignoring_directory_hooks(context: IntegrationTestsContext...
function test_renew_empty_hook_scripts (line 473) | def test_renew_empty_hook_scripts(context: IntegrationTestsContext) -> N...
function test_renew_hook_override (line 491) | def test_renew_hook_override(context: IntegrationTestsContext) -> None:
function test_renew_hook_env_vars (line 536) | def test_renew_hook_env_vars(context: IntegrationTestsContext) -> None:
function test_invalid_domain_with_dns_challenge (line 570) | def test_invalid_domain_with_dns_challenge(context: IntegrationTestsCont...
function test_reuse_key (line 587) | def test_reuse_key(context: IntegrationTestsContext) -> None:
function test_reuse_key_allow_subset_of_names (line 629) | def test_reuse_key_allow_subset_of_names(context: IntegrationTestsContex...
function test_new_key (line 665) | def test_new_key(context: IntegrationTestsContext) -> None:
function test_incorrect_key_type (line 713) | def test_incorrect_key_type(context: IntegrationTestsContext) -> None:
function test_ecdsa (line 718) | def test_ecdsa(context: IntegrationTestsContext) -> None:
function test_default_key_type (line 742) | def test_default_key_type(context: IntegrationTestsContext) -> None:
function test_default_rsa_size (line 753) | def test_default_rsa_size(context: IntegrationTestsContext) -> None:
function test_ecdsa_curves (line 769) | def test_ecdsa_curves(context: IntegrationTestsContext, curve: str,
function test_renew_with_ec_keys (line 782) | def test_renew_with_ec_keys(context: IntegrationTestsContext) -> None:
function test_ocsp_must_staple (line 833) | def test_ocsp_must_staple(context: IntegrationTestsContext) -> None:
function test_revoke_simple (line 848) | def test_revoke_simple(context: IntegrationTestsContext) -> None:
function test_revoke_and_unregister (line 879) | def test_revoke_and_unregister(context: IntegrationTestsContext) -> None:
function test_revoke_ecdsa_cert_key (line 912) | def test_revoke_ecdsa_cert_key(
function test_revoke_ecdsa_cert_key_delete (line 937) | def test_revoke_ecdsa_cert_key_delete(
function test_revoke_mutual_exclusive_flags (line 956) | def test_revoke_mutual_exclusive_flags(context: IntegrationTestsContext)...
function test_revoke_multiple_lineages (line 968) | def test_revoke_multiple_lineages(context: IntegrationTestsContext) -> N...
function test_reconfigure (line 1000) | def test_reconfigure(context: IntegrationTestsContext) -> None:
function test_wildcard_certificates (line 1019) | def test_wildcard_certificates(context: IntegrationTestsContext) -> None:
function test_ocsp_status_stale (line 1033) | def test_ocsp_status_stale(context: IntegrationTestsContext) -> None:
function test_ocsp_status_live (line 1044) | def test_ocsp_status_live(context: IntegrationTestsContext) -> None:
function test_ocsp_renew (line 1063) | def test_ocsp_renew(context: IntegrationTestsContext) -> None:
function test_dry_run_deactivate_authzs (line 1080) | def test_dry_run_deactivate_authzs(context: IntegrationTestsContext) -> ...
function test_preferred_chain (line 1098) | def test_preferred_chain(context: IntegrationTestsContext) -> None:
function test_ancient_rsa_key_type_preserved (line 1127) | def test_ancient_rsa_key_type_preserved(context: IntegrationTestsContext...
FILE: certbot-ci/src/certbot_integration_tests/conftest.py
function pytest_addoption (line 17) | def pytest_addoption(parser):
function pytest_configure (line 28) | def pytest_configure(config):
function pytest_configure_node (line 38) | def pytest_configure_node(node):
function _print_on_err (line 48) | def _print_on_err():
function _setup_primary_node (line 62) | def _setup_primary_node(config):
FILE: certbot-ci/src/certbot_integration_tests/nginx_tests/context.py
class IntegrationTestsContext (line 15) | class IntegrationTestsContext(certbot_context.IntegrationTestsContext):
method __init__ (line 17) | def __init__(self, request: pytest.FixtureRequest) -> None:
method cleanup (line 34) | def cleanup(self) -> None:
method certbot_test_nginx (line 38) | def certbot_test_nginx(self, args: Iterable[str]) -> tuple[str, str]:
method _start_nginx (line 51) | def _start_nginx(self, default_server: bool) -> subprocess.Popen[bytes]:
method _stop_nginx (line 65) | def _stop_nginx(self) -> None:
FILE: certbot-ci/src/certbot_integration_tests/nginx_tests/nginx_config.py
function construct_nginx_config (line 10) | def construct_nginx_config(nginx_root: str, nginx_webroot: str, http_por...
FILE: certbot-ci/src/certbot_integration_tests/nginx_tests/test_main.py
function test_context (line 12) | def test_context(request: pytest.FixtureRequest) -> Generator[Integratio...
function test_certificate_deployment (line 35) | def test_certificate_deployment(certname_pattern: str, params: list[str],
FILE: certbot-ci/src/certbot_integration_tests/rfc2136_tests/context.py
class IntegrationTestsContext (line 14) | class IntegrationTestsContext(certbot_context.IntegrationTestsContext):
method __init__ (line 16) | def __init__(self, request: pytest.FixtureRequest) -> None:
method certbot_test_rfc2136 (line 26) | def certbot_test_rfc2136(self, args: Iterable[str]) -> tuple[str, str]:
method rfc2136_credentials (line 38) | def rfc2136_credentials(self, label: str = 'default') -> Generator[str...
method skip_if_no_bind9_server (line 60) | def skip_if_no_bind9_server(self) -> None:
FILE: certbot-ci/src/certbot_integration_tests/rfc2136_tests/test_main.py
function test_context (line 10) | def test_context(request: pytest.FixtureRequest) -> Generator[Integratio...
function test_get_certificate (line 21) | def test_get_certificate(domain: str, context: IntegrationTestsContext) ...
FILE: certbot-ci/src/certbot_integration_tests/utils/acme_server.py
class ACMEServer (line 32) | class ACMEServer:
method __init__ (line 44) | def __init__(self, nodes: list[str], http_proxy: bool = True,
method start (line 70) | def start(self) -> None:
method stop (line 80) | def stop(self) -> None:
method __enter__ (line 101) | def __enter__(self) -> dict[str, Any]:
method __exit__ (line 105) | def __exit__(self, exc_type: Optional[type[BaseException]], exc: Optio...
method _construct_acme_xdist (line 109) | def _construct_acme_xdist(self, nodes: list[str]) -> None:
method _prepare_pebble_server (line 130) | def _prepare_pebble_server(self) -> None:
method _prepare_http_proxy (line 165) | def _prepare_http_proxy(self) -> None:
method _launch_process (line 183) | def _launch_process(self, command: list[str], cwd: str = os.getcwd(),
function main (line 198) | def main() -> None:
FILE: certbot-ci/src/certbot_integration_tests/utils/certbot_call.py
function certbot_test (line 15) | def certbot_test(certbot_args: list[str], directory_url: Optional[str], ...
function _prepare_environ (line 45) | def _prepare_environ(workspace: str) -> dict[str, str]:
function _prepare_args_env (line 83) | def _prepare_args_env(certbot_args: list[str], directory_url: Optional[s...
function main (line 120) | def main() -> None:
FILE: certbot-ci/src/certbot_integration_tests/utils/dns_server.py
class DNSServer (line 26) | class DNSServer:
method __init__ (line 36) | def __init__(self, unused_nodes: list[str], show_output: bool = False)...
method start (line 54) | def start(self) -> None:
method stop (line 63) | def stop(self) -> None:
method _configure_bind (line 77) | def _configure_bind(self) -> None:
method _start_bind (line 86) | def _start_bind(self) -> None:
method _wait_until_ready (line 119) | def _wait_until_ready(self, attempts: int = 30) -> None:
method __start__ (line 155) | def __start__(self) -> dict[str, Any]:
method __exit__ (line 159) | def __exit__(self, exc_type: Optional[type[BaseException]], exc: Optio...
FILE: certbot-ci/src/certbot_integration_tests/utils/misc.py
function _suppress_x509_verification_warnings (line 47) | def _suppress_x509_verification_warnings() -> None:
function check_until_timeout (line 52) | def check_until_timeout(url: str, attempts: int = 30) -> None:
class GracefulTCPServer (line 72) | class GracefulTCPServer(socketserver.TCPServer):
function create_http_server (line 85) | def create_http_server(port: int) -> Generator[str, None, None]:
function list_renewal_hooks_dirs (line 109) | def list_renewal_hooks_dirs(config_dir: str) -> list[str]:
function generate_test_file_hooks (line 119) | def generate_test_file_hooks(config_dir: str, hook_probe: str) -> None:
function manual_http_hooks (line 165) | def manual_http_hooks(http_server_root: str) -> Generator[tuple[str, str...
function generate_csr (line 205) | def generate_csr(
function read_certificate (line 245) | def read_certificate(cert_path: str) -> Certificate:
function load_sample_data_path (line 257) | def load_sample_data_path(workspace: str) -> str:
function echo (line 290) | def echo(keyword: str, path: Optional[str] = None) -> str:
function get_acme_issuers (line 305) | def get_acme_issuers() -> list[Certificate]:
function set_ari_response (line 322) | def set_ari_response(certificate_pem: str, response_json: str) -> None:
FILE: certbot-ci/src/certbot_integration_tests/utils/pebble_artifacts.py
function fetch (line 21) | def fetch(workspace: str, http_01_port: int = DEFAULT_HTTP_01_PORT) -> t...
function _fetch_asset (line 35) | def _fetch_asset(asset: str, assets_path: str) -> str:
function _get_validated_os_and_architecture (line 53) | def _get_validated_os_and_architecture() -> tuple[str, str]:
function _unzip_asset (line 69) | def _unzip_asset(zipped_data: bytes, asset_name: str) -> Optional[bytes]:
function _build_pebble_config (line 77) | def _build_pebble_config(workspace: str, http_01_port: int, assets_path:...
FILE: certbot-ci/src/certbot_integration_tests/utils/pebble_ocsp_server.py
class _ProxyHandler (line 27) | class _ProxyHandler(BaseHTTPServer.BaseHTTPRequestHandler):
method do_POST (line 29) | def do_POST(self) -> None:
FILE: certbot-ci/src/certbot_integration_tests/utils/proxy.py
function _create_proxy (line 19) | def _create_proxy(mapping: Mapping[str, str]) -> type[BaseHTTPServer.Bas...
FILE: certbot-ci/src/snap_integration_tests/conftest.py
function pytest_addoption (line 14) | def pytest_addoption(parser):
function pytest_configure (line 28) | def pytest_configure(config):
function pytest_generate_tests (line 39) | def pytest_generate_tests(metafunc):
FILE: certbot-ci/src/snap_integration_tests/dns_tests/test_main.py
function install_certbot_snap (line 13) | def install_certbot_snap(request: pytest.FixtureRequest) -> Generator[No...
function test_dns_plugin_install (line 28) | def test_dns_plugin_install(dns_snap_path: str) -> None:
FILE: certbot-compatibility-test/nginx/roundtrip.py
function roundtrip (line 9) | def roundtrip(stuff):
FILE: certbot-compatibility-test/src/certbot_compatibility_test/configurators/apache/common.py
class Proxy (line 17) | class Proxy(configurators_common.Proxy):
method __init__ (line 20) | def __init__(self, args: argparse.Namespace) -> None:
method load_config (line 32) | def load_config(self) -> str:
method _prepare_configurator (line 52) | def _prepare_configurator(self) -> None:
method cleanup_from_tests (line 63) | def cleanup_from_tests(self) -> None:
function _get_server_root (line 69) | def _get_server_root(config: str) -> str:
function _get_names (line 81) | def _get_names(config: str) -> tuple[set[str], set[str]]:
FILE: certbot-compatibility-test/src/certbot_compatibility_test/configurators/common.py
class Proxy (line 25) | class Proxy(interfaces.ConfiguratorProxy):
method add_parser_arguments (line 29) | def add_parser_arguments(cls, parser: argparse.ArgumentParser) -> None:
method __init__ (line 32) | def __init__(self, args: argparse.Namespace) -> None:
method has_more_configs (line 52) | def has_more_configs(self) -> bool:
method cleanup_from_tests (line 57) | def cleanup_from_tests(self) -> None:
method load_config (line 60) | def load_config(self) -> str:
method copy_certs_and_keys (line 68) | def copy_certs_and_keys(self, cert_path: str, key_path: str,
method copy_certs_and_keys (line 72) | def copy_certs_and_keys(self, cert_path: str, key_path: str,
method copy_certs_and_keys (line 75) | def copy_certs_and_keys(self, cert_path: str, key_path: str,
method get_all_names_answer (line 93) | def get_all_names_answer(self) -> set[str]:
method get_testable_domain_names (line 99) | def get_testable_domain_names(self) -> set[str]:
method deploy_cert (line 105) | def deploy_cert(self, domain: str, cert_path: str, key_path: str, chai...
method cleanup (line 114) | def cleanup(self, achalls: list[AnnotatedChallenge]) -> None:
method config_test (line 117) | def config_test(self) -> None:
method enhance (line 120) | def enhance(self, domain: str, enhancement: str,
method get_all_names (line 124) | def get_all_names(self) -> Iterable[str]:
method get_chall_pref (line 127) | def get_chall_pref(self, identifier: str) -> Iterable[type[Challenge]]:
method inject_parser_options (line 131) | def inject_parser_options(cls, parser: argparse.ArgumentParser, name: ...
method more_info (line 134) | def more_info(self) -> str:
method perform (line 137) | def perform(self, achalls: list[AnnotatedChallenge]) -> list[challenge...
method prepare (line 140) | def prepare(self) -> None:
method recovery_routine (line 143) | def recovery_routine(self) -> None:
method restart (line 146) | def restart(self) -> None:
method rollback_checkpoints (line 149) | def rollback_checkpoints(self, rollback: int = 1) -> None:
method save (line 152) | def save(self, title: Optional[str] = None, temporary: bool = False) -...
method supported_enhancements (line 155) | def supported_enhancements(self) -> list[str]:
FILE: certbot-compatibility-test/src/certbot_compatibility_test/configurators/nginx/common.py
class Proxy (line 14) | class Proxy(configurators_common.Proxy):
method load_config (line 17) | def load_config(self) -> str:
method _prepare_configurator (line 40) | def _prepare_configurator(self) -> None:
method cleanup_from_tests (line 49) | def cleanup_from_tests(self) -> None:
function _get_server_root (line 53) | def _get_server_root(config: str) -> str:
function _get_names (line 65) | def _get_names(config: str) -> tuple[set[str], set[str]]:
function _get_server_names (line 76) | def _get_server_names(root: str, filename: str) -> set[str]:
FILE: certbot-compatibility-test/src/certbot_compatibility_test/errors.py
class Error (line 4) | class Error(Exception):
FILE: certbot-compatibility-test/src/certbot_compatibility_test/interfaces.py
class PluginProxy (line 11) | class PluginProxy(interfaces.Plugin, metaclass=ABCMeta):
method add_parser_arguments (line 22) | def add_parser_arguments(cls, parser: argparse.ArgumentParser) -> None:
method __init__ (line 26) | def __init__(self, args: argparse.Namespace) -> None:
method cleanup_from_tests (line 31) | def cleanup_from_tests(self) -> None:
method has_more_configs (line 39) | def has_more_configs(self) -> bool:
method load_config (line 43) | def load_config(self) -> str:
method get_testable_domain_names (line 47) | def get_testable_domain_names(self) -> set[str]:
class AuthenticatorProxy (line 51) | class AuthenticatorProxy(PluginProxy, interfaces.Authenticator, metaclas...
class InstallerProxy (line 55) | class InstallerProxy(PluginProxy, interfaces.Installer, metaclass=ABCMeta):
method get_all_names_answer (line 59) | def get_all_names_answer(self) -> set[str]:
class ConfiguratorProxy (line 63) | class ConfiguratorProxy(AuthenticatorProxy, InstallerProxy, metaclass=AB...
FILE: certbot-compatibility-test/src/certbot_compatibility_test/test_driver.py
function test_authenticator (line 46) | def test_authenticator(plugin: common.Proxy, config: str, temp_dir: str)...
function _create_achalls (line 101) | def _create_achalls(plugin: common.Proxy) -> list[achallenges.AnnotatedC...
function test_installer (line 122) | def test_installer(args: argparse.Namespace, plugin: common.Proxy, confi...
function test_deploy_cert (line 143) | def test_deploy_cert(plugin: common.Proxy, temp_dir: str, domains: list[...
function test_enhancements (line 176) | def test_enhancements(plugin: common.Proxy, domains: Iterable[str]) -> b...
function _save_and_restart (line 221) | def _save_and_restart(plugin: common.Proxy, title: Optional[str] = None)...
function test_rollback (line 232) | def test_rollback(plugin: common.Proxy, config: str, backup: str) -> bool:
function _create_backup (line 247) | def _create_backup(config: str, temp_dir: str) -> str:
function _dirs_are_unequal (line 256) | def _dirs_are_unequal(dir1: str, dir2: str) -> bool:
function get_args (line 288) | def get_args() -> argparse.Namespace:
function setup_logging (line 325) | def setup_logging(args: argparse.Namespace) -> None:
function setup_display (line 334) | def setup_display() -> None:
function main (line 340) | def main() -> None:
function _fake_dns_resolution (line 384) | def _fake_dns_resolution(resolved_ip: str) -> Generator[None, None, None]:
FILE: certbot-compatibility-test/src/certbot_compatibility_test/util.py
function create_le_config (line 26) | def create_le_config(parent_dir: str) -> argparse.Namespace:
function extract_configs (line 43) | def extract_configs(configs: str, parent_dir: str) -> str:
function make_self_signed_cert (line 58) | def make_self_signed_cert(private_key: types.CertificateIssuerPrivateKey...
FILE: certbot-compatibility-test/src/certbot_compatibility_test/validator.py
class Validator (line 22) | class Validator:
method certificate (line 25) | def certificate(self, cert: x509.Certificate, name: Union[str, bytes],
method redirect (line 45) | def redirect(self, name: str, port: int = 80,
method any_redirect (line 70) | def any_redirect(self, name: str, port: int = 80,
method hsts (line 84) | def hsts(self, name: str) -> bool:
method ocsp_stapling (line 114) | def ocsp_stapling(self, name: str) -> None:
function _probe_sni (line 120) | def _probe_sni(name: bytes, host: bytes, port: int = 443) -> x509.Certif...
FILE: certbot-dns-cloudflare/src/certbot_dns_cloudflare/_internal/dns_cloudflare.py
class Authenticator (line 19) | class Authenticator(dns_common.DNSAuthenticator):
method __init__ (line 29) | def __init__(self, *args: Any, **kwargs: Any) -> None:
method add_parser_arguments (line 34) | def add_parser_arguments(cls, add: Callable[..., None],
method more_info (line 39) | def more_info(self) -> str:
method _validate_credentials (line 43) | def _validate_credentials(self, credentials: CredentialsConfiguration)...
method _setup_credentials (line 66) | def _setup_credentials(self) -> None:
method _perform (line 74) | def _perform(self, domain: str, validation_name: str, validation: str)...
method _cleanup (line 77) | def _cleanup(self, domain: str, validation_name: str, validation: str)...
method _get_cloudflare_client (line 80) | def _get_cloudflare_client(self) -> "_CloudflareClient":
class _CloudflareClient (line 89) | class _CloudflareClient:
method __init__ (line 94) | def __init__(self, email: Optional[str] = None, api_key: Optional[str]...
method add_txt_record (line 108) | def add_txt_record(self, domain: str, record_name: str, record_content...
method del_txt_record (line 144) | def del_txt_record(self, domain: str, record_name: str, record_content...
method _find_zone_id (line 178) | def _find_zone_id(self, domain: str) -> str:
method _find_txt_record_id (line 243) | def _find_txt_record_id(self, zone_id: str, record_name: str,
FILE: certbot-dns-cloudflare/src/certbot_dns_cloudflare/_internal/tests/dns_cloudflare_test.py
class AuthenticatorTest (line 24) | class AuthenticatorTest(test_util.TempDirTestCase, dns_test_common.BaseA...
method setUp (line 26) | def setUp(self):
method test_perform (line 46) | def test_perform(self, unused_mock_get_utility):
method test_cleanup (line 52) | def test_cleanup(self):
method test_api_token (line 61) | def test_api_token(self, unused_mock_get_utility):
method test_no_creds (line 69) | def test_no_creds(self):
method test_missing_email_or_key (line 74) | def test_missing_email_or_key(self):
method test_email_or_key_with_token (line 83) | def test_email_or_key_with_token(self):
class CloudflareClientTest (line 100) | class CloudflareClientTest(unittest.TestCase):
method setUp (line 107) | def setUp(self):
method test_add_txt_record (line 115) | def test_add_txt_record(self):
method test_add_txt_record_error (line 130) | def test_add_txt_record_error(self):
method test_add_txt_record_error_during_zone_lookup (line 138) | def test_add_txt_record_error_during_zone_lookup(self):
method test_add_txt_record_zone_not_found (line 144) | def test_add_txt_record_zone_not_found(self):
method test_add_txt_record_bad_creds (line 150) | def test_add_txt_record_bad_creds(self):
method test_del_txt_record (line 167) | def test_del_txt_record(self):
method test_del_txt_record_error_during_zone_lookup (line 185) | def test_del_txt_record_error_during_zone_lookup(self):
method test_del_txt_record_error_during_delete (line 190) | def test_del_txt_record_error_during_delete(self):
method test_del_txt_record_error_during_get (line 202) | def test_del_txt_record_error_during_get(self):
method test_del_txt_record_no_record (line 212) | def test_del_txt_record_no_record(self):
method test_del_txt_record_no_zone (line 222) | def test_del_txt_record_no_zone(self):
FILE: certbot-dns-digitalocean/src/certbot_dns_digitalocean/_internal/dns_digitalocean.py
class Authenticator (line 17) | class Authenticator(dns_common.DNSAuthenticator):
method __init__ (line 27) | def __init__(self, *args: Any, **kwargs: Any) -> None:
method add_parser_arguments (line 32) | def add_parser_arguments(cls, add: Callable[..., None],
method more_info (line 37) | def more_info(self) -> str:
method _setup_credentials (line 41) | def _setup_credentials(self) -> None:
method _perform (line 50) | def _perform(self, domain: str, validation_name: str, validation: str)...
method _cleanup (line 54) | def _cleanup(self, domain: str, validation_name: str, validation: str)...
method _get_digitalocean_client (line 57) | def _get_digitalocean_client(self) -> "_DigitalOceanClient":
class _DigitalOceanClient (line 63) | class _DigitalOceanClient:
method __init__ (line 68) | def __init__(self, token: str) -> None:
method add_txt_record (line 71) | def add_txt_record(self, domain_name: str, record_name: str, record_co...
method del_txt_record (line 115) | def del_txt_record(self, domain_name: str, record_name: str, record_co...
method _find_domain (line 154) | def _find_domain(self, domain_name: str) -> digitalocean.Domain:
method _compute_record_name (line 180) | def _compute_record_name(domain: digitalocean.Domain, full_record_name...
FILE: certbot-dns-digitalocean/src/certbot_dns_digitalocean/_internal/tests/dns_digitalocean_test.py
class AuthenticatorTest (line 20) | class AuthenticatorTest(test_util.TempDirTestCase, dns_test_common.BaseA...
method setUp (line 22) | def setUp(self):
method test_perform (line 43) | def test_perform(self, unused_mock_get_utility):
method test_cleanup (line 49) | def test_cleanup(self):
class DigitalOceanClientTest (line 58) | class DigitalOceanClientTest(unittest.TestCase):
method setUp (line 66) | def setUp(self):
method test_add_txt_record (line 74) | def test_add_txt_record(self):
method test_add_txt_record_fail_to_find_domain (line 93) | def test_add_txt_record_fail_to_find_domain(self):
method test_add_txt_record_error_finding_domain (line 99) | def test_add_txt_record_error_finding_domain(self):
method test_add_txt_record_error_creating_record (line 105) | def test_add_txt_record_error_creating_record(self):
method test_del_txt_record (line 115) | def test_del_txt_record(self):
method test_del_txt_record_error_finding_domain (line 146) | def test_del_txt_record_error_finding_domain(self):
method test_del_txt_record_error_finding_record (line 151) | def test_del_txt_record_error_finding_record(self):
method test_del_txt_record_error_deleting_record (line 160) | def test_del_txt_record_error_deleting_record(self):
FILE: certbot-dns-dnsimple/src/certbot_dns_dnsimple/_internal/dns_dnsimple.py
class Authenticator (line 16) | class Authenticator(dns_common_lexicon.LexiconDNSAuthenticator):
method __init__ (line 24) | def __init__(self, *args: Any, **kwargs: Any) -> None:
method add_parser_arguments (line 31) | def add_parser_arguments(cls, add: Callable[..., None],
method more_info (line 36) | def more_info(self) -> str:
method _provider_name (line 41) | def _provider_name(self) -> str:
method _handle_http_error (line 44) | def _handle_http_error(self, e: HTTPError, domain_name: str) -> errors...
FILE: certbot-dns-dnsimple/src/certbot_dns_dnsimple/_internal/tests/dns_dnsimple_test.py
class AuthenticatorTest (line 17) | class AuthenticatorTest(test_util.TempDirTestCase,
method setUp (line 22) | def setUp(self):
FILE: certbot-dns-dnsmadeeasy/src/certbot_dns_dnsmadeeasy/_internal/dns_dnsmadeeasy.py
class Authenticator (line 17) | class Authenticator(dns_common_lexicon.LexiconDNSAuthenticator):
method __init__ (line 26) | def __init__(self, *args: Any, **kwargs: Any) -> None:
method add_parser_arguments (line 38) | def add_parser_arguments(cls, add: Callable[..., None],
method more_info (line 43) | def more_info(self) -> str:
method _provider_name (line 48) | def _provider_name(self) -> str:
method _handle_http_error (line 51) | def _handle_http_error(self, e: HTTPError, domain_name: str) -> Option...
FILE: certbot-dns-dnsmadeeasy/src/certbot_dns_dnsmadeeasy/_internal/tests/dns_dnsmadeeasy_test.py
class AuthenticatorTest (line 20) | class AuthenticatorTest(test_util.TempDirTestCase,
method setUp (line 26) | def setUp(self):
FILE: certbot-dns-gehirn/src/certbot_dns_gehirn/_internal/dns_gehirn.py
class Authenticator (line 17) | class Authenticator(dns_common_lexicon.LexiconDNSAuthenticator):
method __init__ (line 27) | def __init__(self, *args: Any, **kwargs: Any) -> None:
method add_parser_arguments (line 39) | def add_parser_arguments(cls, add: Callable[..., None],
method more_info (line 44) | def more_info(self) -> str:
method _provider_name (line 49) | def _provider_name(self) -> str:
method _handle_http_error (line 52) | def _handle_http_error(self, e: HTTPError, domain_name: str) -> Option...
FILE: certbot-dns-gehirn/src/certbot_dns_gehirn/_internal/tests/dns_gehirn_test.py
class AuthenticatorTest (line 20) | class AuthenticatorTest(test_util.TempDirTestCase,
method setUp (line 26) | def setUp(self):
FILE: certbot-dns-google/src/certbot_dns_google/_internal/dns_google.py
class Authenticator (line 26) | class Authenticator(dns_common.DNSAuthenticator):
method add_parser_arguments (line 38) | def add_parser_arguments(cls, add: Callable[..., None],
method more_info (line 54) | def more_info(self) -> str:
method _setup_credentials (line 58) | def _setup_credentials(self) -> None:
method _perform (line 72) | def _perform(self, domain: str, validation_name: str, validation: str)...
method _cleanup (line 75) | def _cleanup(self, domain: str, validation_name: str, validation: str)...
method _get_google_client (line 78) | def _get_google_client(self) -> '_GoogleClient':
class _GoogleClient (line 85) | class _GoogleClient:
method __init__ (line 90) | def __init__(self, account_json: Optional[str] = None,
method add_txt_record (line 124) | def add_txt_record(self, domain: str, record_name: str, record_content...
method del_txt_record (line 194) | def del_txt_record(self, domain: str, record_name: str, record_content...
method get_existing_txt_rrset (line 255) | def get_existing_txt_rrset(self, zone_id: str, record_name: str) -> Op...
method _find_managed_zone_id (line 285) | def _find_managed_zone_id(self, domain: str) -> str:
FILE: certbot-dns-google/src/certbot_dns_google/_internal/tests/dns_google_test.py
class AuthenticatorTest (line 26) | class AuthenticatorTest(test_util.TempDirTestCase, dns_test_common.BaseA...
method setUp (line 28) | def setUp(self):
method test_perform (line 46) | def test_perform(self, unused_mock_get_utility):
method test_cleanup (line 56) | def test_cleanup(self):
method test_without_auth (line 69) | def test_without_auth(self, unused_mock_get_utility):
method test_get_google_client (line 78) | def test_get_google_client(self, client_mock):
method test_get_google_client_cached (line 86) | def test_get_google_client_cached(self):
class GoogleClientTest (line 92) | class GoogleClientTest(unittest.TestCase):
method _setUp_client_with_mock (line 102) | def _setUp_client_with_mock(self,
method test_client_with_default_credentials (line 141) | def test_client_with_default_credentials(self, credential_mock, discov...
method test_client_with_json_credentials (line 154) | def test_client_with_json_credentials(self, credential_mock, discovery...
method test_client_bad_credentials_file (line 167) | def test_client_bad_credentials_file(self, credential_mock):
method test_client_missing_project_id (line 177) | def test_client_missing_project_id(self, credential_mock):
method test_client_with_project_id (line 187) | def test_client_with_project_id(self, credential_mock, unused_discover...
method test_add_txt_record (line 197) | def test_add_txt_record(self, credential_mock):
method test_add_txt_record_and_poll (line 225) | def test_add_txt_record_and_poll(self, credential_mock):
method test_add_txt_record_and_poll_split_horizon (line 245) | def test_add_txt_record_and_poll_split_horizon(self, credential_mock):
method test_add_txt_record_delete_old (line 265) | def test_add_txt_record_delete_old(self, credential_mock):
method test_add_txt_record_delete_old_ttl_case (line 283) | def test_add_txt_record_delete_old_ttl_case(self, credential_mock):
method test_add_txt_record_noop (line 302) | def test_add_txt_record_noop(self, credential_mock):
method test_add_txt_record_error_during_zone_lookup (line 314) | def test_add_txt_record_error_during_zone_lookup(self, credential_mock):
method test_add_txt_record_zone_not_found (line 325) | def test_add_txt_record_zone_not_found(self, credential_mock):
method test_add_txt_record_error_during_add (line 337) | def test_add_txt_record_error_during_add(self, credential_mock):
method test_del_txt_record_multi_rrdatas (line 349) | def test_del_txt_record_multi_rrdatas(self, credential_mock):
method test_del_txt_record_single_rrdatas (line 390) | def test_del_txt_record_single_rrdatas(self, credential_mock):
method test_del_txt_record_error_during_zone_lookup (line 421) | def test_del_txt_record_error_during_zone_lookup(self, credential_mock):
method test_del_txt_record_zone_not_found (line 431) | def test_del_txt_record_zone_not_found(self, credential_mock):
method test_del_txt_record_error_during_delete (line 442) | def test_del_txt_record_error_during_delete(self, credential_mock):
method test_get_existing_found (line 453) | def test_get_existing_found(self, credential_mock):
method test_get_existing_not_found (line 467) | def test_get_existing_not_found(self, credential_mock):
method test_get_existing_with_error (line 478) | def test_get_existing_with_error(self, credential_mock):
method test_get_existing_fallback (line 490) | def test_get_existing_fallback(self, credential_mock):
FILE: certbot-dns-linode/src/certbot_dns_linode/_internal/dns_linode.py
class Authenticator (line 15) | class Authenticator(dns_common_lexicon.LexiconDNSAuthenticator):
method __init__ (line 23) | def __init__(self, *args: Any, **kwargs: Any) -> None:
method add_parser_arguments (line 31) | def add_parser_arguments(cls, add: Callable[..., None],
method more_info (line 36) | def more_info(self) -> str:
method _provider_name (line 41) | def _provider_name(self) -> str:
method _setup_credentials (line 47) | def _setup_credentials(self) -> None:
method _handle_general_error (line 54) | def _handle_general_error(self, e: Exception, domain_name: str) -> Opt...
FILE: certbot-dns-linode/src/certbot_dns_linode/_internal/tests/dns_linode_test.py
class AuthenticatorTest (line 18) | class AuthenticatorTest(test_util.TempDirTestCase,
method setUp (line 23) | def setUp(self):
method test_api_version_4_detection (line 35) | def test_api_version_4_detection(self):
FILE: certbot-dns-luadns/src/certbot_dns_luadns/_internal/dns_luadns.py
class Authenticator (line 16) | class Authenticator(dns_common_lexicon.LexiconDNSAuthenticator):
method __init__ (line 24) | def __init__(self, *args: Any, **kwargs: Any) -> None:
method add_parser_arguments (line 34) | def add_parser_arguments(cls, add: Callable[..., None],
method more_info (line 39) | def more_info(self) -> str:
method _provider_name (line 44) | def _provider_name(self) -> str:
method _handle_http_error (line 47) | def _handle_http_error(self, e: HTTPError, domain_name: str) -> errors...
FILE: certbot-dns-luadns/src/certbot_dns_luadns/_internal/tests/dns_luadns_test.py
class AuthenticatorTest (line 18) | class AuthenticatorTest(test_util.TempDirTestCase,
method setUp (line 23) | def setUp(self):
FILE: certbot-dns-nsone/src/certbot_dns_nsone/_internal/dns_nsone.py
class Authenticator (line 17) | class Authenticator(dns_common_lexicon.LexiconDNSAuthenticator):
method __init__ (line 25) | def __init__(self, *args: Any, **kwargs: Any) -> None:
method add_parser_arguments (line 32) | def add_parser_arguments(cls, add: Callable[..., None],
method more_info (line 37) | def more_info(self) -> str:
method _provider_name (line 42) | def _provider_name(self) -> str:
method _handle_http_error (line 45) | def _handle_http_error(self, e: HTTPError, domain_name: str) -> Option...
FILE: certbot-dns-nsone/src/certbot_dns_nsone/_internal/tests/dns_nsone_test.py
class AuthenticatorTest (line 18) | class AuthenticatorTest(test_util.TempDirTestCase,
method setUp (line 24) | def setUp(self):
FILE: certbot-dns-ovh/src/certbot_dns_ovh/_internal/dns_ovh.py
class Authenticator (line 17) | class Authenticator(dns_common_lexicon.LexiconDNSAuthenticator):
method __init__ (line 25) | def __init__(self, *args: Any, **kwargs: Any) -> None:
method add_parser_arguments (line 41) | def add_parser_arguments(cls, add: Callable[..., None],
method more_info (line 46) | def more_info(self) -> str:
method _provider_name (line 51) | def _provider_name(self) -> str:
method _handle_http_error (line 54) | def _handle_http_error(self, e: HTTPError, domain_name: str) -> errors...
method _handle_general_error (line 66) | def _handle_general_error(self, e: Exception, domain_name: str) -> Opt...
FILE: certbot-dns-ovh/src/certbot_dns_ovh/_internal/tests/dns_ovh_test.py
class AuthenticatorTest (line 20) | class AuthenticatorTest(test_util.TempDirTestCase,
method setUp (line 26) | def setUp(self):
FILE: certbot-dns-rfc2136/src/certbot_dns_rfc2136/_internal/dns_rfc2136.py
class Authenticator (line 28) | class Authenticator(dns_common.DNSAuthenticator):
method __init__ (line 48) | def __init__(self, *args: Any, **kwargs: Any) -> None:
method add_parser_arguments (line 53) | def add_parser_arguments(cls, add: Callable[..., None],
method more_info (line 58) | def more_info(self) -> str:
method _validate_credentials (line 62) | def _validate_credentials(self, credentials: CredentialsConfiguration)...
method _setup_credentials (line 72) | def _setup_credentials(self) -> None:
method _perform (line 84) | def _perform(self, _domain: str, validation_name: str, validation: str...
method _cleanup (line 87) | def _cleanup(self, _domain: str, validation_name: str, validation: str...
method _get_rfc2136_client (line 90) | def _get_rfc2136_client(self) -> "_RFC2136Client":
class _RFC2136Client (line 104) | class _RFC2136Client:
method __init__ (line 108) | def __init__(self, server: str, port: int, key_name: str, key_secret: ...
method add_txt_record (line 120) | def add_txt_record(self, record_name: str, record_content: str, record...
method del_txt_record (line 155) | def del_txt_record(self, record_name: str, record_content: str) -> None:
method _find_domain (line 190) | def _find_domain(self, record_name: str) -> str:
method _query_soa (line 210) | def _query_soa(self, domain_name: str) -> bool:
FILE: certbot-dns-rfc2136/src/certbot_dns_rfc2136/_internal/tests/dns_rfc2136_test.py
class AuthenticatorTest (line 26) | class AuthenticatorTest(test_util.TempDirTestCase, dns_test_common.BaseA...
method setUp (line 28) | def setUp(self):
method test_get_client_default_conf_values (line 48) | def test_get_client_default_conf_values(self):
method test_perform (line 59) | def test_perform(self, unused_mock_get_utility):
method test_cleanup (line 65) | def test_cleanup(self):
method test_invalid_algorithm_raises (line 73) | def test_invalid_algorithm_raises(self):
method test_valid_algorithm_passes (line 83) | def test_valid_algorithm_passes(self, client, unused_mock_get_utility):
method test_invalid_server_raises (line 94) | def test_invalid_server_raises(self):
method test_valid_server_passes (line 103) | def test_valid_server_passes(self, unused_mock_get_utility):
class RFC2136ClientTest (line 115) | class RFC2136ClientTest(unittest.TestCase):
method setUp (line 117) | def setUp(self):
method test_add_txt_record (line 124) | def test_add_txt_record(self, query_mock):
method test_add_txt_record_wraps_errors (line 137) | def test_add_txt_record_wraps_errors(self, query_mock):
method test_add_txt_record_server_error (line 148) | def test_add_txt_record_server_error(self, query_mock):
method test_del_txt_record (line 159) | def test_del_txt_record(self, query_mock):
method test_del_txt_record_wraps_errors (line 172) | def test_del_txt_record_wraps_errors(self, query_mock):
method test_del_txt_record_server_error (line 183) | def test_del_txt_record_server_error(self, query_mock):
method test_find_domain (line 193) | def test_find_domain(self):
method test_find_domain_wraps_errors (line 204) | def test_find_domain_wraps_errors(self):
method test_query_soa_found (line 215) | def test_query_soa_found(self, mock_make_query, query_mock):
method test_query_soa_not_found (line 228) | def test_query_soa_not_found(self, query_mock):
method test_query_soa_wraps_errors (line 238) | def test_query_soa_wraps_errors(self, query_mock):
method test_query_soa_fallback_to_udp (line 246) | def test_query_soa_fallback_to_udp(self, tcp_mock, udp_mock):
method test_query_soa_signed (line 260) | def test_query_soa_signed(self, mock_make_query, unused_mock_query):
FILE: certbot-dns-route53/src/certbot_dns_route53/_internal/dns_route53.py
class Authenticator (line 29) | class Authenticator(common.Plugin, interfaces.Authenticator):
method __init__ (line 40) | def __init__(self, *args: Any, **kwargs: Any) -> None:
method more_info (line 47) | def more_info(self) -> str:
method add_parser_arguments (line 51) | def add_parser_arguments(cls, add: Callable[..., None]) -> None:
method auth_hint (line 55) | def auth_hint(self, failed_achalls: list[achallenges.AnnotatedChalleng...
method prepare (line 61) | def prepare(self) -> None:
method get_chall_pref (line 64) | def get_chall_pref(self, unused_identifier: str) -> Iterable[type[chal...
method perform (line 67) | def perform(self, achalls: list[AnnotatedChallenge]) -> list[challenge...
method cleanup (line 85) | def cleanup(self, achalls: list[achallenges.AnnotatedChallenge]) -> None:
method _cleanup (line 94) | def _cleanup(self, validation_name: str, validation: str) -> None:
method _find_zone_id_for_domain (line 100) | def _find_zone_id_for_domain(self, domain: str) -> str:
method _change_txt_record (line 130) | def _change_txt_record(self, action: str, validation_domain_name: str,...
method _wait_for_change (line 166) | def _wait_for_change(self, change_id: str) -> None:
class HiddenAuthenticator (line 184) | class HiddenAuthenticator(Authenticator):
FILE: certbot-dns-route53/src/certbot_dns_route53/_internal/tests/conftest.py
function mock_sleep (line 6) | def mock_sleep():
FILE: certbot-dns-route53/src/certbot_dns_route53/_internal/tests/dns_route53_test.py
class AuthenticatorTest (line 23) | class AuthenticatorTest(unittest.TestCase):
method setUp (line 31) | def setUp(self):
method tearDown (line 44) | def tearDown(self):
method test_more_info (line 49) | def test_more_info(self) -> None:
method test_get_chall_pref (line 52) | def test_get_chall_pref(self) -> None:
method test_perform (line 55) | def test_perform(self):
method test_perform_no_credentials_error (line 66) | def test_perform_no_credentials_error(self):
method test_perform_client_error (line 73) | def test_perform_client_error(self):
method test_cleanup (line 80) | def test_cleanup(self):
method test_cleanup_no_credentials_error (line 91) | def test_cleanup_no_credentials_error(self):
method test_cleanup_client_error (line 99) | def test_cleanup_client_error(self):
class ClientTest (line 108) | class ClientTest(unittest.TestCase):
method setUp (line 143) | def setUp(self):
method tearDown (line 154) | def tearDown(self):
method test_find_zone_id_for_domain (line 159) | def test_find_zone_id_for_domain(self):
method test_find_zone_id_for_domain_pagination (line 173) | def test_find_zone_id_for_domain_pagination(self):
method test_find_zone_id_for_domain_no_results (line 193) | def test_find_zone_id_for_domain_no_results(self):
method test_find_zone_id_for_domain_no_correct_results (line 200) | def test_find_zone_id_for_domain_no_correct_results(self):
method test_change_txt_record (line 214) | def test_change_txt_record(self):
method test_change_txt_record_delete (line 224) | def test_change_txt_record_delete(self):
method test_change_txt_record_multirecord (line 243) | def test_change_txt_record_multirecord(self):
method test_wait_for_change (line 263) | def test_wait_for_change(self):
FILE: certbot-dns-sakuracloud/src/certbot_dns_sakuracloud/_internal/dns_sakuracloud.py
class Authenticator (line 17) | class Authenticator(dns_common_lexicon.LexiconDNSAuthenticator):
method __init__ (line 26) | def __init__(self, *args: Any, **kwargs: Any) -> None:
method add_parser_arguments (line 36) | def add_parser_arguments(cls, add: Callable[..., None],
method more_info (line 42) | def more_info(self) -> str:
method _provider_name (line 47) | def _provider_name(self) -> str:
method _handle_http_error (line 50) | def _handle_http_error(self, e: HTTPError, domain_name: str) -> Option...
FILE: certbot-dns-sakuracloud/src/certbot_dns_sakuracloud/_internal/tests/dns_sakuracloud_test.py
class AuthenticatorTest (line 19) | class AuthenticatorTest(test_util.TempDirTestCase,
method setUp (line 25) | def setUp(self):
FILE: certbot-nginx/src/certbot_nginx/_internal/configurator.py
class NginxConfigurator (line 45) | class NginxConfigurator(common.Configurator):
method add_parser_arguments (line 74) | def add_parser_arguments(cls, add: Callable[..., None]) -> None:
method nginx_conf (line 86) | def nginx_conf(self) -> str:
method __init__ (line 90) | def __init__(self, *args: Any, **kwargs: Any) -> None:
method mod_ssl_conf_src (line 129) | def mod_ssl_conf_src(self) -> str:
method mod_ssl_conf (line 182) | def mod_ssl_conf(self) -> str:
method updated_mod_ssl_conf_digest (line 187) | def updated_mod_ssl_conf_digest(self) -> str:
method install_ssl_options_conf (line 191) | def install_ssl_options_conf(self, options_ssl: str, options_ssl_diges...
method prepare (line 198) | def prepare(self) -> None:
method deploy_cert (line 234) | def deploy_cert(self, domain: str, cert_path: str, key_path: str, chai...
method _deploy_cert (line 258) | def _deploy_cert(self, vhost: obj.VirtualHost, _cert_path: str, key_pa...
method _choose_vhosts_wildcard (line 278) | def _choose_vhosts_wildcard(self, domain: str, prefer_ssl: bool,
method _choose_vhost_single (line 330) | def _choose_vhost_single(self, target_name: str) -> list[obj.VirtualHo...
method _choose_vhosts_common (line 335) | def _choose_vhosts_common(self, target_name: str) -> list[obj.VirtualH...
method choose_vhosts (line 342) | def choose_vhosts(self, target_name: str) -> list[obj.VirtualHost]:
method choose_or_make_vhosts (line 356) | def choose_or_make_vhosts(self, target_name: str, key_path: str,
method ipv6_info (line 386) | def ipv6_info(self, host: str, port: str) -> tuple[bool, bool]:
method _vhost_from_duplicated_default (line 411) | def _vhost_from_duplicated_default(self, domain: str, allow_port_misma...
method _add_server_name_to_vhost (line 427) | def _add_server_name_to_vhost(self, vhost: obj.VirtualHost, domain: st...
method _get_default_vhost (line 435) | def _get_default_vhost(self, domain: str, allow_port_mismatch: bool,
method _get_ranked_matches (line 461) | def _get_ranked_matches(self, target_name: str) -> list[dict[str, Any]]:
method _select_best_name_match (line 474) | def _select_best_name_match(self,
method _rank_matches_by_name (line 495) | def _rank_matches_by_name(self, vhost_list: Iterable[obj.VirtualHost],
method _rank_matches_by_name_and_ssl (line 533) | def _rank_matches_by_name_and_ssl(self, vhost_list: Iterable[obj.Virtu...
method choose_redirect_vhosts (line 551) | def choose_redirect_vhosts(self, target_name: str, port: str) -> list[...
method choose_auth_vhosts (line 579) | def choose_auth_vhosts(self, target_name: str) -> tuple[list[obj.Virtu...
method _port_matches (line 608) | def _port_matches(self, test_port: str, matching_port: str) -> bool:
method _vhost_listening (line 615) | def _vhost_listening(self, vhost: obj.VirtualHost, port: str, ssl: boo...
method _vhost_listening_on_port_no_ssl (line 645) | def _vhost_listening_on_port_no_ssl(self, vhost: obj.VirtualHost, port...
method _get_redirect_ranked_matches (line 648) | def _get_redirect_ranked_matches(self, target_name: str, port: str) ->...
method get_all_names (line 670) | def get_all_names(self) -> set[str]:
method _make_server_ssl (line 708) | def _make_server_ssl(self, vhost: obj.VirtualHost, key_path: str,
method supported_enhancements (line 788) | def supported_enhancements(self) -> list[str]:
method enhance (line 792) | def enhance(self, domain: str, enhancement: str,
method _has_certbot_redirect (line 810) | def _has_certbot_redirect(self, vhost: obj.VirtualHost, domain: str) -...
method _set_http_header (line 814) | def _set_http_header(self, domain: str, header_substring: Union[str, l...
method _add_redirect_block (line 855) | def _add_redirect_block(self, vhost: obj.VirtualHost, domain: str) -> ...
method _split_block (line 863) | def _split_block(self, vhost: obj.VirtualHost, only_directives: Option...
method _enable_redirect (line 897) | def _enable_redirect(self, domain: str,
method _enable_redirect_single (line 925) | def _enable_redirect_single(self, domain: str, vhost: obj.VirtualHost)...
method _enable_ocsp_stapling (line 954) | def _enable_ocsp_stapling(self, domain: str,
method _enable_ocsp_stapling_single (line 973) | def _enable_ocsp_stapling_single(self, vhost: obj.VirtualHost,
method restart (line 1014) | def restart(self) -> None:
method config_test (line 1022) | def config_test(self) -> None:
method _nginx_version (line 1033) | def _nginx_version(self) -> str:
method get_version (line 1057) | def get_version(self) -> tuple[int, ...]:
method _get_openssl_version (line 1102) | def _get_openssl_version(self) -> str:
method more_info (line 1124) | def more_info(self) -> str:
method auth_hint (line 1134) | def auth_hint(self, # pragma: no cover
method save (line 1145) | def save(self, title: Optional[str] = None, temporary: bool = False) -...
method recovery_routine (line 1169) | def recovery_routine(self) -> None:
method revert_challenge_config (line 1181) | def revert_challenge_config(self) -> None:
method rollback_checkpoints (line 1191) | def rollback_checkpoints(self, rollback: int = 1) -> None:
method get_chall_pref (line 1207) | def get_chall_pref(self, unused_identifier: str) -> list[type[challeng...
method perform (line 1212) | def perform(self, achalls: list[achallenges.AnnotatedChallenge]
method cleanup (line 1248) | def cleanup(self, achalls: list[achallenges.AnnotatedChallenge]) -> None:
function _test_block_from_block (line 1258) | def _test_block_from_block(block: list[Any]) -> list[Any]:
function _redirect_block_for_domain (line 1264) | def _redirect_block_for_domain(domain: str) -> list[Any]:
function nginx_restart (line 1280) | def nginx_restart(nginx_ctl: str, nginx_conf: str, sleep_duration: int) ...
function _determine_default_server_root (line 1325) | def _determine_default_server_root() -> str:
FILE: certbot-nginx/src/certbot_nginx/_internal/constants.py
function os_constant (line 62) | def os_constant(key: str) -> Any:
FILE: certbot-nginx/src/certbot_nginx/_internal/display_ops.py
function select_vhost_multiple (line 12) | def select_vhost_multiple(vhosts: Optional[Iterable[VirtualHost]]) -> li...
function _reversemap_vhosts (line 34) | def _reversemap_vhosts(names: Iterable[str], vhosts: Iterable[VirtualHos...
FILE: certbot-nginx/src/certbot_nginx/_internal/http_01.py
class NginxHttp01 (line 23) | class NginxHttp01(common.ChallengePerformer):
method __init__ (line 43) | def __init__(self, configurator: "NginxConfigurator") -> None:
method perform (line 49) | def perform(self) -> list[KeyAuthorizationChallengeResponse]:
method _mod_config (line 72) | def _mod_config(self) -> None:
method _default_listen_addresses (line 147) | def _default_listen_addresses(self) -> list[Addr]:
method _get_validation_path (line 177) | def _get_validation_path(self, achall: KeyAuthorizationAnnotatedChalle...
method _make_server_block (line 180) | def _make_server_block(self, achall: KeyAuthorizationAnnotatedChalleng...
method _location_directive_for_achall (line 203) | def _location_directive_for_achall(self, achall: KeyAuthorizationAnnot...
method _make_or_mod_server_block (line 213) | def _make_or_mod_server_block(self, achall: KeyAuthorizationAnnotatedC...
FILE: certbot-nginx/src/certbot_nginx/_internal/nginxparser.py
class RawNginxParser (line 31) | class RawNginxParser:
method __init__ (line 70) | def __init__(self, source: str) -> None:
method parse (line 73) | def parse(self) -> ParseResults:
method as_list (line 77) | def as_list(self) -> list[Any]:
class RawNginxDumper (line 82) | class RawNginxDumper:
method __init__ (line 84) | def __init__(self, blocks: list[Any]) -> None:
method __iter__ (line 87) | def __iter__(self, blocks: typing.Optional[list[Any]] = None) -> Itera...
method __str__ (line 111) | def __str__(self) -> str:
function spacey (line 116) | def spacey(x: Any) -> bool:
class UnspacedList (line 121) | class UnspacedList(list[Any]):
method __init__ (line 124) | def __init__(self, list_source: Iterable[Any]) -> None:
method _coerce (line 143) | def _coerce(self, inbound: None) -> tuple[None, None]: ...
method _coerce (line 146) | def _coerce(self, inbound: str) -> tuple[str, str]: ...
method _coerce (line 149) | def _coerce(self, inbound: list[Any]) -> tuple["UnspacedList", list[An...
method _coerce (line 151) | def _coerce(self, inbound: Any) -> tuple[Any, Any]:
method insert (line 167) | def insert(self, i: "SupportsIndex", x: Any) -> None:
method append (line 177) | def append(self, x: Any) -> None:
method extend (line 185) | def extend(self, x: Any) -> None:
method __add__ (line 192) | def __add__(self, other: list[Any]) -> "UnspacedList":
method pop (line 198) | def pop(self, *args: Any, **kwargs: Any) -> None:
method remove (line 202) | def remove(self, *args: Any, **kwargs: Any) -> None:
method reverse (line 206) | def reverse(self) -> None:
method sort (line 210) | def sort(self, *_args: Any, **_kwargs: Any) -> None:
method __setslice__ (line 214) | def __setslice__(self, *args: Any, **kwargs: Any) -> None:
method __setitem__ (line 217) | def __setitem__(self, i: Union["SupportsIndex", slice], value: Any) ->...
method __delitem__ (line 226) | def __delitem__(self, i: Union["SupportsIndex", slice]) -> None:
method __deepcopy__ (line 233) | def __deepcopy__(self, memo: Any) -> "UnspacedList":
method is_dirty (line 239) | def is_dirty(self) -> bool:
method _spaced_position (line 245) | def _spaced_position(self, idx: "SupportsIndex") -> int:
function loads (line 268) | def loads(source: str) -> UnspacedList:
function load (line 279) | def load(file_: IO[Any]) -> UnspacedList:
function dumps (line 290) | def dumps(blocks: UnspacedList) -> str:
function dump (line 300) | def dump(blocks: UnspacedList, file_: IO[Any]) -> None:
FILE: certbot-nginx/src/certbot_nginx/_internal/obj.py
class SocketAddrError (line 13) | class SocketAddrError(Exception):
class Addr (line 17) | class Addr(common.Addr):
method __init__ (line 46) | def __init__(self, host: str, port: str, ssl: bool, default: bool,
method fromstring (line 56) | def fromstring(cls, str_addr: str) -> "Addr":
method to_string (line 114) | def to_string(self, include_default: bool = True) -> str:
method __str__ (line 131) | def __str__(self) -> str:
method __repr__ (line 134) | def __repr__(self) -> str:
method __hash__ (line 137) | def __hash__(self) -> int: # pylint: disable=useless-super-delegation
method super_eq (line 142) | def super_eq(self, other: "Addr") -> bool:
method __eq__ (line 154) | def __eq__(self, other: Any) -> bool:
class VirtualHost (line 162) | class VirtualHost:
method __init__ (line 178) | def __init__(self, filep: str, addrs: Sequence[Addr], ssl: bool, enabl...
method __str__ (line 189) | def __str__(self) -> str:
method __repr__ (line 200) | def __repr__(self) -> str:
method __eq__ (line 203) | def __eq__(self, other: Any) -> bool:
method __hash__ (line 214) | def __hash__(self) -> int:
method has_header (line 219) | def has_header(self, header_name: str) -> bool:
method contains_list (line 227) | def contains_list(self, test: list[Any]) -> bool:
method ipv6_enabled (line 235) | def ipv6_enabled(self) -> bool:
method ipv4_enabled (line 243) | def ipv4_enabled(self) -> bool:
method display_repr (line 253) | def display_repr(self) -> str:
function _find_directive (line 266) | def _find_directive(directives: Optional[Union[str, list[Any]]], directi...
FILE: certbot-nginx/src/certbot_nginx/_internal/parser.py
class NginxParser (line 28) | class NginxParser:
method __init__ (line 37) | def __init__(self, root: str) -> None:
method load (line 48) | def load(self) -> None:
method http_path (line 56) | def http_path(self) -> str:
method _parse_recursively (line 63) | def _parse_recursively(self, filepath: str) -> None:
method abs_path (line 94) | def abs_path(self, path: str) -> str:
method _build_addr_to_ssl (line 107) | def _build_addr_to_ssl(self) -> dict[tuple[str, str], bool]:
method _get_raw_servers (line 124) | def _get_raw_servers(self) -> dict[str, Union[list[Any], UnspacedList]]:
method get_vhosts (line 143) | def get_vhosts(self) -> list[obj.VirtualHost]:
method _update_vhosts_addrs_ssl (line 175) | def _update_vhosts_addrs_ssl(self, vhosts: Iterable[obj.VirtualHost]) ...
method _get_included_directives (line 185) | def _get_included_directives(self, block: UnspacedList) -> UnspacedList:
method _parse_files (line 205) | def _parse_files(self, filepath: str, override: bool = False) -> dict[...
method _find_config_root (line 239) | def _find_config_root(self) -> str:
method filedump (line 250) | def filedump(self, ext: str = 'tmp', lazy: bool = True) -> None:
method parse_server (line 275) | def parse_server(self, server: UnspacedList) -> dict[str, Any]:
method has_ssl_on_directive (line 286) | def has_ssl_on_directive(self, vhost: obj.VirtualHost) -> bool:
method add_server_directives (line 304) | def add_server_directives(self, vhost: obj.VirtualHost, directives: li...
method update_or_add_server_directives (line 326) | def update_or_add_server_directives(self, vhost: obj.VirtualHost, dire...
method remove_server_directives (line 349) | def remove_server_directives(self, vhost: obj.VirtualHost, directive_n...
method _update_vhost_based_on_new_directives (line 362) | def _update_vhost_based_on_new_directives(self, vhost: obj.VirtualHost,
method _modify_server_directives (line 371) | def _modify_server_directives(self, vhost: obj.VirtualHost,
method duplicate_vhost (line 387) | def duplicate_vhost(self, vhost_template: obj.VirtualHost,
function _parse_ssl_options (line 442) | def _parse_ssl_options(ssl_options: Optional[str]) -> list[UnspacedList]:
function _do_for_subarray (line 457) | def _do_for_subarray(entry: list[Any], condition: Callable[[list[Any]], ...
function get_best_match (line 478) | def get_best_match(target_name: str, names: Iterable[str]) -> tuple[Opti...
function _exact_match (line 524) | def _exact_match(target_name: str, name: str) -> bool:
function _wildcard_match (line 529) | def _wildcard_match(target_name: str, name: str, start: bool) -> bool:
function _regex_match (line 554) | def _regex_match(target_name: str, name: str) -> bool:
function _is_include_directive (line 568) | def _is_include_directive(entry: Any) -> bool:
function _is_ssl_on_directive (line 581) | def _is_ssl_on_directive(entry: Any) -> bool:
function _add_directives (line 594) | def _add_directives(directives: list[Any], insert_at_top: bool,
function _update_or_add_directives (line 603) | def _update_or_add_directives(directives: list[Any], insert_at_top: bool,
function comment_directive (line 618) | def comment_directive(block: UnspacedList, location: int) -> None:
function _comment_out_directive (line 638) | def _comment_out_directive(block: UnspacedList, location: int, include_l...
function _find_location (line 662) | def _find_location(block: UnspacedList, directive_name: str,
function _is_whitespace_or_comment (line 670) | def _is_whitespace_or_comment(directive: Sequence[Any]) -> bool:
function _add_directive (line 675) | def _add_directive(block: UnspacedList, directive: Sequence[Any], insert...
function _update_directive (line 740) | def _update_directive(block: UnspacedList, directive: Sequence[Any], loc...
function _update_or_add_directive (line 745) | def _update_or_add_directive(block: UnspacedList, directive: Sequence[Any],
function _is_certbot_comment (line 764) | def _is_certbot_comment(directive: Sequence[Any]) -> bool:
function _remove_directives (line 768) | def _remove_directives(directive_name: str, match_func: Callable[[Any], ...
function _apply_global_addr_ssl (line 782) | def _apply_global_addr_ssl(addr_to_ssl: Mapping[tuple[str, str], bool],
function _parse_server_raw (line 792) | def _parse_server_raw(server: UnspacedList) -> dict[str, Any]:
FILE: certbot-nginx/src/certbot_nginx/_internal/parser_obj.py
class Parsable (line 22) | class Parsable:
method __init__ (line 31) | def __init__(self, parent: Optional["Parsable"] = None):
method parsing_hooks (line 37) | def parsing_hooks(cls) -> tuple[type["Block"], type["Sentence"], type[...
method should_parse (line 48) | def should_parse(lists: Any) -> bool:
method parse (line 57) | def parse(self, raw_list: list[Any], add_spaces: bool = False) -> None:
method iterate (line 72) | def iterate(self, expanded: bool = False,
method get_tabs (line 86) | def get_tabs(self) -> str:
method set_tabs (line 99) | def set_tabs(self, tabs: str = " ") -> None:
method dump (line 108) | def dump(self, include_spaces: bool = False) -> list[Any]:
class Statements (line 123) | class Statements(Parsable):
method __init__ (line 130) | def __init__(self, parent: Optional[Parsable] = None):
method should_parse (line 137) | def should_parse(lists: Any) -> bool:
method set_tabs (line 140) | def set_tabs(self, tabs: str = " ") -> None:
method parse (line 153) | def parse(self, raw_list: list[Any], add_spaces: bool = False) -> None:
method get_tabs (line 166) | def get_tabs(self) -> str:
method dump (line 173) | def dump(self, include_spaces: bool = False) -> list[Any]:
method iterate (line 181) | def iterate(self, expanded: bool = False,
function _space_list (line 190) | def _space_list(list_: Sequence[Any]) -> list[str]:
class Sentence (line 200) | class Sentence(Parsable):
method should_parse (line 206) | def should_parse(lists: Any) -> bool:
method parse (line 217) | def parse(self, raw_list: list[Any], add_spaces: bool = False) -> None:
method iterate (line 227) | def iterate(self, expanded: bool = False,
method set_tabs (line 233) | def set_tabs(self, tabs: str = " ") -> None:
method dump (line 240) | def dump(self, include_spaces: bool = False) -> list[Any]:
method get_tabs (line 246) | def get_tabs(self) -> str:
method words (line 258) | def words(self) -> list[str]:
method __getitem__ (line 262) | def __getitem__(self, index: int) -> str:
method __contains__ (line 265) | def __contains__(self, word: str) -> bool:
class Block (line 269) | class Block(Parsable):
method __init__ (line 280) | def __init__(self, parent: Optional[Parsable] = None) -> None:
method should_parse (line 286) | def should_parse(lists: Any) -> bool:
method set_tabs (line 297) | def set_tabs(self, tabs: str = " ") -> None:
method iterate (line 303) | def iterate(self, expanded: bool = False,
method parse (line 311) | def parse(self, raw_list: list[Any], add_spaces: bool = False) -> None:
method get_tabs (line 333) | def get_tabs(self) -> str:
function _is_comment (line 338) | def _is_comment(parsed_obj: Parsable) -> bool:
function _is_certbot_comment (line 351) | def _is_certbot_comment(parsed_obj: Parsable) -> bool:
function _certbot_comment (line 369) | def _certbot_comment(parent: Parsable, preceding_spaces: int = 4) -> Sen...
function _choose_parser (line 381) | def _choose_parser(parent: Parsable, list_: Any) -> Parsable:
function parse_raw (line 394) | def parse_raw(lists_: Any, parent: Optional[Parsable] = None, add_spaces...
FILE: certbot-nginx/src/certbot_nginx/_internal/tests/configurator_test.py
class NginxConfiguratorTest (line 21) | class NginxConfiguratorTest(util.NginxTest):
method setUp (line 24) | def setUp(self):
method test_prepare_no_install (line 35) | def test_prepare_no_install(self, mock_exe_exists):
method test_prepare (line 40) | def test_prepare(self):
method test_prepare_initializes_version (line 46) | def test_prepare_initializes_version(self, mock_run, mock_exe_exists):
method test_prepare_locked (line 63) | def test_prepare_locked(self):
method _test_prepare_locked (line 80) | def _test_prepare_locked(self, unused_exe_exists):
method test_get_all_names (line 92) | def test_get_all_names(self, mock_gethostbyaddr, mock_gethostname):
method test_supported_enhancements (line 103) | def test_supported_enhancements(self):
method test_enhance (line 107) | def test_enhance(self):
method test_get_chall_pref (line 111) | def test_get_chall_pref(self):
method test_save (line 115) | def test_save(self):
method test_choose_or_make_vhosts_alias (line 137) | def test_choose_or_make_vhosts_alias(self):
method test_choose_or_make_vhosts_example_com (line 140) | def test_choose_or_make_vhosts_example_com(self):
method test_choose_or_make_vhosts_localhost (line 143) | def test_choose_or_make_vhosts_localhost(self):
method test_choose_or_make_vhosts_example_com_uk_test (line 146) | def test_choose_or_make_vhosts_example_com_uk_test(self):
method test_choose_or_make_vhosts_www_example_com (line 149) | def test_choose_or_make_vhosts_www_example_com(self):
method test_choose_or_make_vhosts_test_www_example_com (line 152) | def test_choose_or_make_vhosts_test_www_example_com(self):
method test_choose_or_make_vhosts_abc_www_foo_com (line 155) | def test_choose_or_make_vhosts_abc_www_foo_com(self):
method test_choose_or_make_vhosts_www_bar_co_uk (line 158) | def test_choose_or_make_vhosts_www_bar_co_uk(self):
method test_choose_or_make_vhosts_ipv6_com (line 161) | def test_choose_or_make_vhosts_ipv6_com(self):
method _test_choose_or_make_vhosts_common (line 164) | def _test_choose_or_make_vhosts_common(self, name, conf):
method test_choose_or_make_vhosts_bad (line 193) | def test_choose_or_make_vhosts_bad(self):
method test_choose_or_make_vhosts_keep_ip_address (line 202) | def test_choose_or_make_vhosts_keep_ip_address(self):
method test_choose_or_make_vhost_ssl_directives (line 232) | def test_choose_or_make_vhost_ssl_directives(self):
method test_ipv6only (line 246) | def test_ipv6only(self):
method test_ipv6only_detection (line 252) | def test_ipv6only_detection(self):
method test_more_info (line 259) | def test_more_info(self):
method test_deploy_cert_requires_fullchain_path (line 262) | def test_deploy_cert_requires_fullchain_path(self):
method test_deploy_cert_raise_on_add_error (line 272) | def test_deploy_cert_raise_on_add_error(self, mock_update_or_add_serve...
method test_deploy_cert (line 281) | def test_deploy_cert(self):
method test_deploy_cert_add_explicit_listen (line 342) | def test_deploy_cert_add_explicit_listen(self):
method test_perform_and_cleanup (line 370) | def test_perform_and_cleanup(self, mock_revert, mock_restart, mock_htt...
method test_get_version (line 398) | def test_get_version(self, mock_run):
method test_get_openssl_version (line 459) | def test_get_openssl_version(self, mock_run):
method test_nginx_restart (line 522) | def test_nginx_restart(self, mock_time, mock_run):
method test_nginx_restart_fail (line 533) | def test_nginx_restart_fail(self, mock_log_debug, mock_run):
method test_no_nginx_start (line 544) | def test_no_nginx_start(self, mock_run):
method test_config_test_bad_process (line 550) | def test_config_test_bad_process(self, mock_run_script):
method test_config_test (line 556) | def test_config_test(self, _):
method test_recovery_routine_throws_error_from_reverter (line 560) | def test_recovery_routine_throws_error_from_reverter(self, mock_recove...
method test_rollback_checkpoints_throws_error_from_reverter (line 566) | def test_rollback_checkpoints_throws_error_from_reverter(self, mock_ro...
method test_revert_challenge_config_throws_error_from_reverter (line 572) | def test_revert_challenge_config_throws_error_from_reverter(self, mock...
method test_save_throws_error_from_reverter (line 578) | def test_save_throws_error_from_reverter(self, mock_add_to_checkpoint):
method test_redirect_enhance (line 583) | def test_redirect_enhance(self):
method test_split_for_redirect (line 604) | def test_split_for_redirect(self):
method test_split_for_headers (line 634) | def test_split_for_headers(self):
method test_http_header_hsts (line 664) | def test_http_header_hsts(self):
method test_multiple_headers_hsts (line 673) | def test_multiple_headers_hsts(self):
method test_http_header_hsts_twice (line 682) | def test_http_header_hsts_twice(self):
method test_certbot_redirect_exists (line 691) | def test_certbot_redirect_exists(self, mock_contains_list):
method test_redirect_dont_enhance (line 701) | def test_redirect_dont_enhance(self):
method test_double_redirect (line 708) | def test_double_redirect(self):
method test_staple_ocsp_bad_version (line 721) | def test_staple_ocsp_bad_version(self):
method test_staple_ocsp_no_chain_path (line 726) | def test_staple_ocsp_no_chain_path(self):
method test_staple_ocsp_internal_error (line 730) | def test_staple_ocsp_internal_error(self):
method test_staple_ocsp (line 738) | def test_staple_ocsp(self):
method test_deploy_no_match_default_set (line 755) | def test_deploy_no_match_default_set(self):
method test_deploy_no_match_default_set_multi_level_path (line 808) | def test_deploy_no_match_default_set_multi_level_path(self):
method test_deploy_no_match_no_default_set (line 841) | def test_deploy_no_match_no_default_set(self):
method test_deploy_no_match_fail_multiple_defaults (line 853) | def test_deploy_no_match_fail_multiple_defaults(self):
method test_deploy_no_match_multiple_defaults_ok (line 859) | def test_deploy_no_match_multiple_defaults_ok(self):
method test_deploy_no_match_add_redirect (line 866) | def test_deploy_no_match_add_redirect(self):
method test_parser_reload_after_config_changes (line 899) | def test_parser_reload_after_config_changes(self, mock_parser_load, un...
method test_choose_vhosts_wildcard (line 905) | def test_choose_vhosts_wildcard(self):
method test_choose_vhosts_wildcard_redirect (line 921) | def test_choose_vhosts_wildcard_redirect(self):
method test_deploy_cert_wildcard (line 937) | def test_deploy_cert_wildcard(self):
method test_deploy_cert_wildcard_no_vhosts (line 953) | def test_deploy_cert_wildcard_no_vhosts(self, mock_dialog):
method test_enhance_wildcard_ocsp_after_install (line 961) | def test_enhance_wildcard_ocsp_after_install(self, mock_dialog):
method test_enhance_wildcard_redirect_or_ocsp_no_install (line 970) | def test_enhance_wildcard_redirect_or_ocsp_no_install(self, mock_dialog):
method test_enhance_wildcard_double_redirect (line 980) | def test_enhance_wildcard_double_redirect(self, mock_dialog):
method test_choose_vhosts_wildcard_no_ssl_filter_port (line 988) | def test_choose_vhosts_wildcard_no_ssl_filter_port(self):
method test_choose_auth_vhosts (line 999) | def test_choose_auth_vhosts(self):
class InstallSslOptionsConfTest (line 1012) | class InstallSslOptionsConfTest(util.NginxTest):
method setUp (line 1015) | def setUp(self):
method _call (line 1021) | def _call(self):
method _current_ssl_options_hash (line 1025) | def _current_ssl_options_hash(self):
method _assert_current_file (line 1028) | def _assert_current_file(self):
method test_no_file (line 1033) | def test_no_file(self):
method test_current_file (line 1041) | def test_current_file(self):
method _mock_hash_except_ssl_conf_src (line 1046) | def _mock_hash_except_ssl_conf_src(self, fake_hash):
method test_prev_file_updates_to_current (line 1057) | def test_prev_file_updates_to_current(self):
method test_prev_file_updates_to_current_old_nginx (line 1064) | def test_prev_file_updates_to_current_old_nginx(self):
method test_manually_modified_current_file_does_not_update (line 1072) | def test_manually_modified_current_file_does_not_update(self):
method test_manually_modified_past_file_warns (line 1084) | def test_manually_modified_past_file_warns(self):
method test_current_file_hash_in_all_hashes (line 1101) | def test_current_file_hash_in_all_hashes(self):
method test_ssl_config_files_hash_in_all_hashes (line 1107) | def test_ssl_config_files_hash_in_all_hashes(self):
method test_nginx_version_uses_correct_config (line 1127) | def test_nginx_version_uses_correct_config(self):
class DetermineDefaultServerRootTest (line 1151) | class DetermineDefaultServerRootTest(certbot_test_util.ConfigTestCase):
method _call (line 1154) | def _call(self):
method test_docs_value (line 1159) | def test_docs_value(self):
method test_real_values (line 1163) | def test_real_values(self):
method _test (line 1166) | def _test(self, expect_both_values):
FILE: certbot-nginx/src/certbot_nginx/_internal/tests/display_ops_test.py
class SelectVhostMultiTest (line 13) | class SelectVhostMultiTest(util.NginxTest):
method setUp (line 16) | def setUp(self):
method test_select_no_input (line 21) | def test_select_no_input(self):
method test_select_correct (line 25) | def test_select_correct(self, mock_util):
method test_select_cancel (line 37) | def test_select_cancel(self, mock_util):
FILE: certbot-nginx/src/certbot_nginx/_internal/tests/http_01_test.py
class HttpPerformTest (line 18) | class HttpPerformTest(util.NginxTest):
method setUp (line 56) | def setUp(self):
method test_perform0 (line 65) | def test_perform0(self):
method test_perform1 (line 70) | def test_perform1(self, mock_save):
method test_perform2 (line 79) | def test_perform2(self):
method test_mod_config (line 91) | def test_mod_config(self):
method test_mod_config_http_and_https (line 116) | def test_mod_config_http_and_https(self, mock_add_server_directives):
method test_mod_config_only_https (line 128) | def test_mod_config_only_https(self, mock_add_server_directives, mock_...
method test_mod_config_deduplicate (line 140) | def test_mod_config_deduplicate(self, mock_add_server_directives):
method test_mod_config_insert_bucket_directive (line 153) | def test_mod_config_insert_bucket_directive(self):
method test_mod_config_update_bucket_directive_in_included_file (line 168) | def test_mod_config_update_bucket_directive_in_included_file(self):
method test_default_listen_addresses_no_memoization (line 202) | def test_default_listen_addresses_no_memoization(self, ipv6_info):
method test_default_listen_addresses_t_t (line 212) | def test_default_listen_addresses_t_t(self, ipv6_info):
method test_default_listen_addresses_t_f (line 221) | def test_default_listen_addresses_t_f(self, ipv6_info):
method test_default_listen_addresses_f_f (line 230) | def test_default_listen_addresses_f_f(self, ipv6_info):
FILE: certbot-nginx/src/certbot_nginx/_internal/tests/nginxparser_test
Condensed preview — 1210 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (4,963K chars).
[
{
"path": ".azure-pipelines/INSTALL.md",
"chars": 5867,
"preview": "# Configuring Azure Pipelines with Certbot\n\nLet's begin. All pipelines are defined in `.azure-pipelines`. Currently ther"
},
{
"path": ".azure-pipelines/advanced-test.yml",
"chars": 457,
"preview": "# Advanced pipeline for running our full test suite on demand.\ntrigger:\n # When changing these triggers, please ensure "
},
{
"path": ".azure-pipelines/main.yml",
"chars": 657,
"preview": "# We run the test suite on commits to main so codecov gets coverage data\n# about the main branch and can use it to track"
},
{
"path": ".azure-pipelines/nightly.yml",
"chars": 426,
"preview": "# Nightly pipeline running each day for main.\ntrigger: none\npr: none\nschedules:\n - cron: \"30 4 * * *\"\n displayName: "
},
{
"path": ".azure-pipelines/release.yml",
"chars": 423,
"preview": "# Release pipeline to run our full test suite, build artifacts, and deploy them\n# for GitHub release tags.\ntrigger:\n ta"
},
{
"path": ".azure-pipelines/templates/jobs/common-deploy-jobs.yml",
"chars": 5149,
"preview": "# As (somewhat) described at\n# https://docs.microsoft.com/en-us/azure/devops/pipelines/process/templates?view=azure-devo"
},
{
"path": ".azure-pipelines/templates/jobs/extended-tests-jobs.yml",
"chars": 1967,
"preview": "jobs:\n - job: extended_test\n variables:\n - name: IMAGE_NAME\n value: ubuntu-22.04\n - name: PYTHON_VE"
},
{
"path": ".azure-pipelines/templates/jobs/packaging-jobs.yml",
"chars": 5484,
"preview": "jobs:\n - job: docker_build\n pool:\n vmImage: ubuntu-24.04\n strategy:\n matrix:\n arm32v6:\n "
},
{
"path": ".azure-pipelines/templates/jobs/standard-tests-jobs.yml",
"chars": 1661,
"preview": "jobs:\n - job: test\n variables:\n PYTHON_VERSION: 3.14\n strategy:\n matrix:\n macos-cover:\n "
},
{
"path": ".azure-pipelines/templates/stages/changelog-stage.yml",
"chars": 908,
"preview": "stages:\n - stage: Changelog\n jobs:\n - job: prepare\n pool:\n vmImage: ubuntu-latest\n steps"
},
{
"path": ".azure-pipelines/templates/stages/nightly-deploy-stage.yml",
"chars": 140,
"preview": "stages:\n - stage: Deploy\n jobs:\n - template: ../jobs/common-deploy-jobs.yml\n parameters:\n snapR"
},
{
"path": ".azure-pipelines/templates/stages/release-deploy-stage.yml",
"chars": 1237,
"preview": "stages:\n - stage: Deploy\n jobs:\n - template: ../jobs/common-deploy-jobs.yml\n parameters:\n snapR"
},
{
"path": ".azure-pipelines/templates/stages/test-and-package-stage.yml",
"chars": 189,
"preview": "stages:\n - stage: TestAndPackage\n jobs:\n - template: ../jobs/standard-tests-jobs.yml\n - template: ../jobs/"
},
{
"path": ".azure-pipelines/templates/steps/sphinx-steps.yml",
"chars": 737,
"preview": "steps:\n - bash: |\n set -e\n sudo apt-get update\n sudo apt-get install -y --no-install-recommends libaugea"
},
{
"path": ".azure-pipelines/templates/steps/tox-steps.yml",
"chars": 3006,
"preview": "# This does not include the dependencies needed to build cryptography. See\n# https://cryptography.io/en/latest/installat"
},
{
"path": ".coveragerc",
"chars": 458,
"preview": "[run]\nomit = */setup.py\nsource =\n acme\n certbot\n certbot-apache\n certbot-dns-cloudflare\n certbot-dns-digi"
},
{
"path": ".dockerignore",
"chars": 312,
"preview": "# this file uses slightly different syntax than .gitignore,\n# e.g. \".tox/\" will not ignore .tox directory\n\n# well, offic"
},
{
"path": ".editorconfig",
"chars": 253,
"preview": "# https://editorconfig.org/\n\nroot = true\n\n[*]\ninsert_final_newline = true\ntrim_trailing_whitespace = true\nend_of_line = "
},
{
"path": ".gitattributes",
"chars": 265,
"preview": "#Default, normalize CRLF into LF in non-binary files\n# Files identified as binary by Git are not changed\n* crlf=auto\n\n# "
},
{
"path": ".github/CODEOWNERS",
"chars": 20,
"preview": "* @certbot/eff-devs\n"
},
{
"path": ".github/FUNDING.yml",
"chars": 66,
"preview": "custom: https://supporters.eff.org/donate/support-work-on-certbot\n"
},
{
"path": ".github/ISSUE_TEMPLATE/bug.yaml",
"chars": 2572,
"preview": "name: Bug Report\ndescription: File a bug report.\ntitle: \"[Bug]: \"\ntype: Bug\nbody:\n - type: markdown\n attributes:\n "
},
{
"path": ".github/ISSUE_TEMPLATE/config.yml",
"chars": 572,
"preview": "blank_issues_enabled: false\ncontact_links:\n - name: Let's Encrypt Community Support\n url: https://community.letsencr"
},
{
"path": ".github/ISSUE_TEMPLATE/feature.yaml",
"chars": 1004,
"preview": "name: Feature Request\ndescription: Suggest a new feature or improvement to Certbot\ntitle: \"[Feature Request]: \"\ntype: Fe"
},
{
"path": ".github/ISSUE_TEMPLATE/task.yaml",
"chars": 523,
"preview": "name: Task\ndescription: A codebase upkeep task such as managing deprecations and refactoring\ntitle: \"[Task]: \"\ntype: Tas"
},
{
"path": ".github/codecov.yml",
"chars": 203,
"preview": "# This disables all reporting from codecov. Let's just set it up to collect\n# data for now and then we can play with the"
},
{
"path": ".github/pull_request_template.md",
"chars": 1232,
"preview": "## Pull Request Checklist\n\n- [ ] The Certbot team has recently expressed interest in reviewing a PR for this. If not, th"
},
{
"path": ".github/workflows/assigned.yaml",
"chars": 1095,
"preview": "name: Issue Assigned\n\non:\n issues:\n types: [assigned]\npermissions: {} # let's not use any permissions we don't need"
},
{
"path": ".github/workflows/merged.yaml",
"chars": 1310,
"preview": "name: Merge Event\n\non:\n pull_request_target:\n types:\n - closed\npermissions: {} # let's not use any permissions"
},
{
"path": ".github/workflows/notify_weekly.yaml",
"chars": 1265,
"preview": "name: Weekly Github Update\n\non:\n schedule:\n # Every week on Thursday @ 10:00\n - cron: \"0 10 * * 4\"\n workflow_dis"
},
{
"path": ".github/workflows/review_requested.yaml",
"chars": 1237,
"preview": "name: Review Requested\n\non:\n pull_request_target:\n types: [review_requested]\npermissions: {}\njobs:\n send-mattermost"
},
{
"path": ".github/workflows/stale.yml",
"chars": 1869,
"preview": "name: Update Stale Issues\non:\n schedule:\n # Run 1:24AM every night\n - cron: '24 1 * * *'\n workflow_dispatch:\nper"
},
{
"path": ".gitignore",
"chars": 759,
"preview": "*.pyc\n*.egg-info/\n.eggs/\nbuild/\ndist*/\n/venv*/\n/.tox/\n/releases*/\n/log*\nletsencrypt.log\ncertbot.log\npoetry.lock\n\n# cover"
},
{
"path": ".isort.cfg",
"chars": 197,
"preview": "[settings]\nskip_glob=venv*\nforce_sort_within_sections=True\nforce_single_line=True\norder_by_type=False\nline_length=400\nsr"
},
{
"path": ".pylintrc",
"chars": 21568,
"preview": "[MAIN]\n\n# Analyse import fallback blocks. This can be used to support both Python 2 and\n# 3 compatible code, which means"
},
{
"path": "AUTHORS.md",
"chars": 14047,
"preview": "Authors\n=======\n\n* [Aaron Gable](https://github.com/aarongable)\n* [Aaron Zirbes](https://github.com/aaronzirbes)\n* Aaron"
},
{
"path": "CODE_OF_CONDUCT.md",
"chars": 103,
"preview": "This project is governed by [EFF's Public Projects Code of Conduct](https://www.eff.org/pages/eppcode)."
},
{
"path": "CONTRIBUTING.md",
"chars": 1803,
"preview": "<!---\n\nzoracon: (This is an old comment below, not sure how accurate this is anymore. \nSince Github seems to lean more t"
},
{
"path": "LICENSE.txt",
"chars": 11456,
"preview": "Certbot ACME Client\nCopyright (c) Electronic Frontier Foundation and others\nLicensed Apache Version 2.0\n\nThe nginx plugi"
},
{
"path": "SECURITY.md",
"chars": 581,
"preview": "# Security Policy\n\n## Supported Versions\n\nExplanation on supported versions [here](https://github.com/certbot/certbot/wi"
},
{
"path": "acme/.readthedocs.yaml",
"chars": 984,
"preview": "# Read the Docs configuration file for Sphinx projects\n# See https://docs.readthedocs.io/en/stable/config-file/v2.html f"
},
{
"path": "acme/LICENSE.txt",
"chars": 10786,
"preview": " Copyright 2015 Electronic Frontier Foundation and others\n\n Licensed under the Apache License, Version 2.0 (the \"Lic"
},
{
"path": "acme/MANIFEST.in",
"chars": 225,
"preview": "include LICENSE.txt\ninclude README.rst\nrecursive-include docs *\nrecursive-include examples *\nrecursive-include src/acme/"
},
{
"path": "acme/README.rst",
"chars": 39,
"preview": "ACME protocol implementation in Python\n"
},
{
"path": "acme/docs/.gitignore",
"chars": 9,
"preview": "/_build/\n"
},
{
"path": "acme/docs/Makefile",
"chars": 7434,
"preview": "# Makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line.\nSPHINXOPTS =\nSPHINXBUILD "
},
{
"path": "acme/docs/_static/.gitignore",
"chars": 0,
"preview": ""
},
{
"path": "acme/docs/_templates/.gitignore",
"chars": 0,
"preview": ""
},
{
"path": "acme/docs/api/challenges.rst",
"chars": 68,
"preview": "Challenges\n----------\n\n.. automodule:: acme.challenges\n :members:\n"
},
{
"path": "acme/docs/api/client.rst",
"chars": 56,
"preview": "Client\n------\n\n.. automodule:: acme.client\n :members:\n"
},
{
"path": "acme/docs/api/crypto_util.rst",
"chars": 71,
"preview": "Crypto_util\n-----------\n\n.. automodule:: acme.crypto_util\n :members:\n"
},
{
"path": "acme/docs/api/errors.rst",
"chars": 56,
"preview": "Errors\n------\n\n.. automodule:: acme.errors\n :members:\n"
},
{
"path": "acme/docs/api/fields.rst",
"chars": 56,
"preview": "Fields\n------\n\n.. automodule:: acme.fields\n :members:\n"
},
{
"path": "acme/docs/api/jose.rst",
"chars": 161,
"preview": "JOSE\n----\n\nThe ``acme.jose`` module was moved to its own package \"josepy_\".\nPlease refer to its documentation there.\n\n.."
},
{
"path": "acme/docs/api/jws.rst",
"chars": 47,
"preview": "JWS\n---\n\n.. automodule:: acme.jws\n :members:\n"
},
{
"path": "acme/docs/api/messages.rst",
"chars": 62,
"preview": "Messages\n--------\n\n.. automodule:: acme.messages\n :members:\n"
},
{
"path": "acme/docs/api/standalone.rst",
"chars": 68,
"preview": "Standalone\n----------\n\n.. automodule:: acme.standalone\n :members:\n"
},
{
"path": "acme/docs/api/util.rst",
"chars": 50,
"preview": "Util\n----\n\n.. automodule:: acme.util\n :members:\n"
},
{
"path": "acme/docs/api.rst",
"chars": 88,
"preview": "=================\nAPI Documentation\n=================\n\n.. toctree::\n :glob:\n\n api/*\n"
},
{
"path": "acme/docs/conf.py",
"chars": 9795,
"preview": "# -*- coding: utf-8 -*-\n#\n# acme-python documentation build configuration file, created by\n# sphinx-quickstart on Sun Oc"
},
{
"path": "acme/docs/index.rst",
"chars": 479,
"preview": ".. acme-python documentation master file, created by\n sphinx-quickstart on Sun Oct 18 13:38:06 2015.\n You can adapt "
},
{
"path": "acme/docs/jws-help.txt",
"chars": 156,
"preview": "usage: jws [-h] [--compact] {sign,verify} ...\n\npositional arguments:\n {sign,verify}\n\noptions:\n -h, --help show thi"
},
{
"path": "acme/docs/make.bat",
"chars": 7259,
"preview": "@ECHO OFF\r\n\r\nREM Command file for Sphinx documentation\r\n\r\nif \"%SPHINXBUILD%\" == \"\" (\r\n\tset SPHINXBUILD=sphinx-build\r\n)\r\n"
},
{
"path": "acme/docs/man/jws.rst",
"chars": 46,
"preview": ":orphan:\n\n.. literalinclude:: ../jws-help.txt\n"
},
{
"path": "acme/examples/http01_example.py",
"chars": 7118,
"preview": "\"\"\"Example ACME-V2 API for HTTP-01 challenge.\n\nBrief:\n\nThis a complete usage example of the python-acme API.\n\nLimitation"
},
{
"path": "acme/pyproject.toml",
"chars": 1430,
"preview": "[build-system]\nrequires = [\"setuptools\"]\nbuild-backend = \"setuptools.build_meta\"\n\n[project]\nname = \"acme\"\ndynamic = [\"ve"
},
{
"path": "acme/readthedocs.org.requirements.txt",
"chars": 584,
"preview": "# readthedocs.org gives no way to change the install command to \"pip\n# install -e acme[docs]\" (that would in turn instal"
},
{
"path": "acme/setup.py",
"chars": 84,
"preview": "from setuptools import setup\n\nversion = '5.5.0.dev0'\n\nsetup(\n version=version,\n)\n"
},
{
"path": "acme/src/acme/__init__.py",
"chars": 749,
"preview": "\"\"\"ACME protocol implementation.\n\nThis module is an implementation of the `ACME protocol`_.\n\n.. _`ACME protocol`: https:"
},
{
"path": "acme/src/acme/_internal/__init__.py",
"chars": 37,
"preview": "\"\"\"acme's internal implementation\"\"\"\n"
},
{
"path": "acme/src/acme/_internal/tests/__init__.py",
"chars": 17,
"preview": "\"\"\"acme tests\"\"\"\n"
},
{
"path": "acme/src/acme/_internal/tests/challenges_test.py",
"chars": 14643,
"preview": "\"\"\"Tests for acme.challenges.\"\"\"\nimport sys\nfrom typing import TYPE_CHECKING\nimport unittest\nfrom unittest import mock\ni"
},
{
"path": "acme/src/acme/_internal/tests/client_test.py",
"chars": 47205,
"preview": "\"\"\"Tests for acme.client.\"\"\"\n# pylint: disable=too-many-lines\nimport copy\nimport datetime\nimport http.client as http_cli"
},
{
"path": "acme/src/acme/_internal/tests/conftest.py",
"chars": 482,
"preview": "from unittest import mock\n\nimport pytest\n\n# This avoids a bug on mac where getfqdn errors after a long timeout.\n# See ht"
},
{
"path": "acme/src/acme/_internal/tests/crypto_util_test.py",
"chars": 9621,
"preview": "\"\"\"Tests for acme.crypto_util.\"\"\"\nimport ipaddress\nimport itertools\nimport sys\nimport unittest\nfrom unittest import mock"
},
{
"path": "acme/src/acme/_internal/tests/errors_test.py",
"chars": 2722,
"preview": "\"\"\"Tests for acme.errors.\"\"\"\nimport sys\nimport unittest\nfrom unittest import mock\n\nimport pytest\n\n\nclass BadNonceTest(un"
},
{
"path": "acme/src/acme/_internal/tests/fields_test.py",
"chars": 1704,
"preview": "\"\"\"Tests for acme.fields.\"\"\"\nimport datetime\nimport sys\nimport unittest\n\nimport josepy as jose\nimport pytest\n\n\nclass Fix"
},
{
"path": "acme/src/acme/_internal/tests/jose_test.py",
"chars": 1849,
"preview": "\"\"\"Tests for acme.jose shim.\"\"\"\nimport importlib\nimport sys\n\nimport pytest\n\n\ndef _test_it(submodule, attribute):\n if "
},
{
"path": "acme/src/acme/_internal/tests/jws_test.py",
"chars": 2128,
"preview": "\"\"\"Tests for acme.jws.\"\"\"\nimport sys\nimport unittest\n\nimport josepy as jose\nimport pytest\n\nfrom acme._internal.tests imp"
},
{
"path": "acme/src/acme/_internal/tests/messages_test.py",
"chars": 21468,
"preview": "\"\"\"Tests for acme.messages.\"\"\"\nimport sys\nimport json\nimport unittest\nfrom unittest import mock\n\nimport josepy as jose\ni"
},
{
"path": "acme/src/acme/_internal/tests/standalone_test.py",
"chars": 7049,
"preview": "\"\"\"Tests for acme.standalone.\"\"\"\nimport http.client as http_client\nimport socket\nimport socketserver\nimport sys\nimport t"
},
{
"path": "acme/src/acme/_internal/tests/test_util.py",
"chars": 2044,
"preview": "\"\"\"Test utilities.\n\n.. warning:: This module is not part of the public API.\n\n\"\"\"\nimport importlib.resources\nimport os\nfr"
},
{
"path": "acme/src/acme/_internal/tests/testdata/README",
"chars": 858,
"preview": "In order for acme.test_util._guess_loader to work properly, make sure\nto use appropriate extension for vector filenames:"
},
{
"path": "acme/src/acme/_internal/tests/testdata/cert-100sans.pem",
"chars": 2752,
"preview": "-----BEGIN CERTIFICATE-----\nMIIHxDCCB26gAwIBAgIJAOGrG1Un9lHiMA0GCSqGSIb3DQEBCwUAMGQxCzAJBgNV\nBAgMAkNBMRYwFAYDVQQHDA1TYW4"
},
{
"path": "acme/src/acme/_internal/tests/testdata/cert-idnsans.pem",
"chars": 1866,
"preview": "-----BEGIN CERTIFICATE-----\nMIIFNjCCBOCgAwIBAgIJAP4rNqqOKifCMA0GCSqGSIb3DQEBCwUAMGQxCzAJBgNV\nBAgMAkNBMRYwFAYDVQQHDA1TYW4"
},
{
"path": "acme/src/acme/_internal/tests/testdata/cert-ipsans.pem",
"chars": 1289,
"preview": "-----BEGIN CERTIFICATE-----\nMIIDizCCAnOgAwIBAgIIPNBLQXwhoUkwDQYJKoZIhvcNAQELBQAwKDEmMCQGA1UE\nAxMdUGViYmxlIEludGVybWVkaWF"
},
{
"path": "acme/src/acme/_internal/tests/testdata/cert-ipv6sans.pem",
"chars": 1310,
"preview": "-----BEGIN CERTIFICATE-----\nMIIDmzCCAoOgAwIBAgIIFdxeZP+v2rgwDQYJKoZIhvcNAQELBQAwKDEmMCQGA1UE\nAxMdUGViYmxlIEludGVybWVkaWF"
},
{
"path": "acme/src/acme/_internal/tests/testdata/cert-san.pem",
"chars": 786,
"preview": "-----BEGIN CERTIFICATE-----\nMIICFjCCAcCgAwIBAgICBTkwDQYJKoZIhvcNAQELBQAwdzELMAkGA1UEBhMCVVMx\nETAPBgNVBAgMCE1pY2hpZ2FuMRI"
},
{
"path": "acme/src/acme/_internal/tests/testdata/cert.pem",
"chars": 709,
"preview": "-----BEGIN CERTIFICATE-----\nMIIB3jCCAYigAwIBAgICBTkwDQYJKoZIhvcNAQELBQAwdzELMAkGA1UEBhMCVVMx\nETAPBgNVBAgMCE1pY2hpZ2FuMRI"
},
{
"path": "acme/src/acme/_internal/tests/testdata/critical-san.pem",
"chars": 1683,
"preview": "-----BEGIN CERTIFICATE-----\nMIIErTCCA5WgAwIBAgIKETb7VQAAAAAdGTANBgkqhkiG9w0BAQsFADCBkTELMAkG\nA1UEBhMCVVMxDTALBgNVBAgTBFV"
},
{
"path": "acme/src/acme/_internal/tests/testdata/csr-100sans.pem",
"chars": 2577,
"preview": "-----BEGIN CERTIFICATE REQUEST-----\nMIIHNTCCBt8CAQAwZDELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDVNhbiBGcmFuY2lz\nY28xJzAlBgNVBAsMHkV"
},
{
"path": "acme/src/acme/_internal/tests/testdata/csr-6sans.pem",
"chars": 676,
"preview": "-----BEGIN CERTIFICATE REQUEST-----\nMIIBuzCCAWUCAQAweTELMAkGA1UEBhMCVVMxETAPBgNVBAgTCE1pY2hpZ2FuMRIw\nEAYDVQQHEwlBbm4gQXJ"
},
{
"path": "acme/src/acme/_internal/tests/testdata/csr-idnsans.pem",
"chars": 1691,
"preview": "-----BEGIN CERTIFICATE REQUEST-----\nMIIEpzCCBFECAQAwZDELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDVNhbiBGcmFuY2lz\nY28xJzAlBgNVBAsMHkV"
},
{
"path": "acme/src/acme/_internal/tests/testdata/csr-ipsans.pem",
"chars": 920,
"preview": "-----BEGIN CERTIFICATE REQUEST-----\nMIICbTCCAVUCAQIwADCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKT/\nCE7Y5EYBvI4p7Frt763"
},
{
"path": "acme/src/acme/_internal/tests/testdata/csr-ipv6sans.pem",
"chars": 952,
"preview": "-----BEGIN CERTIFICATE REQUEST-----\nMIIChTCCAW0CAQIwADCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOIc\nUAppcqJfTkSqqOFqGt1"
},
{
"path": "acme/src/acme/_internal/tests/testdata/csr-mixed.pem",
"chars": 932,
"preview": "-----BEGIN CERTIFICATE REQUEST-----\nMIICdjCCAV4CAQAwADCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANoV\nT1pdvRUUBOqvm7M2ebL"
},
{
"path": "acme/src/acme/_internal/tests/testdata/csr-nosans.pem",
"chars": 452,
"preview": "-----BEGIN CERTIFICATE REQUEST-----\nMIIBFTCBwAIBADBbMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEh\nMB8GA1UECgwYSW50ZXJ"
},
{
"path": "acme/src/acme/_internal/tests/testdata/csr-san.pem",
"chars": 574,
"preview": "-----BEGIN CERTIFICATE REQUEST-----\nMIIBbjCCARgCAQAweTELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE1pY2hpZ2FuMRIw\nEAYDVQQHDAlBbm4gQXJ"
},
{
"path": "acme/src/acme/_internal/tests/testdata/csr.pem",
"chars": 550,
"preview": "-----BEGIN CERTIFICATE REQUEST-----\nMIIBXTCCAQcCAQAweTELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE1pY2hpZ2FuMRIw\nEAYDVQQHDAlBbm4gQXJ"
},
{
"path": "acme/src/acme/_internal/tests/testdata/dsa512_key.pem",
"chars": 684,
"preview": "-----BEGIN DSA PARAMETERS-----\nMIGdAkEAwebEoGBfokKQeALHHnAZMQwYU35ILEBdV8oUmzv7qpSVUoHihyqfn6GC\nOixAKSP8EJYcTilIqPbFbfFy"
},
{
"path": "acme/src/acme/_internal/tests/testdata/ec_secp384r1_key.pem",
"chars": 306,
"preview": "-----BEGIN PRIVATE KEY-----\nMIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDArTn0pbFk3xHfKeXte\nxJgS4JVdJQ8mqvezhaNpULZPnwb"
},
{
"path": "acme/src/acme/_internal/tests/testdata/rsa1024_cert.pem",
"chars": 749,
"preview": "-----BEGIN CERTIFICATE-----\nMIIB/TCCAWagAwIBAgIJAOyRIBs3QT8QMA0GCSqGSIb3DQEBCwUAMBYxFDASBgNV\nBAMMC2V4YW1wbGUuY29tMB4XDTE"
},
{
"path": "acme/src/acme/_internal/tests/testdata/rsa1024_key.pem",
"chars": 887,
"preview": "-----BEGIN RSA PRIVATE KEY-----\nMIICXAIBAAKBgQCaifO0fGlcAcjjcYEAPYcIL0Hf0KiNa9VCJ14RBdlZxLWRrVFi\n4tdNCKSKqzKuKrrA8DWd4PH"
},
{
"path": "acme/src/acme/_internal/tests/testdata/rsa2048_cert.pem",
"chars": 1294,
"preview": "-----BEGIN CERTIFICATE-----\nMIIDjjCCAnagAwIBAgIJALVG/VbBb5U7MA0GCSqGSIb3DQEBCwUAMFsxCzAJBgNV\nBAYTAkFVMQswCQYDVQQIDAJXQTE"
},
{
"path": "acme/src/acme/_internal/tests/testdata/rsa2048_key.pem",
"chars": 1704,
"preview": "-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDaFU9aXb0VFATq\nr5uzNnmyxB1e4YoFB+6gBlGRJHz"
},
{
"path": "acme/src/acme/_internal/tests/testdata/rsa256_key.pem",
"chars": 298,
"preview": "-----BEGIN RSA PRIVATE KEY-----\nMIGrAgEAAiEAm2Fylv+Uz7trgTW8EBHP3FQSMeZs2GNQ6VRo1sIVJEkCAwEAAQIh\nAJT0BA/xD01dFCAXzSNyj9n"
},
{
"path": "acme/src/acme/_internal/tests/testdata/rsa4096_cert.pem",
"chars": 1814,
"preview": "-----BEGIN CERTIFICATE-----\nMIIFDTCCAvWgAwIBAgIUImqDrP53V69vFROsjP/gL0YtoA4wDQYJKoZIhvcNAQEL\nBQAwFjEUMBIGA1UEAwwLZXhhbXB"
},
{
"path": "acme/src/acme/_internal/tests/testdata/rsa4096_key.pem",
"chars": 3247,
"preview": "-----BEGIN RSA PRIVATE KEY-----\nMIIJKgIBAAKCAgEA1j0souT0PGfQxQxAUfAGhM3h6ENJYHCzYpzK2kWZzyb0x+TX\nCZvh9BIpi0rfAgUx8jKj0dC"
},
{
"path": "acme/src/acme/_internal/tests/testdata/rsa512_key.pem",
"chars": 493,
"preview": "-----BEGIN RSA PRIVATE KEY-----\nMIIBOgIBAAJBAKx1c7RR7R/drnBSQ/zfx1vQLHUbFLh1AQQQ5R8DZUXd36efNK79\nvukFhN9HFoHZiUvOjm0c+pV"
},
{
"path": "acme/src/acme/_internal/tests/util_test.py",
"chars": 380,
"preview": "\"\"\"Tests for acme.util.\"\"\"\nimport sys\n\nimport pytest\n\n\ndef test_it():\n from acme.util import map_keys\n assert {'a'"
},
{
"path": "acme/src/acme/challenges.py",
"chars": 16102,
"preview": "\"\"\"ACME Identifier Validation Challenges.\"\"\"\nimport abc\nimport functools\nimport hashlib\nimport ipaddress\nimport logging\n"
},
{
"path": "acme/src/acme/client.py",
"chars": 36103,
"preview": "\"\"\"ACME client API.\"\"\"\nimport base64\nimport datetime\nfrom email.utils import parsedate_tz\nimport http.client as http_cli"
},
{
"path": "acme/src/acme/crypto_util.py",
"chars": 12088,
"preview": "\"\"\"Crypto utilities.\"\"\"\nimport enum\nfrom datetime import datetime, timedelta, timezone\nimport ipaddress\nimport logging\nf"
},
{
"path": "acme/src/acme/errors.py",
"chars": 5020,
"preview": "\"\"\"ACME errors.\"\"\"\nimport datetime\nimport typing\nfrom typing import Any\nfrom typing import Mapping\n\nfrom josepy import e"
},
{
"path": "acme/src/acme/fields.py",
"chars": 1665,
"preview": "\"\"\"ACME JSON fields.\"\"\"\nimport datetime\nimport logging\nfrom typing import Any\n\nimport josepy as jose\nimport pyrfc3339\n\nl"
},
{
"path": "acme/src/acme/jws.py",
"chars": 2564,
"preview": "\"\"\"ACME-specific JWS.\n\nThe JWS implementation in josepy only implements the base JOSE standard. In\norder to support the "
},
{
"path": "acme/src/acme/messages.py",
"chars": 27520,
"preview": "\"\"\"ACME protocol messages.\"\"\"\nfrom collections.abc import Hashable\nimport datetime\nimport json\nfrom typing import Any\nfr"
},
{
"path": "acme/src/acme/py.typed",
"chars": 0,
"preview": ""
},
{
"path": "acme/src/acme/standalone.py",
"chars": 9215,
"preview": "\"\"\"Support for standalone client challenge solvers. \"\"\"\nfrom __future__ import annotations\n\nimport collections\nimport fu"
},
{
"path": "acme/src/acme/util.py",
"chars": 279,
"preview": "\"\"\"ACME utilities.\"\"\"\nfrom typing import Any\nfrom typing import Callable\nfrom typing import Mapping\n\n\ndef map_keys(dikt:"
},
{
"path": "certbot/.readthedocs.yaml",
"chars": 990,
"preview": "# Read the Docs configuration file for Sphinx projects\n# See https://docs.readthedocs.io/en/stable/config-file/v2.html f"
},
{
"path": "certbot/CHANGELOG.md",
"chars": 138204,
"preview": "# Certbot change log\n\nCertbot adheres to [Semantic Versioning](https://semver.org/).\n\n<!-- towncrier release notes start"
},
{
"path": "certbot/LICENSE.txt",
"chars": 11456,
"preview": "Certbot ACME Client\nCopyright (c) Electronic Frontier Foundation and others\nLicensed Apache Version 2.0\n\nThe nginx plugi"
},
{
"path": "certbot/MANIFEST.in",
"chars": 279,
"preview": "include README.rst\ninclude CHANGELOG.md\ninclude LICENSE.txt\nrecursive-include docs *\nrecursive-include examples *\nrecurs"
},
{
"path": "certbot/README.rst",
"chars": 4540,
"preview": ".. This file contains a series of comments that are used to include sections of this README in other files. Do not modif"
},
{
"path": "certbot/docs/.gitignore",
"chars": 9,
"preview": "/_build/\n"
},
{
"path": "certbot/docs/Makefile",
"chars": 7073,
"preview": "# Makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line.\nSPHINXOPTS =\nSPHINXBUILD "
},
{
"path": "certbot/docs/_static/.gitignore",
"chars": 0,
"preview": ""
},
{
"path": "certbot/docs/_templates/footer.html",
"chars": 2004,
"preview": "<footer>\n {% if (theme_prev_next_buttons_location == 'bottom' or theme_prev_next_buttons_location == 'both') and (next "
},
{
"path": "certbot/docs/api/certbot.achallenges.rst",
"chars": 148,
"preview": "certbot.achallenges module\n==========================\n\n.. automodule:: certbot.achallenges\n :members:\n :undoc-memb"
},
{
"path": "certbot/docs/api/certbot.compat.filesystem.rst",
"chars": 166,
"preview": "certbot.compat.filesystem module\n================================\n\n.. automodule:: certbot.compat.filesystem\n :member"
},
{
"path": "certbot/docs/api/certbot.compat.misc.rst",
"chars": 148,
"preview": "certbot.compat.misc module\n==========================\n\n.. automodule:: certbot.compat.misc\n :members:\n :undoc-memb"
},
{
"path": "certbot/docs/api/certbot.compat.os.rst",
"chars": 180,
"preview": "certbot.compat.os module\n========================\n\n.. automodule:: certbot.compat.os\n :members: chmod, umask, chown, "
},
{
"path": "certbot/docs/api/certbot.compat.rst",
"chars": 247,
"preview": "certbot.compat package\n======================\n\n.. automodule:: certbot.compat\n :members:\n :undoc-members:\n :sho"
},
{
"path": "certbot/docs/api/certbot.crypto_util.rst",
"chars": 150,
"preview": "certbot.crypto\\_util module\n===========================\n\n.. automodule:: certbot.crypto_util\n :members:\n :undoc-me"
},
{
"path": "certbot/docs/api/certbot.display.ops.rst",
"chars": 148,
"preview": "certbot.display.ops module\n==========================\n\n.. automodule:: certbot.display.ops\n :members:\n :undoc-memb"
},
{
"path": "certbot/docs/api/certbot.display.rst",
"chars": 224,
"preview": "certbot.display package\n=======================\n\n.. automodule:: certbot.display\n :members:\n :undoc-members:\n :"
},
{
"path": "certbot/docs/api/certbot.display.util.rst",
"chars": 151,
"preview": "certbot.display.util module\n===========================\n\n.. automodule:: certbot.display.util\n :members:\n :undoc-m"
},
{
"path": "certbot/docs/api/certbot.errors.rst",
"chars": 133,
"preview": "certbot.errors module\n=====================\n\n.. automodule:: certbot.errors\n :members:\n :undoc-members:\n :show-"
},
{
"path": "certbot/docs/api/certbot.interfaces.rst",
"chars": 145,
"preview": "certbot.interfaces module\n=========================\n\n.. automodule:: certbot.interfaces\n :members:\n :undoc-members"
},
{
"path": "certbot/docs/api/certbot.main.rst",
"chars": 127,
"preview": "certbot.main module\n===================\n\n.. automodule:: certbot.main\n :members:\n :undoc-members:\n :show-inheri"
},
{
"path": "certbot/docs/api/certbot.plugins.common.rst",
"chars": 157,
"preview": "certbot.plugins.common module\n=============================\n\n.. automodule:: certbot.plugins.common\n :members:\n :u"
},
{
"path": "certbot/docs/api/certbot.plugins.dns_common.rst",
"chars": 171,
"preview": "certbot.plugins.dns\\_common module\n==================================\n\n.. automodule:: certbot.plugins.dns_common\n :m"
},
{
"path": "certbot/docs/api/certbot.plugins.dns_common_lexicon.rst",
"chars": 197,
"preview": "certbot.plugins.dns\\_common\\_lexicon module\n===========================================\n\n.. automodule:: certbot.plugins"
},
{
"path": "certbot/docs/api/certbot.plugins.dns_test_common.rst",
"chars": 188,
"preview": "certbot.plugins.dns\\_test\\_common module\n========================================\n\n.. automodule:: certbot.plugins.dns_t"
},
{
"path": "certbot/docs/api/certbot.plugins.dns_test_common_lexicon.rst",
"chars": 214,
"preview": "certbot.plugins.dns\\_test\\_common\\_lexicon module\n=================================================\n\n.. automodule:: cer"
},
{
"path": "certbot/docs/api/certbot.plugins.enhancements.rst",
"chars": 175,
"preview": "certbot.plugins.enhancements module\n===================================\n\n.. automodule:: certbot.plugins.enhancements\n "
},
{
"path": "certbot/docs/api/certbot.plugins.rst",
"chars": 432,
"preview": "certbot.plugins package\n=======================\n\n.. automodule:: certbot.plugins\n :members:\n :undoc-members:\n :"
},
{
"path": "certbot/docs/api/certbot.plugins.storage.rst",
"chars": 160,
"preview": "certbot.plugins.storage module\n==============================\n\n.. automodule:: certbot.plugins.storage\n :members:\n "
},
{
"path": "certbot/docs/api/certbot.plugins.util.rst",
"chars": 151,
"preview": "certbot.plugins.util module\n===========================\n\n.. automodule:: certbot.plugins.util\n :members:\n :undoc-m"
},
{
"path": "certbot/docs/api/certbot.reverter.rst",
"chars": 139,
"preview": "certbot.reverter module\n=======================\n\n.. automodule:: certbot.reverter\n :members:\n :undoc-members:\n "
},
{
"path": "certbot/docs/api/certbot.rst",
"chars": 408,
"preview": "certbot package\n===============\n\n.. automodule:: certbot\n :members:\n :undoc-members:\n :show-inheritance:\n\nSubpa"
},
{
"path": "certbot/docs/api/certbot.tests.acme_util.rst",
"chars": 162,
"preview": "certbot.tests.acme\\_util module\n===============================\n\n.. automodule:: certbot.tests.acme_util\n :members:\n "
},
{
"path": "certbot/docs/api/certbot.tests.rst",
"chars": 220,
"preview": "certbot.tests package\n=====================\n\n.. automodule:: certbot.tests\n :members:\n :undoc-members:\n :show-i"
},
{
"path": "certbot/docs/api/certbot.tests.util.rst",
"chars": 145,
"preview": "certbot.tests.util module\n=========================\n\n.. automodule:: certbot.tests.util\n :members:\n :undoc-members"
},
{
"path": "certbot/docs/api/certbot.util.rst",
"chars": 127,
"preview": "certbot.util module\n===================\n\n.. automodule:: certbot.util\n :members:\n :undoc-members:\n :show-inheri"
},
{
"path": "certbot/docs/api.rst",
"chars": 100,
"preview": "=================\nAPI Documentation\n=================\n\n.. toctree::\n :maxdepth: 4\n\n api/certbot\n"
},
{
"path": "certbot/docs/challenges.rst",
"chars": 4695,
"preview": "Challenges\n==========\n\nTo receive a certificate from Let's Encrypt certificate authority (CA), you must pass a *challeng"
},
{
"path": "certbot/docs/ciphers.rst",
"chars": 14996,
"preview": "..\n Sphinx complains that this file isn't included in any toctree, however, we\n currently link to it in the section ab"
},
{
"path": "certbot/docs/cli-help.txt",
"chars": 42440,
"preview": "usage: \n certbot [SUBCOMMAND] [options] [-d DOMAIN] [-d DOMAIN] ...\n\nCertbot can obtain and install HTTPS/TLS/SSL certi"
},
{
"path": "certbot/docs/compatibility.rst",
"chars": 2001,
"preview": "=======================\nBackwards Compatibility\n=======================\n\nAll Certbot components including `acme <https:/"
},
{
"path": "certbot/docs/conf.py",
"chars": 10313,
"preview": "# -*- coding: utf-8 -*-\n#\n# Certbot documentation build configuration file, created by\n# sphinx-quickstart on Sun Nov 23"
},
{
"path": "certbot/docs/contributing.rst",
"chars": 27113,
"preview": "===============\nDeveloper Guide\n===============\n\n.. contents:: Table of Contents\n :local:\n\n\n.. _getting_started:\n\nGett"
},
{
"path": "certbot/docs/index.rst",
"chars": 347,
"preview": "Welcome to the Certbot documentation!\n==================================================\n\n.. toctree::\n :maxdepth: 2\n\n"
},
{
"path": "certbot/docs/install.rst",
"chars": 5935,
"preview": "=====================\nGet Certbot\n=====================\n\n.. contents:: Table of Contents\n :local:\n\n\n.. _system_require"
},
{
"path": "certbot/docs/intro.rst",
"chars": 258,
"preview": "=====================\nIntroduction\n=====================\n\n.. note::\n To get started quickly, use the `interactive ins"
},
{
"path": "certbot/docs/make.bat",
"chars": 7259,
"preview": "@ECHO OFF\r\n\r\nREM Command file for Sphinx documentation\r\n\r\nif \"%SPHINXBUILD%\" == \"\" (\r\n\tset SPHINXBUILD=sphinx-build\r\n)\r\n"
},
{
"path": "certbot/docs/man/certbot.rst",
"chars": 751,
"preview": ":orphan:\n\n=======\ncertbot\n=======\n\nSynopsis\n========\nThe objective of Certbot, Let's Encrypt, and the ACME (Automated Ce"
},
{
"path": "certbot/docs/packaging.rst",
"chars": 2819,
"preview": "===============\nPackaging Guide\n===============\n\nReleases\n========\n\nWe release packages and upload them to PyPI (wheels "
},
{
"path": "certbot/docs/resources.rst",
"chars": 147,
"preview": "=====================\nResources\n=====================\n\n.. include:: ../README.rst\n :start-after: tag:links-begin\n "
},
{
"path": "certbot/docs/using.rst",
"chars": 63481,
"preview": "==========\nUser Guide\n==========\n\n.. contents:: Table of Contents\n :local:\n\nCertbot Commands\n================\n\nCertbot"
},
{
"path": "certbot/docs/what.rst",
"chars": 1712,
"preview": "======================\nWhat is a Certificate?\n======================\n\nA public key or digital *certificate* (formerly ca"
},
{
"path": "certbot/examples/.gitignore",
"chars": 36,
"preview": "# generate-csr.sh:\n/key.pem\n/csr.der"
},
{
"path": "certbot/examples/cli.ini",
"chars": 1282,
"preview": "# This is an example of the kind of things you can do in a configuration file.\n# All flags used by the client can be con"
},
{
"path": "certbot/examples/dev-cli.ini",
"chars": 453,
"preview": "# Always use the staging/testing server - avoids rate limiting\nserver = https://acme-staging-v02.api.letsencrypt.org/dir"
},
{
"path": "certbot/examples/generate-csr.sh",
"chars": 721,
"preview": "#!/bin/sh\n# This script generates a simple SAN CSR to be used with Let's Encrypt\n# CA. Mostly intended for \"auth --csr\" "
},
{
"path": "certbot/examples/openssl.cnf",
"chars": 114,
"preview": "[ req ]\ndistinguished_name = req_distinguished_name\n[ req_distinguished_name ]\n[ san ]\nsubjectAltName=${ENV::SAN}\n"
},
{
"path": "certbot/examples/plugins/certbot_example_plugins.py",
"chars": 674,
"preview": "\"\"\"Example Certbot plugins.\n\nFor full examples, see `certbot.plugins`.\n\n\"\"\"\nfrom certbot import interfaces\nfrom certbot."
},
{
"path": "certbot/examples/plugins/setup.py",
"chars": 378,
"preview": "from setuptools import setup\n\nsetup(\n name='certbot-example-plugins',\n package='certbot_example_plugins.py',\n i"
},
{
"path": "certbot/pyproject.toml",
"chars": 2903,
"preview": "[build-system]\nrequires = [\"setuptools\"]\nbuild-backend = \"setuptools.build_meta\"\n\n[project]\nname = \"certbot\"\ndynamic = ["
},
{
"path": "certbot/readthedocs.org.requirements.txt",
"chars": 598,
"preview": "# readthedocs.org gives no way to change the install command to \"pip\n# install -e certbot[docs]\" (that would in turn ins"
},
{
"path": "certbot/setup.py",
"chars": 1361,
"preview": "import codecs\nimport os\nimport re\n\nfrom setuptools import setup\n\n\ndef read_file(filename, encoding='utf8'):\n \"\"\"Read "
},
{
"path": "certbot/src/certbot/__init__.py",
"chars": 118,
"preview": "\"\"\"Certbot client.\"\"\"\n\n# version number like 1.2.3a0, must have at least 2 parts, like 1.2\n__version__ = '5.5.0.dev0'\n"
},
{
"path": "certbot/src/certbot/_internal/__init__.py",
"chars": 184,
"preview": "\"\"\"\nModules internal to Certbot.\n\nThis package contains modules that are not considered part of Certbot's public\nAPI. Th"
},
{
"path": "certbot/src/certbot/_internal/account.py",
"chars": 14599,
"preview": "\"\"\"Creates ACME accounts for server.\"\"\"\nimport datetime\nimport functools\nimport hashlib\nimport logging\nimport shutil\nimp"
},
{
"path": "certbot/src/certbot/_internal/auth_handler.py",
"chars": 21351,
"preview": "\"\"\"ACME AuthHandler.\"\"\"\nimport datetime\nimport logging\nimport time\nfrom typing import Iterable\nfrom typing import Option"
},
{
"path": "certbot/src/certbot/_internal/cert_manager.py",
"chars": 17111,
"preview": "\"\"\"Tools for managing certificates.\"\"\"\nimport datetime\nimport logging\nimport re\nimport traceback\nfrom typing import Any\n"
},
{
"path": "certbot/src/certbot/_internal/cli/__init__.py",
"chars": 26766,
"preview": "\"\"\"Certbot command line argument & config processing.\"\"\"\n# pylint: disable=too-many-lines\n# ruff: noqa: F401\nimport argp"
},
{
"path": "certbot/src/certbot/_internal/cli/cli_constants.py",
"chars": 3975,
"preview": "\"\"\"Certbot command line constants\"\"\"\ncli_command = \"certbot\"\n\n\n# Argparse's help formatting has a lot of unhelpful pecul"
},
{
"path": "certbot/src/certbot/_internal/cli/cli_utils.py",
"chars": 11163,
"preview": "\"\"\"Certbot command line util function\"\"\"\nimport argparse\nimport copy\nimport glob\nimport inspect\nfrom typing import Any\nf"
},
{
"path": "certbot/src/certbot/_internal/cli/group_adder.py",
"chars": 1073,
"preview": "\"\"\"This module contains a function to add the groups of arguments for the help\ndisplay\"\"\"\nfrom typing import TYPE_CHECKI"
},
{
"path": "certbot/src/certbot/_internal/cli/helpful.py",
"chars": 22843,
"preview": "\"\"\"Certbot command line argument parser\"\"\"\n\nimport argparse\nimport functools\nimport sys\nfrom typing import Any\nfrom typi"
},
{
"path": "certbot/src/certbot/_internal/cli/paths_parser.py",
"chars": 2055,
"preview": "\"\"\"This is a module that adds configuration to the argument parser regarding\npaths for certificates\"\"\"\nfrom typing impor"
},
{
"path": "certbot/src/certbot/_internal/cli/plugins_parsing.py",
"chars": 6210,
"preview": "\"\"\"This is a module that handles parsing of plugins for the argument parser\"\"\"\nfrom typing import TYPE_CHECKING\n\nfrom ce"
},
{
"path": "certbot/src/certbot/_internal/cli/subparsers.py",
"chars": 4192,
"preview": "\"\"\"This module creates subparsers for the argument parser\"\"\"\nfrom typing import TYPE_CHECKING\n\nfrom certbot import inter"
},
{
"path": "certbot/src/certbot/_internal/cli/verb_help.py",
"chars": 5223,
"preview": "\"\"\"This module contain help information for verbs supported by certbot\"\"\"\nfrom certbot._internal.cli.cli_constants impor"
},
{
"path": "certbot/src/certbot/_internal/client.py",
"chars": 38444,
"preview": "\"\"\"Certbot client API.\"\"\"\nimport datetime\nimport logging\nimport platform\nfrom typing import Any\nfrom typing import Calla"
},
{
"path": "certbot/src/certbot/_internal/constants.py",
"chars": 7654,
"preview": "\"\"\"Certbot constants.\"\"\"\nimport atexit\nimport importlib.resources\nimport logging\nfrom contextlib import ExitStack\nfrom t"
},
{
"path": "certbot/src/certbot/_internal/display/__init__.py",
"chars": 33,
"preview": "\"\"\"Certbot display utilities.\"\"\"\n"
},
{
"path": "certbot/src/certbot/_internal/display/completer.py",
"chars": 2554,
"preview": "\"\"\"Provides Tab completion when prompting users for a path.\"\"\"\nimport glob\nfrom types import TracebackType\nfrom typing i"
}
]
// ... and 1010 more files (download for full content)
About this extraction
This page contains the full source code of the certbot/certbot GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1210 files (4.5 MB), approximately 1.2M tokens, and a symbol index with 4908 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.