From dfd08741e515a400eb00f09979d7ab2bfb624cb2 Mon Sep 17 00:00:00 2001 From: grindsa Date: Tue, 2 Jan 2024 16:17:43 +0100 Subject: [PATCH 001/460] [fix] ssl configuration in rpm_test.sh --- examples/Docker/almalinux-systemd/rpm_tester.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/examples/Docker/almalinux-systemd/rpm_tester.sh b/examples/Docker/almalinux-systemd/rpm_tester.sh index 418fce2a..c4ef36f2 100644 --- a/examples/Docker/almalinux-systemd/rpm_tester.sh +++ b/examples/Docker/almalinux-systemd/rpm_tester.sh @@ -28,6 +28,12 @@ case "$1" in cp -R /tmp/acme2certifier/acme_ca/* /opt/acme2certifier/volume/acme_ca/ fi + if [ -d /tmp/acme2certifier/nginx ] + then + mkdir -p /etc/nginx + yes | cp -R /tmp/acme2certifier/nginx/* /etc/nginx/ + fi + chown -R nginx.nginx /opt/acme2certifier/volume/ ls -la /opt/acme2certifier/ ls -la /opt/acme2certifier/volume From 8cd5c32eab7182c72d8c059a5d67e3cfb7c293d4 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 6 Jan 2024 16:58:16 +0100 Subject: [PATCH 002/460] [feat] asa_ca_hander.py --- README.md | 30 +- acme_srv/helper.py | 53 +- docs/asa.md | 52 ++ examples/ca_handler/asa_ca_handler.py | 356 +++++++++++++ test/test_asa_ca_handler.py | 711 ++++++++++++++++++++++++++ test/test_helper.py | 459 ++++++++++------- 6 files changed, 1442 insertions(+), 219 deletions(-) create mode 100644 docs/asa.md create mode 100644 examples/ca_handler/asa_ca_handler.py create mode 100644 test/test_asa_ca_handler.py diff --git a/README.md b/README.md index e032b8d1..1e42b130 100644 --- a/README.md +++ b/README.md @@ -14,9 +14,7 @@ [![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=grindsa_acme2certifier&metric=reliability_rating)](https://sonarcloud.io/summary/overall?id=grindsa_acme2certifier) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=grindsa_acme2certifier&metric=alert_status)](https://sonarcloud.io/summary/overall?id=grindsa_acme2certifier) -acme2certifier is development project to create an ACME protocol proxy. Main -intention is to provide ACME services on CA servers which do not support this -protocol yet. It consists of two libraries: +acme2certifier is development project to create an ACME protocol proxy. Main intention is to provide ACME services on CA servers which do not support this protocol yet. It consists of two libraries: - acme_srv/*.py - a bunch of classes implementing ACME server functionality based on [rfc8555](https://tools.ietf.org/html/rfc8555) @@ -25,6 +23,7 @@ is to be modular that an [adaption to other CA servers](docs/ca_handler.md) should be straight forward. As of today the following handlers are available: - [NetGuard Certificate Manager/Insta Certifier](docs/certifier.md) - [NetGuard Certificate Lifecycle Manager](docs/nclm.md) + - Insta ActiveCMS - [EJBCA](docs/ejbca.md) - [OpenXPKI](docs/openxpki.md) - [Microsoft Certificate Enrollment Web Services](docs/mscertsrv.md) @@ -36,8 +35,7 @@ should be straight forward. As of today the following handlers are available: - [XCA](docs/xca.md) - [acme2dfn](https://github.com/pfisterer/acme2dfn) (external; ACME proxy for the [German research network's PKI](https://www.pki.dfn.de/ueberblick-dfn-pki/) -For more up-to-date information and further documentation, please visit the -project's home page at: [https://github.com/grindsa/acme2certifier](https://github.com/grindsa/acme2certifier) +For more up-to-date information and further documentation, please visit the project's home page at: [https://github.com/grindsa/acme2certifier](https://github.com/grindsa/acme2certifier) ## ChangeLog @@ -57,14 +55,11 @@ Following acme-clients are used for regular testing of server functionality - [Posh-ACME](https://github.com/rmbolger/Posh-ACME) - [win-acme](https://www.win-acme.com/) -Other clients are on my list for later testing. In case you are bored, feel -free to test other ACME clients and raise [issues](https://github.com/grindsa/acme2certifier/issues/new) -if something does not work as expected. +Other clients are on my list for later testing. In case you are bored, feel free to test other ACME clients and raise [issues](https://github.com/grindsa/acme2certifier/issues/new) if something does not work as expected. [Command-line parameters used for testing](docs/acme-clients.md) -I am not a professional developer. Keep this in mind while laughing about my -code and don’t forget to send patches. +I am not a professional developer. Keep this in mind while laughing about my code and don’t forget to send patches. ## Features @@ -87,12 +82,9 @@ Additional functionality will be added over time. If you are badly missing a cer ## Installation -The proxy can run either as plain wsgi-script on either apache or nginx or as -django project. Running acme2certifier as django project allows to use other -database backends than SQLite. +The proxy can run either as plain wsgi-script on either apache or nginx or as django project. Running acme2certifier as django project allows to use other database backends than SQLite. -The fastest and most convenient way to install acme2certifier is to use docker -containers. There are ready made images available at [dockerhub](https://hub.docker.com/r/grindsa/acme2certifier) and [ghcr.io](https://github.com/grindsa?tab=packages&ecosystem=container) as well as [instructions to build your own container](examples/Docker/). In addition rpm packages for AlmaLinux/CentOS Stream/Redhat EL 9 and deb packages for Ubuntu 22.04 will be provided with every release. +The fastest and most convenient way to install acme2certifier is to use docker containers. There are ready made images available at [dockerhub](https://hub.docker.com/r/grindsa/acme2certifier) and [ghcr.io](https://github.com/grindsa?tab=packages&ecosystem=container) as well as [instructions to build your own container](examples/Docker/). In addition rpm packages for AlmaLinux/CentOS Stream/Redhat EL 9 and deb packages for Ubuntu 22.04 will be provided with every release. - [acme2certifier in Github container repository](https://github.com/grindsa?tab=packages&ecosystem=container) - [acme2certifier repository at hub.docker.com](https://hub.docker.com/r/grindsa/acme2certifier) @@ -109,15 +101,11 @@ containers. There are ready made images available at [dockerhub](https://hub.do ## Contributing -Please read [CONTRIBUTING.md](docs/CONTRIBUTING.md) for details on my code of -conduct, and the process for submitting pull requests. -Please note that I have a life besides programming. Thus, expect a delay -in answering. +Please read [CONTRIBUTING.md](docs/CONTRIBUTING.md) for details on my code of conduct, and the process for submitting pull requests. Please note that I have a life besides programming. Thus, expect a delay in answering. ## Versioning -I use [SemVer](http://semver.org/) for versioning. For the versions available, -see the [tags on this repository](https://github.com/grindsa/dkb-robo/tags). +I use [SemVer](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/grindsa/dkb-robo/tags). ## License diff --git a/acme_srv/helper.py b/acme_srv/helper.py index 19c56fed..7104688a 100644 --- a/acme_srv/helper.py +++ b/acme_srv/helper.py @@ -373,17 +373,33 @@ def csr_dn_get(logger: logging.Logger, csr: str) -> str: return subject -def csr_pubkey_get(logger, csr): +def csr_pubkey_get(logger, csr, encoding='pem'): """ get public key from certificate request """ logger.debug('CAhandler.csr_pubkey_get()') csr_obj = csr_load(logger, csr) public_key = csr_obj.public_key() - pubkey_str = public_key.public_bytes( - encoding=serialization.Encoding.PEM, - format=serialization.PublicFormat.SubjectPublicKeyInfo - ) - logger.debug('CAhandler.cert_pubkey_get() ended with: {0}'.format(pubkey_str)) - return convert_byte_to_string(pubkey_str) + if encoding == 'pem': + pubkey_str = public_key.public_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PublicFormat.SubjectPublicKeyInfo + ) + pubkey = convert_byte_to_string(pubkey_str) + elif encoding == 'base64der': + pubkey_str = public_key.public_bytes( + encoding=serialization.Encoding.DER, + format=serialization.PublicFormat.SubjectPublicKeyInfo + ) + pubkey = b64_encode(logger, pubkey_str) + + elif encoding == 'der': + pubkey = public_key.public_bytes( + encoding=serialization.Encoding.DER, + format=serialization.PublicFormat.SubjectPublicKeyInfo + ) + else: + pubkey = None + logger.debug('CAhandler.cert_pubkey_get() ended with: {0}'.format(pubkey)) + return pubkey def csr_san_get(logger: logging.Logger, csr: str) -> List[str]: @@ -411,6 +427,29 @@ def csr_san_get(logger: logging.Logger, csr: str) -> List[str]: return sans +def csr_san_byte_get(logger: logging.Logger, csr: str) -> bytes: + """ get sans from CSR as base64 encoded byte squence""" + # Load the CSR + logger.debug('csr_san_byte_get()') + + csr = csr_load(logger, csr) + + # Get the SAN extension + san_extension = csr.extensions.get_extension_for_oid(x509.oid.ExtensionOID.SUBJECT_ALTERNATIVE_NAME) + + # Get the SANs + sans = san_extension.value + + # Serialize the SANs to a byte sequence + sans_bytes = sans.public_bytes() + + # Encode the byte sequence as base64 + sans_base64 = b64_encode(logger, sans_bytes) + + logger.debug('csr_san_byte_get() ended') + return sans_base64 + + def csr_extensions_get(logger: logging.Logger, csr: str) -> List[str]: """ get extensions from certificate """ logger.debug('csr_extensions_get()') diff --git a/docs/asa.md b/docs/asa.md new file mode 100644 index 00000000..6f8e9f79 --- /dev/null +++ b/docs/asa.md @@ -0,0 +1,52 @@ + + +# Connecting to Insta ActiveCMS + +## Prerequisites + +- ActiveCMS needs to have Active Security API activated +- you need to have user, password and an api key to access the ASA +- you need ot have permissions to revoke and enroll certificates + +## Configuration + +- modify the server configuration (`/acme_srv/acme_srv.cfg`) and add the following parameters + +```config +[CAhandler] +handler_file: examples/ca_handler/asa_ca_handler.py +api_host: http://: +api_user: +api_password: +api_key: +ca_bundle: +ca_name: +profile_name: +cert_validity_days: +``` + +- api_host - URL of Active Security API +- api_user - REST user +- api_user_variable - *optional* - name of the environment variable containing the REST username (a configured `api_user` parameter in acme_srv.cfg takes precedence) +- api_password - password for REST user +- api_password_variable - *optional* - name of the environment variable containing the password for the REST user (a configured `api_password` parameter in acme_srv.cfg takes precedence) +- api_key - key for REST user +- api_key_variable - *optional* - name of the environment variable containing the api_key for the REST access (a configured `api_key` parameter in acme_srv.cfg takes precedence) +- ca_bundle - certificate bundle needed to validate the server certificate - can be True/False or a filename (default: None) +- ca_name - name of the CA used to enroll certificates +- profile_name - profile name +- cert_validity_days - optional - polling timeout (default: 60s) + +You can get the list of certificate authrities by running the following REST call against ASA. + +```bash +root@rlh:~# curl -u '$api_user':'$api_password' -H "x-api-key: $api_host'/list_issuers +``` + +You can get the list of profiles by running the following REST call against ASA (ca_name parameter must be [url-encoded](https://en.wikipedia.org/wiki/Percent-encoding)). + +```bash +root@rlh:~# curl -u '$api_user':'$api_password' -H "x-api-key: $api_host'/list_profiles?issuerName= +``` + +The CA handler will verify ca_name and profile_name parameters before enrollment. diff --git a/examples/ca_handler/asa_ca_handler.py b/examples/ca_handler/asa_ca_handler.py new file mode 100644 index 00000000..0a3fd2ad --- /dev/null +++ b/examples/ca_handler/asa_ca_handler.py @@ -0,0 +1,356 @@ +# -*- coding: utf-8 -*- +""" Insta Active Security API handler""" +from __future__ import print_function +from typing import Tuple, Dict +import requests +from requests.auth import HTTPBasicAuth +# pylint: disable=C0209, E0401 +from acme_srv.helper import load_config, encode_url, csr_pubkey_get, csr_cn_get, csr_san_get, csr_san_byte_get, uts_now, uts_to_date_utc, b64_decode, cert_der2pem, convert_byte_to_string, cert_serial_get + + +class CAhandler(object): + """ EST CA handler """ + + def __init__(self, _debug: bool = None, logger: object = None): + self.logger = logger + self.api_host = None + self.api_user = None + self.api_password = None + self.api_key = None + self.ca_bundle = None + self.proxy = None + self.request_timeout = 10 + self.ca_name = None + self.auth = None + self.profile_name = None + self.cert_validity_days = 30 + + def __enter__(self): + """ Makes CAhandler a Context Manager """ + if not self.api_host: + self._config_load() + return self + + def __exit__(self, *args): + """ cose the connection at the end of the context """ + + def _api_get(self, url: str) -> Dict[str, str]: + """ post data to API """ + self.logger.debug('CAhandler._api_get()') + headers = {'x-api-key': self.api_key} + + try: + api_response = requests.get(url=url, headers=headers, auth=self.auth, verify=self.ca_bundle, proxies=self.proxy, timeout=self.request_timeout) + code = api_response.status_code + try: + content = api_response.json() + except Exception as err_: + self.logger.error('CAhandler._api_get() returned error: {0}'.format(err_)) + content = str(err_) + except Exception as err_: + self.logger.error('CAhandler._api_post() returned error: {0}'.format(err_)) + code = 500 + content = str(err_) + + return code, content + + def _api_post(self, url: str, data: Dict[str, str]) -> Dict[str, str]: + """ post data to API """ + self.logger.debug('CAhandler._api_post()') + headers = {'x-api-key': self.api_key} + + try: + api_response = requests.post(url=url, headers=headers, json=data, auth=self.auth, verify=self.ca_bundle, proxies=self.proxy, timeout=self.request_timeout) + code = api_response.status_code + try: + content = api_response.json() + except Exception as err_: + self.logger.error('CAhandler._api_post() returned error: {0}'.format(err_)) + content = str(err_) + except Exception as err_: + self.logger.error('CAhandler._api_post() returned error: {0}'.format(err_)) + code = 500 + content = str(err_) + + return code, content + + def _auth_set(self): + """ set basic authentication header """ + self.logger.debug('CAhandler._auth_set()') + if self.api_user and self.api_password: + self.auth = HTTPBasicAuth(self.api_user, self.api_password) + else: + self.logger.error('CAhandler._auth_set(): auth information incomplete. Either "api_user" or "api_password" parameter is missing in config file') + self.logger.debug('CAhandler._auth_set() ended') + + def _config_load(self): + """" load config from file """ + self.logger.debug('CAhandler._config_load()') + + config_dic = load_config(self.logger, 'CAhandler') + if 'CAhandler' in config_dic: + self.api_host = config_dic['CAhandler'].get('api_host') + self.api_user = config_dic['CAhandler'].get('api_user') + self.api_password = config_dic['CAhandler'].get('api_password') + self.api_key = config_dic['CAhandler'].get('api_key') + self.ca_name = config_dic['CAhandler'].get('ca_name') + self.profile_name = config_dic['CAhandler'].get('profile_name') + + if 'ca_bundle' in config_dic['CAhandler'] and config_dic['CAhandler']['ca_bundle'] == 'False': + self.ca_bundle = False + else: + self.ca_bundle = config_dic['CAhandler'].get('ca_bundle') + + try: + self.request_timeout = int(config_dic['CAhandler'].get('request_timeout', 10)) + except Exception: + self.logger.error('CAhandler._config_load(): request_timeout not an integer') + + try: + self.cert_validity_days = int(config_dic['CAhandler'].get('cert_validity_days', 30)) + except Exception: + self.logger.error('CAhandler._config_load(): cert_validity_days not an integer') + + for ele in ['api_host', 'api_user', 'api_password', 'api_key', 'ca_name', 'profile_name']: + if not getattr(self, ele): + self.logger.error('CAhandler._config_load(): {0} not set'.format(ele)) + + self._auth_set() + + self.logger.debug('CAhandler._config_load() ended') + + def _csr_cn_get(self, csr: str) -> str: + """ get CN from csr """ + self.logger.debug('CAhandler._csr_cn_get()') + + cn = csr_cn_get(self.logger, csr) + + if not cn: + self.logger.info('CAhandler._csr_cn_get(): CN not found in CSR') + san_list = csr_san_get(self.logger, csr) + if san_list: + (_type, san_value) = san_list[0].split(':') + cn = san_value + self.logger.info('CAhandler._csr_cn_get(): CN not found in CSR. Using first SAN entry as CN: {0}'.format(san_value)) + else: + self.logger.error('CAhandler._csr_cn_get(): CN not found in CSR. No SAN entries found') + + self.logger.debug('CAhandler._csr_cn_get() ended with: {0}'.format(cn)) + return cn + + def _issuer_verify(self) -> str: + """ verify issuer """ + self.logger.debug('CAhandler._issuer_verify()') + + api_response = self._issuers_list() + + if 'issuers' in api_response: + if self.ca_name in api_response['issuers']: + error = None + else: + error = 'CA {0} not found'.format(self.ca_name) + self.logger.error('CAhandler.enroll(): CA {0} not found'.format(self.ca_name)) + else: + error = 'Malformed response' + self.logger.error('CAhandler.enroll(): "Malformed response. "issuers" key not found') + + self.logger.debug('CAhandler._issuer_verify() ended with: {0}'.format(error)) + return error + + def _issuers_list(self): + """ list issuers """ + self.logger.debug('CAhandler._list_issuers()') + + url = '{0}/list_issuers'.format(self.api_host) + _code, api_response = self._api_get(url) + + self.logger.debug('CAhandler._list_issuers() ended') + return api_response + + def _profiles_list(self): + """ list profiles """ + self.logger.debug('CAhandler._profiles_list()') + + url = '{0}/list_profiles?issuerName={1}'.format(self.api_host, encode_url(self.logger, self.ca_name)) + _code, api_response = self._api_get(url) + + self.logger.debug('CAhandler._profiles_list() ended') + return api_response + + def _profile_verify(self) -> str: + """ verify profile """ + self.logger.debug('CAhandler._profile_verify()') + api_response = self._profiles_list() + + if 'profiles' in api_response: + if self.profile_name in api_response['profiles']: + error = None + else: + error = 'Profile {0} not found'.format(self.profile_name) + self.logger.error('CAhandler.enroll(): Profile {0} not found'.format(self.profile_name)) + else: + error = 'Malformed response' + self.logger.error('CAhandler.enroll(): "Malformed response. "profiles" key not found') + + self.logger.debug('CAhandler._profile_verify() ended with: {0}'.format(error)) + return error + + def _validity_dates_get(self) -> Tuple[str, str]: + """ calculate validity dates """ + self.logger.debug('CAhandler._validity_dates_get()') + + uts_now_ = uts_now() + validfrom = uts_to_date_utc(uts_now_, tformat='%Y-%m-%dT%H:%M:%S') + validto = uts_to_date_utc(uts_now_ + (self.cert_validity_days * 24 * 60 * 60), tformat='%Y-%m-%dT%H:%M:%S') + + self.logger.debug('CAhandler._validity_dates_get() ended') + return validfrom, validto + + def _pem_cert_chain_generate(self, certs_list: list) -> str: + """ generate PEM certificate chain """ + self.logger.debug('CAhandler._pem_cert_chain_generate()') + + pem_chain = '' + for cert in certs_list: + pem_chain += convert_byte_to_string(cert_der2pem(b64_decode(self.logger, cert))) + + self.logger.debug('CAhandler._pem_cert_chain_generate() ended') + return pem_chain + + def _issuer_chain_get(self) -> str: + """ get issuer chain """ + self.logger.debug('CAhandler._issuer_chain_get()') + + url = '{0}/get_issuer_chain?issuerName={1}'.format(self.api_host, encode_url(self.logger, self.ca_name)) + _code, api_response = self._api_get(url) + if 'certs' in api_response: + pem_chain = self._pem_cert_chain_generate(api_response['certs']) + else: + self.logger.error('CAhandler._issuer_chain_get(): "certs" key not found') + pem_chain = None + + self.logger.debug('CAhandler._issuer_chain_get() ended') + return pem_chain + + def _cert_get(self, data_dic: Dict[str, str]) -> str: + """ get certificate """ + self.logger.debug('CAhandler._cert_get()') + + url = '{0}/issue_certificate'.format(self.api_host) + code, api_response = self._api_post(url, data_dic) + + if code == 200 and api_response: + cert = api_response + else: + self.logger.error('CAhandler._cert_get(): enrollment failed: {0}/{1}'.format(code, api_response)) + cert = None + + self.logger.debug('CAhandler._cert_get() ended') + return cert + + def _enrollment_dic_create(self, csr: str) -> Dict[str, str]: + """ create enrollment dic """ + self.logger.debug('CAhandler._enrollment_dic_create()') + + # get public key from csr + csr_pubkey = csr_pubkey_get(self.logger, csr, encoding='base64der') + if csr_pubkey: + # get CN from csr + csr_cn = self._csr_cn_get(csr) + + # calculate validiaty dates + validfrom, validto = self._validity_dates_get() + + # prepare payload for api call + data_dic = {'publicKey': csr_pubkey, 'profileName': self.profile_name, 'issuerName': self.ca_name, 'cn': csr_cn, 'notBefore': validfrom, 'notAfter': validto} + + # get SANs from csr as base64 encoded byte sequence + sans_base64 = csr_san_byte_get(self.logger, csr) + # if sans_base64: + # data_dic['extensions'] = [{'oid': '2.5.29.17', 'value': sans_base64}] # 'Zm9vLmJhci5sb2NhbA==' + + else: + self.logger.error('CAhandler._enrollment_dic_create(): public key not found') + data_dic = None + + return data_dic + + def enroll(self, csr: str) -> Tuple[str, str, str, str]: + """ enroll certificate """ + self.logger.debug('CAhandler.enroll()') + + cert_bundle = None + error = None + cert_raw = None + poll_indentifier = None + + # verify issuer + error = self._issuer_verify() + + if not error: + + error = self._profile_verify() + if not error: + + # get issuer chain + issuer_chain = self._issuer_chain_get() + + data_dic = self._enrollment_dic_create(csr) + if data_dic: + cert_raw = self._cert_get(data_dic) + + if cert_raw: + cert = convert_byte_to_string(cert_der2pem(b64_decode(self.logger, cert_raw))) + cert_bundle = cert + issuer_chain + else: + error = 'Enrollment failed' + + self.logger.debug('Certificate.enroll() ended with: {0}'.format(error)) + return (error, cert_bundle, cert_raw, poll_indentifier) + + def poll(self, _cert_name: str, poll_identifier: str, _csr: str) -> Tuple[str, str, str, str, bool]: + """ poll status of pending CSR and download certificates """ + self.logger.debug('CAhandler.poll()') + + error = 'Method not implemented.' + cert_bundle = None + cert_raw = None + rejected = False + + self.logger.debug('CAhandler.poll() ended') + return (error, cert_bundle, cert_raw, poll_identifier, rejected) + + def revoke(self, cert: str, _rev_reason: str = 'unspecified', _rev_date: str = uts_to_date_utc(uts_now())) -> Tuple[int, str, str]: + """ revoke certificate """ + self.logger.debug('CAhandler.revoke()') + + code = None + message = None + detail = None + + cert_serial = cert_serial_get(self.logger, cert, hexformat=True) # get serial number from certificate + url = '{0}/revoke_certificate?issuerName={1}&certificateId={2}'.format(self.api_host, encode_url(self.logger, self.ca_name), cert_serial) + data_dic = {} + code, content_dic = self._api_post(url, data_dic) + if content_dic: + message = 'urn:ietf:params:acme:error:serverInternal' + if 'Message' in content_dic: + detail = content_dic.get('Message') + elif 'message' in content_dic: + detail = content_dic.get('message') + else: + detail = 'Unknown error' + + self.logger.debug('Certificate.revoke() ended') + return (code, message, detail) + + def trigger(self, _payload: str) -> Tuple[str, str, str]: + """ process trigger message and return certificate """ + self.logger.debug('CAhandler.trigger()') + + error = 'Method not implemented.' + cert_bundle = None + cert_raw = None + + self.logger.debug('CAhandler.trigger() ended with error: {0}'.format(error)) + return (error, cert_bundle, cert_raw) diff --git a/test/test_asa_ca_handler.py b/test/test_asa_ca_handler.py new file mode 100644 index 00000000..7666ee55 --- /dev/null +++ b/test/test_asa_ca_handler.py @@ -0,0 +1,711 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +""" unittests for openssl_ca_handler """ +# pylint: disable=C0415, R0904, W0212 +import sys +import os +import unittest +from unittest.mock import patch, Mock +import requests +import base64 + +sys.path.insert(0, '.') +sys.path.insert(1, '..') + +class TestACMEHandler(unittest.TestCase): + """ test class for cgi_handler """ + + def setUp(self): + """ setup unittest """ + import logging + from examples.ca_handler.asa_ca_handler import CAhandler + logging.basicConfig(level=logging.CRITICAL) + self.logger = logging.getLogger('test_a2c') + self.cahandler = CAhandler(False, self.logger) + self.dir_path = os.path.dirname(os.path.realpath(__file__)) + self.maxDiff = None + + def test_001_default(self): + """ default test which always passes """ + self.assertEqual('foo', 'foo') + + @patch('examples.ca_handler.asa_ca_handler.CAhandler._config_load') + def test_055__enter__(self, mock_cfg): + """ test enter called """ + mock_cfg.return_value = True + self.cahandler.__enter__() + self.assertTrue(mock_cfg.called) + + def test_038_poll(self): + """ test polling """ + self.assertEqual(('Method not implemented.', None, None, 'poll_identifier', False), self.cahandler.poll('cert_name', 'poll_identifier', 'csr')) + + def test_039_trigger(self): + """ test polling """ + self.assertEqual(('Method not implemented.', None, None), self.cahandler.trigger('payload')) + + + @patch('examples.ca_handler.asa_ca_handler.load_config') + def test_002_config_load(self, mock_config_load): + """ test _config_load """ + mock_config_load.return_value = {'CAhandler': {'api_host': 'api_host'}} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.cahandler._config_load() + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_user not set', lcm.output) + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_password not set', lcm.output) + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_key not set', lcm.output) + self.assertEqual('api_host', self.cahandler.api_host) + self.assertFalse(self.cahandler.api_user) + self.assertFalse(self.cahandler.api_password) + self.assertFalse(self.cahandler.api_key) + self.assertFalse(self.cahandler.ca_bundle) + self.assertFalse(self.cahandler.proxy) + self.assertEqual(10, self.cahandler.request_timeout) + self.assertEqual(30, self.cahandler.cert_validity_days) + + @patch('examples.ca_handler.asa_ca_handler.load_config') + def test_003_config_load(self, mock_config_load): + """ test _config_load """ + mock_config_load.return_value = {'CAhandler': {'api_user': 'api_user'}} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.cahandler._config_load() + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_host not set', lcm.output) + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_password not set', lcm.output) + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_key not set', lcm.output) + self.assertFalse(self.cahandler.api_host) + self.assertEqual('api_user', self.cahandler.api_user) + self.assertFalse(self.cahandler.api_password) + self.assertFalse(self.cahandler.api_key) + self.assertFalse(self.cahandler.ca_bundle) + self.assertFalse(self.cahandler.proxy) + self.assertEqual(10, self.cahandler.request_timeout) + self.assertEqual(30, self.cahandler.cert_validity_days) + + @patch('examples.ca_handler.asa_ca_handler.load_config') + def test_004_config_load(self, mock_config_load): + """ test _config_load """ + mock_config_load.return_value = {'CAhandler': {'api_password': 'api_password'}} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.cahandler._config_load() + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_host not set', lcm.output) + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_user not set', lcm.output) + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_key not set', lcm.output) + self.assertFalse(self.cahandler.api_host) + self.assertFalse(self.cahandler.api_user) + self.assertEqual('api_password', self.cahandler.api_password) + self.assertFalse(self.cahandler.api_key) + self.assertFalse(self.cahandler.ca_bundle) + self.assertFalse(self.cahandler.proxy) + self.assertEqual(10, self.cahandler.request_timeout) + self.assertEqual(30, self.cahandler.cert_validity_days) + + @patch('examples.ca_handler.asa_ca_handler.load_config') + def test_005_config_load(self, mock_config_load): + """ test _config_load """ + mock_config_load.return_value = {'CAhandler': {'api_key': 'api_key'}} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.cahandler._config_load() + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_host not set', lcm.output) + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_user not set', lcm.output) + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_password not set', lcm.output) + self.assertFalse(self.cahandler.api_host) + self.assertFalse(self.cahandler.api_user) + self.assertFalse(self.cahandler.api_password) + self.assertEqual('api_key', self.cahandler.api_key) + self.assertFalse(self.cahandler.ca_bundle) + self.assertFalse(self.cahandler.proxy) + self.assertEqual(10, self.cahandler.request_timeout) + self.assertEqual(30, self.cahandler.cert_validity_days) + + @patch('examples.ca_handler.asa_ca_handler.load_config') + def test_006_config_load(self, mock_config_load): + """ test _config_load """ + mock_config_load.return_value = {'CAhandler': {'api_host': 'api_host', 'api_user': 'api_user', 'api_password': 'api_password', 'api_key': 'api_key'}} + self.cahandler._config_load() + self.assertEqual('api_host', self.cahandler.api_host) + self.assertEqual('api_user', self.cahandler.api_user) + self.assertEqual('api_password', self.cahandler.api_password) + self.assertEqual('api_key', self.cahandler.api_key) + self.assertFalse(self.cahandler.proxy) + self.assertEqual(10, self.cahandler.request_timeout) + self.assertEqual(30, self.cahandler.cert_validity_days) + + @patch('examples.ca_handler.asa_ca_handler.load_config') + def test_007_config_load(self, mock_config_load): + """ test _config_load """ + mock_config_load.return_value = {'foo': 'bar'} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.cahandler._config_load() + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_host not set', lcm.output) + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_user not set', lcm.output) + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_password not set', lcm.output) + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_key not set', lcm.output) + self.assertFalse(self.cahandler.api_host) + self.assertFalse(self.cahandler.api_user) + self.assertFalse(self.cahandler.api_password) + self.assertFalse(self.cahandler.api_key) + self.assertFalse(self.cahandler.ca_bundle) + self.assertFalse(self.cahandler.proxy) + self.assertEqual(10, self.cahandler.request_timeout) + self.assertEqual(30, self.cahandler.cert_validity_days) + + @patch('examples.ca_handler.asa_ca_handler.load_config') + def test_008_config_load(self, mock_config_load): + """ test _config_load """ + mock_config_load.return_value = {'CAhandler': {'request_timeout': 20}} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.cahandler._config_load() + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_host not set', lcm.output) + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_user not set', lcm.output) + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_key not set', lcm.output) + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_password not set', lcm.output) + self.assertFalse(self.cahandler.api_host) + self.assertFalse(self.cahandler.api_user) + self.assertFalse(self.cahandler.api_password) + self.assertFalse(self.cahandler.api_key) + self.assertFalse(self.cahandler.ca_bundle) + self.assertFalse(self.cahandler.proxy) + self.assertEqual(20, self.cahandler.request_timeout) + self.assertEqual(30, self.cahandler.cert_validity_days) + + @patch('examples.ca_handler.asa_ca_handler.load_config') + def test_008_config_load(self, mock_config_load): + """ test _config_load """ + mock_config_load.return_value = {'CAhandler': {'request_timeout': 'aa'}} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.cahandler._config_load() + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_host not set', lcm.output) + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_user not set', lcm.output) + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_key not set', lcm.output) + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_password not set', lcm.output) + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): request_timeout not an integer', lcm.output) + self.assertFalse(self.cahandler.api_host) + self.assertFalse(self.cahandler.api_user) + self.assertFalse(self.cahandler.api_password) + self.assertFalse(self.cahandler.api_key) + self.assertFalse(self.cahandler.ca_bundle) + self.assertFalse(self.cahandler.proxy) + self.assertEqual(10, self.cahandler.request_timeout) + self.assertEqual(30, self.cahandler.cert_validity_days) + + @patch('examples.ca_handler.asa_ca_handler.load_config') + def test_009_config_load(self, mock_config_load): + """ test _config_load """ + mock_config_load.return_value = {'CAhandler': {'cert_validity_days': 10}} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.cahandler._config_load() + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_host not set', lcm.output) + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_user not set', lcm.output) + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_key not set', lcm.output) + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_password not set', lcm.output) + # self.assertIn('ERROR:test_a2c:CAhandler._config_load(): request_timeout not an integer', lcm.output) + self.assertFalse(self.cahandler.api_host) + self.assertFalse(self.cahandler.api_user) + self.assertFalse(self.cahandler.api_password) + self.assertFalse(self.cahandler.api_key) + self.assertFalse(self.cahandler.ca_bundle) + self.assertFalse(self.cahandler.proxy) + self.assertEqual(10, self.cahandler.request_timeout) + self.assertEqual(10, self.cahandler.cert_validity_days) + + @patch('examples.ca_handler.asa_ca_handler.load_config') + def test_010_config_load(self, mock_config_load): + """ test _config_load """ + mock_config_load.return_value = {'CAhandler': {'cert_validity_days': 'aa'}} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.cahandler._config_load() + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_host not set', lcm.output) + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_user not set', lcm.output) + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_key not set', lcm.output) + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_password not set', lcm.output) + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): cert_validity_days not an integer', lcm.output) + self.assertFalse(self.cahandler.api_host) + self.assertFalse(self.cahandler.api_user) + self.assertFalse(self.cahandler.api_password) + self.assertFalse(self.cahandler.api_key) + self.assertFalse(self.cahandler.ca_bundle) + self.assertFalse(self.cahandler.proxy) + self.assertEqual(10, self.cahandler.request_timeout) + self.assertEqual(30, self.cahandler.cert_validity_days) + + @patch('examples.ca_handler.asa_ca_handler.load_config') + def test_011_config_load(self, mock_config_load): + """ test _config_load """ + mock_config_load.return_value = {'CAhandler': {'ca_bundle': 'aa'}} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.cahandler._config_load() + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_host not set', lcm.output) + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_user not set', lcm.output) + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_key not set', lcm.output) + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_password not set', lcm.output) + self.assertFalse(self.cahandler.api_host) + self.assertFalse(self.cahandler.api_user) + self.assertFalse(self.cahandler.api_password) + self.assertFalse(self.cahandler.api_key) + self.assertEqual('aa', self.cahandler.ca_bundle) + self.assertFalse(self.cahandler.proxy) + self.assertEqual(10, self.cahandler.request_timeout) + self.assertEqual(30, self.cahandler.cert_validity_days) + + @patch('examples.ca_handler.asa_ca_handler.load_config') + def test_012_config_load(self, mock_config_load): + """ test _config_load """ + mock_config_load.return_value = {'CAhandler': {'ca_bundle': 'False'}} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.cahandler._config_load() + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_host not set', lcm.output) + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_user not set', lcm.output) + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_key not set', lcm.output) + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_password not set', lcm.output) + self.assertFalse(self.cahandler.api_host) + self.assertFalse(self.cahandler.api_user) + self.assertFalse(self.cahandler.api_password) + self.assertFalse(self.cahandler.api_key) + self.assertFalse(self.cahandler.ca_bundle) + self.assertFalse(self.cahandler.proxy) + self.assertEqual(10, self.cahandler.request_timeout) + self.assertEqual(30, self.cahandler.cert_validity_days) + + @patch.object(requests, 'post') + def test_013__api_post(self, mock_req): + """ test _api_post() """ + mockresponse = Mock() + mockresponse.status_code = 'status_code' + mockresponse.json = lambda: {'foo': 'bar'} + mock_req.return_value = mockresponse + self.assertEqual(('status_code', {'foo': 'bar'}), self.cahandler._api_post('url', 'data')) + + @patch('requests.post') + def test_014__api_post(self, mock_req): + """ test _api_post() """ + mockresponse = Mock() + mockresponse.status_code = 'status_code' + mockresponse.json = "aaaa" + mock_req.return_value = mockresponse + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertEqual(('status_code', "'str' object is not callable"), self.cahandler._api_post('url', 'data')) + self.assertIn("ERROR:test_a2c:CAhandler._api_post() returned error: 'str' object is not callable", lcm.output) + + @patch('requests.post') + def test_15__api_post(self, mock_req): + """ test _api_post(= """ + self.cahandler.api_host = 'api_host' + self.cahandler.auth = 'auth' + mock_req.side_effect = Exception('exc_api_post') + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertEqual((500, 'exc_api_post'), self.cahandler._api_post('url', 'data')) + self.assertIn('ERROR:test_a2c:CAhandler._api_post() returned error: exc_api_post', lcm.output) + + @patch.object(requests, 'get') + def test_016__api_get(self, mock_req): + """ test _api_get() """ + mockresponse = Mock() + mockresponse.status_code = 'status_code' + mockresponse.json = lambda: {'foo': 'bar'} + mock_req.return_value = mockresponse + self.assertEqual(('status_code', {'foo': 'bar'}), self.cahandler._api_get('url')) + + @patch('requests.get') + def test_018__api_get(self, mock_req): + """ test _api_get() """ + mockresponse = Mock() + mockresponse.status_code = 'status_code' + mockresponse.json = "aaaa" + mock_req.return_value = mockresponse + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertEqual(('status_code', "'str' object is not callable"), self.cahandler._api_get('url')) + self.assertIn("ERROR:test_a2c:CAhandler._api_get() returned error: 'str' object is not callable", lcm.output) + + @patch('requests.get') + def test_019__api_get(self, mock_req): + """ test _api_get() """ + self.cahandler.api_host = 'api_host' + self.cahandler.auth = 'auth' + mock_req.side_effect = Exception('exc_api_get') + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertEqual((500, 'exc_api_get'), self.cahandler._api_get('url')) + self.assertIn('ERROR:test_a2c:CAhandler._api_post() returned error: exc_api_get', lcm.output) + + @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_get') + def test_020__issuers_list(self, mock_get): + """ test _issuers_list()""" + mock_get.return_value = (200, 'content') + self.assertEqual('content', self.cahandler._issuers_list()) + + @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_get') + def test_021__profiles_list(self, mock_get): + """ test _profiles_list()""" + self.cahandler.ca_name = 'ca_name' + mock_get.return_value = (200, 'content') + self.assertEqual('content', self.cahandler._profiles_list()) + + @patch('examples.ca_handler.asa_ca_handler.csr_san_get') + @patch('examples.ca_handler.asa_ca_handler.csr_cn_get') + def test_022__csr_cn_get(self, mock_cn, mock_san): + """ test _csr_cn_get() """ + mock_cn.return_value = 'cn' + mock_san.return_value = ['san0', 'san1'] + self.assertEqual('cn', self.cahandler._csr_cn_get('csr')) + self.assertFalse(mock_san.called) + + @patch('examples.ca_handler.asa_ca_handler.csr_san_get') + @patch('examples.ca_handler.asa_ca_handler.csr_cn_get') + def test_023__csr_cn_get(self, mock_cn, mock_san): + """ test _csr_cn_get() """ + mock_cn.return_value = None + mock_san.return_value = ['dns:san0', 'dns:san1'] + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertEqual('san0', self.cahandler._csr_cn_get('csr')) + self.assertIn('INFO:test_a2c:CAhandler._csr_cn_get(): CN not found in CSR', lcm.output) + self.assertIn('INFO:test_a2c:CAhandler._csr_cn_get(): CN not found in CSR. Using first SAN entry as CN: san0', lcm.output) + self.assertTrue(mock_san.called) + + @patch('examples.ca_handler.asa_ca_handler.csr_san_get') + @patch('examples.ca_handler.asa_ca_handler.csr_cn_get') + def test_024__csr_cn_get(self, mock_cn, mock_san): + """ test _csr_cn_get() """ + mock_cn.return_value = None + mock_san.return_value = None + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertEqual(None, self.cahandler._csr_cn_get('csr')) + self.assertIn('INFO:test_a2c:CAhandler._csr_cn_get(): CN not found in CSR', lcm.output) + self.assertIn('ERROR:test_a2c:CAhandler._csr_cn_get(): CN not found in CSR. No SAN entries found', lcm.output) + self.assertTrue(mock_san.called) + + @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuers_list') + def test_025_issuer_verify(self, mock_list): + """ _issuer_verify() """ + self.cahandler.ca_name = 'ca_name' + mock_list.return_value = {'issuers': ['1', '2', 'ca_name']} + self.assertFalse(self.cahandler._issuer_verify()) + + @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuers_list') + def test_026_issuer_verify(self, mock_list): + """ _issuer_verify() """ + self.cahandler.ca_name = 'ca_name' + mock_list.return_value = {'issuers': ['1', '2', '3']} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertEqual('CA ca_name not found', self.cahandler._issuer_verify()) + self.assertIn('ERROR:test_a2c:CAhandler.enroll(): CA ca_name not found', lcm.output) + + @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuers_list') + def test_027_issuer_verify(self, mock_list): + """ _issuer_verify() """ + self.cahandler.ca_name = 'ca_name' + mock_list.return_value = {'foo': 'bar'} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertEqual('Malformed response', self.cahandler._issuer_verify()) + self.assertIn('ERROR:test_a2c:CAhandler.enroll(): "Malformed response. "issuers" key not found', lcm.output) + + @patch('examples.ca_handler.asa_ca_handler.CAhandler._profiles_list') + def test_025_profile_verify(self, mock_list): + """ _profile_verify() """ + self.cahandler.profile_name = 'profile_name' + mock_list.return_value = {'profiles': ['1', '2', 'profile_name']} + self.assertFalse(self.cahandler._profile_verify()) + + @patch('examples.ca_handler.asa_ca_handler.CAhandler._profiles_list') + def test_026_profile_verify(self, mock_list): + """ _profile_verify() """ + self.cahandler.profile_name = 'profile_name' + mock_list.return_value = {'profiles': ['1', '2', '3']} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertEqual('Profile profile_name not found', self.cahandler._profile_verify()) + self.assertIn('ERROR:test_a2c:CAhandler.enroll(): Profile profile_name not found', lcm.output) + + @patch('examples.ca_handler.asa_ca_handler.CAhandler._profiles_list') + def test_027_profile_verify(self, mock_list): + """ _profile_verify() """ + self.cahandler.ca_name = 'ca_name' + mock_list.return_value = {'foo': 'bar'} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertEqual('Malformed response', self.cahandler._profile_verify()) + self.assertIn('ERROR:test_a2c:CAhandler.enroll(): "Malformed response. "profiles" key not found', lcm.output) + + @patch('examples.ca_handler.asa_ca_handler.uts_to_date_utc') + @patch('examples.ca_handler.asa_ca_handler.uts_now') + def test_028__validity_dates_get(self, mock_now, mock_utc): + """ test _validity_dates_get() """ + mock_now.return_value = 10 + mock_utc.side_effect = ['date1', 'date2'] + self.assertEqual(('date1', 'date2'), self.cahandler._validity_dates_get()) + self.assertTrue(mock_now.called) + + @patch('examples.ca_handler.asa_ca_handler.convert_byte_to_string') + @patch('examples.ca_handler.asa_ca_handler.cert_der2pem') + @patch('examples.ca_handler.asa_ca_handler.b64_decode') + def test_029__pem_cert_chain_generate(self, mock_dec, mock_d2p, mock_b2s): + """ test _pem_cert_chain_generate() """ + mock_b2s.return_value = 'cert' + self.assertEqual('certcert', self.cahandler._pem_cert_chain_generate(['cert', 'chain'])) + + def test_030__pem_cert_chain_generate(self): + """ test _pem_cert_chain_generate() """ + cert_list = ['MIIF7DCCBFSgAwIBAgIKB/8cQ9wAI3UbITANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJERTERMA8GA1UECgwIT3BlblhQS0kxDDAKBgNVBAsMA1BLSTEqMCgGA1UEAwwhT3BlblhQS0kgRGVtbyBJc3N1aW5nIENBIDIwMjMwMjA0MB4XDTIzMDIwNTA2NDY0MloXDTI0MDIwNTA2NDY0MlowazETMBEGCgmSJomT8ixkARkWA29yZzEYMBYGCgmSJomT8ixkARkWCE9wZW5YUEtJMR8wHQYKCZImiZPyLGQBGRYPVGVzdCBEZXBsb3ltZW50MRkwFwYDVQQDDBBhY21lMS5keW5hbW9wLmRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAre1jtb8Xjqr49QH3fWe2kH+yDk3NXfxHyOmKcNcBke68WMRB5Irrdj15JfAsXxu9psLVEOJgvdOLOnUbhN57uBLHwMAC1LH6HruYuCqtbaSezgJIYIEACvtQmIy6BIvigqwX31eLkA7kk7YXeJCnvrr461t/uZkhmaXZM9+G4asSj6fT0ffA7OVVqewDdE+d2VgCjPlH9uqPMOVK2m/AQj+jEVV/IV2znngZmkAsmYi6h2Wg08vEzTMyvhZIEma3xo6M9g9VIsTQP/ETxxhAAgzEQ0Jlz90rOioZK7mkx8xH1fLlhyfX53vqcEbva5evy1YMGEs0XZPYu2B6Oya9WQIDAQABo4ICITCCAh0wgYcGCCsGAQUFBwEBBHsweTBRBggrBgEFBQcwAoZFaHR0cDovL3BraS5leGFtcGxlLmNvbS9kb3dubG9hZC9PcGVuWFBLSV9EZW1vX0lzc3VpbmdfQ0FfMjAyMzAyMDQuY2VyMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5leGFtcGxlLmNvbS8wHwYDVR0jBBgwFoAU0f8PWcniVXltJeA6q7wYtyJrNFAwDAYDVR0TAQH/BAIwADBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vcGtpLmV4YW1wbGUuY29tL2Rvd25sb2FkL09wZW5YUEtJX0RlbW9fSXNzdWluZ19DQV8yMDIzMDIwNC5jcmwwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDgYDVR0PAQH/BAQDAgWgMIGoBgNVHSAEgaAwgZ0wgZoGAyoDBDCBkjArBggrBgEFBQcCARYfaHR0cDovL3BraS5leGFtcGxlLmNvbS9jcHMuaHRtbDArBggrBgEFBQcCARYfaHR0cDovL3BraS5leGFtcGxlLmNvbS9jcHMuaHRtbDA2BggrBgEFBQcCAjAqGihUaGlzIGlzIGEgY29tbWVudCBmb3IgcG9saWN5IG9pZCAxLjIuMy40MBsGA1UdEQQUMBKCEGFjbWUxLmR5bmFtb3AuZGUwHQYDVR0OBBYEFA3AUTV0pg0fsd3Cd6/BskOEB9MVMA0GCSqGSIb3DQEBCwUAA4IBgQB0xnnl6BJDXrbTQr7TdkRPmcCDFUmi8aVTYozbQ8EKxIYEPsfzxOFbSG/wn+4Sjz7HqvzqxyisfTopqWrvpqIhlXOEFMnNYTDO4LzCd81Dcs4czjoIRxRTisgNCvWR9hbeH9HzdRT1UF/c4VxxLEONSsGHksoXa+G4u7XmPwD4dTUIP49Mmj2a28z/viG8KftcjAEo1S7OB+/xyPeVDYrgagMR31a69pI+yuQa0J66O/LJQrzjWf6wHToQErQPcEBtDxY2wx3hROMtdla9lUEU8XLb3e9zByZwOfDhFpw8iYkJx/BUZlsmIKaZSpYVS+0D5LI1R5PENhT/2gRxaA31RiNLK/E8CSU7MMadqImkFLkDHU2x+2SRENwvoOEUAOewjVlhB1pK0r5WEye2lBjl8cUa+8qhIrAOqggApQ7eCQq7v2bL08VxKz5baOhKfLZ9u4MH6q52pnqXmll0W7JXrJSbam5r3YoSelm94VwVyaSkfd+LT4YMAP7GDDvtT6Y='] + result = """-----BEGIN CERTIFICATE----- +MIIF7DCCBFSgAwIBAgIKB/8cQ9wAI3UbITANBgkqhkiG9w0BAQsFADBaMQswCQYD +VQQGEwJERTERMA8GA1UECgwIT3BlblhQS0kxDDAKBgNVBAsMA1BLSTEqMCgGA1UE +AwwhT3BlblhQS0kgRGVtbyBJc3N1aW5nIENBIDIwMjMwMjA0MB4XDTIzMDIwNTA2 +NDY0MloXDTI0MDIwNTA2NDY0MlowazETMBEGCgmSJomT8ixkARkWA29yZzEYMBYG +CgmSJomT8ixkARkWCE9wZW5YUEtJMR8wHQYKCZImiZPyLGQBGRYPVGVzdCBEZXBs +b3ltZW50MRkwFwYDVQQDDBBhY21lMS5keW5hbW9wLmRlMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAre1jtb8Xjqr49QH3fWe2kH+yDk3NXfxHyOmKcNcB +ke68WMRB5Irrdj15JfAsXxu9psLVEOJgvdOLOnUbhN57uBLHwMAC1LH6HruYuCqt +baSezgJIYIEACvtQmIy6BIvigqwX31eLkA7kk7YXeJCnvrr461t/uZkhmaXZM9+G +4asSj6fT0ffA7OVVqewDdE+d2VgCjPlH9uqPMOVK2m/AQj+jEVV/IV2znngZmkAs +mYi6h2Wg08vEzTMyvhZIEma3xo6M9g9VIsTQP/ETxxhAAgzEQ0Jlz90rOioZK7mk +x8xH1fLlhyfX53vqcEbva5evy1YMGEs0XZPYu2B6Oya9WQIDAQABo4ICITCCAh0w +gYcGCCsGAQUFBwEBBHsweTBRBggrBgEFBQcwAoZFaHR0cDovL3BraS5leGFtcGxl +LmNvbS9kb3dubG9hZC9PcGVuWFBLSV9EZW1vX0lzc3VpbmdfQ0FfMjAyMzAyMDQu +Y2VyMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5leGFtcGxlLmNvbS8wHwYDVR0j +BBgwFoAU0f8PWcniVXltJeA6q7wYtyJrNFAwDAYDVR0TAQH/BAIwADBWBgNVHR8E +TzBNMEugSaBHhkVodHRwOi8vcGtpLmV4YW1wbGUuY29tL2Rvd25sb2FkL09wZW5Y +UEtJX0RlbW9fSXNzdWluZ19DQV8yMDIzMDIwNC5jcmwwEwYDVR0lBAwwCgYIKwYB +BQUHAwEwDgYDVR0PAQH/BAQDAgWgMIGoBgNVHSAEgaAwgZ0wgZoGAyoDBDCBkjAr +BggrBgEFBQcCARYfaHR0cDovL3BraS5leGFtcGxlLmNvbS9jcHMuaHRtbDArBggr +BgEFBQcCARYfaHR0cDovL3BraS5leGFtcGxlLmNvbS9jcHMuaHRtbDA2BggrBgEF +BQcCAjAqGihUaGlzIGlzIGEgY29tbWVudCBmb3IgcG9saWN5IG9pZCAxLjIuMy40 +MBsGA1UdEQQUMBKCEGFjbWUxLmR5bmFtb3AuZGUwHQYDVR0OBBYEFA3AUTV0pg0f +sd3Cd6/BskOEB9MVMA0GCSqGSIb3DQEBCwUAA4IBgQB0xnnl6BJDXrbTQr7TdkRP +mcCDFUmi8aVTYozbQ8EKxIYEPsfzxOFbSG/wn+4Sjz7HqvzqxyisfTopqWrvpqIh +lXOEFMnNYTDO4LzCd81Dcs4czjoIRxRTisgNCvWR9hbeH9HzdRT1UF/c4VxxLEON +SsGHksoXa+G4u7XmPwD4dTUIP49Mmj2a28z/viG8KftcjAEo1S7OB+/xyPeVDYrg +agMR31a69pI+yuQa0J66O/LJQrzjWf6wHToQErQPcEBtDxY2wx3hROMtdla9lUEU +8XLb3e9zByZwOfDhFpw8iYkJx/BUZlsmIKaZSpYVS+0D5LI1R5PENhT/2gRxaA31 +RiNLK/E8CSU7MMadqImkFLkDHU2x+2SRENwvoOEUAOewjVlhB1pK0r5WEye2lBjl +8cUa+8qhIrAOqggApQ7eCQq7v2bL08VxKz5baOhKfLZ9u4MH6q52pnqXmll0W7JX +rJSbam5r3YoSelm94VwVyaSkfd+LT4YMAP7GDDvtT6Y= +-----END CERTIFICATE----- +""" + self.assertEqual(result, self.cahandler._pem_cert_chain_generate(cert_list)) + + @patch('examples.ca_handler.asa_ca_handler.CAhandler._pem_cert_chain_generate') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_get') + def test_031___issuer_chain_get(self, mock_req, mock_pem): + """ test _issuer_chain_get() """ + mock_req.return_value = ('code', {'certs': ['bar', 'foo']}) + mock_pem.return_value = 'issuer_chain' + self.cahandler.ca_name = 'ca_name' + self.assertEqual('issuer_chain', self.cahandler._issuer_chain_get()) + self.assertTrue(mock_pem.called) + + @patch('examples.ca_handler.asa_ca_handler.CAhandler._pem_cert_chain_generate') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_get') + def test_032___issuer_chain_get(self, mock_req, mock_pem): + """ test _issuer_chain_get() """ + mock_req.return_value = ('code', {'foobar': ['bar', 'foo']}) + mock_pem.return_value = 'issuer_chain' + self.cahandler.ca_name = 'ca_name' + self.assertFalse(self.cahandler._issuer_chain_get()) + self.assertFalse(mock_pem.called) + + @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_post') + @patch('examples.ca_handler.asa_ca_handler.convert_byte_to_string') + @patch('examples.ca_handler.asa_ca_handler.cert_der2pem') + @patch('examples.ca_handler.asa_ca_handler.b64_decode') + @patch('examples.ca_handler.asa_ca_handler.csr_san_byte_get') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._validity_dates_get') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._csr_cn_get') + @patch('examples.ca_handler.asa_ca_handler.csr_pubkey_get') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_chain_get') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_verify') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_verify') + def test_033_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_csbg, mock_b64, mock_d2p, mock_b2s, mock_post): + """ test enroll() """ + mock_iv.return_value = None + mock_pv.return_value = None + mock_icg.return_value = 'issuer_chain' + mock_vdg.return_value = ('date1', 'date2') + mock_post.return_value = (200, 'cert') + mock_b2s.return_value = 'bcert' + self.assertEqual((None, 'bcertissuer_chain', 'cert', None), self.cahandler.enroll('csr')) + self.assertTrue(mock_iv.called) + self.assertTrue(mock_pv.called) + self.assertTrue(mock_icg.called) + self.assertTrue(mock_cpg.called) + self.assertTrue(mockccg.called) + self.assertTrue(mock_vdg.called) + self.assertTrue(mock_csbg.called) + self.assertTrue(mock_b64.called) + self.assertTrue(mock_post.called) + self.assertTrue(mock_b2s.called) + self.assertTrue(mock_d2p.called) + + @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_post') + @patch('examples.ca_handler.asa_ca_handler.convert_byte_to_string') + @patch('examples.ca_handler.asa_ca_handler.cert_der2pem') + @patch('examples.ca_handler.asa_ca_handler.b64_decode') + @patch('examples.ca_handler.asa_ca_handler.csr_san_byte_get') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._validity_dates_get') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._csr_cn_get') + @patch('examples.ca_handler.asa_ca_handler.csr_pubkey_get') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_chain_get') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_verify') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_verify') + def test_034_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_csbg, mock_b64, mock_d2p, mock_b2s, mock_post): + """ test enroll() """ + mock_iv.return_value = 'mock_iv' + mock_pv.return_value = None + mock_icg.return_value = 'issuer_chain' + mock_vdg.return_value = ('date1', 'date2') + mock_post.return_value = ('code', 'cert') + mock_b2s.return_value = 'bcert' + self.assertEqual(('mock_iv', None, None, None), self.cahandler.enroll('csr')) + self.assertTrue(mock_iv.called) + self.assertFalse(mock_pv.called) + self.assertFalse(mock_icg.called) + self.assertFalse(mock_cpg.called) + self.assertFalse(mockccg.called) + self.assertFalse(mock_vdg.called) + self.assertFalse(mock_csbg.called) + self.assertFalse(mock_b64.called) + self.assertFalse(mock_post.called) + self.assertFalse(mock_b2s.called) + self.assertFalse(mock_d2p.called) + + @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_post') + @patch('examples.ca_handler.asa_ca_handler.convert_byte_to_string') + @patch('examples.ca_handler.asa_ca_handler.cert_der2pem') + @patch('examples.ca_handler.asa_ca_handler.b64_decode') + @patch('examples.ca_handler.asa_ca_handler.csr_san_byte_get') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._validity_dates_get') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._csr_cn_get') + @patch('examples.ca_handler.asa_ca_handler.csr_pubkey_get') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_chain_get') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_verify') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_verify') + def test_035_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_csbg, mock_b64, mock_d2p, mock_b2s, mock_post): + """ test enroll() """ + mock_iv.return_value = None + mock_pv.return_value = 'mock_pv' + mock_icg.return_value = 'issuer_chain' + mock_vdg.return_value = ('date1', 'date2') + mock_post.return_value = ('code', 'cert') + mock_b2s.return_value = 'bcert' + self.assertEqual(('mock_pv', None, None, None), self.cahandler.enroll('csr')) + self.assertTrue(mock_iv.called) + self.assertTrue(mock_pv.called) + self.assertFalse(mock_icg.called) + self.assertFalse(mock_cpg.called) + self.assertFalse(mockccg.called) + self.assertFalse(mock_vdg.called) + self.assertFalse(mock_csbg.called) + self.assertFalse(mock_b64.called) + self.assertFalse(mock_post.called) + self.assertFalse(mock_b2s.called) + self.assertFalse(mock_d2p.called) + + @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_post') + @patch('examples.ca_handler.asa_ca_handler.convert_byte_to_string') + @patch('examples.ca_handler.asa_ca_handler.cert_der2pem') + @patch('examples.ca_handler.asa_ca_handler.b64_decode') + @patch('examples.ca_handler.asa_ca_handler.csr_san_byte_get') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._validity_dates_get') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._csr_cn_get') + @patch('examples.ca_handler.asa_ca_handler.csr_pubkey_get') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_chain_get') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_verify') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_verify') + def test_036_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_csbg, mock_b64, mock_d2p, mock_b2s, mock_post): + """ test enroll() """ + mock_iv.return_value = None + mock_pv.return_value = None + mock_icg.return_value = 'issuer_chain' + mock_vdg.return_value = ('date1', 'date2') + mock_post.return_value = (500, 'cert') + mock_b2s.return_value = 'bcert' + self.assertEqual(('Enrollment failed', None, None, None), self.cahandler.enroll('csr')) + self.assertTrue(mock_iv.called) + self.assertTrue(mock_pv.called) + self.assertTrue(mock_icg.called) + self.assertTrue(mock_cpg.called) + self.assertTrue(mockccg.called) + self.assertTrue(mock_vdg.called) + self.assertTrue(mock_csbg.called) + self.assertFalse(mock_b64.called) + self.assertTrue(mock_post.called) + self.assertFalse(mock_b2s.called) + self.assertFalse(mock_d2p.called) + + @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_post') + @patch('examples.ca_handler.asa_ca_handler.convert_byte_to_string') + @patch('examples.ca_handler.asa_ca_handler.cert_der2pem') + @patch('examples.ca_handler.asa_ca_handler.b64_decode') + @patch('examples.ca_handler.asa_ca_handler.csr_san_byte_get') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._validity_dates_get') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._csr_cn_get') + @patch('examples.ca_handler.asa_ca_handler.csr_pubkey_get') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_chain_get') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_verify') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_verify') + def test_037_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_csbg, mock_b64, mock_d2p, mock_b2s, mock_post): + """ test enroll() """ + mock_iv.return_value = None + mock_pv.return_value = None + mock_icg.return_value = 'issuer_chain' + mock_vdg.return_value = ('date1', 'date2') + mock_post.return_value = (500, 'cert') + mock_b2s.return_value = 'bcert' + mock_cpg.return_value = None + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertEqual(('Enrollment failed', None, None, None), self.cahandler.enroll('csr')) + self.assertIn('ERROR:test_a2c:CAhandler._enrollment_dic_create(): public key not found', lcm.output) + self.assertTrue(mock_iv.called) + self.assertTrue(mock_pv.called) + self.assertTrue(mock_icg.called) + self.assertTrue(mock_cpg.called) + self.assertFalse(mockccg.called) + self.assertFalse(mock_vdg.called) + self.assertFalse(mock_csbg.called) + self.assertFalse(mock_b64.called) + self.assertFalse(mock_post.called) + self.assertFalse(mock_b2s.called) + self.assertFalse(mock_d2p.called) + + @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_post') + @patch('examples.ca_handler.asa_ca_handler.cert_serial_get') + def test_039_revoke(self, mock_serial, mock_post): + """ test revoke() """ + self.cahandler.ca_name = 'ca_name' + mock_serial.return_value = 'serial' + mock_post.return_value = ('code', None) + self.assertEqual(('code', None, None), self.cahandler.revoke('cert')) + self.assertTrue(mock_serial.called) + self.assertTrue(mock_post.called) + + @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_post') + @patch('examples.ca_handler.asa_ca_handler.cert_serial_get') + def test_040_revoke(self, mock_serial, mock_post): + """ test revoke() """ + self.cahandler.ca_name = 'ca_name' + mock_serial.return_value = 'serial' + mock_post.return_value = ('code', {'message': 'message'}) + self.assertEqual(('code', 'urn:ietf:params:acme:error:serverInternal', 'message'), self.cahandler.revoke('cert')) + self.assertTrue(mock_serial.called) + self.assertTrue(mock_post.called) + + @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_post') + @patch('examples.ca_handler.asa_ca_handler.cert_serial_get') + def test_041_revoke(self, mock_serial, mock_post): + """ test revoke() """ + self.cahandler.ca_name = 'ca_name' + mock_serial.return_value = 'serial' + mock_post.return_value = ('code', {'Message': 'Message'}) + self.assertEqual(('code', 'urn:ietf:params:acme:error:serverInternal', 'Message'), self.cahandler.revoke('cert')) + self.assertTrue(mock_serial.called) + self.assertTrue(mock_post.called) + + @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_post') + @patch('examples.ca_handler.asa_ca_handler.cert_serial_get') + def test_042_revoke(self, mock_serial, mock_post): + """ test revoke() """ + self.cahandler.ca_name = 'ca_name' + mock_serial.return_value = 'serial' + mock_post.return_value = ('code', {'foo': 'bar'}) + self.assertEqual(('code', 'urn:ietf:params:acme:error:serverInternal', 'Unknown error'), self.cahandler.revoke('cert')) + self.assertTrue(mock_serial.called) + self.assertTrue(mock_post.called) + +if __name__ == '__main__': + + unittest.main() diff --git a/test/test_helper.py b/test/test_helper.py index 2958e47c..918c05da 100644 --- a/test/test_helper.py +++ b/test/test_helper.py @@ -9,6 +9,7 @@ import socket from unittest.mock import patch, MagicMock, Mock import dns.resolver +import base64 sys.path.insert(0, '.') sys.path.insert(1, '..') @@ -25,7 +26,7 @@ def setUp(self): """ setup unittest """ import logging logging.basicConfig(level=logging.CRITICAL) - from acme_srv.helper import b64decode_pad, b64_decode, b64_encode, b64_url_encode, b64_url_recode, convert_string_to_byte, convert_byte_to_string, decode_message, decode_deserialize, get_url, generate_random_string, signature_check, validate_email, uts_to_date_utc, date_to_uts_utc, load_config, cert_serial_get, cert_san_get, cert_dates_get, build_pem_file, date_to_datestr, datestr_to_date, dkeys_lower, csr_cn_get, cert_pubkey_get, csr_pubkey_get, url_get, url_get_with_own_dns, dns_server_list_load, csr_san_get, csr_extensions_get, fqdn_resolve, fqdn_in_san_check, sha256_hash, sha256_hash_hex, cert_der2pem, cert_pem2der, cert_extensions_get, csr_dn_get, logger_setup, logger_info, print_debug, jwk_thumbprint_get, allowed_gai_family, patched_create_connection, validate_csr, servercert_get, txt_get, proxystring_convert, proxy_check, handle_exception, ca_handler_load, eab_handler_load, hooks_load, error_dic_get, _logger_nonce_modify, _logger_certificate_modify, _logger_token_modify, _logger_challenges_modify, config_check, cert_issuer_get, cert_cn_get, string_sanitize, pembundle_to_list, certid_asn1_get, certid_check, certid_hex_get, v6_adjust, ipv6_chk, header_info_get + from acme_srv.helper import b64decode_pad, b64_decode, b64_encode, b64_url_encode, b64_url_recode, convert_string_to_byte, convert_byte_to_string, decode_message, decode_deserialize, get_url, generate_random_string, signature_check, validate_email, uts_to_date_utc, date_to_uts_utc, load_config, cert_serial_get, cert_san_get, cert_dates_get, build_pem_file, date_to_datestr, datestr_to_date, dkeys_lower, csr_cn_get, cert_pubkey_get, csr_pubkey_get, url_get, url_get_with_own_dns, dns_server_list_load, csr_san_get, csr_san_byte_get, csr_extensions_get, fqdn_resolve, fqdn_in_san_check, sha256_hash, sha256_hash_hex, cert_der2pem, cert_pem2der, cert_extensions_get, csr_dn_get, logger_setup, logger_info, print_debug, jwk_thumbprint_get, allowed_gai_family, patched_create_connection, validate_csr, servercert_get, txt_get, proxystring_convert, proxy_check, handle_exception, ca_handler_load, eab_handler_load, hooks_load, error_dic_get, _logger_nonce_modify, _logger_certificate_modify, _logger_token_modify, _logger_challenges_modify, config_check, cert_issuer_get, cert_cn_get, string_sanitize, pembundle_to_list, certid_asn1_get, certid_check, certid_hex_get, v6_adjust, ipv6_chk, ip_validate, header_info_get, encode_url, uts_now self.logger = logging.getLogger('test_a2c') self.allowed_gai_family = allowed_gai_family self.b64_decode = b64_decode @@ -97,6 +98,10 @@ def setUp(self): self.v6_adjust = v6_adjust self.handle_exception = handle_exception self.header_info_get = header_info_get + self.csr_san_byte_get = csr_san_byte_get + self.encode_url = encode_url + self.uts_now = uts_now + self.ip_validate = ip_validate def test_001_helper_b64decode_pad(self): """ test b64decode_pad() method with a regular base64 encoded string """ @@ -691,137 +696,171 @@ def test_072_helper_csr_pubkey_get(self): """ self.assertEqual(pub_key, self.csr_pubkey_get(self.logger, csr)) - def test_073_helper_convert_byte_to_string(self): + def test_073_helper_csr_pubkey_get(self): + """ test get public_key from certificate """ + csr = """MIIClzCCAX8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBvH7P73CwR7AF/WGeTfIDLlMWD6VZV3CTZBF0AwNMTFU/zbdAX8r63pzElX/5C5ZVsc36XHqdAJcioJlI33uE3RhOSvDyOcDgWlnPK9gj2soQ7enizGqd1u7hf6C3IwFtc4uGNOU3Z/tnTzVdYiCSKS+5lTZfMxn4FtEUN+w90NHBvC+AlTo3Gl0gqbYOZgg/UwWj60u7S2gBzSeb2/w62Z7bz+SknGZbeI4ySo30ET6oCSCAUN42jE+1dHI/Y+tGBtqP3h7W7OezKeLsJjD9r07U0+uMoVCY9oKTyT0gK8+gsde0tpt6QKa93HJGUPAP9ehrKCl335QcJESFw67/AgMBAAGgOTA3BgkqhkiG9w0BCQ4xKjAoMAsGA1UdDwQEAwIF4DAZBgNVHREEEjAQgg5mb28xLmJhci5sb2NhbDANBgkqhkiG9w0BAQsFAAOCAQEAf4cdGpYHLqX+06BFF7+NqXLmKvc7n66vAfevLN75eu/pCXhhRSdpXvcYm+mAVEXJCPaG2kFGt6wfBvVWoVX/91d+OuAtiUHmhY95Oi7g3RF3ThCrvT2mR4zsNiKgC34jXbl9489iIiFRBQXkq2fLwN5JwBYutUENwkDIeApRRbmUzTDbar1xoBAQ3GjVtOAEjHc/3S1yyKkCpM6Qkg8uWOJAXw9INJqH6x55nMZrvTUuXkURc/mvhV+bp2vdKoigGvfa3VVfoAI0BZLQMohQ9QLKoNQsKxEs3JidvpZrl3o23LMGEPoJs3zIuowTa217PHwdBw4UwtD7KxJK/+344A==""" + + pub_key = """-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwbx+z+9wsEewBf1hnk3y +Ay5TFg+lWVdwk2QRdAMDTExVP823QF/K+t6cxJV/+QuWVbHN+lx6nQCXIqCZSN97 +hN0YTkrw8jnA4FpZzyvYI9rKEO3p4sxqndbu4X+gtyMBbXOLhjTlN2f7Z081XWIg +kikvuZU2XzMZ+BbRFDfsPdDRwbwvgJU6NxpdIKm2DmYIP1MFo+tLu0toAc0nm9v8 +Otme28/kpJxmW3iOMkqN9BE+qAkggFDeNoxPtXRyP2PrRgbaj94e1uznsyni7CYw +/a9O1NPrjKFQmPaCk8k9ICvPoLHXtLabekCmvdxyRlDwD/Xoaygpd9+UHCREhcOu +/wIDAQAB +-----END PUBLIC KEY----- +""" + self.assertEqual(pub_key, self.csr_pubkey_get(self.logger, csr, encoding='pem')) + + def test_074_helper_csr_pubkey_get(self): + """ test get public_key from certificate """ + csr = """MIIClzCCAX8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBvH7P73CwR7AF/WGeTfIDLlMWD6VZV3CTZBF0AwNMTFU/zbdAX8r63pzElX/5C5ZVsc36XHqdAJcioJlI33uE3RhOSvDyOcDgWlnPK9gj2soQ7enizGqd1u7hf6C3IwFtc4uGNOU3Z/tnTzVdYiCSKS+5lTZfMxn4FtEUN+w90NHBvC+AlTo3Gl0gqbYOZgg/UwWj60u7S2gBzSeb2/w62Z7bz+SknGZbeI4ySo30ET6oCSCAUN42jE+1dHI/Y+tGBtqP3h7W7OezKeLsJjD9r07U0+uMoVCY9oKTyT0gK8+gsde0tpt6QKa93HJGUPAP9ehrKCl335QcJESFw67/AgMBAAGgOTA3BgkqhkiG9w0BCQ4xKjAoMAsGA1UdDwQEAwIF4DAZBgNVHREEEjAQgg5mb28xLmJhci5sb2NhbDANBgkqhkiG9w0BAQsFAAOCAQEAf4cdGpYHLqX+06BFF7+NqXLmKvc7n66vAfevLN75eu/pCXhhRSdpXvcYm+mAVEXJCPaG2kFGt6wfBvVWoVX/91d+OuAtiUHmhY95Oi7g3RF3ThCrvT2mR4zsNiKgC34jXbl9489iIiFRBQXkq2fLwN5JwBYutUENwkDIeApRRbmUzTDbar1xoBAQ3GjVtOAEjHc/3S1yyKkCpM6Qkg8uWOJAXw9INJqH6x55nMZrvTUuXkURc/mvhV+bp2vdKoigGvfa3VVfoAI0BZLQMohQ9QLKoNQsKxEs3JidvpZrl3o23LMGEPoJs3zIuowTa217PHwdBw4UwtD7KxJK/+344A==""" + pub_key = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwbx+z+9wsEewBf1hnk3yAy5TFg+lWVdwk2QRdAMDTExVP823QF/K+t6cxJV/+QuWVbHN+lx6nQCXIqCZSN97hN0YTkrw8jnA4FpZzyvYI9rKEO3p4sxqndbu4X+gtyMBbXOLhjTlN2f7Z081XWIgkikvuZU2XzMZ+BbRFDfsPdDRwbwvgJU6NxpdIKm2DmYIP1MFo+tLu0toAc0nm9v8Otme28/kpJxmW3iOMkqN9BE+qAkggFDeNoxPtXRyP2PrRgbaj94e1uznsyni7CYw/a9O1NPrjKFQmPaCk8k9ICvPoLHXtLabekCmvdxyRlDwD/Xoaygpd9+UHCREhcOu/wIDAQAB' + self.assertEqual(pub_key, self.csr_pubkey_get(self.logger, csr, encoding='base64der')) + + def test_075_helper_csr_pubkey_get(self): + """ test get public_key from certificate """ + csr = """MIIClzCCAX8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBvH7P73CwR7AF/WGeTfIDLlMWD6VZV3CTZBF0AwNMTFU/zbdAX8r63pzElX/5C5ZVsc36XHqdAJcioJlI33uE3RhOSvDyOcDgWlnPK9gj2soQ7enizGqd1u7hf6C3IwFtc4uGNOU3Z/tnTzVdYiCSKS+5lTZfMxn4FtEUN+w90NHBvC+AlTo3Gl0gqbYOZgg/UwWj60u7S2gBzSeb2/w62Z7bz+SknGZbeI4ySo30ET6oCSCAUN42jE+1dHI/Y+tGBtqP3h7W7OezKeLsJjD9r07U0+uMoVCY9oKTyT0gK8+gsde0tpt6QKa93HJGUPAP9ehrKCl335QcJESFw67/AgMBAAGgOTA3BgkqhkiG9w0BCQ4xKjAoMAsGA1UdDwQEAwIF4DAZBgNVHREEEjAQgg5mb28xLmJhci5sb2NhbDANBgkqhkiG9w0BAQsFAAOCAQEAf4cdGpYHLqX+06BFF7+NqXLmKvc7n66vAfevLN75eu/pCXhhRSdpXvcYm+mAVEXJCPaG2kFGt6wfBvVWoVX/91d+OuAtiUHmhY95Oi7g3RF3ThCrvT2mR4zsNiKgC34jXbl9489iIiFRBQXkq2fLwN5JwBYutUENwkDIeApRRbmUzTDbar1xoBAQ3GjVtOAEjHc/3S1yyKkCpM6Qkg8uWOJAXw9INJqH6x55nMZrvTUuXkURc/mvhV+bp2vdKoigGvfa3VVfoAI0BZLQMohQ9QLKoNQsKxEs3JidvpZrl3o23LMGEPoJs3zIuowTa217PHwdBw4UwtD7KxJK/+344A==""" + pub_key = b'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwbx+z+9wsEewBf1hnk3yAy5TFg+lWVdwk2QRdAMDTExVP823QF/K+t6cxJV/+QuWVbHN+lx6nQCXIqCZSN97hN0YTkrw8jnA4FpZzyvYI9rKEO3p4sxqndbu4X+gtyMBbXOLhjTlN2f7Z081XWIgkikvuZU2XzMZ+BbRFDfsPdDRwbwvgJU6NxpdIKm2DmYIP1MFo+tLu0toAc0nm9v8Otme28/kpJxmW3iOMkqN9BE+qAkggFDeNoxPtXRyP2PrRgbaj94e1uznsyni7CYw/a9O1NPrjKFQmPaCk8k9ICvPoLHXtLabekCmvdxyRlDwD/Xoaygpd9+UHCREhcOu/wIDAQAB' + self.assertEqual(pub_key, base64.b64encode(self.csr_pubkey_get(self.logger, csr, encoding='der'))) + + def test_076_helper_csr_pubkey_get(self): + """ test get public_key from certificate """ + csr = """MIIClzCCAX8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBvH7P73CwR7AF/WGeTfIDLlMWD6VZV3CTZBF0AwNMTFU/zbdAX8r63pzElX/5C5ZVsc36XHqdAJcioJlI33uE3RhOSvDyOcDgWlnPK9gj2soQ7enizGqd1u7hf6C3IwFtc4uGNOU3Z/tnTzVdYiCSKS+5lTZfMxn4FtEUN+w90NHBvC+AlTo3Gl0gqbYOZgg/UwWj60u7S2gBzSeb2/w62Z7bz+SknGZbeI4ySo30ET6oCSCAUN42jE+1dHI/Y+tGBtqP3h7W7OezKeLsJjD9r07U0+uMoVCY9oKTyT0gK8+gsde0tpt6QKa93HJGUPAP9ehrKCl335QcJESFw67/AgMBAAGgOTA3BgkqhkiG9w0BCQ4xKjAoMAsGA1UdDwQEAwIF4DAZBgNVHREEEjAQgg5mb28xLmJhci5sb2NhbDANBgkqhkiG9w0BAQsFAAOCAQEAf4cdGpYHLqX+06BFF7+NqXLmKvc7n66vAfevLN75eu/pCXhhRSdpXvcYm+mAVEXJCPaG2kFGt6wfBvVWoVX/91d+OuAtiUHmhY95Oi7g3RF3ThCrvT2mR4zsNiKgC34jXbl9489iIiFRBQXkq2fLwN5JwBYutUENwkDIeApRRbmUzTDbar1xoBAQ3GjVtOAEjHc/3S1yyKkCpM6Qkg8uWOJAXw9INJqH6x55nMZrvTUuXkURc/mvhV+bp2vdKoigGvfa3VVfoAI0BZLQMohQ9QLKoNQsKxEs3JidvpZrl3o23LMGEPoJs3zIuowTa217PHwdBw4UwtD7KxJK/+344A==""" + pub_key = b'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwbx+z+9wsEewBf1hnk3yAy5TFg+lWVdwk2QRdAMDTExVP823QF/K+t6cxJV/+QuWVbHN+lx6nQCXIqCZSN97hN0YTkrw8jnA4FpZzyvYI9rKEO3p4sxqndbu4X+gtyMBbXOLhjTlN2f7Z081XWIgkikvuZU2XzMZ+BbRFDfsPdDRwbwvgJU6NxpdIKm2DmYIP1MFo+tLu0toAc0nm9v8Otme28/kpJxmW3iOMkqN9BE+qAkggFDeNoxPtXRyP2PrRgbaj94e1uznsyni7CYw/a9O1NPrjKFQmPaCk8k9ICvPoLHXtLabekCmvdxyRlDwD/Xoaygpd9+UHCREhcOu/wIDAQAB' + self.assertFalse(self.csr_pubkey_get(self.logger, csr, encoding='unk')) + + def test_077_helper_convert_byte_to_string(self): """ convert byte2string for a string value """ self.assertEqual('foo', self.convert_byte_to_string('foo')) - def test_074_helper_convert_byte_to_string(self): + def test_078_helper_convert_byte_to_string(self): """ convert byte2string for a string value """ self.assertEqual('foo', self.convert_byte_to_string('foo')) - def test_075_helper_convert_byte_to_string(self): + def test_079_helper_convert_byte_to_string(self): """ convert byte2string for a string value """ self.assertNotEqual('foo', self.convert_byte_to_string('foobar')) - def test_076_helper_convert_byte_to_string(self): + def test_080_helper_convert_byte_to_string(self): """ convert byte2string for a string value """ self.assertNotEqual('foo', self.convert_byte_to_string(b'foobar')) - def test_077_helper_b64_url_encode(self): + def test_081_helper_b64_url_encode(self): """ test b64_url_encode of string """ self.assertEqual(b'c3RyaW5n', self.b64_url_encode(self.logger, 'string')) - def test_078_helper_b64_url_encode(self): + def test_082_helper_b64_url_encode(self): """ test b64_url_encode of byte """ self.assertEqual(b'Ynl0ZQ', self.b64_url_encode(self.logger, b'byte')) - def test_079_helper_csr_cn_get(self): + def test_083_helper_csr_cn_get(self): """ get cn of csr """ csr = 'MIIClzCCAX8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0lk4lyEIa0VL/u5ic01Zo/o+gyYqFpU7xe+nbFgiKA+R1rqrzP/sR6xjHqS0Rkv/BcBXf81sp/+iDmwIQLVlBTkKdimqVHCJMAbTL8ZNpcLDaRUce4liyX1cmczPTSqI/kcyEr8tKpYN+KzvKZZsNx2Pbgu7y7/70P2uSywiW+sqYZ+X28KGFxq6wwENzJtweDVsbWql9LLtw6daF41UQg10auNlRL1nhW0SlWZh1zPPW/0sa6C3xX28jjVh843b4ekkRNLXSEYQMTi0qYR2LomQ5aTlQ/hellf17UknfN2aA2RH5D7Ek+mndj/rH21bxQg26KRmHlaJld9K1IfvJAgMBAAGgOTA3BgkqhkiG9w0BCQ4xKjAoMAsGA1UdDwQEAwIF4DAZBgNVHREEEjAQgg5mb28xLmJhci5sb2NhbDANBgkqhkiG9w0BAQsFAAOCAQEAl3egrkO3I94IpxxfSJmVetd7s9uW3lSBqh9OiypFevQO7ZgUxau+k05NKTUNpSq3W9H/lRr5AG5x3/VX8XZVbcLKXQ0d6e38uXBAUFQQJmjBVYqd8KcMfqLeFFUBsLcG04yek2tNIbhXZfBtw9UYO27Y5ktMgWjAz2VskIXl3E2L0b8tGnSKDoMB07IVpYB9bHfHX4o+ccIgq1HxyYT1d+eVIQuSHHxR7j7Wkgb8RG9bCWpVWaYWKWU0Inh3gMnP06kPBJ9nOB4adgC3Hz37ab/0KpmBuQBEgmMfINwV/OpJVv2Su1FYK+uX7E1qUGae6QDsfg0Yor9uP0Vkv4b1NA==' self.assertEqual('foo1.bar.local', self.csr_cn_get(self.logger, csr)) - def test_080_helper_csr_cn_get(self): + def test_084_helper_csr_cn_get(self): """ get cn of csr """ csr = b'MIIClzCCAX8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0lk4lyEIa0VL/u5ic01Zo/o+gyYqFpU7xe+nbFgiKA+R1rqrzP/sR6xjHqS0Rkv/BcBXf81sp/+iDmwIQLVlBTkKdimqVHCJMAbTL8ZNpcLDaRUce4liyX1cmczPTSqI/kcyEr8tKpYN+KzvKZZsNx2Pbgu7y7/70P2uSywiW+sqYZ+X28KGFxq6wwENzJtweDVsbWql9LLtw6daF41UQg10auNlRL1nhW0SlWZh1zPPW/0sa6C3xX28jjVh843b4ekkRNLXSEYQMTi0qYR2LomQ5aTlQ/hellf17UknfN2aA2RH5D7Ek+mndj/rH21bxQg26KRmHlaJld9K1IfvJAgMBAAGgOTA3BgkqhkiG9w0BCQ4xKjAoMAsGA1UdDwQEAwIF4DAZBgNVHREEEjAQgg5mb28xLmJhci5sb2NhbDANBgkqhkiG9w0BAQsFAAOCAQEAl3egrkO3I94IpxxfSJmVetd7s9uW3lSBqh9OiypFevQO7ZgUxau+k05NKTUNpSq3W9H/lRr5AG5x3/VX8XZVbcLKXQ0d6e38uXBAUFQQJmjBVYqd8KcMfqLeFFUBsLcG04yek2tNIbhXZfBtw9UYO27Y5ktMgWjAz2VskIXl3E2L0b8tGnSKDoMB07IVpYB9bHfHX4o+ccIgq1HxyYT1d+eVIQuSHHxR7j7Wkgb8RG9bCWpVWaYWKWU0Inh3gMnP06kPBJ9nOB4adgC3Hz37ab/0KpmBuQBEgmMfINwV/OpJVv2Su1FYK+uX7E1qUGae6QDsfg0Yor9uP0Vkv4b1NA==' self.assertEqual('foo1.bar.local', self.csr_cn_get(self.logger, csr)) - def test_081_helper_convert_string_to_byte(self): + def test_085_helper_convert_string_to_byte(self): """ convert string value to byte """ value = 'foo.bar' self.assertEqual(b'foo.bar', self.convert_string_to_byte(value)) - def test_082_helper_convert_string_to_byte(self): + def test_086_helper_convert_string_to_byte(self): """ convert string value to byte """ value = b'foo.bar' self.assertEqual(b'foo.bar', self.convert_string_to_byte(value)) - def test_083_helper_convert_string_to_byte(self): + def test_087_helper_convert_string_to_byte(self): """ convert string value to byte """ value = b'' self.assertEqual(b'', self.convert_string_to_byte(value)) - def test_084_helper_convert_string_to_byte(self): + def test_088_helper_convert_string_to_byte(self): """ convert string value to byte """ value = '' self.assertEqual(b'', self.convert_string_to_byte(value)) - def test_085_helper_convert_string_to_byte(self): + def test_089_helper_convert_string_to_byte(self): """ convert string value to byte """ value = None self.assertFalse(self.convert_string_to_byte(value)) - def test_086_helper_get_url(self): + def test_090_helper_get_url(self): """ get_url https """ data_dic = {'HTTP_HOST': 'http_host', 'SERVER_PORT': '443', 'PATH_INFO': 'path_info'} self.assertEqual('https://http_host', self.get_url(data_dic, False)) - def test_087_helper_get_url(self): + def test_091_helper_get_url(self): """ get_url http """ data_dic = {'HTTP_HOST': 'http_host', 'SERVER_PORT': '80', 'PATH_INFO': 'path_info'} self.assertEqual('http://http_host', self.get_url(data_dic, False)) - def test_088_helper_get_url(self): + def test_092_helper_get_url(self): """ get_url http wsgi.scheme """ data_dic = {'HTTP_HOST': 'http_host', 'SERVER_PORT': '80', 'PATH_INFO': 'path_info', 'wsgi.url_scheme': 'wsgi.url_scheme'} self.assertEqual('wsgi.url_scheme://http_host', self.get_url(data_dic, False)) - def test_089_helper_get_url(self): + def test_093_helper_get_url(self): """ get_url https include_path true bot no pathinfo""" data_dic = {'HTTP_HOST': 'http_host', 'SERVER_PORT': '443'} self.assertEqual('https://http_host', self.get_url(data_dic, True)) - def test_090_helper_get_url(self): + def test_094_helper_get_url(self): """ get_url https and path info""" data_dic = {'HTTP_HOST': 'http_host', 'SERVER_PORT': '443', 'PATH_INFO': 'path_info'} self.assertEqual('https://http_hostpath_info', self.get_url(data_dic, True)) - def test_091_helper_get_url(self): + def test_095_helper_get_url(self): """ get_url wsgi.url and pathinfo """ data_dic = {'HTTP_HOST': 'http_host', 'SERVER_PORT': '80', 'PATH_INFO': 'path_info', 'wsgi.url_scheme': 'wsgi.url_scheme'} self.assertEqual('wsgi.url_scheme://http_hostpath_info', self.get_url(data_dic, True)) - def test_092_helper_get_url(self): + def test_096_helper_get_url(self): """ get_url http and pathinfo""" data_dic = {'HTTP_HOST': 'http_host', 'SERVER_PORT': '80', 'PATH_INFO': 'path_info'} self.assertEqual('http://http_hostpath_info', self.get_url(data_dic, True)) - def test_093_helper_get_url(self): + def test_097_helper_get_url(self): """ get_url without hostinfo """ data_dic = {'SERVER_PORT': '80', 'PATH_INFO': 'path_info'} self.assertEqual('http://localhost', self.get_url(data_dic, False)) - def test_094_helper_get_url(self): + def test_098_helper_get_url(self): """ get_url without SERVER_PORT """ data_dic = {'HTTP_HOST': 'http_host'} self.assertEqual('http://http_host', self.get_url(data_dic, True)) @patch('acme_srv.helper.requests.get') - def test_095_helper_url_get(self, mock_request): + def test_099_helper_url_get(self, mock_request): """ successful url get without dns servers """ mock_request.return_value.text = 'foo' self.assertEqual('foo', self.url_get(self.logger, 'url')) @patch('acme_srv.helper.requests.get') - def test_096_helper_url_get(self, mock_request): + def test_100_helper_url_get(self, mock_request): """ successful url get without dns servers """ mock_request.return_value.text = 'foo' self.assertEqual('foo', self.url_get(self.logger, 'url', 'dns', 'proxy')) @patch('acme_srv.helper.requests.get') - def test_097_helper_url_get(self, mock_request): + def test_101_helper_url_get(self, mock_request): """ unsuccessful url get without dns servers """ # this is stupid but triggrs an expeption mock_request.return_value = {'foo': 'foo'} self.assertEqual(None, self.url_get(self.logger, 'url')) @patch('acme_srv.helper.url_get_with_own_dns') - def test_098_helper_url_get(self, mock_request): + def test_102_helper_url_get(self, mock_request): """ successful url get with dns servers """ mock_request.return_value = 'foo' self.assertEqual('foo', self.url_get(self.logger, 'url', 'dns')) @patch('acme_srv.helper.requests.get', side_effect=Mock(side_effect=Exception('foo'))) - def test_099_helper_url_get(self, mock_request): + def test_103_helper_url_get(self, mock_request): """ unsuccessful url_get """ # mock_request.return_value.text = 'foo' with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -829,7 +868,7 @@ def test_099_helper_url_get(self, mock_request): self.assertIn('ERROR:test_a2c:url_get error: foo', lcm.output) @patch('acme_srv.helper.requests.get') - def test_100_helper_url_get(self, mock_request): + def test_104_helper_url_get(self, mock_request): """ unsuccessful url_get fallback to v4""" object = Mock() object.text = 'foo' @@ -837,79 +876,84 @@ def test_100_helper_url_get(self, mock_request): self.assertEqual('foo', self.url_get(self.logger, 'url')) @patch('acme_srv.helper.requests.get') - def test_101_helper_url_get_with_own_dns(self, mock_request): + def test_105_helper_url_get_with_own_dns(self, mock_request): """ successful url_get_with_own_dns get with dns servers """ mock_request.return_value.text = 'foo' self.assertEqual('foo', self.url_get_with_own_dns(self.logger, 'url')) @patch('acme_srv.helper.requests.get') - def test_102_helper_url_get_with_own_dns(self, mock_request): + def test_106_helper_url_get_with_own_dns(self, mock_request): """ successful url_get_with_own_dns get with dns servers """ mock_request.return_value = {'foo': 'foo'} self.assertEqual(None, self.url_get_with_own_dns(self.logger, 'url')) @patch('acme_srv.helper.load_config') - def test_103_helper_dns_server_list_load(self, mock_load_config): + def test_107_helper_dns_server_list_load(self, mock_load_config): """ successful dns_server_list_load with empty config file """ mock_load_config.return_value = {} self.assertEqual(['9.9.9.9', '8.8.8.8'], self.dns_server_list_load()) @patch('acme_srv.helper.load_config') - def test_104_helper_dns_server_list_load(self, mock_load_config): + def test_108_helper_dns_server_list_load(self, mock_load_config): """ successful dns_server_list_load with empty Challenge section """ mock_load_config.return_value = {'Challenge': {}} self.assertEqual(['9.9.9.9', '8.8.8.8'], self.dns_server_list_load()) @patch('acme_srv.helper.load_config') - def test_105_helper_dns_server_list_load(self, mock_load_config): + def test_109_helper_dns_server_list_load(self, mock_load_config): """ successful dns_server_list_load with wrong Challenge section """ mock_load_config.return_value = {'Challenge': {'foo': 'bar'}} self.assertEqual(['9.9.9.9', '8.8.8.8'], self.dns_server_list_load()) @patch('acme_srv.helper.load_config') - def test_106_helper_dns_server_list_load(self, mock_load_config): + def test_110_helper_dns_server_list_load(self, mock_load_config): """ successful dns_server_list_load with wrong json format """ mock_load_config.return_value = {'Challenge': {'dns_server_list': 'bar'}} self.assertEqual(['9.9.9.9', '8.8.8.8'], self.dns_server_list_load()) @patch('acme_srv.helper.load_config') - def test_107_helper_dns_server_list_load(self, mock_load_config): + def test_111_helper_dns_server_list_load(self, mock_load_config): """ successful dns_server_list_load with wrong json format """ mock_load_config.return_value = {'Challenge': {'dns_server_list': '["foo", "bar"]'}} self.assertEqual(['foo', 'bar'], self.dns_server_list_load()) - def test_108_helper_csr_san_get(self): + def test_112_helper_csr_san_get(self): """ get sans but no csr """ csr = None self.assertEqual([], self.csr_san_get(self.logger, csr)) - def test_109_helper_csr_san_get(self): + def test_113_helper_csr_san_get(self): """ get sans but one san with == """ csr = 'MIIClzCCAX8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDMwfxxbCCTsZY8mTFZkoQ5cAJyQZLUiz34sDDRvEpI9ZzdNNm2AEZR7AgKNuBkLwzUzY5iQ182huNzYJYZZEvYX++ocF2ngapTMQgfB+bWS5bpWIdjnAcz1/86jmJgTciwL25dSnEWL17Yn3pAWweoewr730rq/PMyIbviQrasksnSo7abe2mctxkHjHb5sZ+Z1yRTN6ir/bObXmxr+vHeeD2vLRv4Hd5XaA1d+k31J2FVMnrn5OpWbxGHo49zd0xdy2mgTdZ9UraLaQnyGlkjYzV0rqHIAIm8HOUjGN5U75/rlOPF0x62FCICZU/z1AgRvugaA5eO8zTSQJiMiBe3AgMBAAGgOTA3BgkqhkiG9w0BCQ4xKjAoMAsGA1UdDwQEAwIF4DAZBgNVHREEEjAQgg5mb28xLmJhci5sb2NhbDANBgkqhkiG9w0BAQsFAAOCAQEANAXOIkv0CovmdzyoAv1dsiK0TK2XHBdBTEPFDsrT7MnrIXOFS4FnDrg8zpn7QBzBRTl3HaKN8fnpIHkA/6ZRDqaEJq0AeskjxIg9LKDBBx5TEdgPh1CwruRWLlXtrqU7XXQmk0wLIo/kfaDRcTjyJ3yHTEK06mCAaws0sTKlTw2D4pIiDRp8zbLHeSEUX5UKOSGbLSSUY/F2XwgPB8nC2BCD/gkvHRR+dMQSdOCiS9GLwZdYAAyESw6WhmGPjmVbeTRgSt/9//yx3JKQgkFYmpSMLKR2G525M+l1qfku/4b0iMOa4vQjFRj5AXZH0SBpAKtvnFxUpP6P9mTE7+akOQ==' self.assertEqual(['DNS:foo1.bar.local'], self.csr_san_get(self.logger, csr)) - def test_110_helper_csr_san_get(self): + def test_114_helper_csr_san_get(self): """ get sans but one san without == """ csr = 'MIIClzCCAX8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDMwfxxbCCTsZY8mTFZkoQ5cAJyQZLUiz34sDDRvEpI9ZzdNNm2AEZR7AgKNuBkLwzUzY5iQ182huNzYJYZZEvYX++ocF2ngapTMQgfB+bWS5bpWIdjnAcz1/86jmJgTciwL25dSnEWL17Yn3pAWweoewr730rq/PMyIbviQrasksnSo7abe2mctxkHjHb5sZ+Z1yRTN6ir/bObXmxr+vHeeD2vLRv4Hd5XaA1d+k31J2FVMnrn5OpWbxGHo49zd0xdy2mgTdZ9UraLaQnyGlkjYzV0rqHIAIm8HOUjGN5U75/rlOPF0x62FCICZU/z1AgRvugaA5eO8zTSQJiMiBe3AgMBAAGgOTA3BgkqhkiG9w0BCQ4xKjAoMAsGA1UdDwQEAwIF4DAZBgNVHREEEjAQgg5mb28xLmJhci5sb2NhbDANBgkqhkiG9w0BAQsFAAOCAQEANAXOIkv0CovmdzyoAv1dsiK0TK2XHBdBTEPFDsrT7MnrIXOFS4FnDrg8zpn7QBzBRTl3HaKN8fnpIHkA/6ZRDqaEJq0AeskjxIg9LKDBBx5TEdgPh1CwruRWLlXtrqU7XXQmk0wLIo/kfaDRcTjyJ3yHTEK06mCAaws0sTKlTw2D4pIiDRp8zbLHeSEUX5UKOSGbLSSUY/F2XwgPB8nC2BCD/gkvHRR+dMQSdOCiS9GLwZdYAAyESw6WhmGPjmVbeTRgSt/9//yx3JKQgkFYmpSMLKR2G525M+l1qfku/4b0iMOa4vQjFRj5AXZH0SBpAKtvnFxUpP6P9mTE7+akOQ' self.assertEqual(['DNS:foo1.bar.local'], self.csr_san_get(self.logger, csr)) - def test_111_helper_csr_san_get(self): + def test_115_helper_csr_san_get(self): """ get sans but two sans """ csr = 'MIICpzCCAY8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDMwfxxbCCTsZY8mTFZkoQ5cAJyQZLUiz34sDDRvEpI9ZzdNNm2AEZR7AgKNuBkLwzUzY5iQ182huNzYJYZZEvYX++ocF2ngapTMQgfB+bWS5bpWIdjnAcz1/86jmJgTciwL25dSnEWL17Yn3pAWweoewr730rq/PMyIbviQrasksnSo7abe2mctxkHjHb5sZ+Z1yRTN6ir/bObXmxr+vHeeD2vLRv4Hd5XaA1d+k31J2FVMnrn5OpWbxGHo49zd0xdy2mgTdZ9UraLaQnyGlkjYzV0rqHIAIm8HOUjGN5U75/rlOPF0x62FCICZU/z1AgRvugaA5eO8zTSQJiMiBe3AgMBAAGgSTBHBgkqhkiG9w0BCQ4xOjA4MAsGA1UdDwQEAwIF4DApBgNVHREEIjAggg5mb28xLmJhci5sb2NhbIIOZm9vMi5iYXIubG9jYWwwDQYJKoZIhvcNAQELBQADggEBADeuf4J8Xziw2OuvLNnLOSgHQl2HdMFtRdgJoun7zPobsP3L3qyXLvvhJcQsIJggu5ZepnHGrCxroSbtRSO65GtLQA0Rq3DCGcPIC1fe9AYrqoynx8bWt2Hd+PyDrBppHVoQzj6yNCt6XNSDs04BMtjs9Pu4DD6DDHmxFMVNdHXea2Rms7C5nLQvXgw7yOF3Zk1vEu7Kue7d3zZMhN+HwwrNEA7RGAEzHHlCv5LL4Mw+kf6OJ8nf/WDiLDKEQIh6bnOuB42Y2wUMpzui8Uur0VJO+twY46MvjiVMMBZE3aPJU33eNPAQVC7GinStn+zQIJA5AADdcO8Lk1qdtaDiGp8' self.assertEqual(['DNS:foo1.bar.local', 'DNS:foo2.bar.local'], self.csr_san_get(self.logger, csr)) - def test_112_helper_csr_san_get(self): + def test_116_helper_csr_san_get(self): """ get sans but three sans """ csr = 'MIICtzCCAZ8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDMwfxxbCCTsZY8mTFZkoQ5cAJyQZLUiz34sDDRvEpI9ZzdNNm2AEZR7AgKNuBkLwzUzY5iQ182huNzYJYZZEvYX++ocF2ngapTMQgfB+bWS5bpWIdjnAcz1/86jmJgTciwL25dSnEWL17Yn3pAWweoewr730rq/PMyIbviQrasksnSo7abe2mctxkHjHb5sZ+Z1yRTN6ir/bObXmxr+vHeeD2vLRv4Hd5XaA1d+k31J2FVMnrn5OpWbxGHo49zd0xdy2mgTdZ9UraLaQnyGlkjYzV0rqHIAIm8HOUjGN5U75/rlOPF0x62FCICZU/z1AgRvugaA5eO8zTSQJiMiBe3AgMBAAGgWTBXBgkqhkiG9w0BCQ4xSjBIMAsGA1UdDwQEAwIF4DA5BgNVHREEMjAwgg5mb28xLmJhci5sb2NhbIIOZm9vMi5iYXIubG9jYWyCDmZvbzMuYmFyLmxvY2FsMA0GCSqGSIb3DQEBCwUAA4IBAQAQRkub6G4uijaXOYpCkoz40I+SVRsbRDgnMNjsooZz1+7DVglFjrr6Pb0PPTOvOxtmbHP2KK0WokDn4LqOD2t0heuI+KPQy7m/ROpOB/YZOzTWEB8yS4vjkf/RFiJ7fnCAc8vA+3K/mBVb+89F8w/KlyPmpg1GK7UNgjEa5bnznTox8q12CocCJVykPEiC8AT/VPWUOPfg6gs+V6LO8R73VRPMVy0ttYKGX80ob+KczDTMUhoxXg8OG+G+bXXU+4Tu4l+nQWf2lFejECi/vNKzUT90IbcGJwyk7rc4Q7BJ/t/5nMo+vuV9f+2HI7qakHcw6u9RGylL4OYDf1CrqF1R' self.assertEqual(['DNS:foo1.bar.local', 'DNS:foo2.bar.local', 'DNS:foo3.bar.local'], self.csr_san_get(self.logger, csr)) - def test_113_helper_csr_san_get(self): + def test_117_helper_csr_san_get(self): """ get sans but three sans """ csr = 'MIIBFjCBvQIBADAYMRYwFAYDVQQDEw1mb28uYmFyLmxvY2FsMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAETOQukalTTCD8y7zoAsmxeAWlbi9oZtzh7XQc7A7KF4fZLP3pYjoZG6s+sXCp7bUpKhuIejrDRp1cFE5NlEK8jaBDMEEGCSqGSIb3DQEJDjE0MDIwMAYDVR0RBCkwJ4INZm9vLmJhci5sb2NhbIcEwKgOg4cQ/oAAAAAAAAACFV3//sABAjAKBggqhkjOPQQDAgNIADBFAiBKUb5r/8aSN4/utaDoi0vIcaASVZz8p1nSJ1YWSCkIpAIhAI20iVBu5j0tBmTc3uRzKIYTqsnXpH0UV8bcONy4m1Sa' self.assertEqual(['DNS:foo.bar.local', 'IP:192.168.14.131', 'IP:fe80::215:5dff:fec0:102'], self.csr_san_get(self.logger, csr)) + def test_118_helper_csr_san_byte_get(self): + """ get sans but two sans """ + csr = 'MIICpzCCAY8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDMwfxxbCCTsZY8mTFZkoQ5cAJyQZLUiz34sDDRvEpI9ZzdNNm2AEZR7AgKNuBkLwzUzY5iQ182huNzYJYZZEvYX++ocF2ngapTMQgfB+bWS5bpWIdjnAcz1/86jmJgTciwL25dSnEWL17Yn3pAWweoewr730rq/PMyIbviQrasksnSo7abe2mctxkHjHb5sZ+Z1yRTN6ir/bObXmxr+vHeeD2vLRv4Hd5XaA1d+k31J2FVMnrn5OpWbxGHo49zd0xdy2mgTdZ9UraLaQnyGlkjYzV0rqHIAIm8HOUjGN5U75/rlOPF0x62FCICZU/z1AgRvugaA5eO8zTSQJiMiBe3AgMBAAGgSTBHBgkqhkiG9w0BCQ4xOjA4MAsGA1UdDwQEAwIF4DApBgNVHREEIjAggg5mb28xLmJhci5sb2NhbIIOZm9vMi5iYXIubG9jYWwwDQYJKoZIhvcNAQELBQADggEBADeuf4J8Xziw2OuvLNnLOSgHQl2HdMFtRdgJoun7zPobsP3L3qyXLvvhJcQsIJggu5ZepnHGrCxroSbtRSO65GtLQA0Rq3DCGcPIC1fe9AYrqoynx8bWt2Hd+PyDrBppHVoQzj6yNCt6XNSDs04BMtjs9Pu4DD6DDHmxFMVNdHXea2Rms7C5nLQvXgw7yOF3Zk1vEu7Kue7d3zZMhN+HwwrNEA7RGAEzHHlCv5LL4Mw+kf6OJ8nf/WDiLDKEQIh6bnOuB42Y2wUMpzui8Uur0VJO+twY46MvjiVMMBZE3aPJU33eNPAQVC7GinStn+zQIJA5AADdcO8Lk1qdtaDiGp8' + self.assertEqual('MCCCDmZvbzEuYmFyLmxvY2Fsgg5mb28yLmJhci5sb2NhbA==', self.csr_san_byte_get(self.logger, csr)) + @patch('acme_srv.helper.csr_load') - def test_114_helper_csr_san_get(self, mock_csrload): + def test_119_helper_csr_san_get(self, mock_csrload): """ get sans but three sans """ csr = 'csr' mock_csrload.return_value = 'mock_csrload' @@ -917,140 +961,140 @@ def test_114_helper_csr_san_get(self, mock_csrload): self.assertEqual([], self.csr_san_get(self.logger, csr)) self.assertIn("ERROR:test_a2c:csr_san_get(): Error: 'str' object has no attribute 'extensions'", lcm.output) - def test_114_helper_csr_extensions_get(self): + def test_120_helper_csr_extensions_get(self): """ get sns in hex """ csr = 'MIIClzCCAX8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDMwfxxbCCTsZY8mTFZkoQ5cAJyQZLUiz34sDDRvEpI9ZzdNNm2AEZR7AgKNuBkLwzUzY5iQ182huNzYJYZZEvYX++ocF2ngapTMQgfB+bWS5bpWIdjnAcz1/86jmJgTciwL25dSnEWL17Yn3pAWweoewr730rq/PMyIbviQrasksnSo7abe2mctxkHjHb5sZ+Z1yRTN6ir/bObXmxr+vHeeD2vLRv4Hd5XaA1d+k31J2FVMnrn5OpWbxGHo49zd0xdy2mgTdZ9UraLaQnyGlkjYzV0rqHIAIm8HOUjGN5U75/rlOPF0x62FCICZU/z1AgRvugaA5eO8zTSQJiMiBe3AgMBAAGgOTA3BgkqhkiG9w0BCQ4xKjAoMAsGA1UdDwQEAwIF4DAZBgNVHREEEjAQgg5mb28xLmJhci5sb2NhbDANBgkqhkiG9w0BAQsFAAOCAQEANAXOIkv0CovmdzyoAv1dsiK0TK2XHBdBTEPFDsrT7MnrIXOFS4FnDrg8zpn7QBzBRTl3HaKN8fnpIHkA/6ZRDqaEJq0AeskjxIg9LKDBBx5TEdgPh1CwruRWLlXtrqU7XXQmk0wLIo/kfaDRcTjyJ3yHTEK06mCAaws0sTKlTw2D4pIiDRp8zbLHeSEUX5UKOSGbLSSUY/F2XwgPB8nC2BCD/gkvHRR+dMQSdOCiS9GLwZdYAAyESw6WhmGPjmVbeTRgSt/9//yx3JKQgkFYmpSMLKR2G525M+l1qfku/4b0iMOa4vQjFRj5AXZH0SBpAKtvnFxUpP6P9mTE7+akOQ' self.assertEqual(['AwIF4A==', 'MBCCDmZvbzEuYmFyLmxvY2Fs'], self.csr_extensions_get(self.logger, csr)) - def test_115_helper_csr_extensions_get(self): + def test_121_helper_csr_extensions_get(self): """ get tnauth identifier """ csr = 'MIICuzCCAaMCAQAwHjEcMBoGA1UEAwwTY2VydC5zdGlyLmJhci5sb2NhbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALsLm4zgkl2lEx2EHy1ENfh3cYB79Xb5sD3ehkY+1pXphIWoM9KYVqHKOurModjsh75YjRBSilRfTFSk6kCUahTJyeCbM6Vzl75CcZy7poUxiK+u80JMU/xymUsrqY4GZlh2/XtFMxXHUSf3bhKZAIjBNugsvR/sHtEvJ6RJiuYqHMWUzZ/Vby5L0ywNl+LPSY7AVTUAZ0lKrnUCP4dHnbjwjf+nPi7vT6G0yrEg0qPOYXtJOXdf7vvjLi8J+ap758NtG2qapLdbToIPr0uOEvMO6zs8z1bIyjOHU3kzlpKHzDsPYy8txxKC/3Rae7sKB9gWm8WUxFBmuA7gaFDGQAECAwEAAaBYMFYGCSqGSIb3DQEJDjFJMEcwCwYDVR0PBAQDAgXgMB4GA1UdEQQXMBWCE2NlcnQuc3Rpci5iYXIubG9jYWwwGAYIKwYBBQUHARoEDDAKoAgWBjEyMzQ1NjANBgkqhkiG9w0BAQsFAAOCAQEAjyhJfgb/zJBMYp6ylRtEXgtBpsX9ePUL/iLgIDMcGtwaFm3pkQOSBr4xiTxftnqN77SlC8UEu7PDR73JX6iqLNJWucPlhAXVrr367ygO8GGLrtGddClZmo0lhRBRErgpagWB/jFkbL8afPGJwgQQXF0KWFMcajAPiIl1l6M0w11KqJ23Pwrmi7VJHzIgh4ys0D2UrX7KuV4PIOOmG0s7jTfBSB+yUH2zwVzOAzbr3wrD1WubD7hRaHDUi4bn4DRbquQOzbqfTI6QhetUcNpq4DwhBRcnZwUMJUIcxLAsFnDgGSW+dmJe6JH8MsS+8ZmOLllyQxWzYEVquQQvxFVTZA' self.assertEqual(['AwIF4A==', 'MBWCE2NlcnQuc3Rpci5iYXIubG9jYWw=', 'MAqgCBYGMTIzNDU2'], self.csr_extensions_get(self.logger, csr)) - def test_116_helper_validate_email(self): + def test_122_helper_validate_email(self): """ validate email containing "-" in domain """ self.assertTrue(self.validate_email(self.logger, 'foo@example-example.com')) - def test_117_helper_validate_email(self): + def test_123_helper_validate_email(self): """ validate email containing "-" in user""" self.assertTrue(self.validate_email(self.logger, 'foo-foo@example.com')) - def test_118_helper_get_url(self): + def test_124_helper_get_url(self): """ get_url with xforwarded https """ data_dic = {'HTTP_X_FORWARDED_PROTO': 'https', 'HTTP_HOST': 'http_host', 'SERVER_PORT': '443', 'PATH_INFO': 'path_info'} self.assertEqual('https://http_host', self.get_url(data_dic, False)) - def test_119_helper_get_url(self): + def test_125_helper_get_url(self): """ get_url with xforwarded http """ data_dic = {'HTTP_X_FORWARDED_PROTO': 'http', 'HTTP_HOST': 'http_host', 'SERVER_PORT': '443', 'PATH_INFO': 'path_info'} self.assertEqual('http://http_host', self.get_url(data_dic, False)) - def test_120_helper_validate_email(self): + def test_126_helper_validate_email(self): """ validate email containing first letter of domain cannot be a number""" self.assertFalse(self.validate_email(self.logger, 'foo@1example.com')) - def test_121_helper_validate_email(self): + def test_127_helper_validate_email(self): """ validate email containing last letter of domain cannot - """ self.assertFalse(self.validate_email(self.logger, 'foo@example-.com')) - def test_122_helper_cert_dates_get(self): + def test_128_helper_cert_dates_get(self): """ get issuing and expiration date from rsa certificate """ cert = 'MIIElTCCAn2gAwIBAgIRAKD_ulfqPUn-ggOUHOxjp40wDQYJKoZIhvcNAQELBQAwSDELMAkGA1UEBhMCREUxDzANBgNVBAgMBkJlcmxpbjEXMBUGA1UECgwOQWNtZTJDZXJ0aWZpZXIxDzANBgNVBAMMBnN1Yi1jYTAeFw0yMDA1MjcxMjMwMjNaFw0yMDA2MjYxMjMwMjNaMBkxFzAVBgNVBAMMDmZvbzEuYmFyLmxvY2FsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwbx-z-9wsEewBf1hnk3yAy5TFg-lWVdwk2QRdAMDTExVP823QF_K-t6cxJV_-QuWVbHN-lx6nQCXIqCZSN97hN0YTkrw8jnA4FpZzyvYI9rKEO3p4sxqndbu4X-gtyMBbXOLhjTlN2f7Z081XWIgkikvuZU2XzMZ-BbRFDfsPdDRwbwvgJU6NxpdIKm2DmYIP1MFo-tLu0toAc0nm9v8Otme28_kpJxmW3iOMkqN9BE-qAkggFDeNoxPtXRyP2PrRgbaj94e1uznsyni7CYw_a9O1NPrjKFQmPaCk8k9ICvPoLHXtLabekCmvdxyRlDwD_Xoaygpd9-UHCREhcOu_wIDAQABo4GoMIGlMAsGA1UdDwQEAwIF4DAZBgNVHREEEjAQgg5mb28xLmJhci5sb2NhbDAdBgNVHQ4EFgQUqy5KOBlkyX29l4EHTCSzhZuDg-EwDgYDVR0PAQH_BAQDAgWgMB8GA1UdIwQYMBaAFBs0P896R0FUZHfnxMJL52ftKQOkMAwGA1UdEwEB_wQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMA0GCSqGSIb3DQEBCwUAA4ICAQB7pQpILzxqcU2RKlr17rcne6NSJTUJnNXALeUFy5PrnjjJY1_B1cKaWluk3p7AMFvUjBpcucGCfEDudW290AQxYjrvl8_ePkzRzEkAo76L7ZqED5upYBZVn_3lA5Alr8L67UC0bDMhKTsy8WJzhWHQlMb37_YFUvtNPoI_MI09Q842VXeNQz5UDZmW9qhyeDIkf6fwOAO66VnGTLuUm2LGQZ-St2GauxR0ZUcRtMJoc-c7WOdHs8DlUCoFtglrzVH98501Sx749CG4nkJr4QNDpkw2hAhlo4Cxzp6PlljPNSgM9MsqqVdrgqDteDM_n-yrVFGezCik4QexDkWARPutRLQtpbhudExVnoFM68ihZ0y3oeDjgUBLybBQpcBAsBqiJ66Q8HTZRSqO9zlKW5Vm1KwAVDh_qgELxvqd0wIVkyxBKPta2l1fvb5YBiVqo4JyNcCTnoBS1emO4vk8XjroKijwLnU0cEXwHrY4JF1uU_kOtoZMGPul5EuBMcODLs7JJ3_IqJd8quI7Vf5zSsaB6nSzQ8XmiQiVogKflBeLl7AWmYCiL-FLP_q4dSJmvdr6fPMNy4-cfDO4Awc8RNfv-VjF5Mq57X1IXJrWKkat4lCEoPMq5WRJV8uVm6XNdwvUJxgCYR9mfol7T6imODDd7BNV4dKYvyteoS0auC0iww' self.assertEqual((1590582623, 1593174623), self.cert_dates_get(self.logger, cert)) - def test_123_helper_cert_dates_get(self): + def test_129_helper_cert_dates_get(self): """ get issuing and expiration date no certificate """ cert = None self.assertEqual((0, 0), self.cert_dates_get(self.logger, cert)) - def test_124_helper_cert_dates_get(self): + def test_130_helper_cert_dates_get(self): """ get issuing and expiration date damaged certificate """ cert = 'foo' self.assertEqual((0, 0), self.cert_dates_get(self.logger, cert)) - def test_125_helper_cert_dates_get(self): + def test_131_helper_cert_dates_get(self): """ get issuing and expiration date ecc certificate """ cert = 'MIIDozCCAYugAwIBAgIIMMxkE7mRR+YwDQYJKoZIhvcNAQELBQAwKjEXMBUGA1UECxMOYWNtZTJjZXJ0aWZpZXIxDzANBgNVBAMTBnN1Yi1jYTAeFw0yMDA3MTEwNDUzMTFaFw0yMTA3MTEwNDUzMTFaMBkxFzAVBgNVBAMMDmZvbzEuYmFyLmxvY2FsMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAER/KMoV5+zQgegqYue2ztPK2nZVpK2vxb02UzwyHw4ebhJ2gBobI23lSBRa1so1ug0kej7U+ohm5aGFdNxLM0G6OBqDCBpTALBgNVHQ8EBAMCBeAwGQYDVR0RBBIwEIIOZm9vMS5iYXIubG9jYWwwHQYDVR0OBBYEFCSaU743wU8jMETIO381r13tVLdMMA4GA1UdDwEB/wQEAwIFoDAfBgNVHSMEGDAWgBS/3o6OBiIiq61DyN3UT6irSEE+1TAMBgNVHRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATANBgkqhkiG9w0BAQsFAAOCAgEAmmhHuBhXNM2Azv53rCKY72yTQIoDVHjYrAvTmS6NsJzYflEOMkI7FCes64dWp54BerSD736Yax67b4XmLXc/+T41d7QAcnhY5xvLJiMpSsW37icHcLZpjlOrYDoRmny2U7n6t1aQ03nwgV+BgdaUQYLkUZuczs4kdqH1c9Ot9CCRTHpqSWlmWzGeRgt2uT4gKhFESP9lzx37YwKBHulBGthv1kcAaz8w8iPXBg01OEDiraXCBZFoYDEpDi2w2Y6ChCr7sNsY7aJ3a+2iHGYlktXEntk78S+g00HW61G9oLoRgeqEH3L6qVIpnswPAU/joub0YhNBIUFenCj8c3HMBgMcczzdZL+qStdymhpVkZetzXtMTKtgmxhkRzAOQUBBcHFc+wM97FqC0S4HJAuoHQ4EJ46MxwZH0jBVqcqCPMSaJ88uV902+VGGXrnxMR8RbGWLoCmsYb1ISmBUt+31PjMCYbXKwLmzvbRpO7XAQimvtOqoufl5yeRUJRLcUS6Let0QzU196/nZ789d7Etep7RjDYQm7/QhiWH197yKZ5/mUxqfyHDQ3hk5iX7S/gbo1jQXElEv5tB8Ozs+zVQmB2bXpN8c+8XUaZnwvYC2y+0LAQN4z7xilReCaasxQSsEOLCrlsannkGV704HYnnaKBS2tI948QotHnADHdfHl3o' self.assertEqual((1594443191, 1625979191), self.cert_dates_get(self.logger, cert)) @patch('dns.resolver.Resolver') - def test_126_helper_fqdn_resolve(self, mock_resolve): + def test_132_helper_fqdn_resolve(self, mock_resolve): """ successful dns-query returning covering github """ mock_resolve.return_value.query.return_value = ['foo'] self.assertEqual((None, False), self.fqdn_resolve('foo', dnssrv='10.0.0.1')) @patch('dns.resolver.Resolver') - def test_127_helper_fqdn_resolve(self, mock_resolve): + def test_133_helper_fqdn_resolve(self, mock_resolve): """ successful dns-query returning covering github """ mock_resolve.return_value.resolve.return_value = ['foo'] self.assertEqual(('foo', False), self.fqdn_resolve('foo.bar.local', dnssrv='10.0.0.1')) @patch('dns.resolver.Resolver') - def test_128_helper_fqdn_resolve(self, mock_resolve): + def test_134_helper_fqdn_resolve(self, mock_resolve): """ successful dns-query returning covering github """ mock_resolve.return_value.resolve.return_value = ['foo'] self.assertEqual((None, False), self.fqdn_resolve('foo')) @patch('dns.resolver.Resolver') - def test_129_helper_fqdn_resolve(self, mock_resolve): + def test_135_helper_fqdn_resolve(self, mock_resolve): """ successful dns-query returning one value """ mock_resolve.return_value.resolve.return_value = ['foo'] self.assertEqual(('foo', False), self.fqdn_resolve('foo.bar.local')) @patch('dns.resolver.Resolver') - def test_130_helper_fqdn_resolve(self, mock_resolve): + def test_136_helper_fqdn_resolve(self, mock_resolve): """ successful dns-query returning two values """ mock_resolve.return_value.resolve.return_value = ['bar', 'foo'] self.assertEqual(('bar', False), self.fqdn_resolve('foo.bar.local')) @patch('dns.resolver.Resolver.resolve', side_effect=Mock(side_effect=dns.resolver.NXDOMAIN)) - def test_131_helper_fqdn_resolve(self, mock_resolve): + def test_137_helper_fqdn_resolve(self, mock_resolve): """ catch NXDOMAIN """ self.assertEqual((None, True), self.fqdn_resolve('foo.bar.local')) @patch('dns.resolver.Resolver.resolve', side_effect=Mock(side_effect=dns.resolver.NoAnswer)) - def test_132_helper_fqdn_resolve(self, mock_resolve): + def test_138_helper_fqdn_resolve(self, mock_resolve): """ catch NoAnswer """ self.assertEqual((None, True), self.fqdn_resolve('foo.bar.local')) @patch('dns.resolver.Resolver.resolve', side_effect=Mock(side_effect=dns.resolver.NoNameservers)) - def test_133_helper_fqdn_resolve(self, mock_resolve): + def test_139_helper_fqdn_resolve(self, mock_resolve): """ catch other dns related execption """ self.assertEqual((None, False), self.fqdn_resolve('foo.bar.local')) @patch('dns.resolver.Resolver.resolve', side_effect=Mock(side_effect=Exception('foo'))) - def test_134_helper_fqdn_resolve(self, mock_resolve): + def test_140_helper_fqdn_resolve(self, mock_resolve): """ catch other execption """ self.assertEqual((None, False), self.fqdn_resolve('foo.bar.local')) @patch('dns.resolver.Resolver.resolve', side_effect=[Mock(side_effect=dns.resolver.NXDOMAIN), ['foo']]) - def test_135_helper_fqdn_resolve(self, mock_resolve): + def test_141_helper_fqdn_resolve(self, mock_resolve): """ catch NXDOMAIN on v4 and fine in v6 """ self.assertEqual(('foo', False), self.fqdn_resolve('foo.bar.local')) @patch('dns.resolver.Resolver.resolve', side_effect=[Mock(side_effect=dns.resolver.NoAnswer), ['foo']]) - def test_136_helper_fqdn_resolve(self, mock_resolve): + def test_142_helper_fqdn_resolve(self, mock_resolve): """ catch NoAnswer on v4 and fine in v6 """ self.assertEqual(('foo', False), self.fqdn_resolve('foo.bar.local')) @patch('dns.resolver.Resolver.resolve', side_effect=[Mock(side_effect=dns.resolver.NoNameservers), ['foo']]) - def test_137_helper_fqdn_resolve(self, mock_resolve): + def test_143_helper_fqdn_resolve(self, mock_resolve): """ catch other dns related execption on v4 and fine in v6 """ self.assertEqual(('foo', False), self.fqdn_resolve('foo.bar.local')) @patch('dns.resolver.Resolver.resolve', side_effect=[Mock(side_effect=Exception('foo')), ['foo']]) - def test_138_helper_fqdn_resolve(self, mock_resolve): + def test_144_helper_fqdn_resolve(self, mock_resolve): """ catch other execption when resolving v4 but fine in v6""" self.assertEqual(('foo', False), self.fqdn_resolve('foo.bar.local')) - def test_139_helper_signature_check(self): + def test_145_helper_signature_check(self): """ sucessful validation symmetric key""" mkey = '{"k": "ZndUSkZvVldvMEFiRzQ5VWNCdERtNkNBNnBTcTl4czNKVEVxdUZiaEdpZXZNUVJBVmRuSFREcDJYX2s3X0NxTA", "kty": "oct"}' message = '{"payload": "eyJlIjogIkFRQUIiLCAia3R5IjogIlJTQSIsICJuIjogIm5kN3ZWUTNraW4zS3BKdTd6RUZNTlVPb0ZIQmVDUWRFRTUyOF9iOHo2djNDNnYtQS0zeUdBcTFWTjZmRTluUXdYSmNlZ2ZNdm1MczlCVVllVjZ2M1FzdGhkVFRCdW5FS1l0TVVZUVRmNkpwaHNEb1pHTkt1dnpCY2ZxSlN2TXpCNHdwa3hORm1Pa2M1QVhwRzhnQWJiTTRuS3JDQkdCQ21lZ2RJUEc3U0g3Mk9tejN6YjIwemZfZlo4dHVoUzk1eUJKdndKRjhZRGtCdDViWUV5ZnQ4aVoyWVFGVmRZZW5FMDhKOGRBUGNVQy1HYld6NmJXUm9Xc0xOT21VNkVjSndsSV9tRXRqazA5aTNlVEhOa2Vna3NrZUJOeXhlSkdtaVRtMHRtS1MwOEVvY0VQTDA1UktxSm9XNnhVcHNITDcwSzdzUVRaUDBHSUY1VXBwSkZXMnlVdyJ9", "protected": "eyJ1cmwiOiAiaHR0cDovL2FjbWUtc3J2LmJhci5sb2NhbC9hY21lL25ld2FjY291bnQiLCAiYWxnIjogIkhTMjU2IiwgImtpZCI6ICJiYXIifQ", "signature": "VXYLfPuoClsn_rhPPV8qjspZV1Q7HyX8rXv6odWYnLI"}' self.assertEqual((True, None), self.signature_check(self.logger, message, mkey, json_=True)) - def test_140_helper_signature_check(self): + def test_146_helper_signature_check(self): """ sucessful validation wrong symmetric key""" mkey = '{"k": "ZndUSkZvVldvMEFiRzQ5VWNCdERtNkNBNnBTcTl4czNKVEVxdUZiaEdpZXZNUVJBVmRuSFREcDJYX2s3X0NxvA", "kty": "oct"}' message = '{"payload": "eyJlIjogIkFRQUIiLCAia3R5IjogIlJTQSIsICJuIjogIm5kN3ZWUTNraW4zS3BKdTd6RUZNTlVPb0ZIQmVDUWRFRTUyOF9iOHo2djNDNnYtQS0zeUdBcTFWTjZmRTluUXdYSmNlZ2ZNdm1MczlCVVllVjZ2M1FzdGhkVFRCdW5FS1l0TVVZUVRmNkpwaHNEb1pHTkt1dnpCY2ZxSlN2TXpCNHdwa3hORm1Pa2M1QVhwRzhnQWJiTTRuS3JDQkdCQ21lZ2RJUEc3U0g3Mk9tejN6YjIwemZfZlo4dHVoUzk1eUJKdndKRjhZRGtCdDViWUV5ZnQ4aVoyWVFGVmRZZW5FMDhKOGRBUGNVQy1HYld6NmJXUm9Xc0xOT21VNkVjSndsSV9tRXRqazA5aTNlVEhOa2Vna3NrZUJOeXhlSkdtaVRtMHRtS1MwOEVvY0VQTDA1UktxSm9XNnhVcHNITDcwSzdzUVRaUDBHSUY1VXBwSkZXMnlVdyJ9", "protected": "eyJ1cmwiOiAiaHR0cDovL2FjbWUtc3J2LmJhci5sb2NhbC9hY21lL25ld2FjY291bnQiLCAiYWxnIjogIkhTMjU2IiwgImtpZCI6ICJiYXIifQ", "signature": "VXYLfPuoClsn_rhPPV8qjspZV1Q7HyX8rXv6odWYnLI"}' @@ -1061,7 +1105,7 @@ def test_140_helper_signature_check(self): error = 'Verification failed for all signatures["Failed: [InvalidJWSSignature(\'Verification failed\')]"]' self.assertEqual((False, error), self.signature_check(self.logger, message, mkey, json_=True)) - def test_141_helper_signature_check(self): + def test_147_helper_signature_check(self): """ sucessful validation wrong symmetric key without json_ flag set """ mkey = '{"k": "ZndUSkZvVldvMEFiRzQ5VWNCdERtNkNBNnBTcTl4czNKVEVxdUZiaEdpZXZNUVJBVmRuSFREcDJYX2s3X0NxvA", "kty": "oct"}' message = '{"payload": "eyJlIjogIkFRQUIiLCAia3R5IjogIlJTQSIsICJuIjogIm5kN3ZWUTNraW4zS3BKdTd6RUZNTlVPb0ZIQmVDUWRFRTUyOF9iOHo2djNDNnYtQS0zeUdBcTFWTjZmRTluUXdYSmNlZ2ZNdm1MczlCVVllVjZ2M1FzdGhkVFRCdW5FS1l0TVVZUVRmNkpwaHNEb1pHTkt1dnpCY2ZxSlN2TXpCNHdwa3hORm1Pa2M1QVhwRzhnQWJiTTRuS3JDQkdCQ21lZ2RJUEc3U0g3Mk9tejN6YjIwemZfZlo4dHVoUzk1eUJKdndKRjhZRGtCdDViWUV5ZnQ4aVoyWVFGVmRZZW5FMDhKOGRBUGNVQy1HYld6NmJXUm9Xc0xOT21VNkVjSndsSV9tRXRqazA5aTNlVEhOa2Vna3NrZUJOeXhlSkdtaVRtMHRtS1MwOEVvY0VQTDA1UktxSm9XNnhVcHNITDcwSzdzUVRaUDBHSUY1VXBwSkZXMnlVdyJ9", "protected": "eyJ1cmwiOiAiaHR0cDovL2FjbWUtc3J2LmJhci5sb2NhbC9hY21lL25ld2FjY291bnQiLCAiYWxnIjogIkhTMjU2IiwgImtpZCI6ICJiYXIifQ", "signature": "VXYLfPuoClsn_rhPPV8qjspZV1Q7HyX8rXv6odWYnLI"}' @@ -1071,61 +1115,61 @@ def test_141_helper_signature_check(self): error = 'jwcrypto.jwk.JWK() argument after ** must be a mapping, not str' self.assertEqual((False, error), self.signature_check(self.logger, message, mkey)) - def test_142_helper_signature_check(self): + def test_148_helper_signature_check(self): """ sucessful validation invalid key """ mkey = 'invalid key' message = '{"payload": "eyJlIjogIkFRQUIiLCAia3R5IjogIlJTQSIsICJuIjogIm5kN3ZWUTNraW4zS3BKdTd6RUZNTlVPb0ZIQmVDUWRFRTUyOF9iOHo2djNDNnYtQS0zeUdBcTFWTjZmRTluUXdYSmNlZ2ZNdm1MczlCVVllVjZ2M1FzdGhkVFRCdW5FS1l0TVVZUVRmNkpwaHNEb1pHTkt1dnpCY2ZxSlN2TXpCNHdwa3hORm1Pa2M1QVhwRzhnQWJiTTRuS3JDQkdCQ21lZ2RJUEc3U0g3Mk9tejN6YjIwemZfZlo4dHVoUzk1eUJKdndKRjhZRGtCdDViWUV5ZnQ4aVoyWVFGVmRZZW5FMDhKOGRBUGNVQy1HYld6NmJXUm9Xc0xOT21VNkVjSndsSV9tRXRqazA5aTNlVEhOa2Vna3NrZUJOeXhlSkdtaVRtMHRtS1MwOEVvY0VQTDA1UktxSm9XNnhVcHNITDcwSzdzUVRaUDBHSUY1VXBwSkZXMnlVdyJ9", "protected": "eyJ1cmwiOiAiaHR0cDovL2FjbWUtc3J2LmJhci5sb2NhbC9hY21lL25ld2FjY291bnQiLCAiYWxnIjogIkhTMjU2IiwgImtpZCI6ICJiYXIifQ", "signature": "VXYLfPuoClsn_rhPPV8qjspZV1Q7HyX8rXv6odWYnLI"}' self.assertEqual((False, ''), self.signature_check(self.logger, message, mkey, json_=True)) - def test_143_fqdn_in_san_check(self): + def test_149_fqdn_in_san_check(self): """ successful check one entry one match """ fqdn = 'foo.bar.local' san_list = ['DNS:foo.bar.local'] self.assertTrue(self.fqdn_in_san_check(self.logger, san_list, fqdn)) - def test_144_fqdn_in_san_check(self): + def test_150_fqdn_in_san_check(self): """ successful check two entries one match """ fqdn = 'foo.bar.local' san_list = ['DNS:foo1.bar.local', 'DNS:foo.bar.local'] self.assertTrue(self.fqdn_in_san_check(self.logger, san_list, fqdn)) - def test_145_fqdn_in_san_check(self): + def test_151_fqdn_in_san_check(self): """ successful check two entries no DNS one match """ fqdn = 'foo.bar.local' san_list = ['IP: 10.0.0.l', 'DNS:foo.bar.local'] self.assertTrue(self.fqdn_in_san_check(self.logger, san_list, fqdn)) - def test_146_fqdn_in_san_check(self): + def test_152_fqdn_in_san_check(self): """ successful check no fqdn """ fqdn = None san_list = ['IP: 10.0.0.l', 'DNS:foo.bar.local'] self.assertFalse(self.fqdn_in_san_check(self.logger, san_list, fqdn)) - def test_147_fqdn_in_san_check(self): + def test_153_fqdn_in_san_check(self): """ successful check no fqdn """ fqdn = '' san_list = ['IP: 10.0.0.l', 'DNS:foo.bar.local'] self.assertFalse(self.fqdn_in_san_check(self.logger, san_list, fqdn)) - def test_148_fqdn_in_san_check(self): + def test_154_fqdn_in_san_check(self): """ successful check blank fqdn """ fqdn = ' ' san_list = ['IP: 10.0.0.l', 'DNS:foo.bar.local'] self.assertFalse(self.fqdn_in_san_check(self.logger, san_list, fqdn)) - def test_149_fqdn_in_san_check(self): + def test_155_fqdn_in_san_check(self): """ successful check empty san_list """ fqdn = 'foo.bar.local' san_list = [] self.assertFalse(self.fqdn_in_san_check(self.logger, san_list, fqdn)) - def test_150_fqdn_in_san_check(self): + def test_156_fqdn_in_san_check(self): """ successful check two entries one match """ fqdn = 'foo.bar.local' san_list = ['foo1.bar.local', 'DNS:foo.bar.local'] self.assertTrue(self.fqdn_in_san_check(self.logger, san_list, fqdn)) - def test_151_fqdn_in_san_check(self): + def test_157_fqdn_in_san_check(self): """ successful check two entries one match """ fqdn = 'foo.bar.local' san_list = ['foo1.bar.local'] @@ -1133,42 +1177,42 @@ def test_151_fqdn_in_san_check(self): self.assertFalse(self.fqdn_in_san_check(self.logger, san_list, fqdn)) self.assertIn('ERROR:test_a2c:ERROR: fqdn_in_san_check() SAN split failed: foo1.bar.local', lcm.output) - def test_152_sha256_hash_hex(self): + def test_158_sha256_hash_hex(self): """ sha256 digest as hex file """ self.assertEqual('2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae', self.sha256_hash_hex(self.logger, 'foo')) - def test_153_sha256_hash_hex(self): + def test_159_sha256_hash_hex(self): """ sha256 digest as hex file """ self.assertEqual('fcde2b2edba56bf408601fb721fe9b5c338d10ee429ea04fae5511b68fbf8fb9', self.sha256_hash_hex(self.logger, 'bar')) - def test_154_sha256_hash(self): + def test_160_sha256_hash(self): """ sha256 digest """ self.assertEqual(b'LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564', self.b64_url_encode(self.logger, self.sha256_hash(self.logger, 'foo'))) - def test_155_sha256_hash(self): + def test_161_sha256_hash(self): """ sha256 digest """ self.assertEqual(b'_N4rLtula_QIYB-3If6bXDONEO5CnqBPrlURto-_j7k', self.b64_url_encode(self.logger, self.sha256_hash(self.logger, 'bar'))) - def test_156_b64_encode(self): + def test_162_b64_encode(self): """ base64 encode string """ self.assertEqual('Zm9v', self.b64_encode(self.logger, b'foo')) - def test_157_b64_encode(self): + def test_163_b64_encode(self): """ base64 encode string """ self.assertEqual('YmFyMQ==', self.b64_encode(self.logger, b'bar1')) - def test_158_b64_encode(self): + def test_164_b64_encode(self): """ base64 encode string """ self.assertEqual('YmFyMTI=', self.b64_encode(self.logger, b'bar12')) - def test_159_cert_der2pem(self): + def test_165_cert_der2pem(self): """ test cert_der2pem """ b64 = 'MIIETjCCAjagAwIBAgIRAIG11e4S8ErJuwCYAKsoU3UwDQYJKoZIhvcNAQELBQAwETEPMA0GA1UEAxMGc3ViLWNhMB4XDTIxMDYxMjA2MjMzOFoXDTIzMDYwMjA2MjMzOFowGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0lk4lyEIa0VL/u5ic01Zo/o+gyYqFpU7xe+nbFgiKA+R1rqrzP/sR6xjHqS0Rkv/BcBXf81sp/+iDmwIQLVlBTkKdimqVHCJMAbTL8ZNpcLDaRUce4liyX1cmczPTSqI/kcyEr8tKpYN+KzvKZZsNx2Pbgu7y7/70P2uSywiW+sqYZ+X28KGFxq6wwENzJtweDVsbWql9LLtw6daF41UQg10auNlRL1nhW0SlWZh1zPPW/0sa6C3xX28jjVh843b4ekkRNLXSEYQMTi0qYR2LomQ5aTlQ/hellf17UknfN2aA2RH5D7Ek+mndj/rH21bxQg26KRmHlaJld9K1IfvJAgMBAAGjgZgwgZUwCwYDVR0PBAQDAgXgMBkGA1UdEQQSMBCCDmZvbzEuYmFyLmxvY2FsMB0GA1UdDgQWBBReDKlEWwro02ljWMCi10HMqhDmbzAfBgNVHSMEGDAWgBSDJ855iatD1k7LCUzmM5yhe4IzeDAMBgNVHRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATANBgkqhkiG9w0BAQsFAAOCAgEAhv7Jco6VjT25FuyOz/C0N5+q2M8sqjcDDYMwUTKXVkIc7/lSsubL8z64eS4I5iBecNOlPXASMoMe0KbdrvzqItYgeisC08rnWQayuDr/dj2Y/v4WptZdTPc0pWZQ7LUSxcZaydMFsIKxtfO2HR84DqrUbpvDfVSP7/UiN2O0TbSBiEC6Xayu6IudGZ9naHTAXzTau6SejcbH+0jWZsDXd1SbDPd3a+ZcHbDLIZAzsjcurleDPS54PIXjblOgMrsheDq/wzxKtvLOZEe8Gr6THwtX6uS0oQ72BFNGfZVVPFiL/q0Dvj2FveBtv7k14QcBqHutE4pEpYb/kcU7cxCVgGlUw8Q8trYQhBB37X9dOHjC2G8cyCeyVr+xfUE12wTKZDRIXjG3FMpKgeB4oNYPWA5m/1GBOGddhmogIB8GXeenDcAjBdVOFuuOrMInHLnLD9w7iEiopfx+six3Nxpo3thDV4xdiTZsWp9ojZhQzW8haEQleJ3Xyl65UuZKHyrRJ0OWR4LRkNwJitG5F0MYg8bjgik/cHTwzIB0HXgnaVeMBJY3sOkvCpAlTGZe1GL9foWIeFkprPG4cePrjtC3Mn8rHH0pIi1mdkcAIdexYdg/qlroKk2ROLXnX5LHmrM1CDZQphgyzLETdwXQdTBOJvc8FsDPhp5p+iqgT2e16QI=' result = b'-----BEGIN CERTIFICATE-----\nMIIETjCCAjagAwIBAgIRAIG11e4S8ErJuwCYAKsoU3UwDQYJKoZIhvcNAQELBQAw\nETEPMA0GA1UEAxMGc3ViLWNhMB4XDTIxMDYxMjA2MjMzOFoXDTIzMDYwMjA2MjMz\nOFowGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUA\nA4IBDwAwggEKAoIBAQC0lk4lyEIa0VL/u5ic01Zo/o+gyYqFpU7xe+nbFgiKA+R1\nrqrzP/sR6xjHqS0Rkv/BcBXf81sp/+iDmwIQLVlBTkKdimqVHCJMAbTL8ZNpcLDa\nRUce4liyX1cmczPTSqI/kcyEr8tKpYN+KzvKZZsNx2Pbgu7y7/70P2uSywiW+sqY\nZ+X28KGFxq6wwENzJtweDVsbWql9LLtw6daF41UQg10auNlRL1nhW0SlWZh1zPPW\n/0sa6C3xX28jjVh843b4ekkRNLXSEYQMTi0qYR2LomQ5aTlQ/hellf17UknfN2aA\n2RH5D7Ek+mndj/rH21bxQg26KRmHlaJld9K1IfvJAgMBAAGjgZgwgZUwCwYDVR0P\nBAQDAgXgMBkGA1UdEQQSMBCCDmZvbzEuYmFyLmxvY2FsMB0GA1UdDgQWBBReDKlE\nWwro02ljWMCi10HMqhDmbzAfBgNVHSMEGDAWgBSDJ855iatD1k7LCUzmM5yhe4Iz\neDAMBgNVHRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAN\nBgkqhkiG9w0BAQsFAAOCAgEAhv7Jco6VjT25FuyOz/C0N5+q2M8sqjcDDYMwUTKX\nVkIc7/lSsubL8z64eS4I5iBecNOlPXASMoMe0KbdrvzqItYgeisC08rnWQayuDr/\ndj2Y/v4WptZdTPc0pWZQ7LUSxcZaydMFsIKxtfO2HR84DqrUbpvDfVSP7/UiN2O0\nTbSBiEC6Xayu6IudGZ9naHTAXzTau6SejcbH+0jWZsDXd1SbDPd3a+ZcHbDLIZAz\nsjcurleDPS54PIXjblOgMrsheDq/wzxKtvLOZEe8Gr6THwtX6uS0oQ72BFNGfZVV\nPFiL/q0Dvj2FveBtv7k14QcBqHutE4pEpYb/kcU7cxCVgGlUw8Q8trYQhBB37X9d\nOHjC2G8cyCeyVr+xfUE12wTKZDRIXjG3FMpKgeB4oNYPWA5m/1GBOGddhmogIB8G\nXeenDcAjBdVOFuuOrMInHLnLD9w7iEiopfx+six3Nxpo3thDV4xdiTZsWp9ojZhQ\nzW8haEQleJ3Xyl65UuZKHyrRJ0OWR4LRkNwJitG5F0MYg8bjgik/cHTwzIB0HXgn\naVeMBJY3sOkvCpAlTGZe1GL9foWIeFkprPG4cePrjtC3Mn8rHH0pIi1mdkcAIdex\nYdg/qlroKk2ROLXnX5LHmrM1CDZQphgyzLETdwXQdTBOJvc8FsDPhp5p+iqgT2e1\n6QI=\n-----END CERTIFICATE-----\n' der = self.b64_decode(self.logger, b64) self.assertEqual(result, self.cert_der2pem(der)) - def test_160_cert_pem2der(self): + def test_166_cert_pem2der(self): """ test cert_der2pem """ cert = """-----BEGIN CERTIFICATE----- MIIEZDCCAkygAwIBAgIIe941mx0FQtAwDQYJKoZIhvcNAQELBQAwKjEXMBUGA1UE @@ -1199,7 +1243,7 @@ def test_160_cert_pem2der(self): result = 'MIIEZDCCAkygAwIBAgIIe941mx0FQtAwDQYJKoZIhvcNAQELBQAwKjEXMBUGA1UECxMOYWNtZTJjZXJ0aWZpZXIxDzANBgNVBAMTBnN1Yi1jYTAeFw0yMTA0MDkxNTUyMDBaFw0yNjA0MDkxNTUyMDBaMBgxFjAUBgNVBAMTDWVzdGNsaWVudC5lc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDAn6IqwTE1RvZUm3gelpu4tmrdFj8Ub98J1YeQz7qrew5iA81NeH9tR484edjcY0ieOt3e1MfxJoziWtaeqxpsfytmVB/i+850kVZmvRCR1jhW/4AzidkVBMQiCR5erPmmheeCxbKkto0rHb7ziRA+F8/fZLKfLNsahEQPxDuMItyQFCOQFHh8Hfuend2NgsQKeZ1r5Czf3n5Q6NFff7HG+MDeNDNdPB3ShgcvvNCFUS1z615/GIItfSqcWTAVaJ7436cA7yy5y4+0SvjfXYtHYfythBj/5UqlUmjni8Irj5K8uEtb1YUujmvlTTbzPkhYqIkSoyr7t21Dz+gcYn49AgMBAAGjgZ8wgZwwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUN3Z0iLv1FE17DCDBfpxW2P+5+kIwCwYDVR0PBAQDAgO4MBMGA1UdJQQMMAoGCCsGAQUFBwMCMBgGA1UdEQQRMA+CDWVzdGNsaWVudC5lc3QwEQYJYIZIAYb4QgEBBAQDAgWgMB4GCWCGSAGG+EIBDQQRFg94Y2EgY2VydGlmaWNhdGUwDQYJKoZIhvcNAQELBQADggIBACMAHHH4/0eAXbS/uKsIjLN1QPnnzgjxC0xoUon8UVM0PUMH+FMg6rs21Xyl5tn5iItmvKI9c3akAZ00RUQKVdmJVFRUKywmfF7n5epBpXtWJrSH817NT9GOp+PO5VUTDV5VkvpVLoy7WzThrheLKz1nC1dWowRz86tcBLAsC1zT17fsNZXQDuv4LiQQXs7QKhUU75r1IxrdBPeBQSP5skGpWxm8sapQSfOALoXu1pSoGIr6tqvNGuEoZGvUuWeQHG/G8c2ufL+6lEzZBBCd6e2tErkqD/vqfCRzbLcGgSPX0HVWdkjH09nHWXI5UhNr2YgGF7YvSTKWJfbDVlTql1BuSn2yTQtDk4E8k9BLr8WfqFSZvYrivT9Ax1n3BD9jvQL5+QRdioH1kqNGMme0Pb43pHciX4hu9L5rGenZRmxeGXZ78uSOR+n2bGxAMw1OY7Rx/lsNSKWDSN+7xIrwjjXO5Uthev1ecrLAK2+EpjITa6Y85ms39V4ypCEdujkKEBeVxuN8DdMJ2GaFGluSRZeYZ0LAPfYr5sp6G6904WF+PcT0WjGenH4PJLXrAttbhhvQxXU0Q8s2CUwUHy5OT/DW3POq7WETc+zmFGwZqiP3W9gmN0hHXsKqkNmz2RYgoH57lPS1PJb0klGUNHG98CtsmlhrivhSTJWqSIOfyKGF' self.assertEqual(result, self.b64_encode(self.logger, self.cert_pem2der(cert))) - def test_161_helper_cert_extensions_get(self): + def test_167_helper_cert_extensions_get(self): """ test cert_san_get for a single SAN and recode = False""" cert = """-----BEGIN CERTIFICATE----- MIIEZDCCAkygAwIBAgIIe941mx0FQtAwDQYJKoZIhvcNAQELBQAwKjEXMBUGA1UE @@ -1229,42 +1273,47 @@ def test_161_helper_cert_extensions_get(self): -----END CERTIFICATE-----""" self.assertEqual(['MAA=', 'BBQ3dnSIu/UUTXsMIMF+nFbY/7n6Qg==', 'AwIDuA==', 'MAoGCCsGAQUFBwMC', 'MA+CDWVzdGNsaWVudC5lc3Q=', 'AwIFoA==', 'Fg94Y2EgY2VydGlmaWNhdGU='], self.cert_extensions_get(self.logger, cert, recode=False)) - def test_162_helper_cert_extensions_get(self): + def test_168_helper_cert_extensions_get(self): """ test cert_san_get for a single SAN and recode = True""" cert = "MIIEZDCCAkygAwIBAgIIe941mx0FQtAwDQYJKoZIhvcNAQELBQAwKjEXMBUGA1UECxMOYWNtZTJjZXJ0aWZpZXIxDzANBgNVBAMTBnN1Yi1jYTAeFw0yMTA0MDkxNTUyMDBaFw0yNjA0MDkxNTUyMDBaMBgxFjAUBgNVBAMTDWVzdGNsaWVudC5lc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDAn6IqwTE1RvZUm3gelpu4tmrdFj8Ub98J1YeQz7qrew5iA81NeH9tR484edjcY0ieOt3e1MfxJoziWtaeqxpsfytmVB/i+850kVZmvRCR1jhW/4AzidkVBMQiCR5erPmmheeCxbKkto0rHb7ziRA+F8/fZLKfLNsahEQPxDuMItyQFCOQFHh8Hfuend2NgsQKeZ1r5Czf3n5Q6NFff7HG+MDeNDNdPB3ShgcvvNCFUS1z615/GIItfSqcWTAVaJ7436cA7yy5y4+0SvjfXYtHYfythBj/5UqlUmjni8Irj5K8uEtb1YUujmvlTTbzPkhYqIkSoyr7t21Dz+gcYn49AgMBAAGjgZ8wgZwwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUN3Z0iLv1FE17DCDBfpxW2P+5+kIwCwYDVR0PBAQDAgO4MBMGA1UdJQQMMAoGCCsGAQUFBwMCMBgGA1UdEQQRMA+CDWVzdGNsaWVudC5lc3QwEQYJYIZIAYb4QgEBBAQDAgWgMB4GCWCGSAGG+EIBDQQRFg94Y2EgY2VydGlmaWNhdGUwDQYJKoZIhvcNAQELBQADggIBACMAHHH4/0eAXbS/uKsIjLN1QPnnzgjxC0xoUon8UVM0PUMH+FMg6rs21Xyl5tn5iItmvKI9c3akAZ00RUQKVdmJVFRUKywmfF7n5epBpXtWJrSH817NT9GOp+PO5VUTDV5VkvpVLoy7WzThrheLKz1nC1dWowRz86tcBLAsC1zT17fsNZXQDuv4LiQQXs7QKhUU75r1IxrdBPeBQSP5skGpWxm8sapQSfOALoXu1pSoGIr6tqvNGuEoZGvUuWeQHG/G8c2ufL+6lEzZBBCd6e2tErkqD/vqfCRzbLcGgSPX0HVWdkjH09nHWXI5UhNr2YgGF7YvSTKWJfbDVlTql1BuSn2yTQtDk4E8k9BLr8WfqFSZvYrivT9Ax1n3BD9jvQL5+QRdioH1kqNGMme0Pb43pHciX4hu9L5rGenZRmxeGXZ78uSOR+n2bGxAMw1OY7Rx/lsNSKWDSN+7xIrwjjXO5Uthev1ecrLAK2+EpjITa6Y85ms39V4ypCEdujkKEBeVxuN8DdMJ2GaFGluSRZeYZ0LAPfYr5sp6G6904WF+PcT0WjGenH4PJLXrAttbhhvQxXU0Q8s2CUwUHy5OT/DW3POq7WETc+zmFGwZqiP3W9gmN0hHXsKqkNmz2RYgoH57lPS1PJb0klGUNHG98CtsmlhrivhSTJWqSIOfyKGF" self.assertEqual(['MAA=', 'BBQ3dnSIu/UUTXsMIMF+nFbY/7n6Qg==', 'AwIDuA==', 'MAoGCCsGAQUFBwMC', 'MA+CDWVzdGNsaWVudC5lc3Q=', 'AwIFoA==', 'Fg94Y2EgY2VydGlmaWNhdGU='], self.cert_extensions_get(self.logger, cert, recode=True)) - def test_163_csr_dn_get(self): + def test_169_csr_dn_get(self): """" test csr_dn_get """ csr = 'MIICjDCCAXQCAQAwFzEVMBMGA1UEAwwMdGVzdF9yZXF1ZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy6VRYaXuLS/DPa+pf5IEwycpjPfZ2vTFlvjvhwu9A3yaQQn4kD33Fu4p+zorIVmsjgpkUel2104lxFeSV081YKGzOtsajzaIRZhF7mHG5aVA8cahVPHlnxT06kO8F545ZsxE6T22tCbrLJpZk4hcaQUmGcZDWZqI7CXhbi1LSuIVIAAF0lTGMsanIM97ZEtA9mhtxFd7TsLlJpmls1l8MTavFcBtAZXqAsi4LnzEbozSjaLnuXsTe7tPmOS0uOLX+EcTAH/SxkbIg3whehTzC/sVmz5STbpklq3QuudtUl/509fpSa/UQ+WFOUUC3GhiiMM813ZsbAnt1BJepKtrfQIDAQABoDAwLgYJKoZIhvcNAQkOMSEwHzAdBgNVHREEFjAUghJ0ZXN0X3JlcXVlc3QubG9jYWwwDQYJKoZIhvcNAQELBQADggEBAFcKxjJXHBVjzqF3e6fCkDbF1JnVtNyDxZB+h4b5lI7SIuA9O/+0hcl/njeFB1gJbRODws10kKkiAYLXvS/fsLJg1gdyFPmDiCd2nJhDUCBcGmVYraGhV45x67jcUmoeqSSj5KyUY9zI+v3nANvZMf+g31ORtW8PuspkiiLJiyuGzFS67DGovbcBRrM67IApO7p04VwLA0hssFUa+wF9PUWIyu9TLx+w0rNYcp3d1wkJ905TB8gwOKXeB0RwkporlOF3KEcT+ueKZE04867bjZ/ZpiuIDFnO23MsUKLKU9ebWgwYN/xzxA8sroM69y+Acpt9Zwn3vRjVlT92Ztl218Q=' self.assertEqual('CN=test_request', self.csr_dn_get(self.logger, csr)) - def test_164_logger_setup(self): + def test_170_logger_setup(self): """ logger setup """ self.assertTrue(self.logger_setup(False)) - def test_165_logger_setup(self): + def test_171_logger_setup(self): """ logger setup """ self.assertTrue(self.logger_setup(True)) @patch('acme_srv.helper.load_config') - def test_166_logger_setup(self, mock_load_cfg): + def test_172_logger_setup(self, mock_load_cfg): """ logger setup """ mock_load_cfg.return_value = {'Helper': {'log_format': 'foo'}} self.assertTrue(self.logger_setup(True)) @patch('configparser.RawConfigParser') - def test_167_load_config(self, mock_parser): + def test_173_load_config(self, mock_parser): """ load config """ self.assertTrue(self.load_config(None, None, None)) + @patch('configparser.RawConfigParser') + def test_174_load_config(self, mock_parser): + """ load config """ + self.assertTrue(self.load_config(self.logger, None, None)) + @patch.dict('os.environ', {'ACME_SRV_CONFIGFILE': 'ACME_SRV_CONFIGFILE'}) @patch('configparser.RawConfigParser') - def test_168_load_config(self, mock_parser): + def test_175_load_config(self, mock_parser): """ load config """ self.assertTrue(self.load_config(None, None, None)) - def test_169_logger_info(self): + def test_176_logger_info(self): """ logger info """ addr = 'addr' url = 'url' @@ -1273,7 +1322,7 @@ def test_169_logger_info(self): self.logger_info(self.logger, addr, url, data_dic) self.assertIn("INFO:test_a2c:addr url {'foo': 'bar'}", lcm.output) - def test_170_logger_info(self): + def test_177_logger_info(self): """ logger info replace remove Nonce in header """ addr = 'addr' url = 'url' @@ -1282,7 +1331,7 @@ def test_170_logger_info(self): self.logger_info(self.logger, addr, url, data_dic) self.assertIn("INFO:test_a2c:addr url {'foo': 'bar', 'header': {'Replay-Nonce': '- modified -'}}", lcm.output) - def test_171_logger_info(self): + def test_178_logger_info(self): """ logger info replace remnove cert """ addr = 'addr' url = '/acme/cert/secret' @@ -1291,7 +1340,7 @@ def test_171_logger_info(self): self.logger_info(self.logger, addr, url, data_dic) self.assertIn("INFO:test_a2c:addr /acme/cert/secret {'foo': 'bar', 'data': ' - certificate - '}", lcm.output) - def test_172_logger_info(self): + def test_179_logger_info(self): """ logger info replace remove token """ addr = 'addr' url = 'url' @@ -1300,7 +1349,7 @@ def test_172_logger_info(self): self.logger_info(self.logger, addr, url, data_dic) self.assertIn("INFO:test_a2c:addr url {'foo': 'bar', 'data': {'token': '- modified -'}}", lcm.output) - def test_173_logger_info(self): + def test_180_logger_info(self): """ logger info replace remove single token in challenges """ addr = 'addr' url = 'url' @@ -1309,7 +1358,7 @@ def test_173_logger_info(self): self.logger_info(self.logger, addr, url, data_dic) self.assertIn("INFO:test_a2c:addr url {'foo': 'bar', 'data': {'challenges': [{'foo1': 'bar1', 'token': '- modified - '}]}}", lcm.output) - def test_174_logger_info(self): + def test_181_logger_info(self): """ logger info replace remove two token in challenges """ addr = 'addr' url = 'url' @@ -1319,31 +1368,31 @@ def test_174_logger_info(self): self.assertIn("INFO:test_a2c:addr url {'foo': 'bar', 'data': {'challenges': [{'foo1': 'bar1', 'token': '- modified - '}, {'foo2': 'bar2', 'token': '- modified - '}]}}", lcm.output) @patch('builtins.print') - def test_175_print_debug(self, mock_print): + def test_182_print_debug(self, mock_print): """ test print_debug """ self.print_debug(False, 'test') self.assertFalse(mock_print.called) @patch('builtins.print') - def test_176_print_debug(self, mock_print): + def test_183_print_debug(self, mock_print): """ test print_debug """ self.print_debug(True, 'test') self.assertTrue(mock_print.called) - def test_177_jwk_thumbprint_get(self): + def test_184_jwk_thumbprint_get(self): """ test jwk_thumbprint_get with empty pubkey """ pub_key = None self.assertFalse(self.jwk_thumbprint_get(self.logger, pub_key)) @patch('jwcrypto.jwk.JWK') - def test_178_jwk_thumbprint_get(self, mock_jwk): + def test_185_jwk_thumbprint_get(self, mock_jwk): """ test jwk_thumbprint_get with pubkey """ pub_key = {'pub_key': 'pub_key'} mock_jwk = Mock() self.assertTrue(self.jwk_thumbprint_get(self.logger, pub_key)) @patch('jwcrypto.jwk.JWK') - def test_179_jwk_thumbprint_get(self, mock_jwk): + def test_186_jwk_thumbprint_get(self, mock_jwk): """ test jwk_thumbprint_get with pubkey """ pub_key = {'pub_key': 'pub_key'} mock_jwk.side_effect = Exception('exc_jwk_jwk') @@ -1352,11 +1401,11 @@ def test_179_jwk_thumbprint_get(self, mock_jwk): self.assertIn('ERROR:test_a2c:jwk_thumbprint_get(): error: exc_jwk_jwk', lcm.output) @patch('socket.AF_INET') - def test_180_allowed_gai_family(self, mock_sock): + def test_187_allowed_gai_family(self, mock_sock): """ test allowed_gai_family """ self.assertTrue(self.allowed_gai_family()) - def test_181_validate_csr(self): + def test_188_validate_csr(self): """ patched_create_connection """ self.assertTrue(self.validate_csr(self.logger, 'oder_dic', 'csr')) @@ -1364,7 +1413,7 @@ def test_181_validate_csr(self): @patch('ssl.DER_cert_to_PEM_cert') @patch('ssl.SSLContext.wrap_socket') @patch('socks.socksocket') - def test_182_servercert_get(self, mock_sock, mock_context, mock_cert, mock_convert): + def test_189_servercert_get(self, mock_sock, mock_context, mock_cert, mock_convert): """ test servercert get """ mock_convert.return_value = ('proxy_proto', 'proxy_addr', 'proxy_port') mock_sock = Mock() @@ -1378,7 +1427,7 @@ def test_182_servercert_get(self, mock_sock, mock_context, mock_cert, mock_conve @patch('ssl.SSLContext.wrap_socket') @patch('socket.socket') @patch('socks.socksocket') - def test_183_servercert_get(self, mock_sock, mock_ssock, mock_context, mock_cert, mock_convert, mock_ipchk): + def test_190_servercert_get(self, mock_sock, mock_ssock, mock_context, mock_cert, mock_convert, mock_ipchk): """ test servercert get ippv6 """ mock_convert.return_value = ('proxy_proto', 'proxy_addr', 'proxy_port') mock_ipchk.return_value = True @@ -1393,7 +1442,7 @@ def test_183_servercert_get(self, mock_sock, mock_ssock, mock_context, mock_cert @patch('ssl.SSLContext.wrap_socket') @patch('socket.socket') @patch('socks.socksocket') - def test_184_servercert_get(self, mock_sock, mock_ssock, mock_context, mock_cert, mock_convert): + def test_191_servercert_get(self, mock_sock, mock_ssock, mock_context, mock_cert, mock_convert): """ test servercert get with proxy """ mock_convert.return_value = ('proxy_proto', 'proxy_addr', 'proxy_port') mock_context = Mock() @@ -1405,7 +1454,7 @@ def test_184_servercert_get(self, mock_sock, mock_ssock, mock_context, mock_cert @patch('ssl.DER_cert_to_PEM_cert') @patch('ssl.SSLContext.wrap_socket') @patch('socks.socksocket') - def test_185_servercert_get(self, mock_sock, mock_context, mock_cert): + def test_192_servercert_get(self, mock_sock, mock_context, mock_cert): """ test servercert exception """ mock_sock = Mock() mock_context.side_effect = Exception('exc_warp_sock') @@ -1417,7 +1466,7 @@ def test_185_servercert_get(self, mock_sock, mock_context, mock_cert): @patch('dns.resolver.Resolver') @patch('dns.resolver.resolve') - def test_186_txt_get(self, mock_resolve, mock_res): + def test_193_txt_get(self, mock_resolve, mock_res): """ successful dns-query returning one txt record """ resp_obj = Mock() resp_obj.strings = ['foo', 'bar'] @@ -1426,7 +1475,7 @@ def test_186_txt_get(self, mock_resolve, mock_res): self.assertTrue(mock_res.called) @patch('dns.resolver.resolve') - def test_187_txt_get(self, mock_resolve): + def test_194_txt_get(self, mock_resolve): """ successful dns-query returning one txt record """ resp_obj = Mock() resp_obj.strings = ['foo', 'bar'] @@ -1434,7 +1483,7 @@ def test_187_txt_get(self, mock_resolve): self.assertEqual(['foo'], self.txt_get(self.logger, 'foo')) @patch('dns.resolver.resolve') - def test_188_txt_get(self, mock_resolve): + def test_195_txt_get(self, mock_resolve): """ successful dns-query returning one txt record """ resp_obj1 = Mock() resp_obj1.strings = ['foo1', 'bar1'] @@ -1444,136 +1493,136 @@ def test_188_txt_get(self, mock_resolve): self.assertEqual(['foo1', 'foo2'], self.txt_get(self.logger, 'foo')) @patch('dns.resolver.resolve') - def test_189_txt_get(self, mock_resolve): + def test_196_txt_get(self, mock_resolve): """ successful dns-query returning one txt record """ mock_resolve.side_effect = Exception('mock_resolve') with self.assertLogs('test_a2c', level='INFO') as lcm: self.assertFalse(self.txt_get(self.logger, 'foo')) self.assertIn('ERROR:test_a2c:txt_get() error: mock_resolve', lcm.output) - def test_190_proxystring_convert(self): + def test_197_proxystring_convert(self): """ convert proxy_string http """ self.assertEqual((3, 'proxy', 8080), self.proxystring_convert(self.logger, 'http://proxy:8080')) - def test_191_proxystring_convert(self): + def test_198_proxystring_convert(self): """ convert proxy_string socks4 """ self.assertEqual((1, 'proxy', 8080), self.proxystring_convert(self.logger, 'socks4://proxy:8080')) - def test_192_proxystring_convert(self): + def test_199_proxystring_convert(self): """ convert proxy_string socks5 """ self.assertEqual((2, 'proxy', 8080), self.proxystring_convert(self.logger, 'socks5://proxy:8080')) - def test_193_proxystring_convert(self): + def test_200_proxystring_convert(self): """ convert proxy_string unknown protocol """ with self.assertLogs('test_a2c', level='INFO') as lcm: self.assertEqual((None, 'proxy', 8080), self.proxystring_convert(self.logger, 'unk://proxy:8080')) self.assertIn('ERROR:test_a2c:proxystring_convert(): unknown proxy protocol: unk', lcm.output) - def test_194_proxystring_convert(self): + def test_201_proxystring_convert(self): """ convert proxy_string unknown protocol """ with self.assertLogs('test_a2c', level='INFO') as lcm: self.assertEqual((3, 'proxy', None), self.proxystring_convert(self.logger, 'http://proxy:ftp')) self.assertIn('ERROR:test_a2c:proxystring_convert(): unknown proxy port: ftp', lcm.output) - def test_195_proxystring_convert(self): + def test_202_proxystring_convert(self): """ convert proxy_string porxy sting without protocol """ with self.assertLogs('test_a2c', level='INFO') as lcm: self.assertEqual((None, None, None), self.proxystring_convert(self.logger, 'proxy')) self.assertIn('ERROR:test_a2c:proxystring_convert(): error splitting proxy_server string: proxy', lcm.output) self.assertIn('ERROR:test_a2c:proxystring_convert(): proxy_proto (None), proxy_addr (None) or proxy_port (None) missing', lcm.output) - def test_196_proxystring_convert(self): + def test_203_proxystring_convert(self): """ convert proxy_string porxy sting without port """ with self.assertLogs('test_a2c', level='INFO') as lcm: self.assertEqual((None, None, None), self.proxystring_convert(self.logger, 'http://proxy')) self.assertIn('ERROR:test_a2c:proxystring_convert(): error splitting proxy into host/port: proxy', lcm.output) self.assertIn('ERROR:test_a2c:proxystring_convert(): proxy_proto (http), proxy_addr (None) or proxy_port (None) missing', lcm.output) - def test_197_proxy_check(self): + def test_204_proxy_check(self): """ check proxy for empty list """ fqdn = 'foo.bar.local' proxy_list = {} self.assertFalse(self.proxy_check(self.logger, fqdn, proxy_list)) - def test_198_proxy_check(self): + def test_205_proxy_check(self): """ check proxy - no match """ fqdn = 'foo.bar.local' proxy_list = {'foo1.bar.local': 'proxy_match'} self.assertFalse(self.proxy_check(self.logger, fqdn, proxy_list)) - def test_199_proxy_check(self): + def test_206_proxy_check(self): """ check proxy - single entry """ fqdn = 'foo.bar.local' proxy_list = {'foo.bar.local': 'proxy_match'} self.assertEqual('proxy_match', self.proxy_check(self.logger, fqdn, proxy_list)) - def test_200_proxy_check(self): + def test_207_proxy_check(self): """ check proxy - multiple entry """ fqdn = 'foo.bar.local' proxy_list = {'bar.bar.local': 'proxy_nomatch', 'foo.bar.local': 'proxy_match'} self.assertEqual('proxy_match', self.proxy_check(self.logger, fqdn, proxy_list)) - def test_201_proxy_check(self): + def test_208_proxy_check(self): """ check proxy - multiple entrie domain match""" fqdn = 'foo.bar.local' proxy_list = {'bar.bar.local': 'proxy_nomatch', 'bar.local$': 'proxy_match'} self.assertEqual('proxy_match', self.proxy_check(self.logger, fqdn, proxy_list)) - def test_202_proxy_check(self): + def test_209_proxy_check(self): """ check proxy for empty list multiple entrie domain match""" fqdn = 'foo.bar.local' proxy_list = {'bar.local$': 'proxy_nomatch', 'foo.bar.local$': 'proxy_match'} self.assertEqual('proxy_match', self.proxy_check(self.logger, fqdn, proxy_list)) - def test_203_proxy_check(self): + def test_210_proxy_check(self): """ check proxy - multiple entrie domain match""" fqdn = 'foo.bar.local' proxy_list = {'bar.local$': 'proxy_match', 'foo1.bar.local$': 'proxy_nomatch'} self.assertEqual('proxy_match', self.proxy_check(self.logger, fqdn, proxy_list)) - def test_204_proxy_check(self): + def test_211_proxy_check(self): """ check proxy - wildcard """ fqdn = 'foo.bar.local' proxy_list = {'foo1.bar.local$': 'proxy_nomatch', '*.bar.local$': 'proxy_match'} self.assertEqual('proxy_match', self.proxy_check(self.logger, fqdn, proxy_list)) - def test_205_proxy_check(self): + def test_212_proxy_check(self): """ check proxy - wildcard """ fqdn = 'foo.bar.local' proxy_list = {'.local$': 'proxy_nomatch', '*.bar.local$': 'proxy_match'} self.assertEqual('proxy_match', self.proxy_check(self.logger, fqdn, proxy_list)) - def test_206_proxy_check(self): + def test_213_proxy_check(self): """ check proxy - wildcard """ fqdn = 'local' proxy_list = {'local$': 'proxy_match', '*.bar.local$': 'proxy_no_match'} self.assertEqual('proxy_match', self.proxy_check(self.logger, fqdn, proxy_list)) - def test_207_proxy_check(self): + def test_214_proxy_check(self): """ check proxy - wildcard """ fqdn = 'foo.bar.local' proxy_list = {'*': 'wildcard', 'notlocal$': 'proxy_no_match', '*.notbar.local$': 'proxy_no_match'} self.assertEqual('wildcard', self.proxy_check(self.logger, fqdn, proxy_list)) - def test_208_handle_exception(self): + def test_215_handle_exception(self): """ test exception handler """ exc_type = FakeDBStore exc_value = Mock() exc_traceback = Mock() self.handle_exception(exc_type, exc_value, exc_traceback) - def test_209_proxy_check(self): + def test_216_proxy_check(self): """ check proxy - wildcard """ fqdn = 'foo.bar.local' proxy_list = {'*.bar.local$': 'proxy_match'} self.assertEqual('proxy_match', self.proxy_check(self.logger, fqdn, proxy_list)) - def test_210_ca_handler_load(self): + def test_217_ca_handler_load(self): """ test ca_handler_load """ config_dic = {'foo': 'bar'} self.assertFalse(self.ca_handler_load(self.logger, config_dic)) - def test_211_ca_handler_load(self): + def test_218_ca_handler_load(self): """ test ca_handler_load """ config_dic = {'foo': 'bar'} with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -1581,7 +1630,7 @@ def test_211_ca_handler_load(self): self.assertIn('ERROR:test_a2c:Helper.ca_handler_load(): CAhandler configuration missing in config file', lcm.output) @patch('importlib.import_module') - def test_212_ca_handler_load(self, mock_imp): + def test_219_ca_handler_load(self, mock_imp): """ test ca_handler_load """ config_dic = {'CAhandler': {'foo': 'bar'}} mock_imp.side_effect = Exception('exc_mock_imp') @@ -1590,14 +1639,14 @@ def test_212_ca_handler_load(self, mock_imp): self.assertIn('CRITICAL:test_a2c:Helper.ca_handler_load(): loading default CAhandler failed with err: exc_mock_imp', lcm.output) @patch('importlib.import_module') - def test_213_ca_handler_load(self, mock_imp): + def test_220_ca_handler_load(self, mock_imp): """ test ca_handler_load """ config_dic = {'CAhandler': {'foo': 'bar'}} mock_imp.return_value = 'foo' self.assertEqual('foo', self.ca_handler_load(self.logger, config_dic)) @patch('importlib.util') - def test_214_ca_handler_load(self, mock_util): + def test_221_ca_handler_load(self, mock_util): """ test ca_handler_load """ config_dic = {'CAhandler': {'handler_file': 'foo'}} mock_util.module_from_spec = Mock(return_value='foo') @@ -1605,7 +1654,7 @@ def test_214_ca_handler_load(self, mock_util): @patch('importlib.import_module') @patch('importlib.util') - def test_215_ca_handler_load(self, mock_util, mock_imp): + def test_222_ca_handler_load(self, mock_util, mock_imp): """ test ca_handler_load """ config_dic = {'CAhandler': {'handler_file': 'foo'}} mock_util.module_from_spec.side_effect = Exception('exc_mock_util') @@ -1616,7 +1665,7 @@ def test_215_ca_handler_load(self, mock_util, mock_imp): @patch('importlib.import_module') @patch('importlib.util') - def test_216_ca_handler_load(self, mock_util, mock_imp): + def test_223_ca_handler_load(self, mock_util, mock_imp): """ test ca_handler_load """ config_dic = {'CAhandler': {'handler_file': 'foo'}} mock_util.module_from_spec.side_effect = Exception('exc_mock_util') @@ -1625,7 +1674,7 @@ def test_216_ca_handler_load(self, mock_util, mock_imp): self.assertFalse(self.ca_handler_load(self.logger, config_dic)) self.assertIn('CRITICAL:test_a2c:Helper.ca_handler_load(): loading default CAhandler failed with err: exc_mock_imp', lcm.output) - def test_217_eab_handler_load(self): + def test_224_eab_handler_load(self): """ test eab_handler_load """ config_dic = {'foo': 'bar'} with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -1633,7 +1682,7 @@ def test_217_eab_handler_load(self): self.assertIn('ERROR:test_a2c:Helper.eab_handler_load(): EABhandler configuration missing in config file', lcm.output) @patch('importlib.import_module') - def test_218_eab_handler_load(self, mock_imp): + def test_225_eab_handler_load(self, mock_imp): """ test eab_handler_load """ config_dic = {'EABhandler': {'foo': 'bar'}} mock_imp.side_effect = Exception('exc_mock_imp') @@ -1642,14 +1691,14 @@ def test_218_eab_handler_load(self, mock_imp): self.assertIn('CRITICAL:test_a2c:Helper.eab_handler_load(): loading default EABhandler failed with err: exc_mock_imp', lcm.output) @patch('importlib.import_module') - def test_219_eab_handler_load(self, mock_imp): + def test_226_eab_handler_load(self, mock_imp): """ test eab_handler_load """ config_dic = {'EABhandler': {'foo': 'bar'}} mock_imp.return_value = 'foo' self.assertEqual('foo', self.eab_handler_load(self.logger, config_dic)) @patch('importlib.util') - def test_220_eab_handler_load(self, mock_util): + def test_227_eab_handler_load(self, mock_util): """ test eab_handler_load """ config_dic = {'EABhandler': {'eab_handler_file': 'foo'}} mock_util.module_from_spec = Mock(return_value='foo') @@ -1657,7 +1706,7 @@ def test_220_eab_handler_load(self, mock_util): @patch('importlib.import_module') @patch('importlib.util') - def test_221_eab_handler_load(self, mock_util, mock_imp): + def test_228_eab_handler_load(self, mock_util, mock_imp): """ test eab_handler_load """ config_dic = {'EABhandler': {'eab_handler_file': 'foo'}} mock_util.module_from_spec.side_effect = Exception('exc_mock_util') @@ -1668,7 +1717,7 @@ def test_221_eab_handler_load(self, mock_util, mock_imp): @patch('importlib.import_module') @patch('importlib.util') - def test_222_eab_handler_load(self, mock_util, mock_imp): + def test_229_eab_handler_load(self, mock_util, mock_imp): """ test eab_handler_load """ config_dic = {'EABhandler': {'eab_handler_file': 'foo'}} mock_util.module_from_spec.side_effect = Exception('exc_mock_util') @@ -1677,18 +1726,18 @@ def test_222_eab_handler_load(self, mock_util, mock_imp): self.assertFalse(self.eab_handler_load(self.logger, config_dic)) self.assertIn('CRITICAL:test_a2c:Helper.eab_handler_load(): loading default EABhandler failed with err: exc_mock_imp', lcm.output) - def test_223_hooks_load(self): + def test_230_hooks_load(self): """ test hooks load with empty config_dic """ config_dic = {} self.assertFalse(self.hooks_load(self.logger, config_dic)) - def test_224_hooks_load(self): + def test_231_hooks_load(self): """ test hooks load with hooks but no hooks_file in config_dic """ config_dic = {'Hooks': {'foo': 'bar'}} self.assertFalse(self.hooks_load(self.logger, config_dic)) @patch('importlib.util') - def test_225_hooks_load(self, mock_util): + def test_232_hooks_load(self, mock_util): """ test hooks load with hooks but no hooks_file in config_dic """ config_dic = {'Hooks': {'hooks_file': 'bar'}} mock_util.module_from_spec = Mock(return_value='foo') @@ -1697,7 +1746,7 @@ def test_225_hooks_load(self, mock_util): self.assertTrue(mock_util.module_from_spec.called) @patch('importlib.util') - def test_226_hooks_load(self, mock_util): + def test_233_hooks_load(self, mock_util): """ test hooks load with hooks but no hooks_file in config_dic """ config_dic = {'Hooks': {'hooks_file': 'bar'}} mock_util.module_from_spec = Exception('exc_mock_util') @@ -1705,7 +1754,7 @@ def test_226_hooks_load(self, mock_util): self.assertFalse(self.hooks_load(self.logger, config_dic)) self.assertIn("CRITICAL:test_a2c:Helper.hooks_load(): loading Hooks configured in cfg failed with err: 'Exception' object is not callable", lcm.output) - def test_227_error_dic_get(self): + def test_234_error_dic_get(self): """ test error_dic_get """ result = { 'badcsr': 'urn:ietf:params:acme:error:badCSR', @@ -1724,64 +1773,64 @@ def test_227_error_dic_get(self): 'badrevocationreason': 'urn:ietf:params:acme:error:badRevocationReason'} self.assertEqual(result, self.error_dic_get(self.logger)) - def test_228_logger_nonce_modify(self): + def test_235_logger_nonce_modify(self): """ test _logger_nonce_modify() """ data_dic = {'foo': 'bar'} self.assertEqual({'foo': 'bar'}, self.logger_nonce_modify(data_dic)) - def test_229_logger_nonce_modify(self): + def test_236_logger_nonce_modify(self): """ test _logger_nonce_modify() """ data_dic = {'foo': 'bar', 'header': {'foo': 'bar'}} self.assertEqual({'foo': 'bar', 'header': {'foo': 'bar'}}, self.logger_nonce_modify(data_dic)) - def test_230_logger_nonce_modify(self): + def test_237_logger_nonce_modify(self): """ test _logger_nonce_modify() """ data_dic = {'foo': 'bar', 'header': {'Replay-Nonce': 'bar'}} self.assertEqual({'foo': 'bar', 'header': {'Replay-Nonce': '- modified -'}}, self.logger_nonce_modify(data_dic)) - def test_231_logger_certificate_modify(self): + def test_238_logger_certificate_modify(self): """ test _logger_certificate_modify() """ data_dic = {'data': 'bar'} self.assertEqual({'data': 'bar'}, self.logger_certificate_modify(data_dic, 'locator')) - def test_232_logger_certificate_modify(self): + def test_239_logger_certificate_modify(self): """ test _logger_certificate_modify() """ data_dic = {'data': 'bar'} self.assertEqual({'data': ' - certificate - '}, self.logger_certificate_modify(data_dic, 'foo/acme/cert')) - def test_233_logger_token_modify(self): + def test_240_logger_token_modify(self): """ test _logger_token_modify() """ data_dic = {'data': 'bar'} self.assertEqual({'data': 'bar'}, self.logger_token_modify(data_dic)) - def test_234_logger_token_modify(self): + def test_241_logger_token_modify(self): """ test _logger_token_modify() """ data_dic = {'data': {'token': 'token'}} self.assertEqual({'data': {'token': '- modified -'}}, self.logger_token_modify(data_dic)) - def test_235_logger_challenges_modify(self): + def test_242_logger_challenges_modify(self): """ test _logger_challenges_modify() """ data_dic = {'data': 'bar'} self.assertEqual({'data': 'bar'}, self.logger_challenges_modify(data_dic)) - def test_236_logger_challenges_modify(self): + def test_243_logger_challenges_modify(self): """ test _logger_challenges_modify() """ data_dic = {'data': {'challenges': [{'token': 'token1'}]}} self.assertEqual({'data': {'challenges': [{'token': '- modified - '}]}}, self.logger_challenges_modify(data_dic)) - def test_237_logger_challenges_modify(self): + def test_244_logger_challenges_modify(self): """ test _logger_challenges_modify() """ data_dic = {'data': {'challenges': [{'token': 'token1'}, {'token': 'token2'}]}} self.assertEqual({'data': {'challenges': [{'token': '- modified - '}, {'token': '- modified - '}]}}, self.logger_challenges_modify(data_dic)) - def test_238_config_check(self): + def test_245_config_check(self): """ test config check """ config_dic = {'foo': {'bar': '"foobar"'}} with self.assertLogs('test_a2c', level='INFO') as lcm: self.config_check(self.logger, config_dic) self.assertIn('WARNING:test_a2c:config_check(): section foo option: bar contains " characters. Check if this is really needed!', lcm.output) - def test_239_helper_cert_cn_get(self): + def test_246_helper_cert_cn_get(self): """ get cn of csr """ cert = """MIIDDTCCAfWgAwIBAgIBCjANBgkqhkiG9w0BAQsFADAaMRgwFgYDVQQDEw9mb28u ZXhhbXBsZS5jb20wHhcNMTkwMTIwMTY1OTIwWhcNMTkwMjE5MTY1OTIwWjAaMRgw @@ -1802,64 +1851,64 @@ def test_239_helper_cert_cn_get(self): t+eRUDECE+0UnjyeCjTn3EU=""" self.assertEqual('foo.example.com', self.cert_cn_get(self.logger, cert)) - def test_240_logger_challenges_modify(self): + def test_247_logger_challenges_modify(self): """ test string_sanitize() """ unsafe_string = 'foo' self.assertEqual('foo', self.string_sanitize(self.logger, unsafe_string)) - def test_241_logger_challenges_modify(self): + def test_248_logger_challenges_modify(self): """ test string_sanitize() """ unsafe_string = 'foo\n;' self.assertEqual('foo;', self.string_sanitize(self.logger, unsafe_string)) - def test_242_logger_challenges_modify(self): + def test_249_logger_challenges_modify(self): """ test string_sanitize() """ unsafe_string = 'fooö' self.assertEqual('foo', self.string_sanitize(self.logger, unsafe_string)) - def test_243_logger_challenges_modify(self): + def test_250_logger_challenges_modify(self): """ test string_sanitize() """ unsafe_string = 'fooö' self.assertEqual('foo', self.string_sanitize(self.logger, unsafe_string)) - def test_244_logger_challenges_modify(self): + def test_251_logger_challenges_modify(self): """ test string_sanitize() """ unsafe_string = 'foo ' self.assertEqual('foo ', self.string_sanitize(self.logger, unsafe_string)) - def test_245_logger_challenges_modify(self): + def test_252_logger_challenges_modify(self): """ test string_sanitize() """ unsafe_string = 'foo\u0009' self.assertEqual('foo ', self.string_sanitize(self.logger, unsafe_string)) - def test_246_pembundle_to_list(self): + def test_253_pembundle_to_list(self): """ bundle to list """ pembundle_to_list = 'foo' self.assertFalse(self.pembundle_to_list(self.logger, pembundle_to_list)) - def test_247_pembundle_to_list(self): + def test_254_pembundle_to_list(self): """ bundle to list """ pembundle_to_list = '-----BEGIN CERTIFICATE-----foo' self.assertEqual(['-----BEGIN CERTIFICATE-----foo\n'], self.pembundle_to_list(self.logger, pembundle_to_list)) - def test_248_pembundle_to_list(self): + def test_255_pembundle_to_list(self): """ bundle to list """ pembundle_to_list = '-----BEGIN CERTIFICATE-----foo\n-----BEGIN CERTIFICATE-----foo1' self.assertEqual(['-----BEGIN CERTIFICATE-----foo\n', '-----BEGIN CERTIFICATE-----foo1\n'], self.pembundle_to_list(self.logger, pembundle_to_list)) - def test_249_certid_check(self): + def test_256_certid_check(self): """ test certid_check """ certid = 'e181efbe6f7ae3ea71c78fc99e4226d7185715be3d289eaa56801dff4696ca4d0420ae0dcf53345691826b81d093e9c7588c35dd5ec5eacf5b1b2606330515d5faf402082cca85f640d54142' renewal_info = 'MFswCwYJYIZIAWUDBAIBBCDhge--b3rj6nHHj8meQibXGFcVvj0onqpWgB3_RpbKTQQgrg3PUzRWkYJrgdCT6cdYjDXdXsXqz1sbJgYzBRXV-vQCCCzKhfZA1UFC' self.assertTrue(self.certid_check(self.logger, renewal_info, certid)) - def test_250_certid_check(self): + def test_257_certid_check(self): """ test certid_check """ certid = 'false' renewal_info = 'MFswCwYJYIZIAWUDBAIBBCDhge--b3rj6nHHj8meQibXGFcVvj0onqpWgB3_RpbKTQQgrg3PUzRWkYJrgdCT6cdYjDXdXsXqz1sbJgYzBRXV-vQCCCzKhfZA1UFC' self.assertFalse(self.certid_check(self.logger, renewal_info, certid)) - def test_251_certid_asn1_get(self): + def test_258_certid_asn1_get(self): """ test certid_asn1_get()""" cert_pem = '''-----BEGIN CERTIFICATE----- @@ -1918,51 +1967,51 @@ def test_251_certid_asn1_get(self): result = 'e181efbe6f7ae3ea71c78fc99e4226d7185715be3d289eaa56801dff4696ca4d0420ae0dcf53345691826b81d093e9c7588c35dd5ec5eacf5b1b2606330515d5faf402082cca85f640d54142' self.assertEqual(result, self.certid_asn1_get(self.logger, cert_pem, issuer_pem)) - def test_252_certid_hex_get(self): + def test_259_certid_hex_get(self): """ test certid_check """ certid = 'false' renewal_info = 'MFswCwYJYIZIAWUDBAIBBCDhge--b3rj6nHHj8meQibXGFcVvj0onqpWgB3_RpbKTQQgrg3PUzRWkYJrgdCT6cdYjDXdXsXqz1sbJgYzBRXV-vQCCCzKhfZA1UFC' self.assertEqual(('300b0609608648016503040201', 'e181efbe6f7ae3ea71c78fc99e4226d7185715be3d289eaa56801dff4696ca4d0420ae0dcf53345691826b81d093e9c7588c35dd5ec5eacf5b1b2606330515d5faf402082cca85f640d54142'), self.certid_hex_get(self.logger, renewal_info)) @patch('acme_srv.helper.USER_AGENT', 'FOOBAR') - def test_253_v6_adjust(self): + def test_260_v6_adjust(self): """ test v6_adjust() """ url = 'http://www.foo.bar' self.assertEqual(({'Connection': 'close', 'Accept-Encoding': 'gzip', 'User-Agent': 'FOOBAR'}, 'http://www.foo.bar'), self.v6_adjust(self.logger, url)) @patch('acme_srv.helper.USER_AGENT', 'FOOBAR') - def test_254_v6_adjust(self): + def test_261_v6_adjust(self): """ test v6_adjust() """ url = 'http://192.168.123.10' self.assertEqual(({'Connection': 'close', 'Accept-Encoding': 'gzip', 'User-Agent': 'FOOBAR'}, 'http://192.168.123.10'), self.v6_adjust(self.logger, url)) @patch('acme_srv.helper.USER_AGENT', 'FOOBAR') - def test_255_v6_adjust(self): + def test_262_v6_adjust(self): """ test v6_adjust() """ url = 'http://fe80::215:5dff:fec0:102' self.assertEqual(({'Connection': 'close', 'Accept-Encoding': 'gzip', 'User-Agent': 'FOOBAR', 'Host': 'fe80::215:5dff:fec0:102'}, 'http://[fe80::215:5dff:fec0:102]/'), self.v6_adjust(self.logger, url)) - def test_256_ipv6_chk(self): + def test_263_ipv6_chk(self): """ test ipv6_chk()""" addr_obj = 'fe80::215:5dff:fec0:102' self.assertTrue(self.ipv6_chk(self.logger, addr_obj)) - def test_257_ipv6_chk(self): + def test_264_ipv6_chk(self): """ test ipv6_chk()""" addr_obj = 'foo.bar.local' self.assertFalse(self.ipv6_chk(self.logger, addr_obj)) - def test_258_ipv6_chk(self): + def test_265_ipv6_chk(self): """ test ipv6_chk()""" addr_obj = '192.168.123.10' self.assertFalse(self.ipv6_chk(self.logger, addr_obj)) - def test_259_ipv6_chk(self): + def test_266_ipv6_chk(self): """ test ipv6_chk()""" addr_obj = None self.assertFalse(self.ipv6_chk(self.logger, addr_obj)) - def test_260_header_info_get(self): + def test_267_header_info_get(self): """ header_info_get () """ models_mock = MagicMock() models_mock.DBstore().certificates_search.return_value = ('foo', 'bar') @@ -1970,7 +2019,7 @@ def test_260_header_info_get(self): patch.dict('sys.modules', modules).start() self.assertEqual(['foo', 'bar'], self.header_info_get(self.logger, 'csr')) - def test_261_header_info_get(self): + def test_268_header_info_get(self): """ header_info_get () """ models_mock = MagicMock() models_mock.DBstore().certificates_search.side_effect = Exception('mock_search') @@ -1980,5 +2029,33 @@ def test_261_header_info_get(self): self.assertFalse(self.header_info_get(self.logger, 'csr')) self.assertIn('ERROR:test_a2c:Helper.header_info_get(): error: mock_search', lcm.output) + def test_269_encode_url(self): + # Test with a simple URL + url = "www.example.com" + self.assertEqual(url, self.encode_url(self.logger, url)) + + def test_270_encode_url(self): + # Test with a URL containing spaces + url = "www.example.com/hello world" + self.assertEqual('www.example.com/hello%20world', self.encode_url(self.logger, url)) + + def test_271_encode_url(self): + # Test with a URL containing special characters + url = "www.example.com/hello@world?foo=bar&bar=foo" + self.assertEqual('www.example.com/hello%40world%3Ffoo%3Dbar%26bar%3Dfoo', self.encode_url(self.logger, url)) + + def test_272_uts_now(self): + """ test uts_now() """ + self.assertIsInstance(self.uts_now(), int) + + def test_273_ip_validate(self): + """ test ip validate """ + self.assertEqual(('1.0.0.10.in-addr.arpa', False), self.ip_validate(self.logger, '10.0.0.1')) + + def test_274_ip_validate(self): + """ test ip validate """ + self.assertEqual((None, True), self.ip_validate(self.logger, '1000.0.0.1')) + + if __name__ == '__main__': unittest.main() From bc80924038b707d16bfc8ee686beae5d0519c0ea Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 6 Jan 2024 16:59:50 +0100 Subject: [PATCH 003/460] [doc] documentation update --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1e42b130..a8d5e1e8 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ is to be modular that an [adaption to other CA servers](docs/ca_handler.md) should be straight forward. As of today the following handlers are available: - [NetGuard Certificate Manager/Insta Certifier](docs/certifier.md) - [NetGuard Certificate Lifecycle Manager](docs/nclm.md) - - Insta ActiveCMS + - [Insta ActiveCMS](docs/asa.md) - [EJBCA](docs/ejbca.md) - [OpenXPKI](docs/openxpki.md) - [Microsoft Certificate Enrollment Web Services](docs/mscertsrv.md) From 5be515fb74c0b0b6b5ed9a4af9a3516dc1444f67 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 6 Jan 2024 17:02:23 +0100 Subject: [PATCH 004/460] [wf] first version of asa workflow --- .github/workflows/ca_handler_tests_asa.yml | 253 +++++++++++++++++++++ 1 file changed, 253 insertions(+) create mode 100644 .github/workflows/ca_handler_tests_asa.yml diff --git a/.github/workflows/ca_handler_tests_asa.yml b/.github/workflows/ca_handler_tests_asa.yml new file mode 100644 index 00000000..a4d26f0d --- /dev/null +++ b/.github/workflows/ca_handler_tests_asa.yml @@ -0,0 +1,253 @@ +name: CA handler Tests - Insta ASA + +on: + push: + pull_request: + branches: [ devel ] + schedule: + # * is a special character in YAML so you have to quote this string + - cron: '0 2 * * 6' + +jobs: + asa_handler_tests: + name: "asa_handler_tests" + runs-on: ubuntu-latest + steps: + - name: "checkout GIT" + uses: actions/checkout@v3 + + - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + working-directory: examples/Docker/ + run: | + sudo mkdir -p data + docker network create acme + docker-compose up -d + docker-compose logs + + - name: "[ PREPARE ] create letsencrypt and lego folder" + run: | + mkdir certbot + mkdir lego + mkdir acme-sh + + - name: "Test http://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "[ PREPARE ] setup a2c with asa_ca_handler" + run: | + sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem + sudo touch examples/Docker/data/acme_srv.cfg + sudo chmod 777 examples/Docker/data/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg + sudo echo "handler_file: examples/ca_handler/asa_ca_handler.py" >> examples/Docker/data/acme_srv.cfg + sudo echo "api_host: $ASA_API_HOST" >> examples/Docker/data/acme_srv.cfg + sudo echo "api_user: $ASA_API_USER" >> examples/Docker/data/acme_srv.cfg + sudo echo "api_password: $ASA_API_PASSWORD" >> examples/Docker/data/acme_srv.cfg + sudo echo "api_key: $ASA_API_KEY" >> examples/Docker/data/acme_srv.cfg + sudo echo "ca_name: $ASA_CA_NAME" >> examples/Docker/data/acme_srv.cfg + sudo echo "ca_bundle: $ASA_CA_BUNDLE" >> examples/Docker/data/acme_srv.cfg + sudo echo "profile_name: $ASA_PROFILE1" >> examples/Docker/data/acme_srv.cfg + cd examples/Docker/ + docker-compose restart + docker-compose logs + env: + ASA_API_HOST: ${{ secrets.ASA_API_HOST }} + ASA_API_USER: ${{ secrets.ASA_API_USER }} + ASA_API_PASSWORD: ${{ secrets.ASA_API_PASSWORD }} + ASA_API_KEY: ${{ secrets.ASA_API_KEY }} + ASA_CA_NAME: ${{ secrets.ASA_CA_NAME }} + ASA_CA_BUNDLE: ${{ secrets.ASA_CA_BUNDLE }} + ASA_PROFILE1: ${{ secrets.ASA_PROFILE1 }} + + - name: "Test http://acme-srv/directory is accessable again" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "[ PREPARE ] prepare acme.sh container" + run: | + docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + + - name: "[ ENROLL ] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --keylength 2048 --debug 3 --output-insecure --force + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -text -noout + + #- name: "revoke via acme.sh" + # run: | + # docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure + + - name: "[ REGISTER ] certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email + + - name: "[ ENROLL ] HTTP-01 single domain certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot --key-type rsa --rsa-key-size 2048 + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem + sudo openssl x509 -in certbot/live/certbot/cert.pem -text -noout + + #- name: "revoke HTTP-01 single domain certbot" + # run: | + # docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot + + - name: "[ ENROLL ] lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --key-type rsa2048 --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + + #- name: "revoke HTTP-01 single domain lego" + # run: | + # docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke + + - name: "[ * ] collecting test logs" + if: ${{ failure() }} + run: | + mkdir -p ${{ github.workspace }}/artifact/upload + sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ + sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + sudo cp -rp certbot/ ${{ github.workspace }}/artifact/certbot/ + sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ + cd examples/Docker + docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh certbot lego + + - name: "[ * ] uploading artificates" + uses: actions/upload-artifact@v3 + if: ${{ failure() }} + with: + name: asa_wsgi.tar.gz + path: ${{ github.workspace }}/artifact/upload/ + + asa_handler_tests_rpm: + name: "asa_handler_tests_rpm" + runs-on: ubuntu-latest + steps: + - name: "checkout GIT" + uses: actions/checkout@v3 + + - name: Retrieve Version from version.py + run: | + echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV + - run: echo "Latest tag is ${{ env.TAG_NAME }}" + + - name: update version number in spec file + run: | + # sudo sed -i "s/Source0:.*/Source0: %{name}-%{version}.tar.gz/g" examples/install_scripts/rpm/acme2certifier.spec + sudo sed -i "s/__version__/${{ env.TAG_NAME }}/g" examples/install_scripts/rpm/acme2certifier.spec + cat examples/install_scripts/rpm/acme2certifier.spec + + - name: build RPM package + id: rpm + uses: grindsa/rpmbuild@alma9 + with: + spec_file: "examples/install_scripts/rpm/acme2certifier.spec" + + - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" + + - name: "[ PREPARE ] setup environment for alma installation" + run: | + docker network create acme + sudo mkdir -p data + sudo chmod -R 777 data + sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data + sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data + + - name: "[ PREPARE ] create letsencrypt and lego folder" + run: | + mkdir certbot + mkdir lego + mkdir acme-sh + + - name: "[ PREPARE ] prepare acme_srv.cfg with certifier_ca_handler" + run: | + mkdir -p data/acme_ca + sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem + sudo touch data/acme_srv.cfg + sudo chmod 777 data/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/acme_srv.cfg + sudo echo "handler_file: examples/ca_handler/asa_ca_handler.py" >> data/acme_srv.cfg + sudo echo "api_host: $ASA_API_HOST" >> data/acme_srv.cfg + sudo echo "api_user: $ASA_API_USER" >> data/acme_srv.cfg + sudo echo "api_password: $ASA_API_PASSWORD" >> data/acme_srv.cfg + sudo echo "api_key: $ASA_API_KEY" >> data/acme_srv.cfg + sudo echo "ca_name: $ASA_CA_NAME" >> data/acme_srv.cfg + sudo echo "ca_bundle: $ASA_CA_BUNDLE" >> data/acme_srv.cfg + sudo echo "profile_name: $ASA_PROFILE1" >> data/acme_srv.cfg + env: + ASA_API_HOST: ${{ secrets.ASA_API_HOST }} + ASA_API_USER: ${{ secrets.ASA_API_USER }} + ASA_API_PASSWORD: ${{ secrets.ASA_API_PASSWORD }} + ASA_API_KEY: ${{ secrets.ASA_API_KEY }} + ASA_CA_NAME: ${{ secrets.ASA_CA_NAME }} + ASA_CA_BUNDLE: ${{ secrets.ASA_CA_BUNDLE }} + ASA_PROFILE1: ${{ secrets.ASA_PROFILE1 }} + + - name: "[ PREPARE ] Almalinux instance" + run: | + cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd + + - name: "[ RUN ] Execute install scipt" + run: | + docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh + + - name: "Test http://acme-srv/directory is accessible" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "[ PREPARE ] prepare acme.sh container" + run: | + docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + + - name: "[ ENROLL ] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --keylength 2048 --debug 3 --output-insecure --force + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -text -noout + + #- name: "revoke via acme.sh" + # run: | + # docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure + + - name: "[ REGISTER ] certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email + + - name: "[ ENROLL ] HTTP-01 single domain certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot --key-type rsa --rsa-key-size 2048 + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem + sudo openssl x509 -in certbot/live/certbot/cert.pem -text -noout + + #- name: "revoke HTTP-01 single domain certbot" + # run: | + # docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot + + - name: "[ ENROLL ] lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --key-type rsa2048 --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + + #- name: "revoke HTTP-01 single domain lego" + # run: | + # docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke + + - name: "[ * ] collecting test logs" + if: ${{ failure() }} + run: | + mkdir -p ${{ github.workspace }}/artifact/upload + docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier + sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh + + - name: "[ * ] uploading artificates" + uses: actions/upload-artifact@v3 + if: ${{ failure() }} + with: + name: asa_handler_tests_rpm.tar.gz + path: ${{ github.workspace }}/artifact/upload/ \ No newline at end of file From e47c73817d4ffb7f0a0d2e0ab818aa0439ef159f Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 7 Jan 2024 08:03:59 +0100 Subject: [PATCH 005/460] [feat] envrioment variable support in asa_hanlder --- examples/ca_handler/asa_ca_handler.py | 81 +++++++++- test/test_asa_ca_handler.py | 205 ++++++++++++++++++++------ 2 files changed, 236 insertions(+), 50 deletions(-) diff --git a/examples/ca_handler/asa_ca_handler.py b/examples/ca_handler/asa_ca_handler.py index 0a3fd2ad..515dc456 100644 --- a/examples/ca_handler/asa_ca_handler.py +++ b/examples/ca_handler/asa_ca_handler.py @@ -2,6 +2,7 @@ """ Insta Active Security API handler""" from __future__ import print_function from typing import Tuple, Dict +import os import requests from requests.auth import HTTPBasicAuth # pylint: disable=C0209, E0401 @@ -83,16 +84,88 @@ def _auth_set(self): self.logger.error('CAhandler._auth_set(): auth information incomplete. Either "api_user" or "api_password" parameter is missing in config file') self.logger.debug('CAhandler._auth_set() ended') + def _config_host_load(self, config_dic: Dict[str, str]): + """ load hostname """ + self.logger.debug('_config_host_load()') + + api_host_variable = config_dic.get('api_host_variable') + if api_host_variable: + self.api_host = os.environ.get(api_host_variable) + if not self.api_host: + self.logger.error(f'CAhandler._config_host_load() could not load host_variable: {api_host_variable}') + + api_host = config_dic.get('api_host') + if api_host: + if self.api_host: + self.logger.info('CAhandler._config_host_load() overwrite api_host') + self.api_host = api_host + + self.logger.debug('_config_host_load() ended') + + def _config_key_load(self, config_dic: Dict[str, str]): + """ load keyname """ + self.logger.debug('_config_key_load()') + + api_key_variable = config_dic.get('api_key_variable') + if api_key_variable: + self.api_key = os.environ.get(api_key_variable) + if not self.api_key: + self.logger.error(f'CAhandler._config_key_load() could not load key_variable: {api_key_variable}') + + api_key = config_dic.get('api_key') + if api_key: + if self.api_key: + self.logger.info('CAhandler._config_key_load() overwrite api_key') + self.api_key = api_key + + self.logger.debug('_config_key_load() ended') + + def _config_password_load(self, config_dic: Dict[str, str]): + """ load passwordname """ + self.logger.debug('_config_password_load()') + + api_password_variable = config_dic.get('api_password_variable') + if api_password_variable: + self.api_password = os.environ.get(api_password_variable) + if not self.api_password: + self.logger.error(f'CAhandler._config_password_load() could not load password_variable: {api_password_variable}') + + api_password = config_dic.get('api_password') + if api_password: + if self.api_password: + self.logger.info('CAhandler._config_password_load() overwrite api_password') + self.api_password = api_password + + self.logger.debug('_config_password_load() ended') + + def _config_user_load(self, config_dic: Dict[str, str]): + """ load username """ + self.logger.debug('_config_user_load()') + + api_user_variable = config_dic.get('api_user_variable') + if api_user_variable: + self.api_user = os.environ.get(api_user_variable) + if not self.api_user: + self.logger.error(f'CAhandler._config_user_load() could not load user_variable: {api_user_variable}') + + api_user = config_dic.get('api_user') + if api_user: + if self.api_user: + self.logger.info('CAhandler._config_user_load() overwrite api_user') + self.api_user = api_user + + self.logger.debug('_config_user_load() ended') + def _config_load(self): """" load config from file """ self.logger.debug('CAhandler._config_load()') config_dic = load_config(self.logger, 'CAhandler') if 'CAhandler' in config_dic: - self.api_host = config_dic['CAhandler'].get('api_host') - self.api_user = config_dic['CAhandler'].get('api_user') - self.api_password = config_dic['CAhandler'].get('api_password') - self.api_key = config_dic['CAhandler'].get('api_key') + self._config_host_load(config_dic['CAhandler']) + self._config_user_load(config_dic['CAhandler']) + self._config_password_load(config_dic['CAhandler']) + self._config_key_load(config_dic['CAhandler']) self.ca_name = config_dic['CAhandler'].get('ca_name') self.profile_name = config_dic['CAhandler'].get('profile_name') diff --git a/test/test_asa_ca_handler.py b/test/test_asa_ca_handler.py index 7666ee55..d51fd25b 100644 --- a/test/test_asa_ca_handler.py +++ b/test/test_asa_ca_handler.py @@ -30,23 +30,23 @@ def test_001_default(self): self.assertEqual('foo', 'foo') @patch('examples.ca_handler.asa_ca_handler.CAhandler._config_load') - def test_055__enter__(self, mock_cfg): + def test_002__enter__(self, mock_cfg): """ test enter called """ mock_cfg.return_value = True self.cahandler.__enter__() self.assertTrue(mock_cfg.called) - def test_038_poll(self): + def test_003_poll(self): """ test polling """ self.assertEqual(('Method not implemented.', None, None, 'poll_identifier', False), self.cahandler.poll('cert_name', 'poll_identifier', 'csr')) - def test_039_trigger(self): + def test_004_trigger(self): """ test polling """ self.assertEqual(('Method not implemented.', None, None), self.cahandler.trigger('payload')) @patch('examples.ca_handler.asa_ca_handler.load_config') - def test_002_config_load(self, mock_config_load): + def test_005_config_load(self, mock_config_load): """ test _config_load """ mock_config_load.return_value = {'CAhandler': {'api_host': 'api_host'}} with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -64,7 +64,7 @@ def test_002_config_load(self, mock_config_load): self.assertEqual(30, self.cahandler.cert_validity_days) @patch('examples.ca_handler.asa_ca_handler.load_config') - def test_003_config_load(self, mock_config_load): + def test_006_config_load(self, mock_config_load): """ test _config_load """ mock_config_load.return_value = {'CAhandler': {'api_user': 'api_user'}} with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -82,7 +82,7 @@ def test_003_config_load(self, mock_config_load): self.assertEqual(30, self.cahandler.cert_validity_days) @patch('examples.ca_handler.asa_ca_handler.load_config') - def test_004_config_load(self, mock_config_load): + def test_007_config_load(self, mock_config_load): """ test _config_load """ mock_config_load.return_value = {'CAhandler': {'api_password': 'api_password'}} with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -100,7 +100,7 @@ def test_004_config_load(self, mock_config_load): self.assertEqual(30, self.cahandler.cert_validity_days) @patch('examples.ca_handler.asa_ca_handler.load_config') - def test_005_config_load(self, mock_config_load): + def test_008_config_load(self, mock_config_load): """ test _config_load """ mock_config_load.return_value = {'CAhandler': {'api_key': 'api_key'}} with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -118,7 +118,7 @@ def test_005_config_load(self, mock_config_load): self.assertEqual(30, self.cahandler.cert_validity_days) @patch('examples.ca_handler.asa_ca_handler.load_config') - def test_006_config_load(self, mock_config_load): + def test_009_config_load(self, mock_config_load): """ test _config_load """ mock_config_load.return_value = {'CAhandler': {'api_host': 'api_host', 'api_user': 'api_user', 'api_password': 'api_password', 'api_key': 'api_key'}} self.cahandler._config_load() @@ -131,7 +131,7 @@ def test_006_config_load(self, mock_config_load): self.assertEqual(30, self.cahandler.cert_validity_days) @patch('examples.ca_handler.asa_ca_handler.load_config') - def test_007_config_load(self, mock_config_load): + def test_010_config_load(self, mock_config_load): """ test _config_load """ mock_config_load.return_value = {'foo': 'bar'} with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -150,7 +150,7 @@ def test_007_config_load(self, mock_config_load): self.assertEqual(30, self.cahandler.cert_validity_days) @patch('examples.ca_handler.asa_ca_handler.load_config') - def test_008_config_load(self, mock_config_load): + def test_011_config_load(self, mock_config_load): """ test _config_load """ mock_config_load.return_value = {'CAhandler': {'request_timeout': 20}} with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -169,7 +169,7 @@ def test_008_config_load(self, mock_config_load): self.assertEqual(30, self.cahandler.cert_validity_days) @patch('examples.ca_handler.asa_ca_handler.load_config') - def test_008_config_load(self, mock_config_load): + def test_012_config_load(self, mock_config_load): """ test _config_load """ mock_config_load.return_value = {'CAhandler': {'request_timeout': 'aa'}} with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -189,7 +189,7 @@ def test_008_config_load(self, mock_config_load): self.assertEqual(30, self.cahandler.cert_validity_days) @patch('examples.ca_handler.asa_ca_handler.load_config') - def test_009_config_load(self, mock_config_load): + def test_013_config_load(self, mock_config_load): """ test _config_load """ mock_config_load.return_value = {'CAhandler': {'cert_validity_days': 10}} with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -209,7 +209,7 @@ def test_009_config_load(self, mock_config_load): self.assertEqual(10, self.cahandler.cert_validity_days) @patch('examples.ca_handler.asa_ca_handler.load_config') - def test_010_config_load(self, mock_config_load): + def test_014_config_load(self, mock_config_load): """ test _config_load """ mock_config_load.return_value = {'CAhandler': {'cert_validity_days': 'aa'}} with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -229,7 +229,7 @@ def test_010_config_load(self, mock_config_load): self.assertEqual(30, self.cahandler.cert_validity_days) @patch('examples.ca_handler.asa_ca_handler.load_config') - def test_011_config_load(self, mock_config_load): + def test_015_config_load(self, mock_config_load): """ test _config_load """ mock_config_load.return_value = {'CAhandler': {'ca_bundle': 'aa'}} with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -248,7 +248,7 @@ def test_011_config_load(self, mock_config_load): self.assertEqual(30, self.cahandler.cert_validity_days) @patch('examples.ca_handler.asa_ca_handler.load_config') - def test_012_config_load(self, mock_config_load): + def test_016_config_load(self, mock_config_load): """ test _config_load """ mock_config_load.return_value = {'CAhandler': {'ca_bundle': 'False'}} with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -267,7 +267,7 @@ def test_012_config_load(self, mock_config_load): self.assertEqual(30, self.cahandler.cert_validity_days) @patch.object(requests, 'post') - def test_013__api_post(self, mock_req): + def test_017__api_post(self, mock_req): """ test _api_post() """ mockresponse = Mock() mockresponse.status_code = 'status_code' @@ -276,7 +276,7 @@ def test_013__api_post(self, mock_req): self.assertEqual(('status_code', {'foo': 'bar'}), self.cahandler._api_post('url', 'data')) @patch('requests.post') - def test_014__api_post(self, mock_req): + def test_018__api_post(self, mock_req): """ test _api_post() """ mockresponse = Mock() mockresponse.status_code = 'status_code' @@ -287,7 +287,7 @@ def test_014__api_post(self, mock_req): self.assertIn("ERROR:test_a2c:CAhandler._api_post() returned error: 'str' object is not callable", lcm.output) @patch('requests.post') - def test_15__api_post(self, mock_req): + def test_019__api_post(self, mock_req): """ test _api_post(= """ self.cahandler.api_host = 'api_host' self.cahandler.auth = 'auth' @@ -297,7 +297,7 @@ def test_15__api_post(self, mock_req): self.assertIn('ERROR:test_a2c:CAhandler._api_post() returned error: exc_api_post', lcm.output) @patch.object(requests, 'get') - def test_016__api_get(self, mock_req): + def test_020__api_get(self, mock_req): """ test _api_get() """ mockresponse = Mock() mockresponse.status_code = 'status_code' @@ -306,7 +306,7 @@ def test_016__api_get(self, mock_req): self.assertEqual(('status_code', {'foo': 'bar'}), self.cahandler._api_get('url')) @patch('requests.get') - def test_018__api_get(self, mock_req): + def test_021__api_get(self, mock_req): """ test _api_get() """ mockresponse = Mock() mockresponse.status_code = 'status_code' @@ -317,7 +317,7 @@ def test_018__api_get(self, mock_req): self.assertIn("ERROR:test_a2c:CAhandler._api_get() returned error: 'str' object is not callable", lcm.output) @patch('requests.get') - def test_019__api_get(self, mock_req): + def test_022__api_get(self, mock_req): """ test _api_get() """ self.cahandler.api_host = 'api_host' self.cahandler.auth = 'auth' @@ -327,13 +327,13 @@ def test_019__api_get(self, mock_req): self.assertIn('ERROR:test_a2c:CAhandler._api_post() returned error: exc_api_get', lcm.output) @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_get') - def test_020__issuers_list(self, mock_get): + def test_023__issuers_list(self, mock_get): """ test _issuers_list()""" mock_get.return_value = (200, 'content') self.assertEqual('content', self.cahandler._issuers_list()) @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_get') - def test_021__profiles_list(self, mock_get): + def test_024__profiles_list(self, mock_get): """ test _profiles_list()""" self.cahandler.ca_name = 'ca_name' mock_get.return_value = (200, 'content') @@ -341,7 +341,7 @@ def test_021__profiles_list(self, mock_get): @patch('examples.ca_handler.asa_ca_handler.csr_san_get') @patch('examples.ca_handler.asa_ca_handler.csr_cn_get') - def test_022__csr_cn_get(self, mock_cn, mock_san): + def test_025__csr_cn_get(self, mock_cn, mock_san): """ test _csr_cn_get() """ mock_cn.return_value = 'cn' mock_san.return_value = ['san0', 'san1'] @@ -350,7 +350,7 @@ def test_022__csr_cn_get(self, mock_cn, mock_san): @patch('examples.ca_handler.asa_ca_handler.csr_san_get') @patch('examples.ca_handler.asa_ca_handler.csr_cn_get') - def test_023__csr_cn_get(self, mock_cn, mock_san): + def test_026__csr_cn_get(self, mock_cn, mock_san): """ test _csr_cn_get() """ mock_cn.return_value = None mock_san.return_value = ['dns:san0', 'dns:san1'] @@ -362,7 +362,7 @@ def test_023__csr_cn_get(self, mock_cn, mock_san): @patch('examples.ca_handler.asa_ca_handler.csr_san_get') @patch('examples.ca_handler.asa_ca_handler.csr_cn_get') - def test_024__csr_cn_get(self, mock_cn, mock_san): + def test_027__csr_cn_get(self, mock_cn, mock_san): """ test _csr_cn_get() """ mock_cn.return_value = None mock_san.return_value = None @@ -373,14 +373,14 @@ def test_024__csr_cn_get(self, mock_cn, mock_san): self.assertTrue(mock_san.called) @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuers_list') - def test_025_issuer_verify(self, mock_list): + def test_028_issuer_verify(self, mock_list): """ _issuer_verify() """ self.cahandler.ca_name = 'ca_name' mock_list.return_value = {'issuers': ['1', '2', 'ca_name']} self.assertFalse(self.cahandler._issuer_verify()) @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuers_list') - def test_026_issuer_verify(self, mock_list): + def test_029_issuer_verify(self, mock_list): """ _issuer_verify() """ self.cahandler.ca_name = 'ca_name' mock_list.return_value = {'issuers': ['1', '2', '3']} @@ -389,7 +389,7 @@ def test_026_issuer_verify(self, mock_list): self.assertIn('ERROR:test_a2c:CAhandler.enroll(): CA ca_name not found', lcm.output) @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuers_list') - def test_027_issuer_verify(self, mock_list): + def test_030_issuer_verify(self, mock_list): """ _issuer_verify() """ self.cahandler.ca_name = 'ca_name' mock_list.return_value = {'foo': 'bar'} @@ -398,14 +398,14 @@ def test_027_issuer_verify(self, mock_list): self.assertIn('ERROR:test_a2c:CAhandler.enroll(): "Malformed response. "issuers" key not found', lcm.output) @patch('examples.ca_handler.asa_ca_handler.CAhandler._profiles_list') - def test_025_profile_verify(self, mock_list): + def test_031_profile_verify(self, mock_list): """ _profile_verify() """ self.cahandler.profile_name = 'profile_name' mock_list.return_value = {'profiles': ['1', '2', 'profile_name']} self.assertFalse(self.cahandler._profile_verify()) @patch('examples.ca_handler.asa_ca_handler.CAhandler._profiles_list') - def test_026_profile_verify(self, mock_list): + def test_032_profile_verify(self, mock_list): """ _profile_verify() """ self.cahandler.profile_name = 'profile_name' mock_list.return_value = {'profiles': ['1', '2', '3']} @@ -414,7 +414,7 @@ def test_026_profile_verify(self, mock_list): self.assertIn('ERROR:test_a2c:CAhandler.enroll(): Profile profile_name not found', lcm.output) @patch('examples.ca_handler.asa_ca_handler.CAhandler._profiles_list') - def test_027_profile_verify(self, mock_list): + def test_033_profile_verify(self, mock_list): """ _profile_verify() """ self.cahandler.ca_name = 'ca_name' mock_list.return_value = {'foo': 'bar'} @@ -424,7 +424,7 @@ def test_027_profile_verify(self, mock_list): @patch('examples.ca_handler.asa_ca_handler.uts_to_date_utc') @patch('examples.ca_handler.asa_ca_handler.uts_now') - def test_028__validity_dates_get(self, mock_now, mock_utc): + def test_034__validity_dates_get(self, mock_now, mock_utc): """ test _validity_dates_get() """ mock_now.return_value = 10 mock_utc.side_effect = ['date1', 'date2'] @@ -434,12 +434,12 @@ def test_028__validity_dates_get(self, mock_now, mock_utc): @patch('examples.ca_handler.asa_ca_handler.convert_byte_to_string') @patch('examples.ca_handler.asa_ca_handler.cert_der2pem') @patch('examples.ca_handler.asa_ca_handler.b64_decode') - def test_029__pem_cert_chain_generate(self, mock_dec, mock_d2p, mock_b2s): + def test_035__pem_cert_chain_generate(self, mock_dec, mock_d2p, mock_b2s): """ test _pem_cert_chain_generate() """ mock_b2s.return_value = 'cert' self.assertEqual('certcert', self.cahandler._pem_cert_chain_generate(['cert', 'chain'])) - def test_030__pem_cert_chain_generate(self): + def test_036__pem_cert_chain_generate(self): """ test _pem_cert_chain_generate() """ cert_list = ['MIIF7DCCBFSgAwIBAgIKB/8cQ9wAI3UbITANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJERTERMA8GA1UECgwIT3BlblhQS0kxDDAKBgNVBAsMA1BLSTEqMCgGA1UEAwwhT3BlblhQS0kgRGVtbyBJc3N1aW5nIENBIDIwMjMwMjA0MB4XDTIzMDIwNTA2NDY0MloXDTI0MDIwNTA2NDY0MlowazETMBEGCgmSJomT8ixkARkWA29yZzEYMBYGCgmSJomT8ixkARkWCE9wZW5YUEtJMR8wHQYKCZImiZPyLGQBGRYPVGVzdCBEZXBsb3ltZW50MRkwFwYDVQQDDBBhY21lMS5keW5hbW9wLmRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAre1jtb8Xjqr49QH3fWe2kH+yDk3NXfxHyOmKcNcBke68WMRB5Irrdj15JfAsXxu9psLVEOJgvdOLOnUbhN57uBLHwMAC1LH6HruYuCqtbaSezgJIYIEACvtQmIy6BIvigqwX31eLkA7kk7YXeJCnvrr461t/uZkhmaXZM9+G4asSj6fT0ffA7OVVqewDdE+d2VgCjPlH9uqPMOVK2m/AQj+jEVV/IV2znngZmkAsmYi6h2Wg08vEzTMyvhZIEma3xo6M9g9VIsTQP/ETxxhAAgzEQ0Jlz90rOioZK7mkx8xH1fLlhyfX53vqcEbva5evy1YMGEs0XZPYu2B6Oya9WQIDAQABo4ICITCCAh0wgYcGCCsGAQUFBwEBBHsweTBRBggrBgEFBQcwAoZFaHR0cDovL3BraS5leGFtcGxlLmNvbS9kb3dubG9hZC9PcGVuWFBLSV9EZW1vX0lzc3VpbmdfQ0FfMjAyMzAyMDQuY2VyMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5leGFtcGxlLmNvbS8wHwYDVR0jBBgwFoAU0f8PWcniVXltJeA6q7wYtyJrNFAwDAYDVR0TAQH/BAIwADBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vcGtpLmV4YW1wbGUuY29tL2Rvd25sb2FkL09wZW5YUEtJX0RlbW9fSXNzdWluZ19DQV8yMDIzMDIwNC5jcmwwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDgYDVR0PAQH/BAQDAgWgMIGoBgNVHSAEgaAwgZ0wgZoGAyoDBDCBkjArBggrBgEFBQcCARYfaHR0cDovL3BraS5leGFtcGxlLmNvbS9jcHMuaHRtbDArBggrBgEFBQcCARYfaHR0cDovL3BraS5leGFtcGxlLmNvbS9jcHMuaHRtbDA2BggrBgEFBQcCAjAqGihUaGlzIGlzIGEgY29tbWVudCBmb3IgcG9saWN5IG9pZCAxLjIuMy40MBsGA1UdEQQUMBKCEGFjbWUxLmR5bmFtb3AuZGUwHQYDVR0OBBYEFA3AUTV0pg0fsd3Cd6/BskOEB9MVMA0GCSqGSIb3DQEBCwUAA4IBgQB0xnnl6BJDXrbTQr7TdkRPmcCDFUmi8aVTYozbQ8EKxIYEPsfzxOFbSG/wn+4Sjz7HqvzqxyisfTopqWrvpqIhlXOEFMnNYTDO4LzCd81Dcs4czjoIRxRTisgNCvWR9hbeH9HzdRT1UF/c4VxxLEONSsGHksoXa+G4u7XmPwD4dTUIP49Mmj2a28z/viG8KftcjAEo1S7OB+/xyPeVDYrgagMR31a69pI+yuQa0J66O/LJQrzjWf6wHToQErQPcEBtDxY2wx3hROMtdla9lUEU8XLb3e9zByZwOfDhFpw8iYkJx/BUZlsmIKaZSpYVS+0D5LI1R5PENhT/2gRxaA31RiNLK/E8CSU7MMadqImkFLkDHU2x+2SRENwvoOEUAOewjVlhB1pK0r5WEye2lBjl8cUa+8qhIrAOqggApQ7eCQq7v2bL08VxKz5baOhKfLZ9u4MH6q52pnqXmll0W7JXrJSbam5r3YoSelm94VwVyaSkfd+LT4YMAP7GDDvtT6Y='] result = """-----BEGIN CERTIFICATE----- @@ -481,7 +481,7 @@ def test_030__pem_cert_chain_generate(self): @patch('examples.ca_handler.asa_ca_handler.CAhandler._pem_cert_chain_generate') @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_get') - def test_031___issuer_chain_get(self, mock_req, mock_pem): + def test_037___issuer_chain_get(self, mock_req, mock_pem): """ test _issuer_chain_get() """ mock_req.return_value = ('code', {'certs': ['bar', 'foo']}) mock_pem.return_value = 'issuer_chain' @@ -491,7 +491,7 @@ def test_031___issuer_chain_get(self, mock_req, mock_pem): @patch('examples.ca_handler.asa_ca_handler.CAhandler._pem_cert_chain_generate') @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_get') - def test_032___issuer_chain_get(self, mock_req, mock_pem): + def test_038___issuer_chain_get(self, mock_req, mock_pem): """ test _issuer_chain_get() """ mock_req.return_value = ('code', {'foobar': ['bar', 'foo']}) mock_pem.return_value = 'issuer_chain' @@ -510,7 +510,7 @@ def test_032___issuer_chain_get(self, mock_req, mock_pem): @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_chain_get') @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_verify') @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_verify') - def test_033_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_csbg, mock_b64, mock_d2p, mock_b2s, mock_post): + def test_039_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_csbg, mock_b64, mock_d2p, mock_b2s, mock_post): """ test enroll() """ mock_iv.return_value = None mock_pv.return_value = None @@ -542,7 +542,7 @@ def test_033_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vd @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_chain_get') @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_verify') @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_verify') - def test_034_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_csbg, mock_b64, mock_d2p, mock_b2s, mock_post): + def test_040_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_csbg, mock_b64, mock_d2p, mock_b2s, mock_post): """ test enroll() """ mock_iv.return_value = 'mock_iv' mock_pv.return_value = None @@ -574,7 +574,7 @@ def test_034_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vd @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_chain_get') @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_verify') @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_verify') - def test_035_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_csbg, mock_b64, mock_d2p, mock_b2s, mock_post): + def test_041_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_csbg, mock_b64, mock_d2p, mock_b2s, mock_post): """ test enroll() """ mock_iv.return_value = None mock_pv.return_value = 'mock_pv' @@ -606,7 +606,7 @@ def test_035_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vd @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_chain_get') @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_verify') @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_verify') - def test_036_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_csbg, mock_b64, mock_d2p, mock_b2s, mock_post): + def test_042_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_csbg, mock_b64, mock_d2p, mock_b2s, mock_post): """ test enroll() """ mock_iv.return_value = None mock_pv.return_value = None @@ -638,7 +638,7 @@ def test_036_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vd @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_chain_get') @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_verify') @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_verify') - def test_037_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_csbg, mock_b64, mock_d2p, mock_b2s, mock_post): + def test_043_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_csbg, mock_b64, mock_d2p, mock_b2s, mock_post): """ test enroll() """ mock_iv.return_value = None mock_pv.return_value = None @@ -664,7 +664,7 @@ def test_037_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vd @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_post') @patch('examples.ca_handler.asa_ca_handler.cert_serial_get') - def test_039_revoke(self, mock_serial, mock_post): + def test_044_revoke(self, mock_serial, mock_post): """ test revoke() """ self.cahandler.ca_name = 'ca_name' mock_serial.return_value = 'serial' @@ -675,7 +675,7 @@ def test_039_revoke(self, mock_serial, mock_post): @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_post') @patch('examples.ca_handler.asa_ca_handler.cert_serial_get') - def test_040_revoke(self, mock_serial, mock_post): + def test_045_revoke(self, mock_serial, mock_post): """ test revoke() """ self.cahandler.ca_name = 'ca_name' mock_serial.return_value = 'serial' @@ -686,7 +686,7 @@ def test_040_revoke(self, mock_serial, mock_post): @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_post') @patch('examples.ca_handler.asa_ca_handler.cert_serial_get') - def test_041_revoke(self, mock_serial, mock_post): + def test_046_revoke(self, mock_serial, mock_post): """ test revoke() """ self.cahandler.ca_name = 'ca_name' mock_serial.return_value = 'serial' @@ -697,7 +697,7 @@ def test_041_revoke(self, mock_serial, mock_post): @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_post') @patch('examples.ca_handler.asa_ca_handler.cert_serial_get') - def test_042_revoke(self, mock_serial, mock_post): + def test_047_revoke(self, mock_serial, mock_post): """ test revoke() """ self.cahandler.ca_name = 'ca_name' mock_serial.return_value = 'serial' @@ -706,6 +706,119 @@ def test_042_revoke(self, mock_serial, mock_post): self.assertTrue(mock_serial.called) self.assertTrue(mock_post.called) + @patch.dict('os.environ', {'api_user_var': 'user_var'}) + def test_048_config_user_load(self): + """ test _config_load - load template with user variable """ + config_dic = {'api_user_variable': 'api_user_var'} + self.cahandler._config_user_load(config_dic) + self.assertEqual('user_var', self.cahandler.api_user) + self.assertFalse(self.cahandler.profile_name) + + @patch.dict('os.environ', {'api_user_var': 'user_var'}) + def test_049_config_user_load(self): + """ test _config_load - load template with user variable """ + config_dic = {'api_user_variable': 'does_not_exist'} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.cahandler._config_user_load(config_dic) + self.assertFalse(self.cahandler.api_user) + self.assertIn('ERROR:test_a2c:CAhandler._config_user_load() could not load user_variable: does_not_exist', lcm.output) + self.assertFalse(self.cahandler.profile_name) + + @patch.dict('os.environ', {'api_user_var': 'user_var'}) + def test_050_config_user_load(self): + """ test _config_load - load template with user variable """ + config_dic = {'api_user_variable': 'api_user_var', 'api_user': 'api_user'} + self.cahandler._config_user_load(config_dic) + # with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertEqual('api_user', self.cahandler.api_user) + # self.assertIn("foo", lcm.output) + self.assertFalse(self.cahandler.profile_name) + + @patch.dict('os.environ', {'api_host_var': 'host_var'}) + def test_051_config_host_load(self): + """ test _config_load - load template with host variable """ + config_dic = {'api_host_variable': 'api_host_var'} + self.cahandler._config_host_load(config_dic) + self.assertEqual('host_var', self.cahandler.api_host) + self.assertFalse(self.cahandler.profile_name) + + @patch.dict('os.environ', {'api_host_var': 'host_var'}) + def test_052_config_host_load(self): + """ test _config_load - load template with host variable """ + config_dic = {'api_host_variable': 'does_not_exist'} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.cahandler._config_host_load(config_dic) + self.assertFalse(self.cahandler.api_host) + self.assertIn('ERROR:test_a2c:CAhandler._config_host_load() could not load host_variable: does_not_exist', lcm.output) + self.assertFalse(self.cahandler.profile_name) + + @patch.dict('os.environ', {'api_host_var': 'host_var'}) + def test_053_config_host_load(self): + """ test _config_load - load template with host variable """ + config_dic = {'api_host_variable': 'api_host_var', 'api_host': 'api_host'} + self.cahandler._config_host_load(config_dic) + # with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertEqual('api_host', self.cahandler.api_host) + # self.assertIn("foo", lcm.output) + self.assertFalse(self.cahandler.profile_name) + + @patch.dict('os.environ', {'api_key_var': 'key_var'}) + def test_054_config_key_load(self): + """ test _config_load - load template with key variable """ + config_dic = {'api_key_variable': 'api_key_var'} + self.cahandler._config_key_load(config_dic) + self.assertEqual('key_var', self.cahandler.api_key) + self.assertFalse(self.cahandler.profile_name) + + @patch.dict('os.environ', {'api_key_var': 'key_var'}) + def test_055_config_key_load(self): + """ test _config_load - load template with key variable """ + config_dic = {'api_key_variable': 'does_not_exist'} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.cahandler._config_key_load(config_dic) + self.assertFalse(self.cahandler.api_key) + self.assertIn('ERROR:test_a2c:CAhandler._config_key_load() could not load key_variable: does_not_exist', lcm.output) + self.assertFalse(self.cahandler.profile_name) + + @patch.dict('os.environ', {'api_key_var': 'key_var'}) + def test_056_config_key_load(self): + """ test _config_load - load template with key variable """ + config_dic = {'api_key_variable': 'api_key_var', 'api_key': 'api_key'} + self.cahandler._config_key_load(config_dic) + # with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertEqual('api_key', self.cahandler.api_key) + # self.assertIn("foo", lcm.output) + self.assertFalse(self.cahandler.profile_name) + + @patch.dict('os.environ', {'api_password_var': 'password_var'}) + def test_057_config_password_load(self): + """ test _config_load - load template with password variable """ + config_dic = {'api_password_variable': 'api_password_var'} + self.cahandler._config_password_load(config_dic) + self.assertEqual('password_var', self.cahandler.api_password) + self.assertFalse(self.cahandler.profile_name) + + @patch.dict('os.environ', {'api_password_var': 'password_var'}) + def test_058_config_password_load(self): + """ test _config_load - load template with password variable """ + config_dic = {'api_password_variable': 'does_not_exist'} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.cahandler._config_password_load(config_dic) + self.assertFalse(self.cahandler.api_password) + self.assertIn('ERROR:test_a2c:CAhandler._config_password_load() could not load password_variable: does_not_exist', lcm.output) + self.assertFalse(self.cahandler.profile_name) + + @patch.dict('os.environ', {'api_password_var': 'password_var'}) + def test_059_config_password_load(self): + """ test _config_load - load template with password variable """ + config_dic = {'api_password_variable': 'api_password_var', 'api_password': 'api_password'} + self.cahandler._config_password_load(config_dic) + # with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertEqual('api_password', self.cahandler.api_password) + # self.assertIn("foo", lcm.output) + self.assertFalse(self.cahandler.profile_name) + + if __name__ == '__main__': unittest.main() From 881e53dffe169be1fbad1d06bbb507c03ed65b7b Mon Sep 17 00:00:00 2001 From: grindsa Date: Mon, 8 Jan 2024 14:10:43 +0100 Subject: [PATCH 006/460] [feat] get SKI for asa_handler.py --- acme_srv/helper.py | 11 +++++++++++ examples/ca_handler/asa_ca_handler.py | 9 +++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/acme_srv/helper.py b/acme_srv/helper.py index 7104688a..5744cfbf 100644 --- a/acme_srv/helper.py +++ b/acme_srv/helper.py @@ -289,6 +289,17 @@ def cert_san_get(logger: logging.Logger, certificate: str, recode: bool = True) logger.debug('cert_san_get() ended') return sans +def cert_ski_get(logger: logging.Logger, certificate: str) -> str: + """ get subject key identifier from certificate """ + logger.debug('cert_ski_get()') + cert = cert_load(logger, certificate, recode=True) + extensions = cert.extensions + print(extensions) + #ski = cert.extensions.get_extension_for_oid(x509.OID_SUBJECT_KEY_IDENTIFIER) + #ski = ski.value.digest.hex() + #logger.debug('cert_ski_get() ended with: {0}'.format(ski)) + #return ski + def cert_extensions_get(logger: logging.Logger, certificate: str, recode: bool = True): """ get extenstions from certificate certificate """ diff --git a/examples/ca_handler/asa_ca_handler.py b/examples/ca_handler/asa_ca_handler.py index 515dc456..1fb3c59a 100644 --- a/examples/ca_handler/asa_ca_handler.py +++ b/examples/ca_handler/asa_ca_handler.py @@ -6,7 +6,7 @@ import requests from requests.auth import HTTPBasicAuth # pylint: disable=C0209, E0401 -from acme_srv.helper import load_config, encode_url, csr_pubkey_get, csr_cn_get, csr_san_get, csr_san_byte_get, uts_now, uts_to_date_utc, b64_decode, cert_der2pem, convert_byte_to_string, cert_serial_get +from acme_srv.helper import load_config, encode_url, csr_pubkey_get, csr_cn_get, csr_san_get, csr_san_byte_get, uts_now, uts_to_date_utc, b64_decode, cert_der2pem, convert_byte_to_string, cert_serial_get, cert_ski_get class CAhandler(object): @@ -252,7 +252,7 @@ def _profiles_list(self): def _profile_verify(self) -> str: """ verify profile """ - self.logger.debug('CAhandler._profile_verify()') + self.logger.debug('CAhandler._profile_verify({0})'.format(self.profile_name)) api_response = self._profiles_list() if 'profiles' in api_response: @@ -402,6 +402,11 @@ def revoke(self, cert: str, _rev_reason: str = 'unspecified', _rev_date: str = u detail = None cert_serial = cert_serial_get(self.logger, cert, hexformat=True) # get serial number from certificate + + cert_ski = cert_ski_get(self.logger, cert) # get subjectKeyIdentifier from certificate + + print(cert_ski) + sys.exit(0) url = '{0}/revoke_certificate?issuerName={1}&certificateId={2}'.format(self.api_host, encode_url(self.logger, self.ca_name), cert_serial) data_dic = {} code, content_dic = self._api_post(url, data_dic) From e0e2999cf033703200e10856f52f0122e5b20ac2 Mon Sep 17 00:00:00 2001 From: grindsa Date: Mon, 8 Jan 2024 15:15:24 +0100 Subject: [PATCH 007/460] [wf] enrollment-timeout and profile support in asa workflow --- .github/workflows/ca_handler_tests_asa.yml | 143 ++++++++++++++++++++- docs/asa.md | 8 ++ 2 files changed, 145 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ca_handler_tests_asa.yml b/.github/workflows/ca_handler_tests_asa.yml index a4d26f0d..ec5d14ef 100644 --- a/.github/workflows/ca_handler_tests_asa.yml +++ b/.github/workflows/ca_handler_tests_asa.yml @@ -47,6 +47,7 @@ jobs: sudo echo "ca_name: $ASA_CA_NAME" >> examples/Docker/data/acme_srv.cfg sudo echo "ca_bundle: $ASA_CA_BUNDLE" >> examples/Docker/data/acme_srv.cfg sudo echo "profile_name: $ASA_PROFILE1" >> examples/Docker/data/acme_srv.cfg + sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout:15/g" examples/Docker/data/acme_srv.cfg cd examples/Docker/ docker-compose restart docker-compose logs @@ -71,7 +72,8 @@ jobs: docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --keylength 2048 --debug 3 --output-insecure --force awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer - openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature" + # openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -text -noout #- name: "revoke via acme.sh" # run: | @@ -85,7 +87,8 @@ jobs: run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot --key-type rsa --rsa-key-size 2048 sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem - sudo openssl x509 -in certbot/live/certbot/cert.pem -text -noout + sudo openssl x509 -in certbot/live/certbot/cert.pem -ext keyUsage -noout | grep "Digital Signature" + # sudo openssl x509 -in certbot/live/certbot/cert.pem -text -noout #- name: "revoke HTTP-01 single domain certbot" # run: | @@ -95,12 +98,75 @@ jobs: run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --key-type rsa2048 --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext keyUsage -noout | grep "Digital Signature" + # sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout #- name: "revoke HTTP-01 single domain lego" # run: | # docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke + - name: "[ PREPARE ] reconfiguration of a2c with asa_ca_handler" + run: | + sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem + sudo touch examples/Docker/data/acme_srv.cfg + sudo chmod 777 examples/Docker/data/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg + sudo echo "handler_file: examples/ca_handler/asa_ca_handler.py" >> examples/Docker/data/acme_srv.cfg + sudo echo "api_host: $ASA_API_HOST" >> examples/Docker/data/acme_srv.cfg + sudo echo "api_user: $ASA_API_USER" >> examples/Docker/data/acme_srv.cfg + sudo echo "api_password: $ASA_API_PASSWORD" >> examples/Docker/data/acme_srv.cfg + sudo echo "api_key: $ASA_API_KEY" >> examples/Docker/data/acme_srv.cfg + sudo echo "ca_name: $ASA_CA_NAME" >> examples/Docker/data/acme_srv.cfg + sudo echo "ca_bundle: $ASA_CA_BUNDLE" >> examples/Docker/data/acme_srv.cfg + sudo echo "profile_name: $ASA_PROFILE2" >> examples/Docker/data/acme_srv.cfg + sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout:15/g" examples/Docker/data/acme_srv.cfg + cd examples/Docker/ + docker-compose restart + docker-compose logs + env: + ASA_API_HOST: ${{ secrets.ASA_API_HOST }} + ASA_API_USER: ${{ secrets.ASA_API_USER }} + ASA_API_PASSWORD: ${{ secrets.ASA_API_PASSWORD }} + ASA_API_KEY: ${{ secrets.ASA_API_KEY }} + ASA_CA_NAME: ${{ secrets.ASA_CA_NAME }} + ASA_CA_BUNDLE: ${{ secrets.ASA_CA_BUNDLE }} + ASA_PROFILE2: ${{ secrets.ASA_PROFILE2 }} + + - name: "[ ENROLL ] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --keylength 2048 --debug 3 --output-insecure --force + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext keyUsage -noout | grep "Key Encipherment, Data Encipherment" + # openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -text -noout + + #- name: "revoke via acme.sh" + # run: | + # docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure + + - name: "[ ENROLL ] HTTP-01 single domain certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot --force-renewal --key-type rsa --rsa-key-size 2048 + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem + sudo openssl x509 -in certbot/live/certbot/cert.pem -ext keyUsage -noout | grep "Key Encipherment, Data Encipherment" + # sudo openssl x509 -in certbot/live/certbot/cert.pem -text -noout + + #- name: "revoke HTTP-01 single domain certbot" + # run: | + # docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot + + - name: "[ ENROLL ] lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --key-type rsa2048 --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext keyUsage -noout | grep "Key Encipherment, Data Encipherment" + # sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + + #- name: "revoke HTTP-01 single domain lego" + # run: | + # docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke + + - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | @@ -175,6 +241,7 @@ jobs: sudo echo "ca_name: $ASA_CA_NAME" >> data/acme_srv.cfg sudo echo "ca_bundle: $ASA_CA_BUNDLE" >> data/acme_srv.cfg sudo echo "profile_name: $ASA_PROFILE1" >> data/acme_srv.cfg + sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout:15/g" data/acme_srv.cfg env: ASA_API_HOST: ${{ secrets.ASA_API_HOST }} ASA_API_USER: ${{ secrets.ASA_API_USER }} @@ -205,7 +272,8 @@ jobs: docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --keylength 2048 --debug 3 --output-insecure --force awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer - openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature" + # openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -text -noout #- name: "revoke via acme.sh" # run: | @@ -219,7 +287,69 @@ jobs: run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot --key-type rsa --rsa-key-size 2048 sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem - sudo openssl x509 -in certbot/live/certbot/cert.pem -text -noout + sudo openssl x509 -in certbot/live/certbot/cert.pem -ext keyUsage -noout | grep "Digital Signature" + # sudo openssl x509 -in certbot/live/certbot/cert.pem -text -noout + + #- name: "revoke HTTP-01 single domain certbot" + # run: | + # docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot + + - name: "[ ENROLL ] lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --key-type rsa2048 --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext keyUsage -noout | grep "Digital Signature" + # sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + + #- name: "revoke HTTP-01 single domain lego" + # run: | + # docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke + + - name: "[ PREPARE ] prepare acme_srv.cfg with certifier_ca_handler" + run: | + sudo touch data/acme_srv.cfg + sudo chmod 777 data/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/acme_srv.cfg + sudo echo "handler_file: examples/ca_handler/asa_ca_handler.py" >> data/acme_srv.cfg + sudo echo "api_host: $ASA_API_HOST" >> data/acme_srv.cfg + sudo echo "api_user: $ASA_API_USER" >> data/acme_srv.cfg + sudo echo "api_password: $ASA_API_PASSWORD" >> data/acme_srv.cfg + sudo echo "api_key: $ASA_API_KEY" >> data/acme_srv.cfg + sudo echo "ca_name: $ASA_CA_NAME" >> data/acme_srv.cfg + sudo echo "ca_bundle: $ASA_CA_BUNDLE" >> data/acme_srv.cfg + sudo echo "profile_name: $ASA_PROFILE2" >> data/acme_srv.cfg + sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout:15/g" data/acme_srv.cfg + env: + ASA_API_HOST: ${{ secrets.ASA_API_HOST }} + ASA_API_USER: ${{ secrets.ASA_API_USER }} + ASA_API_PASSWORD: ${{ secrets.ASA_API_PASSWORD }} + ASA_API_KEY: ${{ secrets.ASA_API_KEY }} + ASA_CA_NAME: ${{ secrets.ASA_CA_NAME }} + ASA_CA_BUNDLE: ${{ secrets.ASA_CA_BUNDLE }} + ASA_PROFILE2: ${{ secrets.ASA_PROFILE2 }} + + - name: "[ PREPARE ] reconfigure a2c " + run: | + docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart + + - name: "[ ENROLL ] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --keylength 2048 --debug 3 --output-insecure --force + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext keyUsage -noout | grep "Key Encipherment, Data Encipherment" + # openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -text -noout + + #- name: "revoke via acme.sh" + # run: | + # docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure + + - name: "[ ENROLL ] HTTP-01 single domain certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot --force-renewal --key-type rsa --rsa-key-size 2048 + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem + sudo openssl x509 -in certbot/live/certbot/cert.pem -ext keyUsage -noout | grep "Key Encipherment, Data Encipherment" + # sudo openssl x509 -in certbot/live/certbot/cert.pem -text -noout #- name: "revoke HTTP-01 single domain certbot" # run: | @@ -229,7 +359,8 @@ jobs: run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --key-type rsa2048 --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext keyUsage -noout | grep "Key Encipherment, Data Encipherment" + # sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout #- name: "revoke HTTP-01 single domain lego" # run: | diff --git a/docs/asa.md b/docs/asa.md index 6f8e9f79..7ed70cc2 100644 --- a/docs/asa.md +++ b/docs/asa.md @@ -37,6 +37,14 @@ cert_validity_days: - profile_name - profile name - cert_validity_days - optional - polling timeout (default: 60s) + +It is also recommended to increase the enrollment timeout to avoid that acme2certifier is closing the connection to early. + +```config +[Certificate] +enrollment_timeout:15 +``` + You can get the list of certificate authrities by running the following REST call against ASA. ```bash From d9f6ad29dd2275381c3b3439c27272337b3dbed5 Mon Sep 17 00:00:00 2001 From: grindsa Date: Mon, 8 Jan 2024 16:46:58 +0100 Subject: [PATCH 008/460] [doc] md linting in asa.md --- docs/asa.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/asa.md b/docs/asa.md index 7ed70cc2..0ac80d70 100644 --- a/docs/asa.md +++ b/docs/asa.md @@ -37,7 +37,6 @@ cert_validity_days: - profile_name - profile name - cert_validity_days - optional - polling timeout (default: 60s) - It is also recommended to increase the enrollment timeout to avoid that acme2certifier is closing the connection to early. ```config From b9c13be328a896393e80f142b04467add0966f0c Mon Sep 17 00:00:00 2001 From: grindsa Date: Mon, 8 Jan 2024 16:55:38 +0100 Subject: [PATCH 009/460] [fix] cert_ski_get() in helper.py --- acme_srv/helper.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/acme_srv/helper.py b/acme_srv/helper.py index 5744cfbf..19754980 100644 --- a/acme_srv/helper.py +++ b/acme_srv/helper.py @@ -289,16 +289,17 @@ def cert_san_get(logger: logging.Logger, certificate: str, recode: bool = True) logger.debug('cert_san_get() ended') return sans + def cert_ski_get(logger: logging.Logger, certificate: str) -> str: """ get subject key identifier from certificate """ logger.debug('cert_ski_get()') + cert = cert_load(logger, certificate, recode=True) - extensions = cert.extensions - print(extensions) - #ski = cert.extensions.get_extension_for_oid(x509.OID_SUBJECT_KEY_IDENTIFIER) - #ski = ski.value.digest.hex() - #logger.debug('cert_ski_get() ended with: {0}'.format(ski)) - #return ski + ski = cert.extensions.get_extension_for_oid(x509.OID_SUBJECT_KEY_IDENTIFIER) + ski = ski.value.digest.hex() + + logger.debug('cert_ski_get() ended with: {0}'.format(ski)) + return ski def cert_extensions_get(logger: logging.Logger, certificate: str, recode: bool = True): From f14995d475125338a908a8eadc3f5dff47f0430b Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 13 Jan 2024 08:18:37 +0100 Subject: [PATCH 010/460] [fix] revocation support in asa_ca_handler --- acme_srv/helper.py | 33 +++++++++++++++++---- examples/ca_handler/asa_ca_handler.py | 42 ++++++++++++++++++++------- 2 files changed, 59 insertions(+), 16 deletions(-) diff --git a/acme_srv/helper.py b/acme_srv/helper.py index 19754980..57fa1f28 100644 --- a/acme_srv/helper.py +++ b/acme_srv/helper.py @@ -289,17 +289,40 @@ def cert_san_get(logger: logging.Logger, certificate: str, recode: bool = True) logger.debug('cert_san_get() ended') return sans +def cert_ski_pyopenssl_cert(logger, certificate: str) -> str: + """Get Subject Key Identifier from a certificate as a hex string.""" + logger.debug('cert_ski_pyopenssl_cert()') + from OpenSSL import crypto + pem_data = convert_string_to_byte(build_pem_file(logger, None, b64_url_recode(logger, certificate), True)) + cert = crypto.load_certificate(crypto.FILETYPE_PEM, pem_data) + # Get the SKI extension + ski = None + for i in range(cert.get_extension_count()): + ext = cert.get_extension(i) + if 'subjectKeyIdentifier' in str(ext.get_short_name()): + ski = ext + + if ski is None: + raise ValueError("No SKI found in certificate") + + # Get the SKI value and convert it to hex + ski_hex = ski.get_data()[2:].hex() + logger.debug('cert_ski_pyopenssl_cert() ended with: {0}'.format(ski_hex)) + return ski_hex def cert_ski_get(logger: logging.Logger, certificate: str) -> str: """ get subject key identifier from certificate """ logger.debug('cert_ski_get()') cert = cert_load(logger, certificate, recode=True) - ski = cert.extensions.get_extension_for_oid(x509.OID_SUBJECT_KEY_IDENTIFIER) - ski = ski.value.digest.hex() - - logger.debug('cert_ski_get() ended with: {0}'.format(ski)) - return ski + try: + ski = cert.extensions.get_extension_for_oid(x509.OID_SUBJECT_KEY_IDENTIFIER) + ski_value = ski.value.digest.hex() + except Exception as err: + logger.error('cert_ski_get(): Error: {0}'.format(err)) + ski_value = cert_ski_pyopenssl_cert(logger, certificate) + logger.debug('cert_ski_get() ended with: {0}'.format(ski_value)) + return ski_value def cert_extensions_get(logger: logging.Logger, certificate: str, recode: bool = True): diff --git a/examples/ca_handler/asa_ca_handler.py b/examples/ca_handler/asa_ca_handler.py index 1fb3c59a..cf8e8ba5 100644 --- a/examples/ca_handler/asa_ca_handler.py +++ b/examples/ca_handler/asa_ca_handler.py @@ -63,11 +63,14 @@ def _api_post(self, url: str, data: Dict[str, str]) -> Dict[str, str]: try: api_response = requests.post(url=url, headers=headers, json=data, auth=self.auth, verify=self.ca_bundle, proxies=self.proxy, timeout=self.request_timeout) code = api_response.status_code - try: - content = api_response.json() - except Exception as err_: - self.logger.error('CAhandler._api_post() returned error: {0}'.format(err_)) - content = str(err_) + if api_response.text: + try: + content = api_response.json() + except Exception as err_: + self.logger.error('CAhandler._api_post() returned error: {0}'.format(err_)) + content = str(err_) + else: + content = None except Exception as err_: self.logger.error('CAhandler._api_post() returned error: {0}'.format(err_)) code = 500 @@ -102,6 +105,16 @@ def _config_host_load(self, config_dic: Dict[str, str]): self.logger.debug('_config_host_load() ended') + def _certificates_list(self) -> Dict[str, str]: + """ list profiles """ + self.logger.debug('CAhandler._certificates_list()') + + url = '{0}/list_certificates?issuerName={1}'.format(self.api_host, encode_url(self.logger, self.ca_name)) + _code, api_response = self._api_get(url) + + self.logger.debug('CAhandler._certificates_list() ended') + return api_response + def _config_key_load(self, config_dic: Dict[str, str]): """ load keyname """ self.logger.debug('_config_key_load()') @@ -230,7 +243,7 @@ def _issuer_verify(self) -> str: self.logger.debug('CAhandler._issuer_verify() ended with: {0}'.format(error)) return error - def _issuers_list(self): + def _issuers_list(self) -> Dict[str, str]: """ list issuers """ self.logger.debug('CAhandler._list_issuers()') @@ -240,7 +253,7 @@ def _issuers_list(self): self.logger.debug('CAhandler._list_issuers() ended') return api_response - def _profiles_list(self): + def _profiles_list(self) -> Dict[str, str]: """ list profiles """ self.logger.debug('CAhandler._profiles_list()') @@ -321,6 +334,16 @@ def _cert_get(self, data_dic: Dict[str, str]) -> str: self.logger.debug('CAhandler._cert_get() ended') return cert + def _cert_status_get(self, certificate: str) -> str: + self.logger.debug('CAhandler._cert_status_get()') + + foo = b64_decode(self.logger, certificate) + data_dic = {'certificateFile': certificate} + url = '{0}/verify_certificate?issuerName={1}'.format(self.api_host, encode_url(self.logger, self.ca_name)) + code, api_response = self._api_post(url, data_dic) + api_response['code'] = code + return api_response + def _enrollment_dic_create(self, csr: str) -> Dict[str, str]: """ create enrollment dic """ self.logger.debug('CAhandler._enrollment_dic_create()') @@ -404,10 +427,7 @@ def revoke(self, cert: str, _rev_reason: str = 'unspecified', _rev_date: str = u cert_serial = cert_serial_get(self.logger, cert, hexformat=True) # get serial number from certificate cert_ski = cert_ski_get(self.logger, cert) # get subjectKeyIdentifier from certificate - - print(cert_ski) - sys.exit(0) - url = '{0}/revoke_certificate?issuerName={1}&certificateId={2}'.format(self.api_host, encode_url(self.logger, self.ca_name), cert_serial) + url = '{0}/revoke_certificate?issuerName={1}&certificateId={2}'.format(self.api_host, encode_url(self.logger, self.ca_name), cert_ski) data_dic = {} code, content_dic = self._api_post(url, data_dic) if content_dic: From d3dfab26179651510e224730a927dc6000846e92 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 13 Jan 2024 15:52:02 +0100 Subject: [PATCH 011/460] [fix] revocation support in asa_ca_handler.py --- .github/workflows/ca_handler_tests_asa.yml | 97 +++++++++++++--------- acme_srv/certificate.py | 7 +- acme_srv/helper.py | 31 ++++++- 3 files changed, 95 insertions(+), 40 deletions(-) diff --git a/.github/workflows/ca_handler_tests_asa.yml b/.github/workflows/ca_handler_tests_asa.yml index ec5d14ef..e7b1d2fd 100644 --- a/.github/workflows/ca_handler_tests_asa.yml +++ b/.github/workflows/ca_handler_tests_asa.yml @@ -75,9 +75,9 @@ jobs: openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature" # openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -text -noout - #- name: "revoke via acme.sh" - # run: | - # docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure + - name: "revoke via acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure - name: "[ REGISTER ] certbot" run: | @@ -90,9 +90,9 @@ jobs: sudo openssl x509 -in certbot/live/certbot/cert.pem -ext keyUsage -noout | grep "Digital Signature" # sudo openssl x509 -in certbot/live/certbot/cert.pem -text -noout - #- name: "revoke HTTP-01 single domain certbot" - # run: | - # docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot + - name: "revoke HTTP-01 single domain certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - name: "[ ENROLL ] lego" run: | @@ -101,11 +101,11 @@ jobs: sudo openssl x509 -in lego/certificates/lego.acme.crt -ext keyUsage -noout | grep "Digital Signature" # sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout - #- name: "revoke HTTP-01 single domain lego" - # run: | - # docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke + - name: "revoke HTTP-01 single domain lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke - - name: "[ PREPARE ] reconfiguration of a2c with asa_ca_handler" + - name: "[ PREPARE ] reconfiguration of a2c with a new profile" run: | sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem sudo touch examples/Docker/data/acme_srv.cfg @@ -132,6 +132,13 @@ jobs: ASA_CA_BUNDLE: ${{ secrets.ASA_CA_BUNDLE }} ASA_PROFILE2: ${{ secrets.ASA_PROFILE2 }} + - name: "[ PREPARE ] create letsencrypt and lego folder" + run: | + sudo rm -rf certbot/* + sudo rm -rf lego/* + sudo rm -rf acme-sh/* + docker restart acme-sh + - name: "[ ENROLL ] acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --keylength 2048 --debug 3 --output-insecure --force @@ -140,9 +147,13 @@ jobs: openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext keyUsage -noout | grep "Key Encipherment, Data Encipherment" # openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -text -noout - #- name: "revoke via acme.sh" - # run: | - # docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure + - name: "revoke via acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure + + - name: "[ REGISTER ] certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - name: "[ ENROLL ] HTTP-01 single domain certbot" run: | @@ -151,9 +162,9 @@ jobs: sudo openssl x509 -in certbot/live/certbot/cert.pem -ext keyUsage -noout | grep "Key Encipherment, Data Encipherment" # sudo openssl x509 -in certbot/live/certbot/cert.pem -text -noout - #- name: "revoke HTTP-01 single domain certbot" - # run: | - # docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot + - name: "revoke HTTP-01 single domain certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - name: "[ ENROLL ] lego" run: | @@ -162,10 +173,9 @@ jobs: sudo openssl x509 -in lego/certificates/lego.acme.crt -ext keyUsage -noout | grep "Key Encipherment, Data Encipherment" # sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout - #- name: "revoke HTTP-01 single domain lego" - # run: | - # docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke - + - name: "revoke HTTP-01 single domain lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke - name: "[ * ] collecting test logs" if: ${{ failure() }} @@ -275,9 +285,9 @@ jobs: openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature" # openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -text -noout - #- name: "revoke via acme.sh" - # run: | - # docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure + - name: "revoke via acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure - name: "[ REGISTER ] certbot" run: | @@ -290,9 +300,9 @@ jobs: sudo openssl x509 -in certbot/live/certbot/cert.pem -ext keyUsage -noout | grep "Digital Signature" # sudo openssl x509 -in certbot/live/certbot/cert.pem -text -noout - #- name: "revoke HTTP-01 single domain certbot" - # run: | - # docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot + - name: "revoke HTTP-01 single domain certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - name: "[ ENROLL ] lego" run: | @@ -301,9 +311,9 @@ jobs: sudo openssl x509 -in lego/certificates/lego.acme.crt -ext keyUsage -noout | grep "Digital Signature" # sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout - #- name: "revoke HTTP-01 single domain lego" - # run: | - # docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke + - name: "revoke HTTP-01 single domain lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke - name: "[ PREPARE ] prepare acme_srv.cfg with certifier_ca_handler" run: | @@ -332,6 +342,13 @@ jobs: run: | docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart + - name: "[ PREPARE ] create letsencrypt and lego folder" + run: | + sudo rm -rf certbot/* + sudo rm -rf lego/* + sudo rm -rf acme-sh/* + docker restart acme-sh + - name: "[ ENROLL ] acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --keylength 2048 --debug 3 --output-insecure --force @@ -340,9 +357,13 @@ jobs: openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext keyUsage -noout | grep "Key Encipherment, Data Encipherment" # openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -text -noout - #- name: "revoke via acme.sh" - # run: | - # docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure + - name: "revoke via acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure + + - name: "[ REGISTER ] certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - name: "[ ENROLL ] HTTP-01 single domain certbot" run: | @@ -351,9 +372,9 @@ jobs: sudo openssl x509 -in certbot/live/certbot/cert.pem -ext keyUsage -noout | grep "Key Encipherment, Data Encipherment" # sudo openssl x509 -in certbot/live/certbot/cert.pem -text -noout - #- name: "revoke HTTP-01 single domain certbot" - # run: | - # docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot + - name: "revoke HTTP-01 single domain certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - name: "[ ENROLL ] lego" run: | @@ -362,9 +383,9 @@ jobs: sudo openssl x509 -in lego/certificates/lego.acme.crt -ext keyUsage -noout | grep "Key Encipherment, Data Encipherment" # sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout - #- name: "revoke HTTP-01 single domain lego" - # run: | - # docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke + - name: "revoke HTTP-01 single domain lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke - name: "[ * ] collecting test logs" if: ${{ failure() }} diff --git a/acme_srv/certificate.py b/acme_srv/certificate.py index 644a8055..afc2a8f3 100644 --- a/acme_srv/certificate.py +++ b/acme_srv/certificate.py @@ -4,7 +4,7 @@ from __future__ import print_function import json from typing import List, Tuple, Dict -from acme_srv.helper import b64_url_recode, generate_random_string, cert_san_get, cert_extensions_get, hooks_load, uts_now, uts_to_date_utc, date_to_uts_utc, load_config, csr_san_get, csr_extensions_get, cert_dates_get, ca_handler_load, error_dic_get, string_sanitize, pembundle_to_list, certid_asn1_get +from acme_srv.helper import b64_url_recode, generate_random_string, cert_cn_get, cert_san_get, cert_extensions_get, hooks_load, uts_now, uts_to_date_utc, date_to_uts_utc, load_config, csr_san_get, csr_extensions_get, cert_dates_get, ca_handler_load, error_dic_get, string_sanitize, pembundle_to_list, certid_asn1_get from acme_srv.db_handler import DBstore from acme_srv.message import Message from acme_srv.threadwithreturnvalue import ThreadWithReturnValue @@ -72,6 +72,11 @@ def _authz_check(self, identifier_dic: Dict[str, str], certificate: str) -> List try: # get sans san_list = cert_san_get(self.logger, certificate) + # add common name to SANs + cert_cn = cert_cn_get(self.logger, certificate) + if cert_cn: + san_list.append('DNS:{0}'.format(cert_cn)) + identifier_status = self._identifer_status_list(identifiers, san_list) except Exception as err_: # enough to set identifier_list as empty list diff --git a/acme_srv/helper.py b/acme_srv/helper.py index 57fa1f28..dac09aed 100644 --- a/acme_srv/helper.py +++ b/acme_srv/helper.py @@ -33,6 +33,7 @@ from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import serialization, hashes from cryptography.x509 import load_pem_x509_certificate, ocsp +from OpenSSL import crypto import requests import requests.packages.urllib3.util.connection as urllib3_cn from .version import __version__ @@ -269,6 +270,31 @@ def cert_pubkey_get(logger: logging.Logger, certificate=str) -> str: return convert_byte_to_string(pubkey_str) +def cert_san_pyopenssl_get(logger, certificate, recode=True): + """ get subject alternate names from certificate """ + logger.debug('cert_san_get()') + if recode: + pem_file = build_pem_file(logger, None, b64_url_recode(logger, certificate), True) + else: + pem_file = certificate + + cert = crypto.load_certificate(crypto.FILETYPE_PEM, pem_file) + san = [] + ext_count = cert.get_extension_count() + for i in range(0, ext_count): + ext = cert.get_extension(i) + if 'subjectAltName' in str(ext.get_short_name()): + # pylint: disable=c2801 + san_list = ext.__str__().split(',') + for san_name in san_list: + san_name = san_name.rstrip() + san_name = san_name.lstrip() + san.append(san_name) + + logger.debug('cert_san_get() ended') + return san + + def cert_san_get(logger: logging.Logger, certificate: str, recode: bool = True) -> List[str]: """ get subject alternate names from certificate """ logger.debug('cert_san_get({0})'.format(recode)) @@ -285,14 +311,16 @@ def cert_san_get(logger: logging.Logger, certificate: str, recode: bool = True) sans.append('IP:{0}'.format(san)) except Exception as err: logger.error('cert_san_get(): Error: {0}'.format(err)) + # sans = cert_san_pyopenssl_get(logger, certificate, recode=recode) logger.debug('cert_san_get() ended') return sans + def cert_ski_pyopenssl_cert(logger, certificate: str) -> str: """Get Subject Key Identifier from a certificate as a hex string.""" logger.debug('cert_ski_pyopenssl_cert()') - from OpenSSL import crypto + pem_data = convert_string_to_byte(build_pem_file(logger, None, b64_url_recode(logger, certificate), True)) cert = crypto.load_certificate(crypto.FILETYPE_PEM, pem_data) # Get the SKI extension @@ -310,6 +338,7 @@ def cert_ski_pyopenssl_cert(logger, certificate: str) -> str: logger.debug('cert_ski_pyopenssl_cert() ended with: {0}'.format(ski_hex)) return ski_hex + def cert_ski_get(logger: logging.Logger, certificate: str) -> str: """ get subject key identifier from certificate """ logger.debug('cert_ski_get()') From d87e71c43eb475cfbb88153eac45ec1c72b63eda Mon Sep 17 00:00:00 2001 From: grindsa Date: Mon, 15 Jan 2024 08:10:25 +0100 Subject: [PATCH 012/460] [test] unittests for revocation in asa_handler.py --- acme_srv/certificate.py | 14 +- acme_srv/helper.py | 16 +- examples/ca_handler/asa_ca_handler.py | 10 +- test/test_asa_ca_handler.py | 127 ++++---- test/test_certificate.py | 405 +++++++++++++++----------- test/test_helper.py | 147 ++++++++-- 6 files changed, 453 insertions(+), 266 deletions(-) diff --git a/acme_srv/certificate.py b/acme_srv/certificate.py index afc2a8f3..f5257194 100644 --- a/acme_srv/certificate.py +++ b/acme_srv/certificate.py @@ -30,6 +30,7 @@ def __init__(self, debug: bool = False, srv_name: str = None, logger=None): self.tnauthlist_support = False self.cert_reusage_timeframe = 0 self.enrollment_timeout = 5 + self.cn2san_add = False def __enter__(self): """ Makes ACMEHandler a Context Manager """ @@ -72,10 +73,11 @@ def _authz_check(self, identifier_dic: Dict[str, str], certificate: str) -> List try: # get sans san_list = cert_san_get(self.logger, certificate) - # add common name to SANs - cert_cn = cert_cn_get(self.logger, certificate) - if cert_cn: - san_list.append('DNS:{0}'.format(cert_cn)) + if self.cn2san_add: + # add common name to SANs + cert_cn = cert_cn_get(self.logger, certificate) + if not san_list and cert_cn: + san_list.append('DNS:{0}'.format(cert_cn)) identifier_status = self._identifer_status_list(identifiers, san_list) except Exception as err_: @@ -194,6 +196,10 @@ def _config_load(self): if 'Order' in config_dic: self.tnauthlist_support = config_dic.getboolean('Order', 'tnauthlist_support', fallback=False) + if 'CAhandler' in config_dic and config_dic.get('CAhandler', 'handler_file', fallback=None) == 'examples/ca_handler/asa_ca_handler.py': + self.cn2san_add = True + self.logger.debug('Certificate._config_load(): cn2san_add enabled') + # load ca_handler according to configuration ca_handler_module = ca_handler_load(self.logger, config_dic) diff --git a/acme_srv/helper.py b/acme_srv/helper.py index dac09aed..4937ab9c 100644 --- a/acme_srv/helper.py +++ b/acme_srv/helper.py @@ -317,7 +317,7 @@ def cert_san_get(logger: logging.Logger, certificate: str, recode: bool = True) return sans -def cert_ski_pyopenssl_cert(logger, certificate: str) -> str: +def cert_ski_pyopenssl_get(logger, certificate: str) -> str: """Get Subject Key Identifier from a certificate as a hex string.""" logger.debug('cert_ski_pyopenssl_cert()') @@ -329,12 +329,12 @@ def cert_ski_pyopenssl_cert(logger, certificate: str) -> str: ext = cert.get_extension(i) if 'subjectKeyIdentifier' in str(ext.get_short_name()): ski = ext - - if ski is None: - raise ValueError("No SKI found in certificate") - - # Get the SKI value and convert it to hex - ski_hex = ski.get_data()[2:].hex() + if ski: + # Get the SKI value and convert it to hex + ski_hex = ski.get_data()[2:].hex() + else: + logger.error("cert_ski_pyopenssl_get(): No SKI found in certificate") + ski_hex = None logger.debug('cert_ski_pyopenssl_cert() ended with: {0}'.format(ski_hex)) return ski_hex @@ -349,7 +349,7 @@ def cert_ski_get(logger: logging.Logger, certificate: str) -> str: ski_value = ski.value.digest.hex() except Exception as err: logger.error('cert_ski_get(): Error: {0}'.format(err)) - ski_value = cert_ski_pyopenssl_cert(logger, certificate) + ski_value = cert_ski_pyopenssl_get(logger, certificate) logger.debug('cert_ski_get() ended with: {0}'.format(ski_value)) return ski_value diff --git a/examples/ca_handler/asa_ca_handler.py b/examples/ca_handler/asa_ca_handler.py index cf8e8ba5..77a29d0d 100644 --- a/examples/ca_handler/asa_ca_handler.py +++ b/examples/ca_handler/asa_ca_handler.py @@ -6,7 +6,7 @@ import requests from requests.auth import HTTPBasicAuth # pylint: disable=C0209, E0401 -from acme_srv.helper import load_config, encode_url, csr_pubkey_get, csr_cn_get, csr_san_get, csr_san_byte_get, uts_now, uts_to_date_utc, b64_decode, cert_der2pem, convert_byte_to_string, cert_serial_get, cert_ski_get +from acme_srv.helper import load_config, encode_url, csr_pubkey_get, csr_cn_get, csr_san_get, csr_san_byte_get, uts_now, uts_to_date_utc, b64_decode, cert_der2pem, convert_byte_to_string, cert_ski_get class CAhandler(object): @@ -335,13 +335,14 @@ def _cert_get(self, data_dic: Dict[str, str]) -> str: return cert def _cert_status_get(self, certificate: str) -> str: + """ get certificate status """ self.logger.debug('CAhandler._cert_status_get()') - foo = b64_decode(self.logger, certificate) data_dic = {'certificateFile': certificate} url = '{0}/verify_certificate?issuerName={1}'.format(self.api_host, encode_url(self.logger, self.ca_name)) code, api_response = self._api_post(url, data_dic) api_response['code'] = code + return api_response def _enrollment_dic_create(self, csr: str) -> Dict[str, str]: @@ -361,7 +362,7 @@ def _enrollment_dic_create(self, csr: str) -> Dict[str, str]: data_dic = {'publicKey': csr_pubkey, 'profileName': self.profile_name, 'issuerName': self.ca_name, 'cn': csr_cn, 'notBefore': validfrom, 'notAfter': validto} # get SANs from csr as base64 encoded byte sequence - sans_base64 = csr_san_byte_get(self.logger, csr) + # sans_base64 = csr_san_byte_get(self.logger, csr) # if sans_base64: # data_dic['extensions'] = [{'oid': '2.5.29.17', 'value': sans_base64}] # 'Zm9vLmJhci5sb2NhbA==' @@ -424,9 +425,8 @@ def revoke(self, cert: str, _rev_reason: str = 'unspecified', _rev_date: str = u message = None detail = None - cert_serial = cert_serial_get(self.logger, cert, hexformat=True) # get serial number from certificate - cert_ski = cert_ski_get(self.logger, cert) # get subjectKeyIdentifier from certificate + url = '{0}/revoke_certificate?issuerName={1}&certificateId={2}'.format(self.api_host, encode_url(self.logger, self.ca_name), cert_ski) data_dic = {} code, content_dic = self._api_post(url, data_dic) diff --git a/test/test_asa_ca_handler.py b/test/test_asa_ca_handler.py index d51fd25b..6e97e072 100644 --- a/test/test_asa_ca_handler.py +++ b/test/test_asa_ca_handler.py @@ -288,6 +288,15 @@ def test_018__api_post(self, mock_req): @patch('requests.post') def test_019__api_post(self, mock_req): + """ test _api_post() """ + mockresponse = Mock() + mockresponse.status_code = 'status_code' + mockresponse.text = None + mock_req.return_value = mockresponse + self.assertEqual(('status_code', None), self.cahandler._api_post('url', 'data')) + + @patch('requests.post') + def test_020__api_post(self, mock_req): """ test _api_post(= """ self.cahandler.api_host = 'api_host' self.cahandler.auth = 'auth' @@ -297,7 +306,7 @@ def test_019__api_post(self, mock_req): self.assertIn('ERROR:test_a2c:CAhandler._api_post() returned error: exc_api_post', lcm.output) @patch.object(requests, 'get') - def test_020__api_get(self, mock_req): + def test_021__api_get(self, mock_req): """ test _api_get() """ mockresponse = Mock() mockresponse.status_code = 'status_code' @@ -306,7 +315,7 @@ def test_020__api_get(self, mock_req): self.assertEqual(('status_code', {'foo': 'bar'}), self.cahandler._api_get('url')) @patch('requests.get') - def test_021__api_get(self, mock_req): + def test_022__api_get(self, mock_req): """ test _api_get() """ mockresponse = Mock() mockresponse.status_code = 'status_code' @@ -317,7 +326,7 @@ def test_021__api_get(self, mock_req): self.assertIn("ERROR:test_a2c:CAhandler._api_get() returned error: 'str' object is not callable", lcm.output) @patch('requests.get') - def test_022__api_get(self, mock_req): + def test_023__api_get(self, mock_req): """ test _api_get() """ self.cahandler.api_host = 'api_host' self.cahandler.auth = 'auth' @@ -327,21 +336,35 @@ def test_022__api_get(self, mock_req): self.assertIn('ERROR:test_a2c:CAhandler._api_post() returned error: exc_api_get', lcm.output) @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_get') - def test_023__issuers_list(self, mock_get): + def test_024__issuers_list(self, mock_get): """ test _issuers_list()""" mock_get.return_value = (200, 'content') self.assertEqual('content', self.cahandler._issuers_list()) @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_get') - def test_024__profiles_list(self, mock_get): + def test_025__profiles_list(self, mock_get): """ test _profiles_list()""" self.cahandler.ca_name = 'ca_name' mock_get.return_value = (200, 'content') self.assertEqual('content', self.cahandler._profiles_list()) + @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_get') + def test_026__certificates_list(self, mock_get): + """ test _profiles_list()""" + self.cahandler.ca_name = 'ca_name' + mock_get.return_value = (200, 'content') + self.assertEqual('content', self.cahandler._certificates_list()) + + @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_post') + def test_027_cert_status_get(self, mock_req): + """ test _profiles_list()""" + self.cahandler.ca_name = 'ca_name' + mock_req.return_value = ('status_code', {'foo': 'bar'}) + self.assertEqual({'foo': 'bar', 'code': 'status_code'}, self.cahandler._cert_status_get('cert')) + @patch('examples.ca_handler.asa_ca_handler.csr_san_get') @patch('examples.ca_handler.asa_ca_handler.csr_cn_get') - def test_025__csr_cn_get(self, mock_cn, mock_san): + def test_028__csr_cn_get(self, mock_cn, mock_san): """ test _csr_cn_get() """ mock_cn.return_value = 'cn' mock_san.return_value = ['san0', 'san1'] @@ -350,7 +373,7 @@ def test_025__csr_cn_get(self, mock_cn, mock_san): @patch('examples.ca_handler.asa_ca_handler.csr_san_get') @patch('examples.ca_handler.asa_ca_handler.csr_cn_get') - def test_026__csr_cn_get(self, mock_cn, mock_san): + def test_029__csr_cn_get(self, mock_cn, mock_san): """ test _csr_cn_get() """ mock_cn.return_value = None mock_san.return_value = ['dns:san0', 'dns:san1'] @@ -362,7 +385,7 @@ def test_026__csr_cn_get(self, mock_cn, mock_san): @patch('examples.ca_handler.asa_ca_handler.csr_san_get') @patch('examples.ca_handler.asa_ca_handler.csr_cn_get') - def test_027__csr_cn_get(self, mock_cn, mock_san): + def test_030__csr_cn_get(self, mock_cn, mock_san): """ test _csr_cn_get() """ mock_cn.return_value = None mock_san.return_value = None @@ -373,14 +396,14 @@ def test_027__csr_cn_get(self, mock_cn, mock_san): self.assertTrue(mock_san.called) @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuers_list') - def test_028_issuer_verify(self, mock_list): + def test_031_issuer_verify(self, mock_list): """ _issuer_verify() """ self.cahandler.ca_name = 'ca_name' mock_list.return_value = {'issuers': ['1', '2', 'ca_name']} self.assertFalse(self.cahandler._issuer_verify()) @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuers_list') - def test_029_issuer_verify(self, mock_list): + def test_032_issuer_verify(self, mock_list): """ _issuer_verify() """ self.cahandler.ca_name = 'ca_name' mock_list.return_value = {'issuers': ['1', '2', '3']} @@ -389,7 +412,7 @@ def test_029_issuer_verify(self, mock_list): self.assertIn('ERROR:test_a2c:CAhandler.enroll(): CA ca_name not found', lcm.output) @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuers_list') - def test_030_issuer_verify(self, mock_list): + def test_033_issuer_verify(self, mock_list): """ _issuer_verify() """ self.cahandler.ca_name = 'ca_name' mock_list.return_value = {'foo': 'bar'} @@ -398,14 +421,14 @@ def test_030_issuer_verify(self, mock_list): self.assertIn('ERROR:test_a2c:CAhandler.enroll(): "Malformed response. "issuers" key not found', lcm.output) @patch('examples.ca_handler.asa_ca_handler.CAhandler._profiles_list') - def test_031_profile_verify(self, mock_list): + def test_034_profile_verify(self, mock_list): """ _profile_verify() """ self.cahandler.profile_name = 'profile_name' mock_list.return_value = {'profiles': ['1', '2', 'profile_name']} self.assertFalse(self.cahandler._profile_verify()) @patch('examples.ca_handler.asa_ca_handler.CAhandler._profiles_list') - def test_032_profile_verify(self, mock_list): + def test_035_profile_verify(self, mock_list): """ _profile_verify() """ self.cahandler.profile_name = 'profile_name' mock_list.return_value = {'profiles': ['1', '2', '3']} @@ -414,7 +437,7 @@ def test_032_profile_verify(self, mock_list): self.assertIn('ERROR:test_a2c:CAhandler.enroll(): Profile profile_name not found', lcm.output) @patch('examples.ca_handler.asa_ca_handler.CAhandler._profiles_list') - def test_033_profile_verify(self, mock_list): + def test_036_profile_verify(self, mock_list): """ _profile_verify() """ self.cahandler.ca_name = 'ca_name' mock_list.return_value = {'foo': 'bar'} @@ -424,7 +447,7 @@ def test_033_profile_verify(self, mock_list): @patch('examples.ca_handler.asa_ca_handler.uts_to_date_utc') @patch('examples.ca_handler.asa_ca_handler.uts_now') - def test_034__validity_dates_get(self, mock_now, mock_utc): + def test_037__validity_dates_get(self, mock_now, mock_utc): """ test _validity_dates_get() """ mock_now.return_value = 10 mock_utc.side_effect = ['date1', 'date2'] @@ -434,12 +457,12 @@ def test_034__validity_dates_get(self, mock_now, mock_utc): @patch('examples.ca_handler.asa_ca_handler.convert_byte_to_string') @patch('examples.ca_handler.asa_ca_handler.cert_der2pem') @patch('examples.ca_handler.asa_ca_handler.b64_decode') - def test_035__pem_cert_chain_generate(self, mock_dec, mock_d2p, mock_b2s): + def test_038__pem_cert_chain_generate(self, mock_dec, mock_d2p, mock_b2s): """ test _pem_cert_chain_generate() """ mock_b2s.return_value = 'cert' self.assertEqual('certcert', self.cahandler._pem_cert_chain_generate(['cert', 'chain'])) - def test_036__pem_cert_chain_generate(self): + def test_039__pem_cert_chain_generate(self): """ test _pem_cert_chain_generate() """ cert_list = ['MIIF7DCCBFSgAwIBAgIKB/8cQ9wAI3UbITANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJERTERMA8GA1UECgwIT3BlblhQS0kxDDAKBgNVBAsMA1BLSTEqMCgGA1UEAwwhT3BlblhQS0kgRGVtbyBJc3N1aW5nIENBIDIwMjMwMjA0MB4XDTIzMDIwNTA2NDY0MloXDTI0MDIwNTA2NDY0MlowazETMBEGCgmSJomT8ixkARkWA29yZzEYMBYGCgmSJomT8ixkARkWCE9wZW5YUEtJMR8wHQYKCZImiZPyLGQBGRYPVGVzdCBEZXBsb3ltZW50MRkwFwYDVQQDDBBhY21lMS5keW5hbW9wLmRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAre1jtb8Xjqr49QH3fWe2kH+yDk3NXfxHyOmKcNcBke68WMRB5Irrdj15JfAsXxu9psLVEOJgvdOLOnUbhN57uBLHwMAC1LH6HruYuCqtbaSezgJIYIEACvtQmIy6BIvigqwX31eLkA7kk7YXeJCnvrr461t/uZkhmaXZM9+G4asSj6fT0ffA7OVVqewDdE+d2VgCjPlH9uqPMOVK2m/AQj+jEVV/IV2znngZmkAsmYi6h2Wg08vEzTMyvhZIEma3xo6M9g9VIsTQP/ETxxhAAgzEQ0Jlz90rOioZK7mkx8xH1fLlhyfX53vqcEbva5evy1YMGEs0XZPYu2B6Oya9WQIDAQABo4ICITCCAh0wgYcGCCsGAQUFBwEBBHsweTBRBggrBgEFBQcwAoZFaHR0cDovL3BraS5leGFtcGxlLmNvbS9kb3dubG9hZC9PcGVuWFBLSV9EZW1vX0lzc3VpbmdfQ0FfMjAyMzAyMDQuY2VyMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5leGFtcGxlLmNvbS8wHwYDVR0jBBgwFoAU0f8PWcniVXltJeA6q7wYtyJrNFAwDAYDVR0TAQH/BAIwADBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vcGtpLmV4YW1wbGUuY29tL2Rvd25sb2FkL09wZW5YUEtJX0RlbW9fSXNzdWluZ19DQV8yMDIzMDIwNC5jcmwwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDgYDVR0PAQH/BAQDAgWgMIGoBgNVHSAEgaAwgZ0wgZoGAyoDBDCBkjArBggrBgEFBQcCARYfaHR0cDovL3BraS5leGFtcGxlLmNvbS9jcHMuaHRtbDArBggrBgEFBQcCARYfaHR0cDovL3BraS5leGFtcGxlLmNvbS9jcHMuaHRtbDA2BggrBgEFBQcCAjAqGihUaGlzIGlzIGEgY29tbWVudCBmb3IgcG9saWN5IG9pZCAxLjIuMy40MBsGA1UdEQQUMBKCEGFjbWUxLmR5bmFtb3AuZGUwHQYDVR0OBBYEFA3AUTV0pg0fsd3Cd6/BskOEB9MVMA0GCSqGSIb3DQEBCwUAA4IBgQB0xnnl6BJDXrbTQr7TdkRPmcCDFUmi8aVTYozbQ8EKxIYEPsfzxOFbSG/wn+4Sjz7HqvzqxyisfTopqWrvpqIhlXOEFMnNYTDO4LzCd81Dcs4czjoIRxRTisgNCvWR9hbeH9HzdRT1UF/c4VxxLEONSsGHksoXa+G4u7XmPwD4dTUIP49Mmj2a28z/viG8KftcjAEo1S7OB+/xyPeVDYrgagMR31a69pI+yuQa0J66O/LJQrzjWf6wHToQErQPcEBtDxY2wx3hROMtdla9lUEU8XLb3e9zByZwOfDhFpw8iYkJx/BUZlsmIKaZSpYVS+0D5LI1R5PENhT/2gRxaA31RiNLK/E8CSU7MMadqImkFLkDHU2x+2SRENwvoOEUAOewjVlhB1pK0r5WEye2lBjl8cUa+8qhIrAOqggApQ7eCQq7v2bL08VxKz5baOhKfLZ9u4MH6q52pnqXmll0W7JXrJSbam5r3YoSelm94VwVyaSkfd+LT4YMAP7GDDvtT6Y='] result = """-----BEGIN CERTIFICATE----- @@ -481,7 +504,7 @@ def test_036__pem_cert_chain_generate(self): @patch('examples.ca_handler.asa_ca_handler.CAhandler._pem_cert_chain_generate') @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_get') - def test_037___issuer_chain_get(self, mock_req, mock_pem): + def test_040___issuer_chain_get(self, mock_req, mock_pem): """ test _issuer_chain_get() """ mock_req.return_value = ('code', {'certs': ['bar', 'foo']}) mock_pem.return_value = 'issuer_chain' @@ -491,7 +514,7 @@ def test_037___issuer_chain_get(self, mock_req, mock_pem): @patch('examples.ca_handler.asa_ca_handler.CAhandler._pem_cert_chain_generate') @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_get') - def test_038___issuer_chain_get(self, mock_req, mock_pem): + def test_041___issuer_chain_get(self, mock_req, mock_pem): """ test _issuer_chain_get() """ mock_req.return_value = ('code', {'foobar': ['bar', 'foo']}) mock_pem.return_value = 'issuer_chain' @@ -510,7 +533,7 @@ def test_038___issuer_chain_get(self, mock_req, mock_pem): @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_chain_get') @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_verify') @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_verify') - def test_039_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_csbg, mock_b64, mock_d2p, mock_b2s, mock_post): + def test_042_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_csbg, mock_b64, mock_d2p, mock_b2s, mock_post): """ test enroll() """ mock_iv.return_value = None mock_pv.return_value = None @@ -542,7 +565,7 @@ def test_039_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vd @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_chain_get') @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_verify') @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_verify') - def test_040_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_csbg, mock_b64, mock_d2p, mock_b2s, mock_post): + def test_043_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_csbg, mock_b64, mock_d2p, mock_b2s, mock_post): """ test enroll() """ mock_iv.return_value = 'mock_iv' mock_pv.return_value = None @@ -574,7 +597,7 @@ def test_040_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vd @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_chain_get') @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_verify') @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_verify') - def test_041_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_csbg, mock_b64, mock_d2p, mock_b2s, mock_post): + def test_044_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_csbg, mock_b64, mock_d2p, mock_b2s, mock_post): """ test enroll() """ mock_iv.return_value = None mock_pv.return_value = 'mock_pv' @@ -606,7 +629,7 @@ def test_041_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vd @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_chain_get') @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_verify') @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_verify') - def test_042_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_csbg, mock_b64, mock_d2p, mock_b2s, mock_post): + def test_045_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_csbg, mock_b64, mock_d2p, mock_b2s, mock_post): """ test enroll() """ mock_iv.return_value = None mock_pv.return_value = None @@ -638,7 +661,7 @@ def test_042_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vd @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_chain_get') @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_verify') @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_verify') - def test_043_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_csbg, mock_b64, mock_d2p, mock_b2s, mock_post): + def test_046_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_csbg, mock_b64, mock_d2p, mock_b2s, mock_post): """ test enroll() """ mock_iv.return_value = None mock_pv.return_value = None @@ -663,51 +686,51 @@ def test_043_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vd self.assertFalse(mock_d2p.called) @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_post') - @patch('examples.ca_handler.asa_ca_handler.cert_serial_get') - def test_044_revoke(self, mock_serial, mock_post): + @patch('examples.ca_handler.asa_ca_handler.cert_ski_get') + def test_047_revoke(self, mock_ski, mock_post): """ test revoke() """ self.cahandler.ca_name = 'ca_name' - mock_serial.return_value = 'serial' + mock_ski.return_value = 'serial' mock_post.return_value = ('code', None) self.assertEqual(('code', None, None), self.cahandler.revoke('cert')) - self.assertTrue(mock_serial.called) + self.assertTrue(mock_ski.called) self.assertTrue(mock_post.called) @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_post') - @patch('examples.ca_handler.asa_ca_handler.cert_serial_get') - def test_045_revoke(self, mock_serial, mock_post): + @patch('examples.ca_handler.asa_ca_handler.cert_ski_get') + def test_048_revoke(self, mock_ski, mock_post): """ test revoke() """ self.cahandler.ca_name = 'ca_name' - mock_serial.return_value = 'serial' + mock_ski.return_value = 'mock_ski' mock_post.return_value = ('code', {'message': 'message'}) self.assertEqual(('code', 'urn:ietf:params:acme:error:serverInternal', 'message'), self.cahandler.revoke('cert')) - self.assertTrue(mock_serial.called) + self.assertTrue(mock_ski.called) self.assertTrue(mock_post.called) @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_post') - @patch('examples.ca_handler.asa_ca_handler.cert_serial_get') - def test_046_revoke(self, mock_serial, mock_post): + @patch('examples.ca_handler.asa_ca_handler.cert_ski_get') + def test_049_revoke(self, mock_ski, mock_post): """ test revoke() """ self.cahandler.ca_name = 'ca_name' - mock_serial.return_value = 'serial' + mock_ski.return_value = 'ski' mock_post.return_value = ('code', {'Message': 'Message'}) self.assertEqual(('code', 'urn:ietf:params:acme:error:serverInternal', 'Message'), self.cahandler.revoke('cert')) - self.assertTrue(mock_serial.called) + self.assertTrue(mock_ski.called) self.assertTrue(mock_post.called) @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_post') - @patch('examples.ca_handler.asa_ca_handler.cert_serial_get') - def test_047_revoke(self, mock_serial, mock_post): + @patch('examples.ca_handler.asa_ca_handler.cert_ski_get') + def test_050_revoke(self, mock_ski, mock_post): """ test revoke() """ self.cahandler.ca_name = 'ca_name' - mock_serial.return_value = 'serial' + mock_ski.return_value = 'ski' mock_post.return_value = ('code', {'foo': 'bar'}) self.assertEqual(('code', 'urn:ietf:params:acme:error:serverInternal', 'Unknown error'), self.cahandler.revoke('cert')) - self.assertTrue(mock_serial.called) + self.assertTrue(mock_ski.called) self.assertTrue(mock_post.called) @patch.dict('os.environ', {'api_user_var': 'user_var'}) - def test_048_config_user_load(self): + def test_051_config_user_load(self): """ test _config_load - load template with user variable """ config_dic = {'api_user_variable': 'api_user_var'} self.cahandler._config_user_load(config_dic) @@ -715,7 +738,7 @@ def test_048_config_user_load(self): self.assertFalse(self.cahandler.profile_name) @patch.dict('os.environ', {'api_user_var': 'user_var'}) - def test_049_config_user_load(self): + def test_052_config_user_load(self): """ test _config_load - load template with user variable """ config_dic = {'api_user_variable': 'does_not_exist'} with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -725,7 +748,7 @@ def test_049_config_user_load(self): self.assertFalse(self.cahandler.profile_name) @patch.dict('os.environ', {'api_user_var': 'user_var'}) - def test_050_config_user_load(self): + def test_053_config_user_load(self): """ test _config_load - load template with user variable """ config_dic = {'api_user_variable': 'api_user_var', 'api_user': 'api_user'} self.cahandler._config_user_load(config_dic) @@ -735,7 +758,7 @@ def test_050_config_user_load(self): self.assertFalse(self.cahandler.profile_name) @patch.dict('os.environ', {'api_host_var': 'host_var'}) - def test_051_config_host_load(self): + def test_054_config_host_load(self): """ test _config_load - load template with host variable """ config_dic = {'api_host_variable': 'api_host_var'} self.cahandler._config_host_load(config_dic) @@ -743,7 +766,7 @@ def test_051_config_host_load(self): self.assertFalse(self.cahandler.profile_name) @patch.dict('os.environ', {'api_host_var': 'host_var'}) - def test_052_config_host_load(self): + def test_055_config_host_load(self): """ test _config_load - load template with host variable """ config_dic = {'api_host_variable': 'does_not_exist'} with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -753,7 +776,7 @@ def test_052_config_host_load(self): self.assertFalse(self.cahandler.profile_name) @patch.dict('os.environ', {'api_host_var': 'host_var'}) - def test_053_config_host_load(self): + def test_056_config_host_load(self): """ test _config_load - load template with host variable """ config_dic = {'api_host_variable': 'api_host_var', 'api_host': 'api_host'} self.cahandler._config_host_load(config_dic) @@ -763,7 +786,7 @@ def test_053_config_host_load(self): self.assertFalse(self.cahandler.profile_name) @patch.dict('os.environ', {'api_key_var': 'key_var'}) - def test_054_config_key_load(self): + def test_057_config_key_load(self): """ test _config_load - load template with key variable """ config_dic = {'api_key_variable': 'api_key_var'} self.cahandler._config_key_load(config_dic) @@ -771,7 +794,7 @@ def test_054_config_key_load(self): self.assertFalse(self.cahandler.profile_name) @patch.dict('os.environ', {'api_key_var': 'key_var'}) - def test_055_config_key_load(self): + def test_058_config_key_load(self): """ test _config_load - load template with key variable """ config_dic = {'api_key_variable': 'does_not_exist'} with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -781,7 +804,7 @@ def test_055_config_key_load(self): self.assertFalse(self.cahandler.profile_name) @patch.dict('os.environ', {'api_key_var': 'key_var'}) - def test_056_config_key_load(self): + def test_059_config_key_load(self): """ test _config_load - load template with key variable """ config_dic = {'api_key_variable': 'api_key_var', 'api_key': 'api_key'} self.cahandler._config_key_load(config_dic) @@ -791,7 +814,7 @@ def test_056_config_key_load(self): self.assertFalse(self.cahandler.profile_name) @patch.dict('os.environ', {'api_password_var': 'password_var'}) - def test_057_config_password_load(self): + def test_060_config_password_load(self): """ test _config_load - load template with password variable """ config_dic = {'api_password_variable': 'api_password_var'} self.cahandler._config_password_load(config_dic) @@ -799,7 +822,7 @@ def test_057_config_password_load(self): self.assertFalse(self.cahandler.profile_name) @patch.dict('os.environ', {'api_password_var': 'password_var'}) - def test_058_config_password_load(self): + def test_061_config_password_load(self): """ test _config_load - load template with password variable """ config_dic = {'api_password_variable': 'does_not_exist'} with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -809,7 +832,7 @@ def test_058_config_password_load(self): self.assertFalse(self.cahandler.profile_name) @patch.dict('os.environ', {'api_password_var': 'password_var'}) - def test_059_config_password_load(self): + def test_062_config_password_load(self): """ test _config_load - load template with password variable """ config_dic = {'api_password_variable': 'api_password_var', 'api_password': 'api_password'} self.cahandler._config_password_load(config_dic) diff --git a/test/test_certificate.py b/test/test_certificate.py index 20a1d697..c4c5a087 100644 --- a/test/test_certificate.py +++ b/test/test_certificate.py @@ -228,20 +228,42 @@ def test_027_certificate__authorization_check(self, mock_san): mock_san.return_value = ['san1.example.com'] self.assertFalse(self.certificate._authorization_check('order_name', 'cert')) - def test_028_certificate__revocation_request_validate(self): + @patch('acme_srv.certificate.cert_cn_get') + @patch('acme_srv.certificate.cert_san_get') + def test_028_certificate__authorization_check(self, mock_san, mock_cn): + """ test Certificate.authorization_check with lowercase SAN entries and uppercase entries in identifier list""" + self.certificate.cn2san_add = True + self.certificate.dbstore.order_lookup.return_value = {'identifiers' : '[{"TYPE": "DNS", "VALUE": "SAN1.EXAMPLE.COM"}]'} + mock_san.return_value = ['dns:san1.example.com'] + mock_cn.return_value = [] + self.assertTrue(self.certificate._authorization_check('order_name', 'cert')) + self.assertTrue(mock_cn.called) + + @patch('acme_srv.certificate.cert_cn_get') + @patch('acme_srv.certificate.cert_san_get') + def test_029_certificate__authorization_check(self, mock_san, mock_cn): + """ test Certificate.authorization_check with lowercase SAN entries and uppercase entries in identifier list""" + self.certificate.cn2san_add = True + self.certificate.dbstore.order_lookup.return_value = {'identifiers' : '[{"type": "dns", "value": "san1.example.com"}]'} + mock_san.return_value = [] + mock_cn.return_value = 'san1.example.com' + self.assertTrue(self.certificate._authorization_check('order_name', 'cert')) + self.assertTrue(mock_cn.called) + + def test_030_certificate__revocation_request_validate(self): """ test Certificate.revocation_request_validate empty payload""" payload = {} self.assertEqual((400, 'unspecified'), self.certificate._revocation_request_validate('account_name', payload)) @patch('acme_srv.certificate.Certificate._revocation_reason_check') - def test_029_certificate__revocation_request_validate(self, mock_revrcheck): + def test_031_certificate__revocation_request_validate(self, mock_revrcheck): """ test Certificate.revocation_request_validate reason_check returns None""" payload = {'reason' : 0} mock_revrcheck.return_value = False self.assertEqual((400, 'urn:ietf:params:acme:error:badRevocationReason'), self.certificate._revocation_request_validate('account_name', payload)) @patch('acme_srv.certificate.Certificate._revocation_reason_check') - def test_030_certificate__revocation_request_validate(self, mock_revrcheck): + def test_032_certificate__revocation_request_validate(self, mock_revrcheck): """ test Certificate.revocation_request_validate reason_check returns a reason""" payload = {'reason' : 0} mock_revrcheck.return_value = 'revrcheck' @@ -250,7 +272,7 @@ def test_030_certificate__revocation_request_validate(self, mock_revrcheck): @patch('acme_srv.certificate.Certificate._authorization_check') @patch('acme_srv.certificate.Certificate._account_check') @patch('acme_srv.certificate.Certificate._revocation_reason_check') - def test_031_certificate__revocation_request_validate(self, mock_revrcheck, mock_account, mock_authz): + def test_033_certificate__revocation_request_validate(self, mock_revrcheck, mock_account, mock_authz): """ test Certificate.revocation_request_validate authz_check failed""" payload = {'reason' : 0, 'certificate': 'certificate'} mock_revrcheck.return_value = 'revrcheck' @@ -261,7 +283,7 @@ def test_031_certificate__revocation_request_validate(self, mock_revrcheck, mock @patch('acme_srv.certificate.Certificate._authorization_check') @patch('acme_srv.certificate.Certificate._account_check') @patch('acme_srv.certificate.Certificate._revocation_reason_check') - def test_032_certificate__revocation_request_validate(self, mock_revrcheck, mock_account, mock_authz): + def test_034_certificate__revocation_request_validate(self, mock_revrcheck, mock_account, mock_authz): """ test Certificate.revocation_request_validate authz_check succeed""" payload = {'reason' : 0, 'certificate': 'certificate'} mock_revrcheck.return_value = 'revrcheck' @@ -271,7 +293,7 @@ def test_032_certificate__revocation_request_validate(self, mock_revrcheck, mock @patch('acme_srv.nonce.Nonce.generate_and_add') @patch('acme_srv.message.Message.check') - def test_033_certificate_revoke(self, mock_mcheck, mock_nnonce): + def test_035_certificate_revoke(self, mock_mcheck, mock_nnonce): """ test Certificate.revoke with failed message check """ mock_mcheck.return_value = (400, 'message', 'detail', None, None, 'account_name') mock_nnonce.return_value = 'new_nonce' @@ -280,7 +302,7 @@ def test_033_certificate_revoke(self, mock_mcheck, mock_nnonce): @patch('acme_srv.nonce.Nonce.generate_and_add') @patch('acme_srv.message.Message.check') - def test_034_certificate_revoke(self, mock_mcheck, mock_nnonce): + def test_036_certificate_revoke(self, mock_mcheck, mock_nnonce): """ test Certificate.revoke with incorrect payload """ mock_mcheck.return_value = (200, 'message', 'detail', None, {}, 'account_name') mock_nnonce.return_value = 'new_nonce' @@ -290,7 +312,7 @@ def test_034_certificate_revoke(self, mock_mcheck, mock_nnonce): @patch('acme_srv.nonce.Nonce.generate_and_add') @patch('acme_srv.certificate.Certificate._revocation_request_validate') @patch('acme_srv.message.Message.check') - def test_035_certificate_revoke(self, mock_mcheck, mock_validate, mock_nnonce): + def test_037_certificate_revoke(self, mock_mcheck, mock_validate, mock_nnonce): """ test Certificate.revoke with failed request validation """ mock_mcheck.return_value = (200, None, None, None, {'certificate' : 'certificate'}, 'account_name') mock_validate.return_value = (400, 'error') @@ -301,7 +323,7 @@ def test_035_certificate_revoke(self, mock_mcheck, mock_validate, mock_nnonce): @patch('acme_srv.nonce.Nonce.generate_and_add') @patch('acme_srv.certificate.Certificate._revocation_request_validate') @patch('acme_srv.message.Message.check') - def test_036_certificate_revoke(self, mock_mcheck, mock_validate, mock_nnonce): + def test_038_certificate_revoke(self, mock_mcheck, mock_validate, mock_nnonce): """ test Certificate.revoke with sucessful request validation """ mock_mcheck.return_value = (200, None, None, None, {'certificate' : 'certificate'}, 'account_name') mock_validate.return_value = (200, 'reason') @@ -311,212 +333,212 @@ def test_036_certificate_revoke(self, mock_mcheck, mock_validate, mock_nnonce): self.certificate.cahandler.revoke = Mock(return_value=(200, 'message', 'detail')) self.assertEqual({'code': 200, 'header': {'Replay-Nonce': 'new_nonce'}}, self.certificate.revoke('content')) - def test_037_certificate__revocation_reason_check(self): + def test_039_certificate__revocation_reason_check(self): """ test Certicate.revocation_reason_check() with a valid revocation reason""" self.assertEqual('unspecified', self.certificate._revocation_reason_check(0)) - def test_038_certificate__revocation_reason_check(self): + def test_040_certificate__revocation_reason_check(self): """ test Certicate.revocation_reason_check() with an invalid revocation reason""" self.assertFalse(self.certificate._revocation_reason_check(2)) - def test_039_certificate__tnauth_identifier_check(self): + def test_041_certificate__tnauth_identifier_check(self): """ identifier check empty """ identifier_dic = [] self.assertFalse(self.certificate._tnauth_identifier_check(identifier_dic)) - def test_040_certificate__tnauth_identifier_check(self): + def test_042_certificate__tnauth_identifier_check(self): """ identifier check none input""" identifier_dic = None self.assertFalse(self.certificate._tnauth_identifier_check(identifier_dic)) - def test_041_certificate__tnauth_identifier_check(self): + def test_043_certificate__tnauth_identifier_check(self): """ identifier check none input""" identifier_dic = 'foo' self.assertFalse(self.certificate._tnauth_identifier_check(identifier_dic)) - def test_042_certificate__tnauth_identifier_check(self): + def test_044_certificate__tnauth_identifier_check(self): """ identifier check one identifier """ identifier_dic = [{'foo': 'bar'}] self.assertFalse(self.certificate._tnauth_identifier_check(identifier_dic)) - def test_043_certificate__tnauth_identifier_check(self): + def test_045_certificate__tnauth_identifier_check(self): """ identifier check two identifiers """ identifier_dic = [{'foo': 'bar'}, {'foo': 'bar'}] self.assertFalse(self.certificate._tnauth_identifier_check(identifier_dic)) - def test_044_certificate__tnauth_identifier_check(self): + def test_046_certificate__tnauth_identifier_check(self): """ identifier check hit first identifiers """ identifier_dic = [{'type': 'bar'}, {'foo': 'bar'}] self.assertFalse(self.certificate._tnauth_identifier_check(identifier_dic)) - def test_045_certificate__tnauth_identifier_check(self): + def test_047_certificate__tnauth_identifier_check(self): """ identifier check hit first identifiers """ identifier_dic = [{'type': 'TNAUTHLIST'}, {'foo': 'bar'}] self.assertTrue(self.certificate._tnauth_identifier_check(identifier_dic)) - def test_046_certificate__tnauth_identifier_check(self): + def test_048_certificate__tnauth_identifier_check(self): """ identifier check hit first identifiers """ identifier_dic = [{'type': 'tnauthlist'}, {'foo': 'bar'}] self.assertTrue(self.certificate._tnauth_identifier_check(identifier_dic)) - def test_047_certificate__tnauth_identifier_check(self): + def test_049_certificate__tnauth_identifier_check(self): """ identifier check hit 2nd identifiers """ identifier_dic = [{'type': 'bar'}, {'type': 'tnauthlist'}] self.assertTrue(self.certificate._tnauth_identifier_check(identifier_dic)) - def test_048_certificate__tnauth_identifier_check(self): + def test_050_certificate__tnauth_identifier_check(self): """ identifier check hit 2nd identifiers """ identifier_dic = [{'type': 'bar'}, {'type': 'TNAUTHLIST'}] self.assertTrue(self.certificate._tnauth_identifier_check(identifier_dic)) - def test_049_certificate__identifer_status_list(self): + def test_051_certificate__identifer_status_list(self): """ failed check identifiers against san """ identifier_dic = [{'foo': 'bar'}, {'foo': 'bar'}] san_list = ['foo:bar', 'foo:bar'] self.assertEqual([False, False], self.certificate._identifer_status_list(identifier_dic, san_list)) - def test_050_certificate__identifer_status_list(self): + def test_052_certificate__identifer_status_list(self): """ failed check no sans """ identifier_dic = [{'foo': 'bar'}] san_list = [] self.assertEqual([False], self.certificate._identifer_status_list(identifier_dic, san_list)) - def test_051_certificate__identifer_status_list(self): + def test_053_certificate__identifer_status_list(self): """ failed check no identifiers """ identifier_dic = [] san_list = ['foo:bar'] self.assertEqual([False], self.certificate._identifer_status_list(identifier_dic, san_list)) - def test_052_certificate__identifer_status_list(self): + def test_054_certificate__identifer_status_list(self): """ failed check no identifiers """ identifier_dic = [] san_list = ['bar'] self.assertEqual([False], self.certificate._identifer_status_list(identifier_dic, san_list)) - def test_053_certificate__identifer_status_list(self): + def test_055_certificate__identifer_status_list(self): """ succ check no identifiers """ identifier_dic = [{'type': 'dns', 'value': 'bar'}] san_list = ['dns:bar'] self.assertEqual([True], self.certificate._identifer_status_list(identifier_dic, san_list)) - def test_054_certificate__identifer_status_list(self): + def test_056_certificate__identifer_status_list(self): """ failed check san in identifier """ identifier_dic = [{'type': 'dns', 'value': 'bar1'}] san_list = ['dns:bar'] self.assertEqual([False], self.certificate._identifer_status_list(identifier_dic, san_list)) - def test_055_certificate__identifer_status_list(self): + def test_057_certificate__identifer_status_list(self): """ failed check identifier in san """ identifier_dic = [{'type': 'dns', 'value': 'bar'}] san_list = ['dns:bar1'] self.assertEqual([False], self.certificate._identifer_status_list(identifier_dic, san_list)) - def test_056_certificate__identifer_status_list(self): + def test_058_certificate__identifer_status_list(self): """ failed check identifier one identifier two sans""" identifier_dic = [{'type': 'dns', 'value': 'bar'}] san_list = ['dns:bar', 'dns:bar2'] self.assertEqual([True, False], self.certificate._identifer_status_list(identifier_dic, san_list)) - def test_057_certificate__identifer_status_list(self): + def test_059_certificate__identifer_status_list(self): """ failed check identifier two identifier one san""" identifier_dic = [{'type': 'dns', 'value': 'bar1'}, {'type': 'dns', 'value': 'bar2'}] san_list = ['dns:bar1'] self.assertEqual([True], self.certificate._identifer_status_list(identifier_dic, san_list)) - def test_058_certificate__identifer_status_list(self): + def test_060_certificate__identifer_status_list(self): """ failed check identifier both ok""" identifier_dic = [{'type': 'dns', 'value': 'bar1'}, {'type': 'dns', 'value': 'bar2'}] san_list = ['dns:bar1', 'dns:bar2'] self.assertEqual([True, True], self.certificate._identifer_status_list(identifier_dic, san_list)) - def test_059_certificate__identifer_status_list(self): + def test_061_certificate__identifer_status_list(self): """ failed check identifier both ok - wrong order""" identifier_dic = [{'type': 'dns', 'value': 'bar1'}, {'type': 'dns', 'value': 'bar2'}] san_list = ['dns:bar2', 'dns:bar1'] self.assertEqual([True, True], self.certificate._identifer_status_list(identifier_dic, san_list)) - def test_060_certificate__identifer_status_list(self): + def test_062_certificate__identifer_status_list(self): """ failed check identifier first ok 2nd nok""" identifier_dic = [{'type': 'dns', 'value': 'bar1'}, {'type': 'dns', 'value': 'bar'}] san_list = ['dns:bar1', 'dns:bar2'] self.assertEqual([True, False], self.certificate._identifer_status_list(identifier_dic, san_list)) - def test_061_certificate__identifer_status_list(self): + def test_063_certificate__identifer_status_list(self): """ failed check identifier first nook 2nd ok""" identifier_dic = [{'type': 'dns', 'value': 'bar1'}, {'type': 'dns', 'value': 'bar2'}] san_list = ['dns:bar', 'dns:bar2'] self.assertEqual([False, True], self.certificate._identifer_status_list(identifier_dic, san_list)) - def test_062_certificate__identifer_tnauth_list(self): + def test_064_certificate__identifer_tnauth_list(self): """ empty identifier dic but tnauth exists """ identifier_dic = [] tnauthlist = 'foo' self.assertEqual([False], self.certificate._identifer_tnauth_list(identifier_dic, tnauthlist)) - def test_063_certificate__identifer_tnauth_list(self): + def test_065_certificate__identifer_tnauth_list(self): """ identifier dic but no tnauth """ identifier_dic = {'foo': 'bar'} tnauthlist = None self.assertEqual([False], self.certificate._identifer_tnauth_list(identifier_dic, tnauthlist)) - def test_064_certificate__identifer_tnauth_list(self): + def test_066_certificate__identifer_tnauth_list(self): """ wrong identifier """ identifier_dic = {'identifiers': '[{"foo": "bar"}]'} tnauthlist = 'foo' self.assertEqual([False], self.certificate._identifer_tnauth_list(identifier_dic, tnauthlist)) - def test_065_certificate__identifer_tnauth_list(self): + def test_067_certificate__identifer_tnauth_list(self): """ wrong type """ identifier_dic = {'identifiers': '[{"type": "bar"}]'} tnauthlist = 'foo' self.assertEqual([False], self.certificate._identifer_tnauth_list(identifier_dic, tnauthlist)) - def test_066_certificate__identifer_tnauth_list(self): + def test_068_certificate__identifer_tnauth_list(self): """ correct type but no value""" identifier_dic = {'identifiers': '[{"type": "TnAuThLiSt"}]'} tnauthlist = 'foo' self.assertEqual([False], self.certificate._identifer_tnauth_list(identifier_dic, tnauthlist)) - def test_067_certificate__identifer_tnauth_list(self): + def test_069_certificate__identifer_tnauth_list(self): """ correct type but wrong value""" identifier_dic = {'identifiers': '[{"type": "TnAuThLiSt", "value": "bar"}]'} tnauthlist = 'foo' self.assertEqual([False], self.certificate._identifer_tnauth_list(identifier_dic, tnauthlist)) - def test_068_certificate__identifer_tnauth_list(self): + def test_070_certificate__identifer_tnauth_list(self): """ correct type but wrong value""" identifier_dic = {'identifiers': '[{"type": "TnAuThLiSt", "value": "foo"}]'} tnauthlist = 'foo' self.assertEqual([True], self.certificate._identifer_tnauth_list(identifier_dic, tnauthlist)) - def test_069_certificate__identifer_tnauth_list(self): + def test_071_certificate__identifer_tnauth_list(self): """ correct type but wrong value""" identifier_dic = {'identifiers': '[{"type": "TnAuThLiSt", "value": "foo"}, {"type": "dns", "value": "foo"}]'} tnauthlist = 'foo' self.assertEqual([True, False], self.certificate._identifer_tnauth_list(identifier_dic, tnauthlist)) @patch('acme_srv.certificate.Certificate._info') - def test_070_certificate__csr_check(self, mock_certinfo): + def test_072_certificate__csr_check(self, mock_certinfo): """ csr-check certname lookup failed """ mock_certinfo.return_value = {} self.assertFalse(self.certificate._csr_check('cert_name', 'csr')) @patch('acme_srv.certificate.Certificate._info') - def test_071_certificate__csr_check(self, mock_certinfo): + def test_073_certificate__csr_check(self, mock_certinfo): """ csr-check order lookup failed """ mock_certinfo.return_value = {'order': 'order'} self.certificate.dbstore.order_lookup.return_value = {} self.assertFalse(self.certificate._csr_check('cert_name', 'csr')) @patch('acme_srv.certificate.Certificate._info') - def test_072_certificate__csr_check(self, mock_certinfo): + def test_074_certificate__csr_check(self, mock_certinfo): """ csr-check order lookup returns rubbish """ mock_certinfo.return_value = {'order': 'order'} self.certificate.dbstore.order_lookup.return_value = {'foo': 'bar'} self.assertFalse(self.certificate._csr_check('cert_name', 'csr')) @patch('acme_srv.certificate.Certificate._info') - def test_073_certificate__csr_check(self, mock_certinfo): + def test_075_certificate__csr_check(self, mock_certinfo): """ csr-check order lookup returns an identifier """ mock_certinfo.return_value = {'order': 'order'} self.certificate.dbstore.order_lookup.return_value = {'foo': 'bar', 'identifiers': 'bar'} @@ -524,7 +546,7 @@ def test_073_certificate__csr_check(self, mock_certinfo): @patch('acme_srv.certificate.Certificate._tnauth_identifier_check') @patch('acme_srv.certificate.Certificate._info') - def test_074_certificate__csr_check(self, mock_certinfo, mock_tnauthin): + def test_076_certificate__csr_check(self, mock_certinfo, mock_tnauthin): """ csr-check no tnauth """ mock_certinfo.return_value = {'order': 'order'} mock_tnauthin.return_value = False @@ -535,7 +557,7 @@ def test_074_certificate__csr_check(self, mock_certinfo, mock_tnauthin): @patch('acme_srv.certificate.Certificate._identifer_status_list') @patch('acme_srv.certificate.Certificate._tnauth_identifier_check') @patch('acme_srv.certificate.Certificate._info') - def test_075_certificate__csr_check(self, mock_certinfo, mock_tnauthin, mock_status, mock_san): + def test_077_certificate__csr_check(self, mock_certinfo, mock_tnauthin, mock_status, mock_san): """ csr-check no tnauth status true """ mock_certinfo.return_value = {'order': 'order'} mock_san.return_value = ['foo'] @@ -548,7 +570,7 @@ def test_075_certificate__csr_check(self, mock_certinfo, mock_tnauthin, mock_sta @patch('acme_srv.certificate.Certificate._identifer_status_list') @patch('acme_srv.certificate.Certificate._tnauth_identifier_check') @patch('acme_srv.certificate.Certificate._info') - def test_076_certificate__csr_check(self, mock_certinfo, mock_tnauthin, mock_status, mock_san): + def test_078_certificate__csr_check(self, mock_certinfo, mock_tnauthin, mock_status, mock_san): """ csr-check no tnauth status False """ mock_certinfo.return_value = {'order': 'order'} mock_san.return_value = ['foo'] @@ -561,7 +583,7 @@ def test_076_certificate__csr_check(self, mock_certinfo, mock_tnauthin, mock_sta @patch('acme_srv.certificate.Certificate._identifer_status_list') @patch('acme_srv.certificate.Certificate._tnauth_identifier_check') @patch('acme_srv.certificate.Certificate._info') - def test_077_certificate__csr_check(self, mock_certinfo, mock_tnauthin, mock_status, mock_san): + def test_079_certificate__csr_check(self, mock_certinfo, mock_tnauthin, mock_status, mock_san): """ csr-check no tnauth status True, False """ mock_certinfo.return_value = {'order': 'order'} mock_san.return_value = ['foo'] @@ -574,7 +596,7 @@ def test_077_certificate__csr_check(self, mock_certinfo, mock_tnauthin, mock_sta @patch('acme_srv.certificate.Certificate._identifer_status_list') @patch('acme_srv.certificate.Certificate._tnauth_identifier_check') @patch('acme_srv.certificate.Certificate._info') - def test_078_certificate__csr_check(self, mock_certinfo, mock_tnauthin, mock_status, mock_san): + def test_080_certificate__csr_check(self, mock_certinfo, mock_tnauthin, mock_status, mock_san): """ csr-check no tnauth status True, False, True """ mock_certinfo.return_value = {'order': 'order'} mock_san.return_value = ['foo'] @@ -587,7 +609,7 @@ def test_078_certificate__csr_check(self, mock_certinfo, mock_tnauthin, mock_sta @patch('acme_srv.certificate.Certificate._identifer_tnauth_list') @patch('acme_srv.certificate.Certificate._tnauth_identifier_check') @patch('acme_srv.certificate.Certificate._info') - def test_079_certificate__csr_check(self, mock_certinfo, mock_tnauthin, mock_status, mock_san): + def test_081_certificate__csr_check(self, mock_certinfo, mock_tnauthin, mock_status, mock_san): """ csr-check tnauth but tnauthlist_support off """ mock_certinfo.return_value = {'order': 'order'} mock_san.return_value = ['foo'] @@ -600,7 +622,7 @@ def test_079_certificate__csr_check(self, mock_certinfo, mock_tnauthin, mock_sta @patch('acme_srv.certificate.Certificate._identifer_tnauth_list') @patch('acme_srv.certificate.Certificate._tnauth_identifier_check') @patch('acme_srv.certificate.Certificate._info') - def test_080_certificate__csr_check(self, mock_certinfo, mock_tnauthin, mock_status, mock_san): + def test_082_certificate__csr_check(self, mock_certinfo, mock_tnauthin, mock_status, mock_san): """ csr-check tnauth but tnauthlist_support on and returns true """ mock_certinfo.return_value = {'order': 'order'} mock_san.return_value = ['foo'] @@ -614,7 +636,7 @@ def test_080_certificate__csr_check(self, mock_certinfo, mock_tnauthin, mock_sta @patch('acme_srv.certificate.Certificate._identifer_tnauth_list') @patch('acme_srv.certificate.Certificate._tnauth_identifier_check') @patch('acme_srv.certificate.Certificate._info') - def test_081_certificate__csr_check(self, mock_certinfo, mock_tnauthin, mock_status, mock_san): + def test_083_certificate__csr_check(self, mock_certinfo, mock_tnauthin, mock_status, mock_san): """ csr-check tnauth but tnauthlist_support on and returns true """ mock_certinfo.return_value = {'order': 'order'} mock_san.return_value = ['foo'] @@ -628,7 +650,7 @@ def test_081_certificate__csr_check(self, mock_certinfo, mock_tnauthin, mock_sta @patch('acme_srv.certificate.Certificate._identifer_tnauth_list') @patch('acme_srv.certificate.Certificate._tnauth_identifier_check') @patch('acme_srv.certificate.Certificate._info') - def test_082_certificate__csr_check(self, mock_certinfo, mock_tnauthin, mock_status, mock_san): + def test_084_certificate__csr_check(self, mock_certinfo, mock_tnauthin, mock_status, mock_san): """ csr-check tnauth but tnauthlist_support on and returns True, False """ mock_certinfo.return_value = {'order': 'order'} mock_san.return_value = ['foo'] @@ -642,7 +664,7 @@ def test_082_certificate__csr_check(self, mock_certinfo, mock_tnauthin, mock_sta @patch('acme_srv.certificate.Certificate._identifer_tnauth_list') @patch('acme_srv.certificate.Certificate._tnauth_identifier_check') @patch('acme_srv.certificate.Certificate._info') - def test_083_certificate__csr_check(self, mock_certinfo, mock_tnauthin, mock_status, mock_san): + def test_085_certificate__csr_check(self, mock_certinfo, mock_tnauthin, mock_status, mock_san): """ csr-check tnauth but tnauthlist_support on and returns True, False """ mock_certinfo.return_value = {'order': 'order'} mock_san.return_value = ['foo'] @@ -656,7 +678,7 @@ def test_083_certificate__csr_check(self, mock_certinfo, mock_tnauthin, mock_sta @patch('acme_srv.certificate.Certificate._identifer_tnauth_list') @patch('acme_srv.certificate.Certificate._tnauth_identifier_check') @patch('acme_srv.certificate.Certificate._info') - def test_084_certificate__csr_check(self, mock_certinfo, mock_tnauthin, mock_status, mock_san): + def test_086_certificate__csr_check(self, mock_certinfo, mock_tnauthin, mock_status, mock_san): """ csr-check tnauth but tnauthlist_support on and returns True, False """ mock_certinfo.return_value = {'order': 'order'} mock_san.return_value = ['foo'] @@ -668,23 +690,23 @@ def test_084_certificate__csr_check(self, mock_certinfo, mock_tnauthin, mock_sta self.assertFalse(self.certificate._csr_check('cert_name', 'csr')) self.assertIn('WARNING:test_a2c:Certificate._csr_check() error while parsing csr.\nerror: mock_status', lcm.output) - def test_085_certificate__authorization_check(self): + def test_087_certificate__authorization_check(self): """ _authorization_check order lookup failed """ self.certificate.dbstore.order_lookup.return_value = {} self.assertFalse(self.certificate._authorization_check('order_name', 'cert')) - def test_086_certificate__authorization_check(self): + def test_088_certificate__authorization_check(self): """ _authorization_check order lookup returns rubbish """ self.certificate.dbstore.order_lookup.return_value = {'foo': 'bar'} self.assertFalse(self.certificate._authorization_check('order_name', 'cert')) - def test_087_certificate__authorization_check(self): + def test_089_certificate__authorization_check(self): """ _authorization_check order lookup returns an identifier """ self.certificate.dbstore.order_lookup.return_value = {'foo': 'bar', 'identifiers': 'bar'} self.assertFalse(self.certificate._authorization_check('order_name', 'cert')) @patch('acme_srv.certificate.Certificate._tnauth_identifier_check') - def test_088_certificate__authorization_check(self, mock_tnauthin): + def test_090_certificate__authorization_check(self, mock_tnauthin): """ _authorization_check no tnauth """ mock_tnauthin.return_value = False self.certificate.dbstore.order_lookup.return_value = {'foo': 'bar', 'identifiers': 'bar'} @@ -693,7 +715,7 @@ def test_088_certificate__authorization_check(self, mock_tnauthin): @patch('acme_srv.certificate.cert_san_get') @patch('acme_srv.certificate.Certificate._identifer_status_list') @patch('acme_srv.certificate.Certificate._tnauth_identifier_check') - def test_089_certificate__authorization_check(self, mock_tnauthin, mock_status, mock_san): + def test_091_certificate__authorization_check(self, mock_tnauthin, mock_status, mock_san): """ _authorization_check no tnauth status true """ mock_san.return_value = ['foo'] mock_tnauthin.return_value = False @@ -704,7 +726,7 @@ def test_089_certificate__authorization_check(self, mock_tnauthin, mock_status, @patch('acme_srv.certificate.cert_san_get') @patch('acme_srv.certificate.Certificate._identifer_status_list') @patch('acme_srv.certificate.Certificate._tnauth_identifier_check') - def test_090_certificate__authorization_check(self, mock_tnauthin, mock_status, mock_san): + def test_092_certificate__authorization_check(self, mock_tnauthin, mock_status, mock_san): """ _authorization_check no tnauth status true """ mock_san.return_value = ['foo'] mock_tnauthin.return_value = False @@ -715,7 +737,7 @@ def test_090_certificate__authorization_check(self, mock_tnauthin, mock_status, @patch('acme_srv.certificate.cert_san_get') @patch('acme_srv.certificate.Certificate._identifer_status_list') @patch('acme_srv.certificate.Certificate._tnauth_identifier_check') - def test_091_certificate__authorization_check(self, mock_tnauthin, mock_status, mock_san): + def test_093_certificate__authorization_check(self, mock_tnauthin, mock_status, mock_san): """ _authorization_check no tnauth status False """ mock_san.return_value = ['foo'] mock_tnauthin.return_value = False @@ -726,7 +748,7 @@ def test_091_certificate__authorization_check(self, mock_tnauthin, mock_status, @patch('acme_srv.certificate.cert_san_get') @patch('acme_srv.certificate.Certificate._identifer_status_list') @patch('acme_srv.certificate.Certificate._tnauth_identifier_check') - def test_092_certificate__authorization_check(self, mock_tnauthin, mock_status, mock_san): + def test_094_certificate__authorization_check(self, mock_tnauthin, mock_status, mock_san): """ _authorization_check no tnauth status True, False """ mock_san.return_value = ['foo'] mock_tnauthin.return_value = False @@ -737,7 +759,7 @@ def test_092_certificate__authorization_check(self, mock_tnauthin, mock_status, @patch('acme_srv.certificate.cert_san_get') @patch('acme_srv.certificate.Certificate._identifer_status_list') @patch('acme_srv.certificate.Certificate._tnauth_identifier_check') - def test_093_certificate__authorization_check(self, mock_tnauthin, mock_status, mock_san): + def test_095_certificate__authorization_check(self, mock_tnauthin, mock_status, mock_san): """ _authorization_check no tnauth status True, False, True """ mock_san.return_value = ['foo'] mock_tnauthin.return_value = False @@ -748,7 +770,7 @@ def test_093_certificate__authorization_check(self, mock_tnauthin, mock_status, @patch('acme_srv.certificate.cert_san_get') @patch('acme_srv.certificate.Certificate._identifer_tnauth_list') @patch('acme_srv.certificate.Certificate._tnauth_identifier_check') - def test_094_certificate__authorization_check(self, mock_tnauthin, mock_status, mock_san): + def test_096_certificate__authorization_check(self, mock_tnauthin, mock_status, mock_san): """ _authorization_check tnauth but tnauthlist_support off """ mock_san.return_value = ['foo'] mock_tnauthin.return_value = True @@ -759,7 +781,7 @@ def test_094_certificate__authorization_check(self, mock_tnauthin, mock_status, @patch('acme_srv.certificate.cert_extensions_get') @patch('acme_srv.certificate.Certificate._identifer_tnauth_list') @patch('acme_srv.certificate.Certificate._tnauth_identifier_check') - def test_095_certificate__authorization_check(self, mock_tnauthin, mock_status, mock_san): + def test_097_certificate__authorization_check(self, mock_tnauthin, mock_status, mock_san): """ _authorization_check tnauth but tnauthlist_support on and returns true """ mock_san.return_value = ['foo'] mock_tnauthin.return_value = True @@ -771,7 +793,7 @@ def test_095_certificate__authorization_check(self, mock_tnauthin, mock_status, @patch('acme_srv.certificate.cert_extensions_get') @patch('acme_srv.certificate.Certificate._identifer_tnauth_list') @patch('acme_srv.certificate.Certificate._tnauth_identifier_check') - def test_096_certificate__authorization_check(self, mock_tnauthin, mock_status, mock_san): + def test_098_certificate__authorization_check(self, mock_tnauthin, mock_status, mock_san): """ _authorization_check tnauth but tnauthlist_support on and returns true """ mock_san.return_value = ['foo'] mock_tnauthin.return_value = True @@ -783,7 +805,7 @@ def test_096_certificate__authorization_check(self, mock_tnauthin, mock_status, @patch('acme_srv.certificate.cert_extensions_get') @patch('acme_srv.certificate.Certificate._identifer_tnauth_list') @patch('acme_srv.certificate.Certificate._tnauth_identifier_check') - def test_097_certificate__authorization_check(self, mock_tnauthin, mock_status, mock_san): + def test_099_certificate__authorization_check(self, mock_tnauthin, mock_status, mock_san): """ _authorization_check tnauth but tnauthlist_support on and returns True, False """ mock_san.return_value = ['foo'] mock_tnauthin.return_value = True @@ -795,7 +817,7 @@ def test_097_certificate__authorization_check(self, mock_tnauthin, mock_status, @patch('acme_srv.certificate.cert_extensions_get') @patch('acme_srv.certificate.Certificate._identifer_tnauth_list') @patch('acme_srv.certificate.Certificate._tnauth_identifier_check') - def test_098_certificate__authorization_check(self, mock_tnauthin, mock_status, mock_san): + def test_100_certificate__authorization_check(self, mock_tnauthin, mock_status, mock_san): """ _authorization_check tnauth but tnauthlist_support on and returns True, False """ mock_san.return_value = ['foo'] mock_tnauthin.return_value = True @@ -805,7 +827,7 @@ def test_098_certificate__authorization_check(self, mock_tnauthin, mock_status, self.assertFalse(self.certificate._authorization_check('cert_name', 'cert')) @patch('acme_srv.certificate.Certificate._csr_check') - def test_099_certificate_enroll_and_store(self, mock_csr): + def test_101_certificate_enroll_and_store(self, mock_csr): """ Certificate.enroll_and_store() csr_check failed """ mock_csr.return_value = False certificate_name = 'cert_name' @@ -815,7 +837,7 @@ def test_099_certificate_enroll_and_store(self, mock_csr): @patch('acme_srv.threadwithreturnvalue.ThreadWithReturnValue.join') @patch('acme_srv.threadwithreturnvalue.ThreadWithReturnValue.start') @patch('acme_srv.certificate.Certificate._csr_check') - def test_100_certificate_enroll_and_store(self, mock_csr, tr_start, tr_join): + def test_102_certificate_enroll_and_store(self, mock_csr, tr_start, tr_join): """ Certificate.enroll_and_store() csr_check successful - timeout during enrollment """ mock_csr.return_value = True tr_start.return_value = True @@ -827,7 +849,7 @@ def test_100_certificate_enroll_and_store(self, mock_csr, tr_start, tr_join): @patch('acme_srv.threadwithreturnvalue.ThreadWithReturnValue.join') @patch('acme_srv.threadwithreturnvalue.ThreadWithReturnValue.start') @patch('acme_srv.certificate.Certificate._csr_check') - def test_101_certificate_enroll_and_store(self, mock_csr, tr_start, tr_join): + def test_103_certificate_enroll_and_store(self, mock_csr, tr_start, tr_join): """ Certificate.enroll_and_store() csr_check successful - enrollment returns something useful """ mock_csr.return_value = True tr_start.return_value = True @@ -839,7 +861,7 @@ def test_101_certificate_enroll_and_store(self, mock_csr, tr_start, tr_join): @patch('acme_srv.threadwithreturnvalue.ThreadWithReturnValue.join') @patch('acme_srv.threadwithreturnvalue.ThreadWithReturnValue.start') @patch('acme_srv.certificate.Certificate._csr_check') - def test_102_certificate_enroll_and_store(self, mock_csr, tr_start, tr_join): + def test_104_certificate_enroll_and_store(self, mock_csr, tr_start, tr_join): """ Certificate.enroll_and_store() csr_check successful - enrollment returns something unexpected """ mock_csr.return_value = True tr_start.return_value = True @@ -854,7 +876,7 @@ def test_102_certificate_enroll_and_store(self, mock_csr, tr_start, tr_join): @patch('acme_srv.certificate.Certificate._order_update') @patch('acme_srv.certificate.Certificate._store_cert') @patch('acme_srv.certificate.Certificate._store_cert_error') - def test_103_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_oupd, mock_chk): + def test_105_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_oupd, mock_chk): """ Certificate.enroll_and_store() enrollment failed without polling_identifier """ # self.certificate.dbstore.order_update.return_value = 'foo' mock_store_err.return_value = True @@ -877,7 +899,7 @@ def test_103_certificate_enroll_and_store(self, mock_store_err, mock_store, mock @patch('acme_srv.certificate.Certificate._order_update') @patch('acme_srv.certificate.Certificate._store_cert') @patch('acme_srv.certificate.Certificate._store_cert_error') - def test_104_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_oupd, mock_chk): + def test_106_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_oupd, mock_chk): """ Certificate.enroll_and_store() enrollment failed with polling_identifier - no order update """ mock_store_err.return_value = True mock_store.return_value = True @@ -899,7 +921,7 @@ def test_104_certificate_enroll_and_store(self, mock_store_err, mock_store, mock @patch('acme_srv.certificate.Certificate._order_update') @patch('acme_srv.certificate.Certificate._store_cert') @patch('acme_srv.certificate.Certificate._store_cert_error') - def test_105_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_oupd, mock_chk): + def test_107_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_oupd, mock_chk): """ Certificate.enroll_and_store() enrollment failed - exception in store_cert_error""" self.certificate.dbstore.order_update.return_value = 'foo' mock_store_err.side_effect = Exception('ex_cert_error_store') @@ -923,7 +945,7 @@ def test_105_certificate_enroll_and_store(self, mock_store_err, mock_store, mock @patch('acme_srv.certificate.cert_dates_get') @patch('acme_srv.certificate.Certificate._store_cert') @patch('acme_srv.certificate.Certificate._store_cert_error') - def test_106_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_dates, mock_oupd, mock_chk): + def test_108_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_dates, mock_oupd, mock_chk): """ Certificate.enroll_and_store() enrollment succhessful with polling_identifier""" mock_store_err.return_value = True mock_store.return_value = True @@ -946,7 +968,7 @@ def test_106_certificate_enroll_and_store(self, mock_store_err, mock_store, mock @patch('acme_srv.certificate.cert_dates_get') @patch('acme_srv.certificate.Certificate._store_cert') @patch('acme_srv.certificate.Certificate._store_cert_error') - def test_107_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_dates, mock_oupd, mock_chk): + def test_109_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_dates, mock_oupd, mock_chk): """ Certificate.enroll_and_store() enrollment succhessful without polling_identifier""" mock_store_err.return_value = True mock_store.return_value = True @@ -969,7 +991,7 @@ def test_107_certificate_enroll_and_store(self, mock_store_err, mock_store, mock @patch('acme_srv.certificate.cert_dates_get') @patch('acme_srv.certificate.Certificate._store_cert') @patch('acme_srv.certificate.Certificate._store_cert_error') - def test_108_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_dates, mock_oupd, mock_chk): + def test_110_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_dates, mock_oupd, mock_chk): """ Certificate.enroll_and_store() enrollment succhessful _store_cert returns None """ mock_store_err.return_value = True mock_store.return_value = None @@ -992,7 +1014,7 @@ def test_108_certificate_enroll_and_store(self, mock_store_err, mock_store, mock @patch('acme_srv.certificate.cert_dates_get') @patch('acme_srv.certificate.Certificate._store_cert') @patch('acme_srv.certificate.Certificate._store_cert_error') - def test_109_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_dates, mock_oupd, mock_chk): + def test_111_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_dates, mock_oupd, mock_chk): """ Certificate.enroll_and_store() enrollment Exception in store_cert """ mock_store_err.return_value = True mock_store.side_effect = Exception('ex_cert_store') @@ -1017,7 +1039,7 @@ def test_109_certificate_enroll_and_store(self, mock_store_err, mock_store, mock @patch('acme_srv.certificate.cert_dates_get') @patch('acme_srv.certificate.Certificate._store_cert') @patch('acme_srv.certificate.Certificate._store_cert_error') - def test_110_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_dates, mock_oupd, mock_chk): + def test_112_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_dates, mock_oupd, mock_chk): """ Certificate.enroll_and_store() _cert_reusage_check successful """ self.certificate.cert_reusage_timeframe = 86400 mock_chk.return_value = (None, 'certificate', 'certificate_raw', 'poll_identifier') @@ -1042,7 +1064,7 @@ def test_110_certificate_enroll_and_store(self, mock_store_err, mock_store, mock @patch('acme_srv.certificate.cert_dates_get') @patch('acme_srv.certificate.Certificate._store_cert') @patch('acme_srv.certificate.Certificate._store_cert_error') - def test_111_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_dates, mock_oupd, mock_chk): + def test_113_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_dates, mock_oupd, mock_chk): """ Certificate.enroll_and_store() _cert_reusage_check no cert """ self.certificate.cert_reusage_timeframe = 86400 mock_chk.return_value = (None, None, 'certificate_raw', 'poll_identifier') @@ -1067,7 +1089,7 @@ def test_111_certificate_enroll_and_store(self, mock_store_err, mock_store, mock @patch('acme_srv.certificate.cert_dates_get') @patch('acme_srv.certificate.Certificate._store_cert') @patch('acme_srv.certificate.Certificate._store_cert_error') - def test_112_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_dates, mock_oupd, mock_chk): + def test_114_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_dates, mock_oupd, mock_chk): """ Certificate.enroll_and_store() _cert_reusage_check no cert_raw """ self.certificate.cert_reusage_timeframe = 86400 mock_chk.return_value = (None, 'certificate', None, 'poll_identifier') @@ -1092,7 +1114,7 @@ def test_112_certificate_enroll_and_store(self, mock_store_err, mock_store, mock @patch('acme_srv.certificate.cert_dates_get') @patch('acme_srv.certificate.Certificate._store_cert') @patch('acme_srv.certificate.Certificate._store_cert_error') - def test_113_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_dates, mock_oupd, mock_chk): + def test_115_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_dates, mock_oupd, mock_chk): """ Certificate.enroll_and_store() _cert_reusage_check no cert and no cert_raw """ self.certificate.cert_reusage_timeframe = 86400 mock_chk.return_value = (None, None, None, 'poll_identifier') @@ -1117,7 +1139,7 @@ def test_113_certificate_enroll_and_store(self, mock_store_err, mock_store, mock @patch('acme_srv.certificate.cert_dates_get') @patch('acme_srv.certificate.Certificate._store_cert') @patch('acme_srv.certificate.Certificate._store_cert_error') - def test_114_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_dates, mock_oupd, mock_chk): + def test_116_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_dates, mock_oupd, mock_chk): """ Certificate.enroll_and_store() enrollment hooks successful """ hooks_module = importlib.import_module('examples.hooks.skeleton_hooks') self.certificate.hooks = hooks_module.Hooks(self.logger) @@ -1148,7 +1170,7 @@ def test_114_certificate_enroll_and_store(self, mock_store_err, mock_store, mock @patch('acme_srv.certificate.cert_dates_get') @patch('acme_srv.certificate.Certificate._store_cert') @patch('acme_srv.certificate.Certificate._store_cert_error') - def test_115_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_dates, mock_oupd, mock_chk): + def test_117_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_dates, mock_oupd, mock_chk): """ Certificate.enroll_and_store() enrollment pre_hook exception """ hooks_module = importlib.import_module('examples.hooks.skeleton_hooks') self.certificate.hooks = hooks_module.Hooks(self.logger) @@ -1181,7 +1203,7 @@ def test_115_certificate_enroll_and_store(self, mock_store_err, mock_store, mock @patch('acme_srv.certificate.cert_dates_get') @patch('acme_srv.certificate.Certificate._store_cert') @patch('acme_srv.certificate.Certificate._store_cert_error') - def test_116_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_dates, mock_oupd, mock_chk): + def test_118_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_dates, mock_oupd, mock_chk): """ Certificate.enroll_and_store() enrollment pre_hook exception / ingore_pre_hook_failure is set to true """ hooks_module = importlib.import_module('examples.hooks.skeleton_hooks') self.certificate.hooks = hooks_module.Hooks(self.logger) @@ -1215,7 +1237,7 @@ def test_116_certificate_enroll_and_store(self, mock_store_err, mock_store, mock @patch('acme_srv.certificate.cert_dates_get') @patch('acme_srv.certificate.Certificate._store_cert') @patch('acme_srv.certificate.Certificate._store_cert_error') - def test_117_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_dates, mock_oupd, mock_chk): + def test_119_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_dates, mock_oupd, mock_chk): """ Certificate.enroll_and_store() enrollment pre_hook exception / ingore_pre_hook_failure is set to false """ hooks_module = importlib.import_module('examples.hooks.skeleton_hooks') self.certificate.hooks = hooks_module.Hooks(self.logger) @@ -1249,7 +1271,7 @@ def test_117_certificate_enroll_and_store(self, mock_store_err, mock_store, mock @patch('acme_srv.certificate.cert_dates_get') @patch('acme_srv.certificate.Certificate._store_cert') @patch('acme_srv.certificate.Certificate._store_cert_error') - def test_118_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_dates, mock_oupd, mock_chk): + def test_120_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_dates, mock_oupd, mock_chk): """ Certificate.enroll_and_store() enrollment success_hook exception """ hooks_module = importlib.import_module('examples.hooks.skeleton_hooks') self.certificate.hooks = hooks_module.Hooks(self.logger) @@ -1282,7 +1304,7 @@ def test_118_certificate_enroll_and_store(self, mock_store_err, mock_store, mock @patch('acme_srv.certificate.cert_dates_get') @patch('acme_srv.certificate.Certificate._store_cert') @patch('acme_srv.certificate.Certificate._store_cert_error') - def test_119_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_dates, mock_oupd, mock_chk): + def test_121_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_dates, mock_oupd, mock_chk): """ Certificate.enroll_and_store() enrollment success_hook exception / ignore_success_hook_failure is set to False """ hooks_module = importlib.import_module('examples.hooks.skeleton_hooks') self.certificate.hooks = hooks_module.Hooks(self.logger) @@ -1316,7 +1338,7 @@ def test_119_certificate_enroll_and_store(self, mock_store_err, mock_store, mock @patch('acme_srv.certificate.cert_dates_get') @patch('acme_srv.certificate.Certificate._store_cert') @patch('acme_srv.certificate.Certificate._store_cert_error') - def test_120_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_dates, mock_oupd, mock_chk): + def test_122_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_dates, mock_oupd, mock_chk): """ Certificate.enroll_and_store() enrollment success_hook exception / ignore_success_hook_failure is set to True """ hooks_module = importlib.import_module('examples.hooks.skeleton_hooks') self.certificate.hooks = hooks_module.Hooks(self.logger) @@ -1350,7 +1372,7 @@ def test_120_certificate_enroll_and_store(self, mock_store_err, mock_store, mock @patch('acme_srv.certificate.cert_dates_get') @patch('acme_srv.certificate.Certificate._store_cert') @patch('acme_srv.certificate.Certificate._store_cert_error') - def test_121_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_dates, mock_oupd, mock_chk): + def test_123_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_dates, mock_oupd, mock_chk): """ Certificate.enroll_and_store() enrollment post_hook exception """ hooks_module = importlib.import_module('examples.hooks.skeleton_hooks') self.certificate.hooks = hooks_module.Hooks(self.logger) @@ -1383,7 +1405,7 @@ def test_121_certificate_enroll_and_store(self, mock_store_err, mock_store, mock @patch('acme_srv.certificate.cert_dates_get') @patch('acme_srv.certificate.Certificate._store_cert') @patch('acme_srv.certificate.Certificate._store_cert_error') - def test_122_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_dates, mock_oupd, mock_chk): + def test_124_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_dates, mock_oupd, mock_chk): """ Certificate.enroll_and_store() enrollment post_hook exception / ignore_post_hook_failure is set to True """ hooks_module = importlib.import_module('examples.hooks.skeleton_hooks') self.certificate.hooks = hooks_module.Hooks(self.logger) @@ -1417,7 +1439,7 @@ def test_122_certificate_enroll_and_store(self, mock_store_err, mock_store, mock @patch('acme_srv.certificate.cert_dates_get') @patch('acme_srv.certificate.Certificate._store_cert') @patch('acme_srv.certificate.Certificate._store_cert_error') - def test_123_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_dates, mock_oupd, mock_chk): + def test_125_certificate_enroll_and_store(self, mock_store_err, mock_store, mock_dates, mock_oupd, mock_chk): """ Certificate.enroll_and_store() enrollment post_hook exception / ignore_post_hook_failure is set to False """ hooks_module = importlib.import_module('examples.hooks.skeleton_hooks') self.certificate.hooks = hooks_module.Hooks(self.logger) @@ -1446,44 +1468,44 @@ def test_123_certificate_enroll_and_store(self, mock_store_err, mock_store, mock self.assertTrue(self.certificate.hooks.success_hook.called) self.assertTrue(self.certificate.hooks.post_hook.called) - def test_124_certificate__invalidation_check(self): + def test_126_certificate__invalidation_check(self): """ test Certificate._invalidation_check() - empty dict """ cert_entry = {} timestamp = 1596240000 self.assertEqual((True, {}), self.certificate._invalidation_check(cert_entry, timestamp)) - def test_125_certificate__invalidation_check(self): + def test_127_certificate__invalidation_check(self): """ test Certificate._invalidation_check() - wrong dict """ cert_entry = {'foo': 'bar'} timestamp = 1596240000 self.assertEqual((True, {'foo': 'bar'}), self.certificate._invalidation_check(cert_entry, timestamp)) - def test_126_certificate__invalidation_check(self): + def test_128_certificate__invalidation_check(self): """ test Certificate._invalidation_check() - certname in but rest ist wrong """ cert_entry = {'name': 'certname', 'foo': 'bar'} timestamp = 1596240000 self.assertEqual((False, {'name': 'certname', 'foo': 'bar'}), self.certificate._invalidation_check(cert_entry, timestamp)) - def test_127_certificate__invalidation_check(self): + def test_129_certificate__invalidation_check(self): """ test Certificate._invalidation_check() - non zero expiry date """ cert_entry = {'name': 'certname', 'expire_uts': 10} timestamp = 1596240000 self.assertEqual((True, {'expire_uts': 10, 'name': 'certname'}), self.certificate._invalidation_check(cert_entry, timestamp)) - def test_128_certificate__invalidation_check(self): + def test_130_certificate__invalidation_check(self): """ test Certificate._invalidation_check() - expire_uts zero but no cert_raw """ cert_entry = {'name': 'certname', 'expire_uts': 0} timestamp = 1596240000 self.assertEqual((True, {'expire_uts': 0, 'name': 'certname'}), self.certificate._invalidation_check(cert_entry, timestamp)) - def test_129_certificate__invalidation_check(self): + def test_131_certificate__invalidation_check(self): """ test Certificate._invalidation_check() - expire_uts zero but no cert_raw """ cert_entry = {'name': 'certname', 'expire_uts': 0, 'cert_raw': 'cert_raw'} timestamp = 1596240000 self.assertEqual((False, {'expire_uts': 0, 'name': 'certname', 'cert_raw': 'cert_raw'}), self.certificate._invalidation_check(cert_entry, timestamp)) @patch('acme_srv.certificate.cert_dates_get') - def test_130_certificate__invalidation_check(self, mock_dates): + def test_132_certificate__invalidation_check(self, mock_dates): """ test Certificate._invalidation_check() - with expiry date lower than timestamp """ cert_entry = {'name': 'certname', 'expire_uts': 0, 'cert_raw': 'cert_raw'} mock_dates.return_value = (10, 1596200000) @@ -1491,7 +1513,7 @@ def test_130_certificate__invalidation_check(self, mock_dates): self.assertEqual((True, {'expire_uts': 1596200000, 'issue_uts': 10, 'name': 'certname', 'cert_raw': 'cert_raw'}), self.certificate._invalidation_check(cert_entry, timestamp)) @patch('acme_srv.certificate.cert_dates_get') - def test_131_certificate__invalidation_check(self, mock_dates): + def test_133_certificate__invalidation_check(self, mock_dates): """ test Certificate._invalidation_check() - with expiry date at timestamp """ cert_entry = {'name': 'certname', 'expire_uts': 0, 'cert_raw': 'cert_raw'} mock_dates.return_value = (10, 1596240000) @@ -1499,21 +1521,21 @@ def test_131_certificate__invalidation_check(self, mock_dates): self.assertEqual((False, {'expire_uts': 0, 'name': 'certname', 'cert_raw': 'cert_raw'}), self.certificate._invalidation_check(cert_entry, timestamp)) @patch('acme_srv.certificate.cert_dates_get') - def test_132_certificate__invalidation_check(self, mock_dates): + def test_134_certificate__invalidation_check(self, mock_dates): """ test Certificate._invalidation_check() - with expiry date higher than timestamp """ cert_entry = {'name': 'certname', 'expire_uts': 0, 'cert_raw': 'cert_raw'} mock_dates.return_value = (10, 1596250000) timestamp = 1596240000 self.assertEqual((False, {'expire_uts': 0, 'name': 'certname', 'cert_raw': 'cert_raw'}), self.certificate._invalidation_check(cert_entry, timestamp)) - def test_133_certificate__invalidation_check(self): + def test_135_certificate__invalidation_check(self): """ test Certificate._invalidation_check() - without created_at date """ cert_entry = {'name': 'certname', 'expire_uts': 0, 'csr': 'csr'} timestamp = 1596240000 self.assertEqual((False, {'expire_uts': 0, 'name': 'certname', 'csr': 'csr'}), self.certificate._invalidation_check(cert_entry, timestamp)) @patch('acme_srv.certificate.date_to_uts_utc') - def test_134_certificate__invalidation_check(self, mock_date): + def test_136_certificate__invalidation_check(self, mock_date): """ test Certificate._invalidation_check() - with zero created_at date """ cert_entry = {'name': 'certname', 'expire_uts': 0, 'csr': 'csr', 'created_at': 'created_at'} mock_date.return_value = 0 @@ -1521,7 +1543,7 @@ def test_134_certificate__invalidation_check(self, mock_date): self.assertEqual((False, {'expire_uts': 0, 'name': 'certname', 'csr': 'csr', 'created_at': 'created_at'}), self.certificate._invalidation_check(cert_entry, timestamp)) @patch('acme_srv.certificate.date_to_uts_utc') - def test_135_certificate__invalidation_check(self, mock_date): + def test_137_certificate__invalidation_check(self, mock_date): """ test Certificate._invalidation_check() - with zero created_at date lower than threshold""" cert_entry = {'name': 'certname', 'expire_uts': 0, 'csr': 'csr', 'created_at': 'created_at'} mock_date.return_value = 1591240000 @@ -1529,39 +1551,39 @@ def test_135_certificate__invalidation_check(self, mock_date): self.assertEqual((True, {'expire_uts': 0, 'name': 'certname', 'csr': 'csr', 'created_at': 'created_at'}), self.certificate._invalidation_check(cert_entry, timestamp)) @patch('acme_srv.certificate.date_to_uts_utc') - def test_136_certificate__invalidation_check(self, mock_date): + def test_138_certificate__invalidation_check(self, mock_date): """ test Certificate._invalidation_check() - with zero created_at higher than threshold """ cert_entry = {'name': 'certname', 'expire_uts': 0, 'csr': 'csr', 'created_at': 'created_at'} mock_date.return_value = 1596220000 timestamp = 1596240000 self.assertEqual((False, {'expire_uts': 0, 'name': 'certname', 'csr': 'csr', 'created_at': 'created_at'}), self.certificate._invalidation_check(cert_entry, timestamp)) - def test_137_certificate__invalidation_check(self): + def test_139_certificate__invalidation_check(self): """ test Certificate._invalidation_check() - removed by in cert """ cert_entry = {'name': 'certname', 'cert': 'removed by foo-bar', 'foo': 'bar'} timestamp = 159624000 self.assertEqual((False, {'name': 'certname', 'cert': 'removed by foo-bar', 'foo': 'bar'}), self.certificate._invalidation_check(cert_entry, timestamp)) - def test_138_certificate__invalidation_check(self): + def test_140_certificate__invalidation_check(self): """ test Certificate._invalidation_check() - removed by in cert """ cert_entry = {'name': 'certname', 'cert': 'removed by foo-bar', 'foo': 'bar'} timestamp = 159624000 self.assertEqual((True, {'name': 'certname', 'cert': 'removed by foo-bar', 'foo': 'bar'}), self.certificate._invalidation_check(cert_entry, timestamp, True)) - def test_139_certificate__invalidation_check(self): + def test_141_certificate__invalidation_check(self): """ test Certificate._invalidation_check() - removed by in cert but in upper-cases """ cert_entry = {'name': 'certname', 'cert': 'ReMoved By foo-bar', 'foo': 'bar'} timestamp = 159624000 self.assertEqual((False, {'name': 'certname', 'cert': 'ReMoved By foo-bar', 'foo': 'bar'}), self.certificate._invalidation_check(cert_entry, timestamp)) - def test_140_certificate__invalidation_check(self): + def test_142_certificate__invalidation_check(self): """ test Certificate._invalidation_check() - cert None """ cert_entry = {'name': 'certname', 'cert': None, 'foo': 'bar'} timestamp = 159624000 self.assertEqual((False, {'name': 'certname', 'cert': None, 'foo': 'bar'}), self.certificate._invalidation_check(cert_entry, timestamp)) @patch('acme_srv.certificate.Certificate._renewal_info_get') - def test_141_certificate_poll(self, mock_renew): + def test_143_certificate_poll(self, mock_renew): """ test Certificate.poll - dbstore.order_update() raises an exception """ self.certificate.dbstore.order_update.side_effect = Exception('exc_cert_poll') ca_handler_module = importlib.import_module('examples.ca_handler.skeleton_ca_handler') @@ -1573,7 +1595,7 @@ def test_141_certificate_poll(self, mock_renew): self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Certificate.poll(): exc_cert_poll', lcm.output) self.assertTrue(mock_renew.called) - def test_142_certificate_poll(self): + def test_144_certificate_poll(self): """ test Certificate.poll - dbstore.order_update() raises an exception and certreq rejected """ self.certificate.dbstore.order_update.side_effect = Exception('exc_cert_poll') ca_handler_module = importlib.import_module('examples.ca_handler.skeleton_ca_handler') @@ -1584,7 +1606,7 @@ def test_142_certificate_poll(self): self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Certificate.poll(): exc_cert_poll', lcm.output) @patch('acme_srv.certificate.Certificate._renewal_info_get') - def test_143_certificate__store_cert(self, mock_renew): + def test_145_certificate__store_cert(self, mock_renew): """ test Certificate.store_cert() - dbstore.certificate_add raises an exception """ self.certificate.dbstore.certificate_add.side_effect = Exception('exc_cert_add') mock_renew.return_value = 'renewal_info' @@ -1593,21 +1615,21 @@ def test_143_certificate__store_cert(self, mock_renew): self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Certificate._store_cert(): exc_cert_add', lcm.output) self.assertTrue(mock_renew.called) - def test_144_certificate__store_cert_error(self): + def test_146_certificate__store_cert_error(self): """ test Certificate.store_cert_error() - dbstore.certificate_add raises an exception """ self.certificate.dbstore.certificate_add.side_effect = Exception('exc_cert_add_error') with self.assertLogs('test_a2c', level='INFO') as lcm: self.certificate._store_cert_error('cert_name', 'error', 'poll') self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Certificate._store_cert(): exc_cert_add_error', lcm.output) - def test_145_certificate__account_check(self): + def test_147_certificate__account_check(self): """ test Certificate._account_check() - dbstore.certificate_account_check raises an exception """ self.certificate.dbstore.certificate_account_check.side_effect = Exception('exc_acc_chk') with self.assertLogs('test_a2c', level='INFO') as lcm: self.certificate._account_check('account_name', 'cert') self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Certificate._account_check(): exc_acc_chk', lcm.output) - def test_146_certificate__authorization_check(self): + def test_148_certificate__authorization_check(self): """ test Certificate._authorization_check() - dbstore.certificate_account_check raises an exception """ self.certificate.dbstore.order_lookup.side_effect = Exception('exc_authz_chk') with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -1615,7 +1637,7 @@ def test_146_certificate__authorization_check(self): self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Certificate._authorization_check(): exc_authz_chk', lcm.output) @patch('acme_srv.certificate.Certificate._info') - def test_147_certificate__csr_check(self, mock_certinfo): + def test_149_certificate__csr_check(self, mock_certinfo): """ csr-check - dbstore.order_lookup() raises an exception """ mock_certinfo.return_value = {'order': 'order'} self.certificate.dbstore.order_lookup.side_effect = Exception('exc_csr_chk') @@ -1624,7 +1646,7 @@ def test_147_certificate__csr_check(self, mock_certinfo): self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Certificate._csr_check(): exc_csr_chk', lcm.output) # self.certificate.dbstore.order_lookup.side_effect = [] - def test_148_certificate__info(self): + def test_150_certificate__info(self): """ test Certificate._info - dbstore.certificate_lookup() raises an exception """ self.certificate.dbstore.certificate_lookup.side_effect = Exception('exc_cert_info') with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -1632,7 +1654,7 @@ def test_148_certificate__info(self): self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Certificate._info(): exc_cert_info', lcm.output) @patch('acme_srv.certificate.uts_now') - def test_149__cert_reusage_check(self, mock_uts): + def test_151__cert_reusage_check(self, mock_uts): """ test Certificate._cert_reusage_check() - one certificate returned """ self.certificate.cert_reusage_timeframe = 86400 mock_uts.return_value = 90000 @@ -1641,7 +1663,7 @@ def test_149__cert_reusage_check(self, mock_uts): self.assertEqual((None, 'cert1', 'cert_raw1', 'reused certificate from id: 1'), self.certificate._cert_reusage_check('csr')) @patch('acme_srv.certificate.uts_now') - def test_150__cert_reusage_check(self, mock_uts): + def test_152__cert_reusage_check(self, mock_uts): """ test Certificate._cert_reusage_check() - two certificates found """ self.certificate.cert_reusage_timeframe = 86400 mock_uts.return_value = 90000 @@ -1653,7 +1675,7 @@ def test_150__cert_reusage_check(self, mock_uts): self.assertEqual((None, 'cert2', 'cert_raw2', 'reused certificate from id: 2'), self.certificate._cert_reusage_check('csr')) @patch('acme_srv.certificate.uts_now') - def test_151__cert_reusage_check(self, mock_uts): + def test_153__cert_reusage_check(self, mock_uts): """ test Certificate._cert_reusage_check() - three certificates found """ self.certificate.cert_reusage_timeframe = 86400 mock_uts.return_value = 90000 @@ -1666,7 +1688,7 @@ def test_151__cert_reusage_check(self, mock_uts): self.assertEqual((None, 'cert3', 'cert_raw3', 'reused certificate from id: 3'), self.certificate._cert_reusage_check('csr')) @patch('acme_srv.certificate.uts_now') - def test_152__cert_reusage_check(self, mock_uts): + def test_154__cert_reusage_check(self, mock_uts): """ test Certificate._cert_reusage_check() - three certificates found in wrong order """ self.certificate.cert_reusage_timeframe = 86400 mock_uts.return_value = 90000 @@ -1679,7 +1701,7 @@ def test_152__cert_reusage_check(self, mock_uts): self.assertEqual((None, 'cert3', 'cert_raw3', 'reused certificate from id: 3'), self.certificate._cert_reusage_check('csr')) @patch('acme_srv.certificate.uts_now') - def test_153__cert_reusage_check(self, mock_uts): + def test_155__cert_reusage_check(self, mock_uts): """ test Certificate._cert_reusage_check() - three certificates found latest certificate exipred """ self.certificate.cert_reusage_timeframe = 86400 mock_uts.return_value = 90000 @@ -1692,7 +1714,7 @@ def test_153__cert_reusage_check(self, mock_uts): self.assertEqual((None, 'cert2', 'cert_raw2', 'reused certificate from id: 2'), self.certificate._cert_reusage_check('csr')) @patch('acme_srv.certificate.uts_now') - def test_154__cert_reusage_check(self, mock_uts): + def test_156__cert_reusage_check(self, mock_uts): """ test Certificate._cert_reusage_check() - three certificates found - last certificate empty cert field """ self.certificate.cert_reusage_timeframe = 86400 mock_uts.return_value = 90000 @@ -1705,7 +1727,7 @@ def test_154__cert_reusage_check(self, mock_uts): self.assertEqual((None, 'cert2', 'cert_raw2', 'reused certificate from id: 2'), self.certificate._cert_reusage_check('csr')) @patch('acme_srv.certificate.uts_now') - def test_155__cert_reusage_check(self, mock_uts): + def test_157__cert_reusage_check(self, mock_uts): """ test Certificate._cert_reusage_check() - three certificates found - last certificate empty cert_raw field """ self.certificate.cert_reusage_timeframe = 86400 mock_uts.return_value = 90000 @@ -1718,7 +1740,7 @@ def test_155__cert_reusage_check(self, mock_uts): self.assertEqual((None, 'cert2', 'cert_raw2', 'reused certificate from id: 2'), self.certificate._cert_reusage_check('csr')) @patch('acme_srv.certificate.uts_now') - def test_156__cert_reusage_check(self, mock_uts): + def test_158__cert_reusage_check(self, mock_uts): """ test Certificate._cert_reusage_check() - three certificates found - last certificate empty 'created_add' """ self.certificate.cert_reusage_timeframe = 86400 mock_uts.return_value = 90000 @@ -1733,7 +1755,7 @@ def test_156__cert_reusage_check(self, mock_uts): self.assertIn('ERROR:test_a2c:acme2certifier date_to_uts_utc() error in Certificate._cert_reusage_check(): id:3/created_at:', lcm.output) @patch('acme_srv.certificate.uts_now') - def test_157__cert_reusage_check(self, mock_uts): + def test_159__cert_reusage_check(self, mock_uts): """ test Certificate._cert_reusage_check() - three certificates found last certificate out of range """ self.certificate.cert_reusage_timeframe = 43200 mock_uts.return_value = 100000 @@ -1746,7 +1768,7 @@ def test_157__cert_reusage_check(self, mock_uts): self.assertEqual((None, 'cert2', 'cert_raw2', 'reused certificate from id: 2'), self.certificate._cert_reusage_check('csr')) @patch('acme_srv.certificate.uts_now') - def test_158__cert_reusage_check(self, mock_uts): + def test_160__cert_reusage_check(self, mock_uts): """ test Certificate._cert_reusage_check() - no match """ self.certificate.cert_reusage_timeframe = 86400 mock_uts.return_value = 200000 @@ -1759,7 +1781,7 @@ def test_158__cert_reusage_check(self, mock_uts): self.assertEqual((None, None, None, None), self.certificate._cert_reusage_check('csr')) @patch('acme_srv.certificate.Certificate._invalidation_check') - def test_159_certificate_cleanup(self, mock_chk): + def test_161_certificate_cleanup(self, mock_chk): """ test Certificate.cleanup - dbstore.certificate_add() raises an exception """ mock_chk.return_value = (True, {'name': 'name', 'expire_uts': 1543640400, 'issue_uts': 1543640400, 'cert_raw': 'cert_raw'}) self.certificate.dbstore.certificates_search.return_value = [{'name', 'name'},] @@ -1769,7 +1791,7 @@ def test_159_certificate_cleanup(self, mock_chk): self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Certificate.cleanup() add: exc_cert_cleanup1', lcm.output) @patch('acme_srv.certificate.Certificate._invalidation_check') - def test_160_certificate_cleanup(self, mock_chk): + def test_162_certificate_cleanup(self, mock_chk): """ test Certificate.cleanup - dbstore.certificate_delete() raises an exception """ mock_chk.return_value = (True, {'id': 2, 'name': 'name', 'expire_uts': 1543640400, 'issue_uts': 1543640400, 'cert_raw': 'cert_raw'}) self.certificate.dbstore.certificates_search.return_value = [{'name', 'name'},] @@ -1778,7 +1800,7 @@ def test_160_certificate_cleanup(self, mock_chk): self.certificate.cleanup(1543640400, True) self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Certificate.cleanup() delete: exc_cert_cleanup2', lcm.output) - def test_161_certificate_cleanup(self): + def test_163_certificate_cleanup(self): """ test Certificate.cleanup - dbstore.certificates_search() raises an exception """ self.certificate.dbstore.certificates_search.side_effect = Exception('exc_cert_cleanup') with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -1786,7 +1808,7 @@ def test_161_certificate_cleanup(self): self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Certificate.cleanup() search: exc_cert_cleanup', lcm.output) @patch('acme_srv.certificate.uts_now') - def test_162__cert_reusage_check(self, mock_uts): + def test_164__cert_reusage_check(self, mock_uts): """ test Certificate._cert_reusage_check() - one certificate returned """ self.certificate.cert_reusage_timeframe = 86400 mock_uts.return_value = 90000 @@ -1796,7 +1818,7 @@ def test_162__cert_reusage_check(self, mock_uts): self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Certificate._cert_reusage_check(): ex_cert_reusage', lcm.output) @patch('acme_srv.certificate.load_config') - def test_163_config_load(self, mock_load_cfg): + def test_165_config_load(self, mock_load_cfg): """ test _config_load empty dictionary """ mock_load_cfg.return_value = {} self.certificate._config_load() @@ -1807,7 +1829,7 @@ def test_163_config_load(self, mock_load_cfg): self.assertFalse(self.certificate.ignore_success_hook_failure) @patch('acme_srv.certificate.load_config') - def test_164_config_load(self, mock_load_cfg): + def test_166_config_load(self, mock_load_cfg): """ test _config_load missing ca_handler """ mock_load_cfg.return_value = {} with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -1819,7 +1841,7 @@ def test_164_config_load(self, mock_load_cfg): self.assertFalse(self.certificate.ignore_success_hook_failure) @patch('acme_srv.certificate.load_config') - def test_165_config_load(self, mock_load_cfg): + def test_167_config_load(self, mock_load_cfg): """ test _config_load missing ca_handler """ parser = configparser.ConfigParser() parser['Order'] = {'tnauthlist_support': False} @@ -1830,9 +1852,10 @@ def test_165_config_load(self, mock_load_cfg): self.assertFalse(self.certificate.ignore_pre_hook_failure) self.assertTrue(self.certificate.ignore_post_hook_failure) self.assertFalse(self.certificate.ignore_success_hook_failure) + self.assertFalse(self.certificate.cn2san_add) @patch('acme_srv.certificate.load_config') - def test_166_config_load(self, mock_load_cfg): + def test_168_config_load(self, mock_load_cfg): """ test _config_load missing ca_handler """ parser = configparser.ConfigParser() parser['Order'] = {'tnauthlist_support': True} @@ -1843,10 +1866,11 @@ def test_166_config_load(self, mock_load_cfg): self.assertFalse(self.certificate.ignore_pre_hook_failure) self.assertTrue(self.certificate.ignore_post_hook_failure) self.assertFalse(self.certificate.ignore_success_hook_failure) + self.assertFalse(self.certificate.cn2san_add) @patch('acme_srv.certificate.ca_handler_load') @patch('acme_srv.certificate.load_config') - def test_167_config_load(self, mock_load_cfg, mock_handler): + def test_169_config_load(self, mock_load_cfg, mock_handler): """ test _config_load missing ca_handler """ parser = configparser.ConfigParser() parser['CAhandler'] = {'handler_file': 'foo'} @@ -1859,10 +1883,28 @@ def test_167_config_load(self, mock_load_cfg, mock_handler): self.assertFalse(self.certificate.ignore_pre_hook_failure) self.assertTrue(self.certificate.ignore_post_hook_failure) self.assertFalse(self.certificate.ignore_success_hook_failure) + self.assertFalse(self.certificate.cn2san_add) + + @patch('acme_srv.certificate.ca_handler_load') + @patch('acme_srv.certificate.load_config') + def test_170_config_load(self, mock_load_cfg, mock_handler): + """ test _config_load missing ca_handler """ + parser = configparser.ConfigParser() + parser['CAhandler'] = {'handler_file': 'examples/ca_handler/asa_ca_handler.py'} + mock_load_cfg.return_value = parser + mock_handler.return_value = None + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.certificate._config_load() + self.assertIn('CRITICAL:test_a2c:Certificate._config_load(): No ca_handler loaded', lcm.output) + self.assertFalse(self.certificate.hooks) + self.assertFalse(self.certificate.ignore_pre_hook_failure) + self.assertTrue(self.certificate.ignore_post_hook_failure) + self.assertFalse(self.certificate.ignore_success_hook_failure) + self.assertTrue(self.certificate.cn2san_add) @patch('importlib.import_module') @patch('acme_srv.certificate.load_config') - def test_168_config_load(self, mock_load_cfg, mock_imp): + def test_171_config_load(self, mock_load_cfg, mock_imp): """ test _config_load missing ca_handler """ parser = configparser.ConfigParser() parser['CAhandler'] = {'handler_file': 'foo'} @@ -1874,9 +1916,10 @@ def test_168_config_load(self, mock_load_cfg, mock_imp): self.assertFalse(self.certificate.ignore_pre_hook_failure) self.assertTrue(self.certificate.ignore_post_hook_failure) self.assertFalse(self.certificate.ignore_success_hook_failure) + self.assertFalse(self.certificate.cn2san_add) @patch('acme_srv.certificate.load_config') - def test_169_config_load(self, mock_load_cfg): + def test_172_config_load(self, mock_load_cfg): """ test _config_load missing ca_handler """ parser = configparser.ConfigParser() parser['Directory'] = {'foo': 'bar', 'url_prefix': 'url_prefix'} @@ -1888,10 +1931,11 @@ def test_169_config_load(self, mock_load_cfg): self.assertFalse(self.certificate.ignore_pre_hook_failure) self.assertTrue(self.certificate.ignore_post_hook_failure) self.assertFalse(self.certificate.ignore_success_hook_failure) + self.assertFalse(self.certificate.cn2san_add) @patch('importlib.import_module') @patch('acme_srv.certificate.load_config') - def test_170_config_load(self, mock_load_cfg, mock_imp): + def test_173_config_load(self, mock_load_cfg, mock_imp): """ test _config_load ca_handler but no handler_file """ parser = configparser.ConfigParser() parser['CAhandler'] = {'foo': 'bar'} @@ -1905,9 +1949,10 @@ def test_170_config_load(self, mock_load_cfg, mock_imp): self.assertFalse(self.certificate.ignore_pre_hook_failure) self.assertTrue(self.certificate.ignore_post_hook_failure) self.assertFalse(self.certificate.ignore_success_hook_failure) + self.assertFalse(self.certificate.cn2san_add) @patch('acme_srv.certificate.load_config') - def test_171_config_load(self, mock_load_cfg): + def test_174_config_load(self, mock_load_cfg): """ test _config_load no cert_reusage_timeframe """ parser = configparser.ConfigParser() parser['Certificate'] = {'foo': 'bar'} @@ -1919,9 +1964,10 @@ def test_171_config_load(self, mock_load_cfg): self.assertFalse(self.certificate.ignore_pre_hook_failure) self.assertTrue(self.certificate.ignore_post_hook_failure) self.assertFalse(self.certificate.ignore_success_hook_failure) + self.assertFalse(self.certificate.cn2san_add) @patch('acme_srv.certificate.load_config') - def test_172_config_load(self, mock_load_cfg): + def test_175_config_load(self, mock_load_cfg): """ test _config_load cert_reusage_timeframe 120 """ parser = configparser.ConfigParser() parser['Certificate'] = {'cert_reusage_timeframe': 1200} @@ -1932,9 +1978,10 @@ def test_172_config_load(self, mock_load_cfg): self.assertFalse(self.certificate.ignore_pre_hook_failure) self.assertTrue(self.certificate.ignore_post_hook_failure) self.assertFalse(self.certificate.ignore_success_hook_failure) + self.assertFalse(self.certificate.cn2san_add) @patch('acme_srv.certificate.load_config') - def test_173_config_load(self, mock_load_cfg): + def test_176_config_load(self, mock_load_cfg): """ test _config_load cert_reusage_timeframe 0 """ parser = configparser.ConfigParser() parser['Certificate'] = {'cert_reusage_timeframe': 0} @@ -1945,9 +1992,10 @@ def test_173_config_load(self, mock_load_cfg): self.assertFalse(self.certificate.ignore_pre_hook_failure) self.assertTrue(self.certificate.ignore_post_hook_failure) self.assertFalse(self.certificate.ignore_success_hook_failure) + self.assertFalse(self.certificate.cn2san_add) @patch('acme_srv.certificate.load_config') - def test_174_config_load(self, mock_load_cfg): + def test_177_config_load(self, mock_load_cfg): """ test _config_load cert_reusage_timeframe text """ parser = configparser.ConfigParser() parser['Certificate'] = {'cert_reusage_timeframe': 'aaa'} @@ -1960,9 +2008,10 @@ def test_174_config_load(self, mock_load_cfg): self.assertFalse(self.certificate.ignore_pre_hook_failure) self.assertTrue(self.certificate.ignore_post_hook_failure) self.assertFalse(self.certificate.ignore_success_hook_failure) + self.assertFalse(self.certificate.cn2san_add) @patch('acme_srv.certificate.load_config') - def test_175_config_load(self, mock_load_cfg): + def test_178_config_load(self, mock_load_cfg): """ test _config_load enrollment_timeout 120 """ parser = configparser.ConfigParser() parser['Certificate'] = {'enrollment_timeout': 120} @@ -1973,9 +2022,10 @@ def test_175_config_load(self, mock_load_cfg): self.assertFalse(self.certificate.ignore_pre_hook_failure) self.assertTrue(self.certificate.ignore_post_hook_failure) self.assertFalse(self.certificate.ignore_success_hook_failure) + self.assertFalse(self.certificate.cn2san_add) @patch('acme_srv.certificate.load_config') - def test_176_config_load(self, mock_load_cfg): + def test_179_config_load(self, mock_load_cfg): """ test _config_load certificate text """ parser = configparser.ConfigParser() parser['Certificate'] = {'enrollment_timeout': 'aaa'} @@ -1988,10 +2038,11 @@ def test_176_config_load(self, mock_load_cfg): self.assertFalse(self.certificate.ignore_pre_hook_failure) self.assertTrue(self.certificate.ignore_post_hook_failure) self.assertFalse(self.certificate.ignore_success_hook_failure) + self.assertFalse(self.certificate.cn2san_add) @patch('acme_srv.certificate.hooks_load') @patch('acme_srv.certificate.load_config') - def test_177_config_load(self, mock_load_cfg, mock_hooks): + def test_180_config_load(self, mock_load_cfg, mock_hooks): """ test _config_load hooks_load() returns None """ parser = configparser.ConfigParser() parser['Certificate'] = {'enrollment_timeout': 120} @@ -2003,10 +2054,11 @@ def test_177_config_load(self, mock_load_cfg, mock_hooks): self.assertFalse(self.certificate.ignore_pre_hook_failure) self.assertTrue(self.certificate.ignore_post_hook_failure) self.assertFalse(self.certificate.ignore_success_hook_failure) + self.assertFalse(self.certificate.cn2san_add) @patch('acme_srv.certificate.hooks_load') @patch('acme_srv.certificate.load_config') - def test_178_config_load(self, mock_load_cfg, mock_hooks): + def test_181_config_load(self, mock_load_cfg, mock_hooks): """ test _config_load hooks_load() returns module """ parser = configparser.ConfigParser() parser['Certificate'] = {'enrollment_timeout': 120} @@ -2018,10 +2070,11 @@ def test_178_config_load(self, mock_load_cfg, mock_hooks): self.assertFalse(self.certificate.ignore_pre_hook_failure) self.assertTrue(self.certificate.ignore_post_hook_failure) self.assertFalse(self.certificate.ignore_success_hook_failure) + self.assertFalse(self.certificate.cn2san_add) @patch('acme_srv.certificate.hooks_load') @patch('acme_srv.certificate.load_config') - def test_179_config_load(self, mock_load_cfg, mock_hooks): + def test_182_config_load(self, mock_load_cfg, mock_hooks): """ test _config_load hooks_load() returns non-module object """ parser = configparser.ConfigParser() parser['Certificate'] = {'enrollment_timeout': 120} @@ -2035,10 +2088,11 @@ def test_179_config_load(self, mock_load_cfg, mock_hooks): self.assertFalse(self.certificate.ignore_pre_hook_failure) self.assertTrue(self.certificate.ignore_post_hook_failure) self.assertFalse(self.certificate.ignore_success_hook_failure) + self.assertFalse(self.certificate.cn2san_add) @patch('acme_srv.certificate.hooks_load') @patch('acme_srv.certificate.load_config') - def test_180_config_load(self, mock_load_cfg, mock_hooks): + def test_183_config_load(self, mock_load_cfg, mock_hooks): """ test _config_load ignore_pre_hook_failure False """ parser = configparser.ConfigParser() parser['Hooks'] = {'ignore_pre_hook_failure': False} @@ -2052,10 +2106,11 @@ def test_180_config_load(self, mock_load_cfg, mock_hooks): self.assertFalse(self.certificate.ignore_pre_hook_failure) self.assertTrue(self.certificate.ignore_post_hook_failure) self.assertFalse(self.certificate.ignore_success_hook_failure) + self.assertFalse(self.certificate.cn2san_add) @patch('acme_srv.certificate.hooks_load') @patch('acme_srv.certificate.load_config') - def test_181_config_load(self, mock_load_cfg, mock_hooks): + def test_184_config_load(self, mock_load_cfg, mock_hooks): """ test _config_load ignore_pre_hook_failure True """ parser = configparser.ConfigParser() parser['Hooks'] = {'ignore_pre_hook_failure': True} @@ -2069,10 +2124,11 @@ def test_181_config_load(self, mock_load_cfg, mock_hooks): self.assertTrue(self.certificate.ignore_pre_hook_failure) self.assertTrue(self.certificate.ignore_post_hook_failure) self.assertFalse(self.certificate.ignore_success_hook_failure) + self.assertFalse(self.certificate.cn2san_add) @patch('acme_srv.certificate.hooks_load') @patch('acme_srv.certificate.load_config') - def test_182_config_load(self, mock_load_cfg, mock_hooks): + def test_185_config_load(self, mock_load_cfg, mock_hooks): """ test _config_load ignore_post_hook_failure False """ parser = configparser.ConfigParser() parser['Hooks'] = {'ignore_post_hook_failure': False} @@ -2086,10 +2142,11 @@ def test_182_config_load(self, mock_load_cfg, mock_hooks): self.assertFalse(self.certificate.ignore_pre_hook_failure) self.assertFalse(self.certificate.ignore_post_hook_failure) self.assertFalse(self.certificate.ignore_success_hook_failure) + self.assertFalse(self.certificate.cn2san_add) @patch('acme_srv.certificate.hooks_load') @patch('acme_srv.certificate.load_config') - def test_183_config_load(self, mock_load_cfg, mock_hooks): + def test_186_config_load(self, mock_load_cfg, mock_hooks): """ test _config_load ignore_post_hook_failure True """ parser = configparser.ConfigParser() parser['Hooks'] = {'ignore_post_hook_failure': True} @@ -2106,7 +2163,7 @@ def test_183_config_load(self, mock_load_cfg, mock_hooks): @patch('acme_srv.certificate.hooks_load') @patch('acme_srv.certificate.load_config') - def test_184_config_load(self, mock_load_cfg, mock_hooks): + def test_187_config_load(self, mock_load_cfg, mock_hooks): """ test _config_load ignore_success_hook_failure False """ parser = configparser.ConfigParser() parser['Hooks'] = {'ignore_success_hook_failure': False} @@ -2120,10 +2177,11 @@ def test_184_config_load(self, mock_load_cfg, mock_hooks): self.assertFalse(self.certificate.ignore_pre_hook_failure) self.assertTrue(self.certificate.ignore_post_hook_failure) self.assertFalse(self.certificate.ignore_success_hook_failure) + self.assertFalse(self.certificate.cn2san_add) @patch('acme_srv.certificate.hooks_load') @patch('acme_srv.certificate.load_config') - def test_185_config_load(self, mock_load_cfg, mock_hooks): + def test_188_config_load(self, mock_load_cfg, mock_hooks): """ test _config_load ignore_success_hook_failure True """ parser = configparser.ConfigParser() parser['Hooks'] = {'ignore_success_hook_failure': True} @@ -2137,9 +2195,10 @@ def test_185_config_load(self, mock_load_cfg, mock_hooks): self.assertFalse(self.certificate.ignore_pre_hook_failure) self.assertTrue(self.certificate.ignore_post_hook_failure) self.assertTrue(self.certificate.ignore_success_hook_failure) + self.assertFalse(self.certificate.cn2san_add) @patch('acme_srv.certificate.cert_san_get') - def test_186_certificate__authorization_check(self, mock_san): + def test_189_certificate__authorization_check(self, mock_san): """ test Certificate.authorization_check - cert_san_get raises exception) """ self.certificate.dbstore.order_lookup.side_effect = None self.certificate.dbstore.order_lookup.return_value = {'identifiers' : 'test'} @@ -2150,7 +2209,7 @@ def test_186_certificate__authorization_check(self, mock_san): @patch('acme_srv.certificate.Certificate._identifer_status_list') @patch('acme_srv.certificate.cert_san_get') - def test_187_certificate__authorization_check(self, mock_san, mock_statlist): + def test_190_certificate__authorization_check(self, mock_san, mock_statlist): """ test Certificate.authorization_check - cert_san_get raises exception) """ self.certificate.dbstore.order_lookup.side_effect = None self.certificate.dbstore.order_lookup.return_value = {'identifiers' : 'test'} @@ -2162,7 +2221,7 @@ def test_187_certificate__authorization_check(self, mock_san, mock_statlist): @patch('acme_srv.certificate.Certificate._tnauth_identifier_check') @patch('acme_srv.certificate.cert_extensions_get') - def test_188_certificate__authorization_check(self, mock_certext, mock_tnin): + def test_191_certificate__authorization_check(self, mock_certext, mock_tnin): """ test Certificate.authorization_check cert_extensions_get raises exception) """ self.certificate.dbstore.order_lookup.side_effect = None self.certificate.dbstore.order_lookup.return_value = {'identifiers' : 'test'} @@ -2176,7 +2235,7 @@ def test_188_certificate__authorization_check(self, mock_certext, mock_tnin): @patch('acme_srv.certificate.Certificate._identifer_tnauth_list') @patch('acme_srv.certificate.Certificate._tnauth_identifier_check') @patch('acme_srv.certificate.cert_extensions_get') - def test_189_certificate__authorization_check(self, mock_certext, mock_tnin, mock_tnlist): + def test_192_certificate__authorization_check(self, mock_certext, mock_tnin, mock_tnlist): """ test Certificate.authorization_check _identifer_tnauth_list raises exception) """ self.certificate.dbstore.order_lookup.side_effect = None self.certificate.dbstore.order_lookup.return_value = {'identifiers' : 'test'} @@ -2189,13 +2248,13 @@ def test_189_certificate__authorization_check(self, mock_certext, mock_tnin, moc self.assertIn('WARNING:test_a2c:Certificate._authorization_check() error while loading parsing certifcate. Error: tnauth_in_exc', lcm.output) @patch('acme_srv.certificate.Certificate.certlist_search') - def test_190_dates_update(self, mock_search): + def test_193_dates_update(self, mock_search): """ dates update """ mock_search.return_value = [{'foo': 'bar'}, {'foo1': 'bar1'}] self.certificate.dates_update() @patch('acme_srv.certificate.Certificate.certlist_search') - def test_191_dates_update(self, mock_search): + def test_194_dates_update(self, mock_search): """ dates update """ mock_search.return_value = [{'issue_uts': 0, 'expire_uts': 0, 'cert_raw': 'cert_raw'}, {'foo1': 'bar1'}] self.certificate.dates_update() @@ -2203,7 +2262,7 @@ def test_191_dates_update(self, mock_search): @patch('acme_srv.certificate.Certificate._store_cert') @patch('acme_srv.certificate.cert_dates_get') @patch('acme_srv.certificate.Certificate.certlist_search') - def test_192_dates_update(self, mock_search, mock_dates_get, mock_store): + def test_195_dates_update(self, mock_search, mock_dates_get, mock_store): """ dates update with a none zero issue-uts """ mock_search.return_value = [{'issue_uts': 2, 'expire_uts': 0, 'cert_raw': 'cert_raw', 'name': 'name', 'cert': 'cert'}, {'foo1': 'bar1'}] mock_dates_get.return_value = (42, 42) @@ -2214,7 +2273,7 @@ def test_192_dates_update(self, mock_search, mock_dates_get, mock_store): @patch('acme_srv.certificate.Certificate._store_cert') @patch('acme_srv.certificate.cert_dates_get') @patch('acme_srv.certificate.Certificate.certlist_search') - def test_193_dates_update(self, mock_search, mock_dates_get, mock_store): + def test_196_dates_update(self, mock_search, mock_dates_get, mock_store): """ dates update with a none zero expire-uts """ mock_search.return_value = [{'issue_uts': 0, 'expire_uts': 2, 'cert_raw': 'cert_raw', 'name': 'name', 'cert': 'cert'}, {'foo1': 'bar1'}] mock_dates_get.return_value = (42, 42) @@ -2225,7 +2284,7 @@ def test_193_dates_update(self, mock_search, mock_dates_get, mock_store): @patch('acme_srv.certificate.Certificate._store_cert') @patch('acme_srv.certificate.cert_dates_get') @patch('acme_srv.certificate.Certificate.certlist_search') - def test_194_dates_update(self, mock_search, mock_dates_get, mock_store): + def test_197_dates_update(self, mock_search, mock_dates_get, mock_store): """ dates update call _cert_store """ mock_search.return_value = [{'issue_uts': 0, 'expire_uts': 0, 'cert_raw': 'cert_raw', 'name': 'name', 'cert': 'cert'}, {'foo1': 'bar1'}] mock_dates_get.return_value = (42, 42) @@ -2236,7 +2295,7 @@ def test_194_dates_update(self, mock_search, mock_dates_get, mock_store): @patch('acme_srv.certificate.Certificate._store_cert') @patch('acme_srv.certificate.cert_dates_get') @patch('acme_srv.certificate.Certificate.certlist_search') - def test_195_dates_update(self, mock_search, mock_dates_get, mock_store): + def test_198_dates_update(self, mock_search, mock_dates_get, mock_store): """ dates update call _cert_store """ mock_search.return_value = [{'issue_uts': 0, 'expire_uts': 0, 'cert_raw': 'cert_raw', 'name': 'name', 'cert': 'cert'}, {'foo1': 'bar1'}] mock_dates_get.return_value = (42, 0) @@ -2247,7 +2306,7 @@ def test_195_dates_update(self, mock_search, mock_dates_get, mock_store): @patch('acme_srv.certificate.Certificate._store_cert') @patch('acme_srv.certificate.cert_dates_get') @patch('acme_srv.certificate.Certificate.certlist_search') - def test_196_dates_update(self, mock_search, mock_dates_get, mock_store): + def test_199_dates_update(self, mock_search, mock_dates_get, mock_store): """ dates update call _cert_store """ mock_search.return_value = [{'issue_uts': 0, 'expire_uts': 0, 'cert_raw': 'cert_raw', 'name': 'name', 'cert': 'cert'}, {'foo1': 'bar1'}] mock_dates_get.return_value = (0, 42) @@ -2258,7 +2317,7 @@ def test_196_dates_update(self, mock_search, mock_dates_get, mock_store): @patch('acme_srv.certificate.Certificate._store_cert') @patch('acme_srv.certificate.cert_dates_get') @patch('acme_srv.certificate.Certificate.certlist_search') - def test_197_dates_update(self, mock_search, mock_dates_get, mock_store): + def test_200_dates_update(self, mock_search, mock_dates_get, mock_store): """ dates update do not call _cert_store bcs cert_dates_get return 0/0 """ mock_search.return_value = [{'issue_uts': 0, 'expire_uts': 0, 'cert_raw': 'cert_raw', 'name': 'name', 'cert': 'cert'}, {'foo1': 'bar1'}] mock_dates_get.return_value = (0, 0) @@ -2266,14 +2325,14 @@ def test_197_dates_update(self, mock_search, mock_dates_get, mock_store): self.assertTrue(mock_dates_get.called) self.assertFalse(mock_store.called) - def test_198_order_update(self): + def test_201_order_update(self): """ test Certificate._order_update - dbstore.order_update() raises an exception """ self.certificate.dbstore.order_update.side_effect = Exception('exc_order_upd') with self.assertLogs('test_a2c', level='INFO') as lcm: self.certificate._order_update({'url': 'url'}) self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Certificate._order_update(): exc_order_upd', lcm.output) - def test_199_certificate_certlist_search(self): + def test_202_certificate_certlist_search(self): """ test Certificate.certlist_search - dbstore.certificates_search() raises an exception """ self.certificate.dbstore.certificates_search.side_effect = Exception('exc_certlist_search') with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -2282,7 +2341,7 @@ def test_199_certificate_certlist_search(self): @patch('acme_srv.certificate.certid_asn1_get') @patch('acme_srv.certificate.pembundle_to_list') - def test_200_renewal_info_get(self, mock_p2l, mock_certid): + def test_203_renewal_info_get(self, mock_p2l, mock_certid): """ _renewal_info_get() """ mock_certid.return_value = 'certid' self.assertEqual('certid', self.certificate._renewal_info_get('cert')) diff --git a/test/test_helper.py b/test/test_helper.py index 918c05da..6c955abc 100644 --- a/test/test_helper.py +++ b/test/test_helper.py @@ -26,7 +26,7 @@ def setUp(self): """ setup unittest """ import logging logging.basicConfig(level=logging.CRITICAL) - from acme_srv.helper import b64decode_pad, b64_decode, b64_encode, b64_url_encode, b64_url_recode, convert_string_to_byte, convert_byte_to_string, decode_message, decode_deserialize, get_url, generate_random_string, signature_check, validate_email, uts_to_date_utc, date_to_uts_utc, load_config, cert_serial_get, cert_san_get, cert_dates_get, build_pem_file, date_to_datestr, datestr_to_date, dkeys_lower, csr_cn_get, cert_pubkey_get, csr_pubkey_get, url_get, url_get_with_own_dns, dns_server_list_load, csr_san_get, csr_san_byte_get, csr_extensions_get, fqdn_resolve, fqdn_in_san_check, sha256_hash, sha256_hash_hex, cert_der2pem, cert_pem2der, cert_extensions_get, csr_dn_get, logger_setup, logger_info, print_debug, jwk_thumbprint_get, allowed_gai_family, patched_create_connection, validate_csr, servercert_get, txt_get, proxystring_convert, proxy_check, handle_exception, ca_handler_load, eab_handler_load, hooks_load, error_dic_get, _logger_nonce_modify, _logger_certificate_modify, _logger_token_modify, _logger_challenges_modify, config_check, cert_issuer_get, cert_cn_get, string_sanitize, pembundle_to_list, certid_asn1_get, certid_check, certid_hex_get, v6_adjust, ipv6_chk, ip_validate, header_info_get, encode_url, uts_now + from acme_srv.helper import b64decode_pad, b64_decode, b64_encode, b64_url_encode, b64_url_recode, convert_string_to_byte, convert_byte_to_string, decode_message, decode_deserialize, get_url, generate_random_string, signature_check, validate_email, uts_to_date_utc, date_to_uts_utc, load_config, cert_serial_get, cert_san_get, cert_san_pyopenssl_get, cert_dates_get, build_pem_file, date_to_datestr, datestr_to_date, dkeys_lower, csr_cn_get, cert_pubkey_get, csr_pubkey_get, url_get, url_get_with_own_dns, dns_server_list_load, csr_san_get, csr_san_byte_get, csr_extensions_get, fqdn_resolve, fqdn_in_san_check, sha256_hash, sha256_hash_hex, cert_der2pem, cert_pem2der, cert_extensions_get, csr_dn_get, logger_setup, logger_info, print_debug, jwk_thumbprint_get, allowed_gai_family, patched_create_connection, validate_csr, servercert_get, txt_get, proxystring_convert, proxy_check, handle_exception, ca_handler_load, eab_handler_load, hooks_load, error_dic_get, _logger_nonce_modify, _logger_certificate_modify, _logger_token_modify, _logger_challenges_modify, config_check, cert_issuer_get, cert_cn_get, string_sanitize, pembundle_to_list, certid_asn1_get, certid_check, certid_hex_get, v6_adjust, ipv6_chk, ip_validate, header_info_get, encode_url, uts_now, cert_ski_get, cert_ski_pyopenssl_get self.logger = logging.getLogger('test_a2c') self.allowed_gai_family = allowed_gai_family self.b64_decode = b64_decode @@ -42,7 +42,10 @@ def setUp(self): self.certid_check = certid_check self.cert_pubkey_get = cert_pubkey_get self.cert_san_get = cert_san_get + self.cert_san_pyopenssl_get = cert_san_pyopenssl_get self.cert_serial_get = cert_serial_get + self.cert_ski_get = cert_ski_get + self.cert_ski_pyopenssl_get = cert_ski_pyopenssl_get self.cert_issuer_get = cert_issuer_get self.cert_pem2der = cert_pem2der self.cert_der2pem = cert_der2pem @@ -446,8 +449,29 @@ def test_048_helper_cert_san_get(self): cert = """MIIDezCCAWOgAwIBAgIIIAuZLppuFT4wDQYJKoZIhvcNAQELBQAwKjEXMBUGA1UECxMOYWNtZTJjZXJ0aWZpZXIxDzANBgNVBAMTBnN1Yi1jYTAeFw0yMzA3MjAwNDIxMTlaFw0yNDA3MTkwNDIxMTlaMBkxFzAVBgNVBAMTDjE5Mi4xNjguMTQuMTMxMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEQTs6Bra1zfVSiReD4AYj8HCKdcaMO5WsgB0zhpVu3HuSQSIQHC8CMe8haCywjYisbbWeDzT654tc674/MjScraOBgDB+MB0GA1UdDgQWBBQQa+M+3oTsdKTSB/Rt3Dk7/Vy0YzAfBgNVHSMEGDAWgBS/3o6OBiIiq61DyN3UT6irSEE+1TALBgNVHQ8EBAMCA+gwDAYDVR0TAQH/BAIwADAhBgNVHREEGjAYghBmb29iYXIuYmFyLmxvY2FshwTAqA6DMA0GCSqGSIb3DQEBCwUAA4ICAQCcevAczULbl5Le/xI1LSQ/PSsROjOZHUjlWf5bRs53aTM6wMqDBsFGdLzTN5vzWqVjie1Nzu8XGSEEuF0L/2bltGgYiYQqD4HKJedEEbYxQbg77o9JLp52MltvXGRH5gYGSGPZbuQ8QANvDn6FqBZjskOtED8SZGGt5spgxK7eguoJoQken68TgdZptL6l6eryTgouPbG0j5vTPPxuZpqxM9vQa4ADyqyvOKRMkZC98IbruChlCtFztILJPkvNx8Gbmlzv201uW9/9mNzcV8vVtlcB+Ftb/+sCfYuU/ShwUuOxOLE7+OKjLlalfniNwqx2l6f30nvvsa11vQc/Rwy1Z+vv96EzyF+GthMx2qLIG4eLLbISATwUfpR0UcLMtr83LRzB578rxrtwcgB5s+AWSDsYEKnzXabQdX1cEuiM3iEdlZ7McFzRvwElObhoDDOqOjGALWmdboox6dDskpQEhe6JALsj3mH07017h5T3W3PvqWD2IAsqH+WTuxCTmfjbqqoAz/Zt2ipIAFtSk79WvWwth/K+xtYhmuoe2+ygocqa9tF9AyoihImSEk1EjXvqKqRLPZwg41C3WKvLlg57fpRFZYR1W28ZqAqqVNf8MMHcsHdZ7koMBhIKKnSe/HdLWm7ghVjAEdYVYvOcOZHzxXBmnV/6ZLRQXu2XQnATJw==""" self.assertEqual(['DNS:foobar.bar.local', 'IP:192.168.14.131'], self.cert_san_get(self.logger, cert)) - def test_049_helper_cert_serial_get(self): - """ test cert_serial for a multiple SAN of different types""" + def test_049_helper_cert_san_pyopenssl_get(self): + """ test cert_san_get for a single SAN """ + cert = """MIIDDTCCAfWgAwIBAgIBCjANBgkqhkiG9w0BAQsFADAaMRgwFgYDVQQDEw9mb28u + ZXhhbXBsZS5jb20wHhcNMTkwMTIwMTY1OTIwWhcNMTkwMjE5MTY1OTIwWjAaMRgw + FgYDVQQDEw9mb28uZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw + ggEKAoIBAQCqUeNzDyBVugUKZq597ishYAdMPgus5Nw5pWE/Jw7PP0koeFE2wODq + HVb+XNFFEX4IOyiE2Pi4ilzfXYGKchhP3wHgnkxGNIwt/cDNZgyTiUpITV/ciFaC + 7avkvQS6ScCYUYrhby7QnvcU02mAyhNcSVGI5TW7HhFdtWrEAK3N8H6yhxHLSi2y + dpQ3kCJyJylqt/Rv3uKNjCvTv867K6A1QSsXoAxtPK9P0UOTRvgHkFf8T32Bn/Er + 1bjkX9Ms8rqDQmicCWJk260lUHzN6vxaeiEg7Kz3TA8Ik3DMIcvwJrE168G1APo+ + FyOIKyx+t78HWOlNINIqZMj5e2DpulV7AgMBAAGjXjBcMB8GA1UdIwQYMBaAFK1Z + zuGt0Pe+NLerCXqQBYmVV7suMB0GA1UdDgQWBBStWc7hrdD3vjS3qwl6kAWJlVe7 + LjAaBgNVHREEEzARgg9mb28uZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQADggEB + AANW0DD4Xp7LH/Rzf2jVLwiFlbtR6iazyn9S/pH2Gwqjkscv/27/dqJb7CfPdD02 + 5ItQcYkZPJhDOsj63kvUaD89QU31RnYQrXrbXFqYOIAq6kxfZUoQmpfEBxbB4Wxm + TW0OWS+FMqNw/SuGs6EQjTRA+gBOeGzj4H9yOFOg0PpadBayZ7UT4lm1LOiFHh8h + bta75ocePrurdNxsxKJhLlXbnKD6lurCb4khRhrmLmpK8JxhuaevEVklSQX0gqlR + fxAH4XQsaqcaedPNI+W5OUITMz40ezDCbUqxS9KEMCGPoOTXNRAjbr72sc4Vkw7H + t+eRUDECE+0UnjyeCjTn3EU=""" + self.assertEqual(['DNS:foo.example.com'], self.cert_san_pyopenssl_get(self.logger, cert)) + + def test_050_cert_san_pyopenssl_get(self): + """ test cert_san_get for a multiple SAN of type DNS""" cert = """MIIDIzCCAgugAwIBAgICBZgwDQYJKoZIhvcNAQELBQAwGjEYMBYGA1UEAxMPZm9v LmV4YW1wbGUuY29tMB4XDTE5MDEyMDE3MDkxMVoXDTE5MDIxOTE3MDkxMVowGjEY MBYGA1UEAxMPZm9vLmV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A @@ -465,28 +489,43 @@ def test_049_helper_cert_serial_get(self): TP6Gp79DzCiPKFt52Y8yVikIET4fnyRzU8kGKLuPoIt+EQQzpG26qWAjeNHAASEM keiA+tedMWzydX52B+tGg+l2svxg34apIBDjK8pF+8ZxTt5yjVUa10GbpffJuiEh NWQddOR8IHg+v6lWc9BtuuKK5ubsg6XOiEjhhr42AKViKalX1i4+""" - self.assertEqual(1432, self.cert_serial_get(self.logger, cert)) + self.assertEqual(['DNS:foo-2.example.com', 'DNS:foo-1.example.com'], self.cert_san_pyopenssl_get(self.logger, cert)) + + def test_051_helper_cert_san_pyopenssl_get(self): + """ test cert_san_get for a multiple SAN of type DNS""" + cert = """MIIDaDCCAVCgAwIBAgIICwL0UBNcUakwDQYJKoZIhvcNAQELBQAwKjEXMBUGA1UECxMOYWNtZTJjZXJ0aWZpZXIxDzANBgNVBAMTBnN1Yi1jYTAeFw0yMzA3MTkxODU5NDRaFw0yNDA3MTgxODU5NDRaMBkxFzAVBgNVBAMTDjE5Mi4xNjguMTQuMTMxMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEN626lPpwBt4SEvdf5Tb0BpP1tl9KiFE/9xCIyYPsi9VXVDq/EcwO3CRp4fy+3bhZj6i43DdnluETcx8ZR2XyE6NuMGwwHQYDVR0OBBYEFBp+ZupvT2BB92sDkxy2GffHXDRLMB8GA1UdIwQYMBaAFL/ejo4GIiKrrUPI3dRPqKtIQT7VMAsGA1UdDwQEAwID6DAMBgNVHRMBAf8EAjAAMA8GA1UdEQQIMAaHBMCoDoMwDQYJKoZIhvcNAQELBQADggIBAFpq5RWGP4kDRnRjq8pte87bGS9LEmSlGOA8HlQZ+kjAoTunNN7/gvDch4F/CIl1N8cbQ/Ty1vx9CznTpQ39c2LNMILnjNHqQpYRIgLSBvCm26pAdlmicy6zdGlRKaePoMXINw4csDZ4REERg/c21ANhFclYyWWUM987bHZuBZJM8zBfR98ZnOzuQMRb5xztRlXSvddW4qEyKihl+5wPduaF8hDui4wbDFW6pUE9DWO/S1m37Tshh1O3NLlAlaMMwLsYaGkW7yzM4OrzmghJCRtdF9lbYYqHoKxLVWyCRF/pXqqQ/y+k4sN0MeZ7Wk4dI18aGHTGEzu6GSynNptyCQNsoTYexDA/rx57ukX7TqrU5JU/VyrKYD+M/rsLMj3vY4YmmH4W12IhAxa6+UmGG9ixHKpTgLVLRJDdzPMLY+IdI9WHdo7nHDOsaKvrFWqmvsCxT214jN0fVkOTMazG4ILg4DZhMWh8QxGULR7ul2oYnlyGUXiag7qLjNu1/RltJg9sp+ZxVC7RWaoCwxp6CIT95wrUAFTt9NBkccafsQKsF2ZtrUNZ8Z7B3y6hzr9d6rWlZCKlcr/ZNSOnrRTwuCz5HL3Gd2/DfyZUmy5U1+URbktMIdddlV5jaeSpwFZI8Xga4cYJAE7xjVq8HN3jbZ6m4PyylfaQfXisozKRECs4""" + self.assertEqual(['IP Address:192.168.14.131'], self.cert_san_pyopenssl_get(self.logger, cert)) + + def test_052_helper_cert_san_pyopenssl_get(self): + """ test cert_san_get for a multiple SAN of type DNS""" + cert = """MIIDezCCAWOgAwIBAgIIIAuZLppuFT4wDQYJKoZIhvcNAQELBQAwKjEXMBUGA1UECxMOYWNtZTJjZXJ0aWZpZXIxDzANBgNVBAMTBnN1Yi1jYTAeFw0yMzA3MjAwNDIxMTlaFw0yNDA3MTkwNDIxMTlaMBkxFzAVBgNVBAMTDjE5Mi4xNjguMTQuMTMxMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEQTs6Bra1zfVSiReD4AYj8HCKdcaMO5WsgB0zhpVu3HuSQSIQHC8CMe8haCywjYisbbWeDzT654tc674/MjScraOBgDB+MB0GA1UdDgQWBBQQa+M+3oTsdKTSB/Rt3Dk7/Vy0YzAfBgNVHSMEGDAWgBS/3o6OBiIiq61DyN3UT6irSEE+1TALBgNVHQ8EBAMCA+gwDAYDVR0TAQH/BAIwADAhBgNVHREEGjAYghBmb29iYXIuYmFyLmxvY2FshwTAqA6DMA0GCSqGSIb3DQEBCwUAA4ICAQCcevAczULbl5Le/xI1LSQ/PSsROjOZHUjlWf5bRs53aTM6wMqDBsFGdLzTN5vzWqVjie1Nzu8XGSEEuF0L/2bltGgYiYQqD4HKJedEEbYxQbg77o9JLp52MltvXGRH5gYGSGPZbuQ8QANvDn6FqBZjskOtED8SZGGt5spgxK7eguoJoQken68TgdZptL6l6eryTgouPbG0j5vTPPxuZpqxM9vQa4ADyqyvOKRMkZC98IbruChlCtFztILJPkvNx8Gbmlzv201uW9/9mNzcV8vVtlcB+Ftb/+sCfYuU/ShwUuOxOLE7+OKjLlalfniNwqx2l6f30nvvsa11vQc/Rwy1Z+vv96EzyF+GthMx2qLIG4eLLbISATwUfpR0UcLMtr83LRzB578rxrtwcgB5s+AWSDsYEKnzXabQdX1cEuiM3iEdlZ7McFzRvwElObhoDDOqOjGALWmdboox6dDskpQEhe6JALsj3mH07017h5T3W3PvqWD2IAsqH+WTuxCTmfjbqqoAz/Zt2ipIAFtSk79WvWwth/K+xtYhmuoe2+ygocqa9tF9AyoihImSEk1EjXvqKqRLPZwg41C3WKvLlg57fpRFZYR1W28ZqAqqVNf8MMHcsHdZ7koMBhIKKnSe/HdLWm7ghVjAEdYVYvOcOZHzxXBmnV/6ZLRQXu2XQnATJw==""" + self.assertEqual(['DNS:foobar.bar.local', 'IP Address:192.168.14.131'], self.cert_san_pyopenssl_get(self.logger, cert)) + + def test_053_helper_cert_san_pyopenssl_get(self): + """ test cert_san_get for a single SAN """ + cert = """ +-----BEGIN CERTIFICATE----- +MIIDDTCCAfWgAwIBAgIBCjANBgkqhkiG9w0BAQsFADAaMRgwFgYDVQQDEw9mb28u +ZXhhbXBsZS5jb20wHhcNMTkwMTIwMTY1OTIwWhcNMTkwMjE5MTY1OTIwWjAaMRgw +FgYDVQQDEw9mb28uZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQCqUeNzDyBVugUKZq597ishYAdMPgus5Nw5pWE/Jw7PP0koeFE2wODq +HVb+XNFFEX4IOyiE2Pi4ilzfXYGKchhP3wHgnkxGNIwt/cDNZgyTiUpITV/ciFaC +7avkvQS6ScCYUYrhby7QnvcU02mAyhNcSVGI5TW7HhFdtWrEAK3N8H6yhxHLSi2y +dpQ3kCJyJylqt/Rv3uKNjCvTv867K6A1QSsXoAxtPK9P0UOTRvgHkFf8T32Bn/Er +1bjkX9Ms8rqDQmicCWJk260lUHzN6vxaeiEg7Kz3TA8Ik3DMIcvwJrE168G1APo+ +FyOIKyx+t78HWOlNINIqZMj5e2DpulV7AgMBAAGjXjBcMB8GA1UdIwQYMBaAFK1Z +zuGt0Pe+NLerCXqQBYmVV7suMB0GA1UdDgQWBBStWc7hrdD3vjS3qwl6kAWJlVe7 +LjAaBgNVHREEEzARgg9mb28uZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQADggEB +AANW0DD4Xp7LH/Rzf2jVLwiFlbtR6iazyn9S/pH2Gwqjkscv/27/dqJb7CfPdD02 +5ItQcYkZPJhDOsj63kvUaD89QU31RnYQrXrbXFqYOIAq6kxfZUoQmpfEBxbB4Wxm +TW0OWS+FMqNw/SuGs6EQjTRA+gBOeGzj4H9yOFOg0PpadBayZ7UT4lm1LOiFHh8h +bta75ocePrurdNxsxKJhLlXbnKD6lurCb4khRhrmLmpK8JxhuaevEVklSQX0gqlR +fxAH4XQsaqcaedPNI+W5OUITMz40ezDCbUqxS9KEMCGPoOTXNRAjbr72sc4Vkw7H +t+eRUDECE+0UnjyeCjTn3EU= +-----END CERTIFICATE----- + """ + self.assertEqual(['DNS:foo.example.com'], self.cert_san_pyopenssl_get(self.logger, cert, recode=False)) - def test_050_helper_cert_san_get(self): - """ test cert_san_get for a single SAN and recode = True""" - cert = """MIIDDTCCAfWgAwIBAgIBCjANBgkqhkiG9w0BAQsFADAaMRgwFgYDVQQDEw9mb28u - ZXhhbXBsZS5jb20wHhcNMTkwMTIwMTY1OTIwWhcNMTkwMjE5MTY1OTIwWjAaMRgw - FgYDVQQDEw9mb28uZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw - ggEKAoIBAQCqUeNzDyBVugUKZq597ishYAdMPgus5Nw5pWE/Jw7PP0koeFE2wODq - HVb+XNFFEX4IOyiE2Pi4ilzfXYGKchhP3wHgnkxGNIwt/cDNZgyTiUpITV/ciFaC - 7avkvQS6ScCYUYrhby7QnvcU02mAyhNcSVGI5TW7HhFdtWrEAK3N8H6yhxHLSi2y - dpQ3kCJyJylqt/Rv3uKNjCvTv867K6A1QSsXoAxtPK9P0UOTRvgHkFf8T32Bn/Er - 1bjkX9Ms8rqDQmicCWJk260lUHzN6vxaeiEg7Kz3TA8Ik3DMIcvwJrE168G1APo+ - FyOIKyx+t78HWOlNINIqZMj5e2DpulV7AgMBAAGjXjBcMB8GA1UdIwQYMBaAFK1Z - zuGt0Pe+NLerCXqQBYmVV7suMB0GA1UdDgQWBBStWc7hrdD3vjS3qwl6kAWJlVe7 - LjAaBgNVHREEEzARgg9mb28uZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQADggEB - AANW0DD4Xp7LH/Rzf2jVLwiFlbtR6iazyn9S/pH2Gwqjkscv/27/dqJb7CfPdD02 - 5ItQcYkZPJhDOsj63kvUaD89QU31RnYQrXrbXFqYOIAq6kxfZUoQmpfEBxbB4Wxm - TW0OWS+FMqNw/SuGs6EQjTRA+gBOeGzj4H9yOFOg0PpadBayZ7UT4lm1LOiFHh8h - bta75ocePrurdNxsxKJhLlXbnKD6lurCb4khRhrmLmpK8JxhuaevEVklSQX0gqlR - fxAH4XQsaqcaedPNI+W5OUITMz40ezDCbUqxS9KEMCGPoOTXNRAjbr72sc4Vkw7H - t+eRUDECE+0UnjyeCjTn3EU=""" - self.assertEqual(['DNS:foo.example.com'], self.cert_san_get(self.logger, cert, recode=True)) def test_051_helper_cert_san_get(self): """ test cert_san_get for a single SAN and recode = False""" @@ -2056,6 +2095,66 @@ def test_274_ip_validate(self): """ test ip validate """ self.assertEqual((None, True), self.ip_validate(self.logger, '1000.0.0.1')) + def test_257_cert_ski_get(self): + """ test cert_san_get for a multiple SAN of type DNS""" + cert = """MIIDIzCCAgugAwIBAgICBZgwDQYJKoZIhvcNAQELBQAwGjEYMBYGA1UEAxMPZm9v + LmV4YW1wbGUuY29tMB4XDTE5MDEyMDE3MDkxMVoXDTE5MDIxOTE3MDkxMVowGjEY + MBYGA1UEAxMPZm9vLmV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A + MIIBCgKCAQEA+EM+gzAyjegQSRbJI+qZJhuAGM9i48xvIfuOQHleXoJPjV+8VZRV + KDljZNXdNT5Zi7K6HY9C622NOV7QefB6zTtm6mSY08ypNsaeorhIvJdnpaJ9gAGH + YeQqJ04fL099kiRXJAv8gT8wdpiekg2KEU4wlXMIRfSHiiB37yjcqUzXl6XYYKGe + 2USMpDfliXL3o8TW2KByGUdCzXUdNbMgzRXwYxkX2+xV2f0vn8NyXHiHg9yJRof2 + HTjyvAcXN5Nr987slq/Ex5lXLtpB861Ov3ZbwxyzREjmreZBlze7KTfP5IY66XuN + Mvhi7AAs0cLTd3SNjpppE/yvUi5q5gfhXQIDAQABo3MwcTAfBgNVHSMEGDAWgBSl + YnpKQw12MmEMpvsTEeQi17UsnDAdBgNVHQ4EFgQUpWJ6SkMNdjJhDKb7ExHkIte1 + LJwwLwYDVR0RBCgwJoIRZm9vLTIuZXhhbXBsZS5jb22CEWZvby0xLmV4YW1wbGUu + Y29tMA0GCSqGSIb3DQEBCwUAA4IBAQASA20TtMPXIHH10dikLhFuI14EOtZzXvCx + kGlJw9/5JuvVKLsL1wd8BC9o/lg8apDqsrDZ/+0Nc8g3Z9HRN99vcLsVDdT27DkM + BslfXdN/qBhKAp3m7jw29uijX5fss+Wz9iHfHciUjVyMJ4DoFxHYPbMWQG8XEUKR + TP6Gp79DzCiPKFt52Y8yVikIET4fnyRzU8kGKLuPoIt+EQQzpG26qWAjeNHAASEM + keiA+tedMWzydX52B+tGg+l2svxg34apIBDjK8pF+8ZxTt5yjVUa10GbpffJuiEh + NWQddOR8IHg+v6lWc9BtuuKK5ubsg6XOiEjhhr42AKViKalX1i4+""" + self.assertEqual('a5627a4a430d7632610ca6fb1311e422d7b52c9c', self.cert_ski_get(self.logger, cert)) + + def test_258_cert_ski_pyopenssl_get(self): + """ test cert_san_get for a multiple SAN of type DNS""" + cert = """MIIDIzCCAgugAwIBAgICBZgwDQYJKoZIhvcNAQELBQAwGjEYMBYGA1UEAxMPZm9v + LmV4YW1wbGUuY29tMB4XDTE5MDEyMDE3MDkxMVoXDTE5MDIxOTE3MDkxMVowGjEY + MBYGA1UEAxMPZm9vLmV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A + MIIBCgKCAQEA+EM+gzAyjegQSRbJI+qZJhuAGM9i48xvIfuOQHleXoJPjV+8VZRV + KDljZNXdNT5Zi7K6HY9C622NOV7QefB6zTtm6mSY08ypNsaeorhIvJdnpaJ9gAGH + YeQqJ04fL099kiRXJAv8gT8wdpiekg2KEU4wlXMIRfSHiiB37yjcqUzXl6XYYKGe + 2USMpDfliXL3o8TW2KByGUdCzXUdNbMgzRXwYxkX2+xV2f0vn8NyXHiHg9yJRof2 + HTjyvAcXN5Nr987slq/Ex5lXLtpB861Ov3ZbwxyzREjmreZBlze7KTfP5IY66XuN + Mvhi7AAs0cLTd3SNjpppE/yvUi5q5gfhXQIDAQABo3MwcTAfBgNVHSMEGDAWgBSl + YnpKQw12MmEMpvsTEeQi17UsnDAdBgNVHQ4EFgQUpWJ6SkMNdjJhDKb7ExHkIte1 + LJwwLwYDVR0RBCgwJoIRZm9vLTIuZXhhbXBsZS5jb22CEWZvby0xLmV4YW1wbGUu + Y29tMA0GCSqGSIb3DQEBCwUAA4IBAQASA20TtMPXIHH10dikLhFuI14EOtZzXvCx + kGlJw9/5JuvVKLsL1wd8BC9o/lg8apDqsrDZ/+0Nc8g3Z9HRN99vcLsVDdT27DkM + BslfXdN/qBhKAp3m7jw29uijX5fss+Wz9iHfHciUjVyMJ4DoFxHYPbMWQG8XEUKR + TP6Gp79DzCiPKFt52Y8yVikIET4fnyRzU8kGKLuPoIt+EQQzpG26qWAjeNHAASEM + keiA+tedMWzydX52B+tGg+l2svxg34apIBDjK8pF+8ZxTt5yjVUa10GbpffJuiEh + NWQddOR8IHg+v6lWc9BtuuKK5ubsg6XOiEjhhr42AKViKalX1i4+""" + self.assertEqual('a5627a4a430d7632610ca6fb1311e422d7b52c9c', self.cert_ski_pyopenssl_get(self.logger, cert)) + + @patch('acme_srv.helper.cert_ski_pyopenssl_get') + @patch('acme_srv.helper.cert_load') + def test_259cert_ski_get(self, mock_load, mock_ski): + """ test cert_ski_get() """ + cert = 'cert' + mock_ski.return_value = 'mock_ski' + mock_load.return_value = 'mock_load' + self.assertEqual('mock_ski', self.cert_ski_get(self.logger, cert)) + self.assertTrue(mock_ski.called) + + @patch('OpenSSL.crypto.load_certificate') + def test_260cert_ski_get(self, mock_load): + """ test cert_ski_get() """ + cert = 'cert' + mock_load.get_extension_count.return_value = 2 + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.cert_ski_pyopenssl_get(self.logger, cert)) + self.assertIn('ERROR:test_a2c:cert_ski_pyopenssl_get(): No SKI found in certificate', lcm.output) if __name__ == '__main__': unittest.main() From 6b7523faae67321ade78bacbdc4a3f643ae18a7e Mon Sep 17 00:00:00 2001 From: grindsa Date: Mon, 15 Jan 2024 11:18:06 +0100 Subject: [PATCH 013/460] [fix] unittests in test_asa_ca_handler.py --- test/test_asa_ca_handler.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/test/test_asa_ca_handler.py b/test/test_asa_ca_handler.py index 6e97e072..ca8a0eb7 100644 --- a/test/test_asa_ca_handler.py +++ b/test/test_asa_ca_handler.py @@ -526,14 +526,13 @@ def test_041___issuer_chain_get(self, mock_req, mock_pem): @patch('examples.ca_handler.asa_ca_handler.convert_byte_to_string') @patch('examples.ca_handler.asa_ca_handler.cert_der2pem') @patch('examples.ca_handler.asa_ca_handler.b64_decode') - @patch('examples.ca_handler.asa_ca_handler.csr_san_byte_get') @patch('examples.ca_handler.asa_ca_handler.CAhandler._validity_dates_get') @patch('examples.ca_handler.asa_ca_handler.CAhandler._csr_cn_get') @patch('examples.ca_handler.asa_ca_handler.csr_pubkey_get') @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_chain_get') @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_verify') @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_verify') - def test_042_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_csbg, mock_b64, mock_d2p, mock_b2s, mock_post): + def test_042_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_b64, mock_d2p, mock_b2s, mock_post): """ test enroll() """ mock_iv.return_value = None mock_pv.return_value = None @@ -548,7 +547,6 @@ def test_042_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vd self.assertTrue(mock_cpg.called) self.assertTrue(mockccg.called) self.assertTrue(mock_vdg.called) - self.assertTrue(mock_csbg.called) self.assertTrue(mock_b64.called) self.assertTrue(mock_post.called) self.assertTrue(mock_b2s.called) @@ -622,14 +620,13 @@ def test_044_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vd @patch('examples.ca_handler.asa_ca_handler.convert_byte_to_string') @patch('examples.ca_handler.asa_ca_handler.cert_der2pem') @patch('examples.ca_handler.asa_ca_handler.b64_decode') - @patch('examples.ca_handler.asa_ca_handler.csr_san_byte_get') @patch('examples.ca_handler.asa_ca_handler.CAhandler._validity_dates_get') @patch('examples.ca_handler.asa_ca_handler.CAhandler._csr_cn_get') @patch('examples.ca_handler.asa_ca_handler.csr_pubkey_get') @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_chain_get') @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_verify') @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_verify') - def test_045_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_csbg, mock_b64, mock_d2p, mock_b2s, mock_post): + def test_045_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_b64, mock_d2p, mock_b2s, mock_post): """ test enroll() """ mock_iv.return_value = None mock_pv.return_value = None @@ -644,7 +641,6 @@ def test_045_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vd self.assertTrue(mock_cpg.called) self.assertTrue(mockccg.called) self.assertTrue(mock_vdg.called) - self.assertTrue(mock_csbg.called) self.assertFalse(mock_b64.called) self.assertTrue(mock_post.called) self.assertFalse(mock_b2s.called) From 574d444b8f567bb204eb600f5fc5153b7064461d Mon Sep 17 00:00:00 2001 From: grindsa Date: Mon, 15 Jan 2024 14:58:12 +0100 Subject: [PATCH 014/460] [doc] profile_name as header_info_field in asa_handler.py --- docs/asa.md | 25 ++++ examples/ca_handler/asa_ca_handler.py | 48 ++++++- test/test_asa_ca_handler.py | 191 +++++++++++++++++++------- 3 files changed, 216 insertions(+), 48 deletions(-) diff --git a/docs/asa.md b/docs/asa.md index 0ac80d70..8c8cbec1 100644 --- a/docs/asa.md +++ b/docs/asa.md @@ -57,3 +57,28 @@ root@rlh:~# curl -u '$api_user':'$api_password' -H "x-api-key: $api_ho ``` The CA handler will verify ca_name and profile_name parameters before enrollment. + +## Passing a profileID from client to server + +The handler makes use of the [header_info_list feature](header_info.md) allowing an acme-client to specify a profile_name to be used during certificate enrollment. This feature is disabled by default and must be activate in `acme_srv.cfg` as shown below + +```config +[Order] +... +header_info_list: ["HTTP_USER_AGENT"] +``` + +The acme-client can then specify the profile_name as part of its user-agent string. + +Example for acme.sh: + +```bash +docker exec -i acme-sh acme.sh --server http:// --issue -d --standalone --useragent profile_name=foo --debug 3 --output-insecure +``` + +Example for lego: + +```bash +docker run -i -v $PWD/lego:/.lego/ --rm --name lego goacme/lego -s http:// -a --email "lego@example.com" --user-agent profile_name= -d --http run +``` + diff --git a/examples/ca_handler/asa_ca_handler.py b/examples/ca_handler/asa_ca_handler.py index 77a29d0d..7aaf3ed3 100644 --- a/examples/ca_handler/asa_ca_handler.py +++ b/examples/ca_handler/asa_ca_handler.py @@ -4,9 +4,10 @@ from typing import Tuple, Dict import os import requests +import json from requests.auth import HTTPBasicAuth # pylint: disable=C0209, E0401 -from acme_srv.helper import load_config, encode_url, csr_pubkey_get, csr_cn_get, csr_san_get, csr_san_byte_get, uts_now, uts_to_date_utc, b64_decode, cert_der2pem, convert_byte_to_string, cert_ski_get +from acme_srv.helper import load_config, encode_url, csr_pubkey_get, csr_cn_get, csr_san_get, csr_san_byte_get, uts_now, uts_to_date_utc, b64_decode, cert_der2pem, convert_byte_to_string, cert_ski_get, header_info_get class CAhandler(object): @@ -25,6 +26,7 @@ def __init__(self, _debug: bool = None, logger: object = None): self.auth = None self.profile_name = None self.cert_validity_days = 30 + self.header_info_field = False def __enter__(self): """ Makes CAhandler a Context Manager """ @@ -115,6 +117,18 @@ def _certificates_list(self) -> Dict[str, str]: self.logger.debug('CAhandler._certificates_list() ended') return api_response + def _config_headerinfo_get(self, config_dic: Dict[str, str]): + """ load parameters """ + self.logger.debug('_config_header_info()') + + if 'Order' in config_dic and 'header_info_list' in config_dic['Order'] and config_dic['Order']['header_info_list']: + try: + self.header_info_field = json.loads(config_dic['Order']['header_info_list'])[0] + except Exception as err_: + self.logger.warning('Order._config_orderconfig_load() header_info_list failed with error: {0}'.format(err_)) + + self.logger.debug('_config_header_info() ended') + def _config_key_load(self, config_dic: Dict[str, str]): """ load keyname """ self.logger.debug('_config_key_load()') @@ -174,6 +188,10 @@ def _config_load(self): self.logger.debug('CAhandler._config_load()') config_dic = load_config(self.logger, 'CAhandler') + + # load headerinfos + self._config_headerinfo_get(config_dic) + if 'CAhandler' in config_dic: self._config_host_load(config_dic['CAhandler']) self._config_user_load(config_dic['CAhandler']) @@ -361,6 +379,13 @@ def _enrollment_dic_create(self, csr: str) -> Dict[str, str]: # prepare payload for api call data_dic = {'publicKey': csr_pubkey, 'profileName': self.profile_name, 'issuerName': self.ca_name, 'cn': csr_cn, 'notBefore': validfrom, 'notAfter': validto} + if self.header_info_field: + # parse profileid from http_header + profile_name = self._profile_name_get(csr=csr) + if profile_name: + self.logger.info('CAhandler._enrollment_dic_create(): profile_name found in header_info: {0}'.format(profile_name)) + data_dic['profileName'] = profile_name + # get SANs from csr as base64 encoded byte sequence # sans_base64 = csr_san_byte_get(self.logger, csr) # if sans_base64: @@ -372,6 +397,27 @@ def _enrollment_dic_create(self, csr: str) -> Dict[str, str]: return data_dic + def _profile_name_get(self, csr: str) -> str: + """ get profile id from csr """ + self.logger.debug('CAhandler._profile_name_get({0})'.format(csr)) + profile_name = None + + # parse profileid from http_header + header_info = header_info_get(self.logger, csr=csr) + if header_info: + try: + header_info_dic = json.loads(header_info[-1]['header_info']) + if self.header_info_field in header_info_dic: + for ele in header_info_dic[self.header_info_field].split(' '): + if 'profile_name' in ele.lower(): + profile_name = ele.split('=')[1] + break + except Exception as err: + self.logger.error('CAhandler._profile_name_get() could not parse profile_name: {0}'.format(err)) + + self.logger.debug('CAhandler._profile_name_get() ended with: {0}'.format(profile_name)) + return profile_name + def enroll(self, csr: str) -> Tuple[str, str, str, str]: """ enroll certificate """ self.logger.debug('CAhandler.enroll()') diff --git a/test/test_asa_ca_handler.py b/test/test_asa_ca_handler.py index ca8a0eb7..11b13217 100644 --- a/test/test_asa_ca_handler.py +++ b/test/test_asa_ca_handler.py @@ -44,7 +44,6 @@ def test_004_trigger(self): """ test polling """ self.assertEqual(('Method not implemented.', None, None), self.cahandler.trigger('payload')) - @patch('examples.ca_handler.asa_ca_handler.load_config') def test_005_config_load(self, mock_config_load): """ test _config_load """ @@ -62,6 +61,7 @@ def test_005_config_load(self, mock_config_load): self.assertFalse(self.cahandler.proxy) self.assertEqual(10, self.cahandler.request_timeout) self.assertEqual(30, self.cahandler.cert_validity_days) + self.assertFalse(self.cahandler.header_info_field) @patch('examples.ca_handler.asa_ca_handler.load_config') def test_006_config_load(self, mock_config_load): @@ -80,6 +80,7 @@ def test_006_config_load(self, mock_config_load): self.assertFalse(self.cahandler.proxy) self.assertEqual(10, self.cahandler.request_timeout) self.assertEqual(30, self.cahandler.cert_validity_days) + self.assertFalse(self.cahandler.header_info_field) @patch('examples.ca_handler.asa_ca_handler.load_config') def test_007_config_load(self, mock_config_load): @@ -98,6 +99,7 @@ def test_007_config_load(self, mock_config_load): self.assertFalse(self.cahandler.proxy) self.assertEqual(10, self.cahandler.request_timeout) self.assertEqual(30, self.cahandler.cert_validity_days) + self.assertFalse(self.cahandler.header_info_field) @patch('examples.ca_handler.asa_ca_handler.load_config') def test_008_config_load(self, mock_config_load): @@ -116,6 +118,7 @@ def test_008_config_load(self, mock_config_load): self.assertFalse(self.cahandler.proxy) self.assertEqual(10, self.cahandler.request_timeout) self.assertEqual(30, self.cahandler.cert_validity_days) + self.assertFalse(self.cahandler.header_info_field) @patch('examples.ca_handler.asa_ca_handler.load_config') def test_009_config_load(self, mock_config_load): @@ -129,6 +132,7 @@ def test_009_config_load(self, mock_config_load): self.assertFalse(self.cahandler.proxy) self.assertEqual(10, self.cahandler.request_timeout) self.assertEqual(30, self.cahandler.cert_validity_days) + self.assertFalse(self.cahandler.header_info_field) @patch('examples.ca_handler.asa_ca_handler.load_config') def test_010_config_load(self, mock_config_load): @@ -148,6 +152,7 @@ def test_010_config_load(self, mock_config_load): self.assertFalse(self.cahandler.proxy) self.assertEqual(10, self.cahandler.request_timeout) self.assertEqual(30, self.cahandler.cert_validity_days) + self.assertFalse(self.cahandler.header_info_field) @patch('examples.ca_handler.asa_ca_handler.load_config') def test_011_config_load(self, mock_config_load): @@ -167,6 +172,7 @@ def test_011_config_load(self, mock_config_load): self.assertFalse(self.cahandler.proxy) self.assertEqual(20, self.cahandler.request_timeout) self.assertEqual(30, self.cahandler.cert_validity_days) + self.assertFalse(self.cahandler.header_info_field) @patch('examples.ca_handler.asa_ca_handler.load_config') def test_012_config_load(self, mock_config_load): @@ -187,6 +193,7 @@ def test_012_config_load(self, mock_config_load): self.assertFalse(self.cahandler.proxy) self.assertEqual(10, self.cahandler.request_timeout) self.assertEqual(30, self.cahandler.cert_validity_days) + self.assertFalse(self.cahandler.header_info_field) @patch('examples.ca_handler.asa_ca_handler.load_config') def test_013_config_load(self, mock_config_load): @@ -207,6 +214,7 @@ def test_013_config_load(self, mock_config_load): self.assertFalse(self.cahandler.proxy) self.assertEqual(10, self.cahandler.request_timeout) self.assertEqual(10, self.cahandler.cert_validity_days) + self.assertFalse(self.cahandler.header_info_field) @patch('examples.ca_handler.asa_ca_handler.load_config') def test_014_config_load(self, mock_config_load): @@ -227,6 +235,7 @@ def test_014_config_load(self, mock_config_load): self.assertFalse(self.cahandler.proxy) self.assertEqual(10, self.cahandler.request_timeout) self.assertEqual(30, self.cahandler.cert_validity_days) + self.assertFalse(self.cahandler.header_info_field) @patch('examples.ca_handler.asa_ca_handler.load_config') def test_015_config_load(self, mock_config_load): @@ -246,6 +255,7 @@ def test_015_config_load(self, mock_config_load): self.assertFalse(self.cahandler.proxy) self.assertEqual(10, self.cahandler.request_timeout) self.assertEqual(30, self.cahandler.cert_validity_days) + self.assertFalse(self.cahandler.header_info_field) @patch('examples.ca_handler.asa_ca_handler.load_config') def test_016_config_load(self, mock_config_load): @@ -265,9 +275,30 @@ def test_016_config_load(self, mock_config_load): self.assertFalse(self.cahandler.proxy) self.assertEqual(10, self.cahandler.request_timeout) self.assertEqual(30, self.cahandler.cert_validity_days) + self.assertFalse(self.cahandler.header_info_field) + + @patch('examples.ca_handler.asa_ca_handler.load_config') + def test_017_config_load(self, mock_config_load): + """ test _config_load """ + mock_config_load.return_value = {'Order': {'header_info_list': '["foo"]'}} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.cahandler._config_load() + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_host not set', lcm.output) + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_user not set', lcm.output) + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_key not set', lcm.output) + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): api_password not set', lcm.output) + self.assertFalse(self.cahandler.api_host) + self.assertFalse(self.cahandler.api_user) + self.assertFalse(self.cahandler.api_password) + self.assertFalse(self.cahandler.api_key) + self.assertFalse(self.cahandler.ca_bundle) + self.assertFalse(self.cahandler.proxy) + self.assertEqual(10, self.cahandler.request_timeout) + self.assertEqual(30, self.cahandler.cert_validity_days) + self.assertEqual('foo', self.cahandler.header_info_field) @patch.object(requests, 'post') - def test_017__api_post(self, mock_req): + def test_018__api_post(self, mock_req): """ test _api_post() """ mockresponse = Mock() mockresponse.status_code = 'status_code' @@ -276,7 +307,7 @@ def test_017__api_post(self, mock_req): self.assertEqual(('status_code', {'foo': 'bar'}), self.cahandler._api_post('url', 'data')) @patch('requests.post') - def test_018__api_post(self, mock_req): + def test_019__api_post(self, mock_req): """ test _api_post() """ mockresponse = Mock() mockresponse.status_code = 'status_code' @@ -287,7 +318,7 @@ def test_018__api_post(self, mock_req): self.assertIn("ERROR:test_a2c:CAhandler._api_post() returned error: 'str' object is not callable", lcm.output) @patch('requests.post') - def test_019__api_post(self, mock_req): + def test_020__api_post(self, mock_req): """ test _api_post() """ mockresponse = Mock() mockresponse.status_code = 'status_code' @@ -296,7 +327,7 @@ def test_019__api_post(self, mock_req): self.assertEqual(('status_code', None), self.cahandler._api_post('url', 'data')) @patch('requests.post') - def test_020__api_post(self, mock_req): + def test_021__api_post(self, mock_req): """ test _api_post(= """ self.cahandler.api_host = 'api_host' self.cahandler.auth = 'auth' @@ -306,7 +337,7 @@ def test_020__api_post(self, mock_req): self.assertIn('ERROR:test_a2c:CAhandler._api_post() returned error: exc_api_post', lcm.output) @patch.object(requests, 'get') - def test_021__api_get(self, mock_req): + def test_022__api_get(self, mock_req): """ test _api_get() """ mockresponse = Mock() mockresponse.status_code = 'status_code' @@ -315,7 +346,7 @@ def test_021__api_get(self, mock_req): self.assertEqual(('status_code', {'foo': 'bar'}), self.cahandler._api_get('url')) @patch('requests.get') - def test_022__api_get(self, mock_req): + def test_023__api_get(self, mock_req): """ test _api_get() """ mockresponse = Mock() mockresponse.status_code = 'status_code' @@ -326,7 +357,7 @@ def test_022__api_get(self, mock_req): self.assertIn("ERROR:test_a2c:CAhandler._api_get() returned error: 'str' object is not callable", lcm.output) @patch('requests.get') - def test_023__api_get(self, mock_req): + def test_024__api_get(self, mock_req): """ test _api_get() """ self.cahandler.api_host = 'api_host' self.cahandler.auth = 'auth' @@ -336,27 +367,27 @@ def test_023__api_get(self, mock_req): self.assertIn('ERROR:test_a2c:CAhandler._api_post() returned error: exc_api_get', lcm.output) @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_get') - def test_024__issuers_list(self, mock_get): + def test_025__issuers_list(self, mock_get): """ test _issuers_list()""" mock_get.return_value = (200, 'content') self.assertEqual('content', self.cahandler._issuers_list()) @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_get') - def test_025__profiles_list(self, mock_get): + def test_026__profiles_list(self, mock_get): """ test _profiles_list()""" self.cahandler.ca_name = 'ca_name' mock_get.return_value = (200, 'content') self.assertEqual('content', self.cahandler._profiles_list()) @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_get') - def test_026__certificates_list(self, mock_get): + def test_027__certificates_list(self, mock_get): """ test _profiles_list()""" self.cahandler.ca_name = 'ca_name' mock_get.return_value = (200, 'content') self.assertEqual('content', self.cahandler._certificates_list()) @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_post') - def test_027_cert_status_get(self, mock_req): + def test_028_cert_status_get(self, mock_req): """ test _profiles_list()""" self.cahandler.ca_name = 'ca_name' mock_req.return_value = ('status_code', {'foo': 'bar'}) @@ -364,7 +395,7 @@ def test_027_cert_status_get(self, mock_req): @patch('examples.ca_handler.asa_ca_handler.csr_san_get') @patch('examples.ca_handler.asa_ca_handler.csr_cn_get') - def test_028__csr_cn_get(self, mock_cn, mock_san): + def test_029__csr_cn_get(self, mock_cn, mock_san): """ test _csr_cn_get() """ mock_cn.return_value = 'cn' mock_san.return_value = ['san0', 'san1'] @@ -373,7 +404,7 @@ def test_028__csr_cn_get(self, mock_cn, mock_san): @patch('examples.ca_handler.asa_ca_handler.csr_san_get') @patch('examples.ca_handler.asa_ca_handler.csr_cn_get') - def test_029__csr_cn_get(self, mock_cn, mock_san): + def test_030__csr_cn_get(self, mock_cn, mock_san): """ test _csr_cn_get() """ mock_cn.return_value = None mock_san.return_value = ['dns:san0', 'dns:san1'] @@ -385,7 +416,7 @@ def test_029__csr_cn_get(self, mock_cn, mock_san): @patch('examples.ca_handler.asa_ca_handler.csr_san_get') @patch('examples.ca_handler.asa_ca_handler.csr_cn_get') - def test_030__csr_cn_get(self, mock_cn, mock_san): + def test_031__csr_cn_get(self, mock_cn, mock_san): """ test _csr_cn_get() """ mock_cn.return_value = None mock_san.return_value = None @@ -396,14 +427,14 @@ def test_030__csr_cn_get(self, mock_cn, mock_san): self.assertTrue(mock_san.called) @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuers_list') - def test_031_issuer_verify(self, mock_list): + def test_032_issuer_verify(self, mock_list): """ _issuer_verify() """ self.cahandler.ca_name = 'ca_name' mock_list.return_value = {'issuers': ['1', '2', 'ca_name']} self.assertFalse(self.cahandler._issuer_verify()) @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuers_list') - def test_032_issuer_verify(self, mock_list): + def test_033_issuer_verify(self, mock_list): """ _issuer_verify() """ self.cahandler.ca_name = 'ca_name' mock_list.return_value = {'issuers': ['1', '2', '3']} @@ -412,7 +443,7 @@ def test_032_issuer_verify(self, mock_list): self.assertIn('ERROR:test_a2c:CAhandler.enroll(): CA ca_name not found', lcm.output) @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuers_list') - def test_033_issuer_verify(self, mock_list): + def test_034_issuer_verify(self, mock_list): """ _issuer_verify() """ self.cahandler.ca_name = 'ca_name' mock_list.return_value = {'foo': 'bar'} @@ -421,14 +452,14 @@ def test_033_issuer_verify(self, mock_list): self.assertIn('ERROR:test_a2c:CAhandler.enroll(): "Malformed response. "issuers" key not found', lcm.output) @patch('examples.ca_handler.asa_ca_handler.CAhandler._profiles_list') - def test_034_profile_verify(self, mock_list): + def test_035_profile_verify(self, mock_list): """ _profile_verify() """ self.cahandler.profile_name = 'profile_name' mock_list.return_value = {'profiles': ['1', '2', 'profile_name']} self.assertFalse(self.cahandler._profile_verify()) @patch('examples.ca_handler.asa_ca_handler.CAhandler._profiles_list') - def test_035_profile_verify(self, mock_list): + def test_036_profile_verify(self, mock_list): """ _profile_verify() """ self.cahandler.profile_name = 'profile_name' mock_list.return_value = {'profiles': ['1', '2', '3']} @@ -437,7 +468,7 @@ def test_035_profile_verify(self, mock_list): self.assertIn('ERROR:test_a2c:CAhandler.enroll(): Profile profile_name not found', lcm.output) @patch('examples.ca_handler.asa_ca_handler.CAhandler._profiles_list') - def test_036_profile_verify(self, mock_list): + def test_037_profile_verify(self, mock_list): """ _profile_verify() """ self.cahandler.ca_name = 'ca_name' mock_list.return_value = {'foo': 'bar'} @@ -447,7 +478,7 @@ def test_036_profile_verify(self, mock_list): @patch('examples.ca_handler.asa_ca_handler.uts_to_date_utc') @patch('examples.ca_handler.asa_ca_handler.uts_now') - def test_037__validity_dates_get(self, mock_now, mock_utc): + def test_038__validity_dates_get(self, mock_now, mock_utc): """ test _validity_dates_get() """ mock_now.return_value = 10 mock_utc.side_effect = ['date1', 'date2'] @@ -457,12 +488,12 @@ def test_037__validity_dates_get(self, mock_now, mock_utc): @patch('examples.ca_handler.asa_ca_handler.convert_byte_to_string') @patch('examples.ca_handler.asa_ca_handler.cert_der2pem') @patch('examples.ca_handler.asa_ca_handler.b64_decode') - def test_038__pem_cert_chain_generate(self, mock_dec, mock_d2p, mock_b2s): + def test_039__pem_cert_chain_generate(self, mock_dec, mock_d2p, mock_b2s): """ test _pem_cert_chain_generate() """ mock_b2s.return_value = 'cert' self.assertEqual('certcert', self.cahandler._pem_cert_chain_generate(['cert', 'chain'])) - def test_039__pem_cert_chain_generate(self): + def test_040__pem_cert_chain_generate(self): """ test _pem_cert_chain_generate() """ cert_list = ['MIIF7DCCBFSgAwIBAgIKB/8cQ9wAI3UbITANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJERTERMA8GA1UECgwIT3BlblhQS0kxDDAKBgNVBAsMA1BLSTEqMCgGA1UEAwwhT3BlblhQS0kgRGVtbyBJc3N1aW5nIENBIDIwMjMwMjA0MB4XDTIzMDIwNTA2NDY0MloXDTI0MDIwNTA2NDY0MlowazETMBEGCgmSJomT8ixkARkWA29yZzEYMBYGCgmSJomT8ixkARkWCE9wZW5YUEtJMR8wHQYKCZImiZPyLGQBGRYPVGVzdCBEZXBsb3ltZW50MRkwFwYDVQQDDBBhY21lMS5keW5hbW9wLmRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAre1jtb8Xjqr49QH3fWe2kH+yDk3NXfxHyOmKcNcBke68WMRB5Irrdj15JfAsXxu9psLVEOJgvdOLOnUbhN57uBLHwMAC1LH6HruYuCqtbaSezgJIYIEACvtQmIy6BIvigqwX31eLkA7kk7YXeJCnvrr461t/uZkhmaXZM9+G4asSj6fT0ffA7OVVqewDdE+d2VgCjPlH9uqPMOVK2m/AQj+jEVV/IV2znngZmkAsmYi6h2Wg08vEzTMyvhZIEma3xo6M9g9VIsTQP/ETxxhAAgzEQ0Jlz90rOioZK7mkx8xH1fLlhyfX53vqcEbva5evy1YMGEs0XZPYu2B6Oya9WQIDAQABo4ICITCCAh0wgYcGCCsGAQUFBwEBBHsweTBRBggrBgEFBQcwAoZFaHR0cDovL3BraS5leGFtcGxlLmNvbS9kb3dubG9hZC9PcGVuWFBLSV9EZW1vX0lzc3VpbmdfQ0FfMjAyMzAyMDQuY2VyMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5leGFtcGxlLmNvbS8wHwYDVR0jBBgwFoAU0f8PWcniVXltJeA6q7wYtyJrNFAwDAYDVR0TAQH/BAIwADBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vcGtpLmV4YW1wbGUuY29tL2Rvd25sb2FkL09wZW5YUEtJX0RlbW9fSXNzdWluZ19DQV8yMDIzMDIwNC5jcmwwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDgYDVR0PAQH/BAQDAgWgMIGoBgNVHSAEgaAwgZ0wgZoGAyoDBDCBkjArBggrBgEFBQcCARYfaHR0cDovL3BraS5leGFtcGxlLmNvbS9jcHMuaHRtbDArBggrBgEFBQcCARYfaHR0cDovL3BraS5leGFtcGxlLmNvbS9jcHMuaHRtbDA2BggrBgEFBQcCAjAqGihUaGlzIGlzIGEgY29tbWVudCBmb3IgcG9saWN5IG9pZCAxLjIuMy40MBsGA1UdEQQUMBKCEGFjbWUxLmR5bmFtb3AuZGUwHQYDVR0OBBYEFA3AUTV0pg0fsd3Cd6/BskOEB9MVMA0GCSqGSIb3DQEBCwUAA4IBgQB0xnnl6BJDXrbTQr7TdkRPmcCDFUmi8aVTYozbQ8EKxIYEPsfzxOFbSG/wn+4Sjz7HqvzqxyisfTopqWrvpqIhlXOEFMnNYTDO4LzCd81Dcs4czjoIRxRTisgNCvWR9hbeH9HzdRT1UF/c4VxxLEONSsGHksoXa+G4u7XmPwD4dTUIP49Mmj2a28z/viG8KftcjAEo1S7OB+/xyPeVDYrgagMR31a69pI+yuQa0J66O/LJQrzjWf6wHToQErQPcEBtDxY2wx3hROMtdla9lUEU8XLb3e9zByZwOfDhFpw8iYkJx/BUZlsmIKaZSpYVS+0D5LI1R5PENhT/2gRxaA31RiNLK/E8CSU7MMadqImkFLkDHU2x+2SRENwvoOEUAOewjVlhB1pK0r5WEye2lBjl8cUa+8qhIrAOqggApQ7eCQq7v2bL08VxKz5baOhKfLZ9u4MH6q52pnqXmll0W7JXrJSbam5r3YoSelm94VwVyaSkfd+LT4YMAP7GDDvtT6Y='] result = """-----BEGIN CERTIFICATE----- @@ -504,7 +535,7 @@ def test_039__pem_cert_chain_generate(self): @patch('examples.ca_handler.asa_ca_handler.CAhandler._pem_cert_chain_generate') @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_get') - def test_040___issuer_chain_get(self, mock_req, mock_pem): + def test_041___issuer_chain_get(self, mock_req, mock_pem): """ test _issuer_chain_get() """ mock_req.return_value = ('code', {'certs': ['bar', 'foo']}) mock_pem.return_value = 'issuer_chain' @@ -514,7 +545,7 @@ def test_040___issuer_chain_get(self, mock_req, mock_pem): @patch('examples.ca_handler.asa_ca_handler.CAhandler._pem_cert_chain_generate') @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_get') - def test_041___issuer_chain_get(self, mock_req, mock_pem): + def test_042___issuer_chain_get(self, mock_req, mock_pem): """ test _issuer_chain_get() """ mock_req.return_value = ('code', {'foobar': ['bar', 'foo']}) mock_pem.return_value = 'issuer_chain' @@ -522,6 +553,7 @@ def test_041___issuer_chain_get(self, mock_req, mock_pem): self.assertFalse(self.cahandler._issuer_chain_get()) self.assertFalse(mock_pem.called) + @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_name_get') @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_post') @patch('examples.ca_handler.asa_ca_handler.convert_byte_to_string') @patch('examples.ca_handler.asa_ca_handler.cert_der2pem') @@ -532,7 +564,7 @@ def test_041___issuer_chain_get(self, mock_req, mock_pem): @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_chain_get') @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_verify') @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_verify') - def test_042_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_b64, mock_d2p, mock_b2s, mock_post): + def test_043_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_b64, mock_d2p, mock_b2s, mock_post, mock_profile): """ test enroll() """ mock_iv.return_value = None mock_pv.return_value = None @@ -551,6 +583,7 @@ def test_042_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vd self.assertTrue(mock_post.called) self.assertTrue(mock_b2s.called) self.assertTrue(mock_d2p.called) + self.assertFalse(mock_profile.called) @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_post') @patch('examples.ca_handler.asa_ca_handler.convert_byte_to_string') @@ -563,7 +596,7 @@ def test_042_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vd @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_chain_get') @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_verify') @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_verify') - def test_043_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_csbg, mock_b64, mock_d2p, mock_b2s, mock_post): + def test_044_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_csbg, mock_b64, mock_d2p, mock_b2s, mock_post): """ test enroll() """ mock_iv.return_value = 'mock_iv' mock_pv.return_value = None @@ -595,7 +628,7 @@ def test_043_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vd @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_chain_get') @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_verify') @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_verify') - def test_044_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_csbg, mock_b64, mock_d2p, mock_b2s, mock_post): + def test_045_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_csbg, mock_b64, mock_d2p, mock_b2s, mock_post): """ test enroll() """ mock_iv.return_value = None mock_pv.return_value = 'mock_pv' @@ -626,7 +659,7 @@ def test_044_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vd @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_chain_get') @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_verify') @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_verify') - def test_045_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_b64, mock_d2p, mock_b2s, mock_post): + def test_046_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_b64, mock_d2p, mock_b2s, mock_post): """ test enroll() """ mock_iv.return_value = None mock_pv.return_value = None @@ -657,7 +690,7 @@ def test_045_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vd @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_chain_get') @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_verify') @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_verify') - def test_046_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_csbg, mock_b64, mock_d2p, mock_b2s, mock_post): + def test_047_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_csbg, mock_b64, mock_d2p, mock_b2s, mock_post): """ test enroll() """ mock_iv.return_value = None mock_pv.return_value = None @@ -683,7 +716,7 @@ def test_046_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vd @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_post') @patch('examples.ca_handler.asa_ca_handler.cert_ski_get') - def test_047_revoke(self, mock_ski, mock_post): + def test_048_revoke(self, mock_ski, mock_post): """ test revoke() """ self.cahandler.ca_name = 'ca_name' mock_ski.return_value = 'serial' @@ -694,7 +727,7 @@ def test_047_revoke(self, mock_ski, mock_post): @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_post') @patch('examples.ca_handler.asa_ca_handler.cert_ski_get') - def test_048_revoke(self, mock_ski, mock_post): + def test_049_revoke(self, mock_ski, mock_post): """ test revoke() """ self.cahandler.ca_name = 'ca_name' mock_ski.return_value = 'mock_ski' @@ -705,7 +738,7 @@ def test_048_revoke(self, mock_ski, mock_post): @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_post') @patch('examples.ca_handler.asa_ca_handler.cert_ski_get') - def test_049_revoke(self, mock_ski, mock_post): + def test_050_revoke(self, mock_ski, mock_post): """ test revoke() """ self.cahandler.ca_name = 'ca_name' mock_ski.return_value = 'ski' @@ -716,7 +749,7 @@ def test_049_revoke(self, mock_ski, mock_post): @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_post') @patch('examples.ca_handler.asa_ca_handler.cert_ski_get') - def test_050_revoke(self, mock_ski, mock_post): + def test_051_revoke(self, mock_ski, mock_post): """ test revoke() """ self.cahandler.ca_name = 'ca_name' mock_ski.return_value = 'ski' @@ -726,7 +759,7 @@ def test_050_revoke(self, mock_ski, mock_post): self.assertTrue(mock_post.called) @patch.dict('os.environ', {'api_user_var': 'user_var'}) - def test_051_config_user_load(self): + def test_052_config_user_load(self): """ test _config_load - load template with user variable """ config_dic = {'api_user_variable': 'api_user_var'} self.cahandler._config_user_load(config_dic) @@ -734,7 +767,7 @@ def test_051_config_user_load(self): self.assertFalse(self.cahandler.profile_name) @patch.dict('os.environ', {'api_user_var': 'user_var'}) - def test_052_config_user_load(self): + def test_053_config_user_load(self): """ test _config_load - load template with user variable """ config_dic = {'api_user_variable': 'does_not_exist'} with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -744,7 +777,7 @@ def test_052_config_user_load(self): self.assertFalse(self.cahandler.profile_name) @patch.dict('os.environ', {'api_user_var': 'user_var'}) - def test_053_config_user_load(self): + def test_054_config_user_load(self): """ test _config_load - load template with user variable """ config_dic = {'api_user_variable': 'api_user_var', 'api_user': 'api_user'} self.cahandler._config_user_load(config_dic) @@ -754,7 +787,7 @@ def test_053_config_user_load(self): self.assertFalse(self.cahandler.profile_name) @patch.dict('os.environ', {'api_host_var': 'host_var'}) - def test_054_config_host_load(self): + def test_055_config_host_load(self): """ test _config_load - load template with host variable """ config_dic = {'api_host_variable': 'api_host_var'} self.cahandler._config_host_load(config_dic) @@ -762,7 +795,7 @@ def test_054_config_host_load(self): self.assertFalse(self.cahandler.profile_name) @patch.dict('os.environ', {'api_host_var': 'host_var'}) - def test_055_config_host_load(self): + def test_056_config_host_load(self): """ test _config_load - load template with host variable """ config_dic = {'api_host_variable': 'does_not_exist'} with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -772,7 +805,7 @@ def test_055_config_host_load(self): self.assertFalse(self.cahandler.profile_name) @patch.dict('os.environ', {'api_host_var': 'host_var'}) - def test_056_config_host_load(self): + def test_057_config_host_load(self): """ test _config_load - load template with host variable """ config_dic = {'api_host_variable': 'api_host_var', 'api_host': 'api_host'} self.cahandler._config_host_load(config_dic) @@ -782,7 +815,7 @@ def test_056_config_host_load(self): self.assertFalse(self.cahandler.profile_name) @patch.dict('os.environ', {'api_key_var': 'key_var'}) - def test_057_config_key_load(self): + def test_058_config_key_load(self): """ test _config_load - load template with key variable """ config_dic = {'api_key_variable': 'api_key_var'} self.cahandler._config_key_load(config_dic) @@ -790,7 +823,7 @@ def test_057_config_key_load(self): self.assertFalse(self.cahandler.profile_name) @patch.dict('os.environ', {'api_key_var': 'key_var'}) - def test_058_config_key_load(self): + def test_059_config_key_load(self): """ test _config_load - load template with key variable """ config_dic = {'api_key_variable': 'does_not_exist'} with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -800,7 +833,7 @@ def test_058_config_key_load(self): self.assertFalse(self.cahandler.profile_name) @patch.dict('os.environ', {'api_key_var': 'key_var'}) - def test_059_config_key_load(self): + def test_060_config_key_load(self): """ test _config_load - load template with key variable """ config_dic = {'api_key_variable': 'api_key_var', 'api_key': 'api_key'} self.cahandler._config_key_load(config_dic) @@ -810,7 +843,7 @@ def test_059_config_key_load(self): self.assertFalse(self.cahandler.profile_name) @patch.dict('os.environ', {'api_password_var': 'password_var'}) - def test_060_config_password_load(self): + def test_061_config_password_load(self): """ test _config_load - load template with password variable """ config_dic = {'api_password_variable': 'api_password_var'} self.cahandler._config_password_load(config_dic) @@ -818,7 +851,7 @@ def test_060_config_password_load(self): self.assertFalse(self.cahandler.profile_name) @patch.dict('os.environ', {'api_password_var': 'password_var'}) - def test_061_config_password_load(self): + def test_062_config_password_load(self): """ test _config_load - load template with password variable """ config_dic = {'api_password_variable': 'does_not_exist'} with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -828,7 +861,7 @@ def test_061_config_password_load(self): self.assertFalse(self.cahandler.profile_name) @patch.dict('os.environ', {'api_password_var': 'password_var'}) - def test_062_config_password_load(self): + def test_063_config_password_load(self): """ test _config_load - load template with password variable """ config_dic = {'api_password_variable': 'api_password_var', 'api_password': 'api_password'} self.cahandler._config_password_load(config_dic) @@ -837,6 +870,70 @@ def test_062_config_password_load(self): # self.assertIn("foo", lcm.output) self.assertFalse(self.cahandler.profile_name) + def test_064_config_headerinfo_get(self): + """ test config_headerinfo_get()""" + config_dic = {'Order': {'header_info_list': '["foo", "bar", "foobar"]'}} + self.cahandler._config_headerinfo_get(config_dic) + self.assertEqual( 'foo', self.cahandler.header_info_field) + + def test_065_config_headerinfo_get(self): + """ test config_headerinfo_get()""" + config_dic = {'Order': {'header_info_list': '["foo"]'}} + self.cahandler._config_headerinfo_get(config_dic) + self.assertEqual( 'foo', self.cahandler.header_info_field) + + def test_066_config_headerinfo_get(self): + """ test config_headerinfo_get()""" + config_dic = {'Order': {'header_info_list': 'foo'}} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.cahandler._config_headerinfo_get(config_dic) + self.assertFalse(self.cahandler.header_info_field) + self.assertIn('WARNING:test_a2c:Order._config_orderconfig_load() header_info_list failed with error: Expecting value: line 1 column 1 (char 0)', lcm.output) + + @patch('examples.ca_handler.asa_ca_handler.header_info_get') + def test_067_profile_name_get(self, mock_header): + """ test _profile_name_get()""" + mock_header.return_value = [{'header_info': '{"header_field": "profile_name=101 lego-cli/4.14.2 xenolf-acme/4.14.2 (release; linux; amd64)"}'}] + self.cahandler.header_info_field = 'header_field' + self.assertEqual('101', self.cahandler._profile_name_get('csr')) + + @patch('examples.ca_handler.asa_ca_handler.header_info_get') + def test_068_profile_name_get(self, mock_header): + """ test _profile_name_get()""" + mock_header.return_value = [{'header_info': 'header_info'}] + self.cahandler.header_info_field = 'header_field' + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.cahandler._profile_name_get('csr')) + self.assertIn('ERROR:test_a2c:CAhandler._profile_name_get() could not parse profile_name: Expecting value: line 1 column 1 (char 0)', lcm.output) + + @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_name_get') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._validity_dates_get') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._csr_cn_get') + @patch('examples.ca_handler.asa_ca_handler.csr_pubkey_get') + def test_069_enrollment_dic_create(self, mock_pkg, mock_ccg, mock_vdg, mock_png): + """ test _enrollment_dic_create()""" + mock_pkg.return_value = 'pubkey' + mock_ccg.return_value = 'cn' + mock_vdg.return_value = ('date1', 'date2') + mock_png.return_value = 'profile_name' + result = {'publicKey': 'pubkey', 'profileName': None, 'issuerName': None, 'cn': 'cn', 'notBefore': 'date1', 'notAfter': 'date2'} + self.assertEqual(result, self.cahandler._enrollment_dic_create('csr')) + self.assertFalse(mock_png.called) + + @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_name_get') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._validity_dates_get') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._csr_cn_get') + @patch('examples.ca_handler.asa_ca_handler.csr_pubkey_get') + def test_070_enrollment_dic_create(self, mock_pkg, mock_ccg, mock_vdg, mock_png): + """ test _enrollment_dic_create()""" + mock_pkg.return_value = 'pubkey' + mock_ccg.return_value = 'cn' + mock_vdg.return_value = ('date1', 'date2') + mock_png.return_value = 'profile_name' + self.cahandler.header_info_field = 'header_field' + result = {'publicKey': 'pubkey', 'profileName': 'profile_name', 'issuerName': None, 'cn': 'cn', 'notBefore': 'date1', 'notAfter': 'date2'} + self.assertEqual(result, self.cahandler._enrollment_dic_create('csr')) + self.assertTrue(mock_png.called) if __name__ == '__main__': From 269367965a62f27cc10812b5e28de072db039c75 Mon Sep 17 00:00:00 2001 From: grindsa Date: Mon, 15 Jan 2024 16:00:38 +0100 Subject: [PATCH 015/460] [fix] header_info parsing --- .github/workflows/ca_handler_tests_asa.yml | 105 +++++++++++++++++++++ examples/ca_handler/asa_ca_handler.py | 15 +-- 2 files changed, 113 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ca_handler_tests_asa.yml b/.github/workflows/ca_handler_tests_asa.yml index e7b1d2fd..c029b816 100644 --- a/.github/workflows/ca_handler_tests_asa.yml +++ b/.github/workflows/ca_handler_tests_asa.yml @@ -402,4 +402,109 @@ jobs: if: ${{ failure() }} with: name: asa_handler_tests_rpm.tar.gz + path: ${{ github.workspace }}/artifact/upload/ + + + asa_handler_headerinfo_tests: + name: "asa_handler_headerinfo_tests" + runs-on: ubuntu-latest + steps: + - name: "checkout GIT" + uses: actions/checkout@v3 + + - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + working-directory: examples/Docker/ + run: | + sudo mkdir -p data + docker network create acme + docker-compose up -d + docker-compose logs + + - name: "[ PREPARE ] create lego folder" + run: | + mkdir lego + + - name: "Test http://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "[ PREPARE ] reconfiguration of a2c with a new profile" + run: | + sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem + sudo touch examples/Docker/data/acme_srv.cfg + sudo chmod 777 examples/Docker/data/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg + sudo echo "handler_file: examples/ca_handler/asa_ca_handler.py" >> examples/Docker/data/acme_srv.cfg + sudo echo "api_host: $ASA_API_HOST" >> examples/Docker/data/acme_srv.cfg + sudo echo "api_user: $ASA_API_USER" >> examples/Docker/data/acme_srv.cfg + sudo echo "api_password: $ASA_API_PASSWORD" >> examples/Docker/data/acme_srv.cfg + sudo echo "api_key: $ASA_API_KEY" >> examples/Docker/data/acme_srv.cfg + sudo echo "ca_name: $ASA_CA_NAME" >> examples/Docker/data/acme_srv.cfg + sudo echo "ca_bundle: $ASA_CA_BUNDLE" >> examples/Docker/data/acme_srv.cfg + sudo echo "profile_name: $ASA_POFILE1" >> examples/Docker/data/acme_srv.cfg + sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout:15/g" examples/Docker/data/acme_srv.cfg + sudo sed -i "s/tnauthlist_support: False/tnauthlist_support: False\nheader_info_list: [\"HTTP_USER_AGENT\"]/g" examples/Docker/data/acme_srv.cfg + cd examples/Docker/ + docker-compose restart + docker-compose logs + env: + ASA_API_HOST: ${{ secrets.ASA_API_HOST }} + ASA_API_USER: ${{ secrets.ASA_API_USER }} + ASA_API_PASSWORD: ${{ secrets.ASA_API_PASSWORD }} + ASA_API_KEY: ${{ secrets.ASA_API_KEY }} + ASA_CA_NAME: ${{ secrets.ASA_CA_NAME }} + ASA_CA_BUNDLE: ${{ secrets.ASA_CA_BUNDLE }} + ASA_PROFILE1: ${{ secrets.ASA_POFILE1 }} + + - name: "Test http://acme-srv/directory is accessable again" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "[ PREPARE ] prepare acme.sh container" + run: | + sudo mkdir acme-sh + docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + + - name: "[ REGISTER] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 + + - name: "[ ENROLL] acme.sh with profileID ACME" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --useragent profile_name=ACME --keylength 2048 --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature" + + - name: "[ ENROLL ] lego with profileID ACME" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent profile_name=ACME -d lego.acme --key-type rsa2048 --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext keyUsage -noout | grep "Digital Signature" + + - name: "[ ENROLL] acme.sh with profileID ACME_2" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --renew --force -d acme-sh.acme --standalone --useragent profile_name=ACME_2 --keylength 2048 --debug 3 --output-insecure + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext keyUsage -noout | grep "Key Encipherment, Data Encipherment" + + - name: "[ ENROLL ] lego with profileID ACME_2" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent profile_name=ACME_2 -d lego.acme --key-type rsa2048 --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext keyUsage -noout | grep "Key Encipherment, Data Encipherment" + + - name: "[ * ] collecting test logs" + if: ${{ failure() }} + run: | + mkdir -p ${{ github.workspace }}/artifact/upload + sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ + sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ + cd examples/Docker + docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego + + - name: "[ * ] uploading artificates" + uses: actions/upload-artifact@v3 + if: ${{ failure() }} + with: + name: asa_handler_headerinfo_tests.tar.gz path: ${{ github.workspace }}/artifact/upload/ \ No newline at end of file diff --git a/examples/ca_handler/asa_ca_handler.py b/examples/ca_handler/asa_ca_handler.py index 7aaf3ed3..f2161df1 100644 --- a/examples/ca_handler/asa_ca_handler.py +++ b/examples/ca_handler/asa_ca_handler.py @@ -379,13 +379,6 @@ def _enrollment_dic_create(self, csr: str) -> Dict[str, str]: # prepare payload for api call data_dic = {'publicKey': csr_pubkey, 'profileName': self.profile_name, 'issuerName': self.ca_name, 'cn': csr_cn, 'notBefore': validfrom, 'notAfter': validto} - if self.header_info_field: - # parse profileid from http_header - profile_name = self._profile_name_get(csr=csr) - if profile_name: - self.logger.info('CAhandler._enrollment_dic_create(): profile_name found in header_info: {0}'.format(profile_name)) - data_dic['profileName'] = profile_name - # get SANs from csr as base64 encoded byte sequence # sans_base64 = csr_san_byte_get(self.logger, csr) # if sans_base64: @@ -432,6 +425,14 @@ def enroll(self, csr: str) -> Tuple[str, str, str, str]: if not error: + if self.header_info_field: + # parse profileid from http_header + profile_name = self._profile_name_get(csr=csr) + if profile_name: + self.logger.info('CAhandler._enrollment_dic_create(): profile_name found in header_info: {0}'.format(profile_name)) + self.profile_name = profile_name + + # verify profile error = self._profile_verify() if not error: From 30e1c3211ab873ab67a77c4a875532099623aa9e Mon Sep 17 00:00:00 2001 From: grindsa Date: Mon, 15 Jan 2024 16:07:57 +0100 Subject: [PATCH 016/460] [fix] unittests --- test/test_asa_ca_handler.py | 51 +++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/test/test_asa_ca_handler.py b/test/test_asa_ca_handler.py index 11b13217..7e8d32d3 100644 --- a/test/test_asa_ca_handler.py +++ b/test/test_asa_ca_handler.py @@ -553,6 +553,42 @@ def test_042___issuer_chain_get(self, mock_req, mock_pem): self.assertFalse(self.cahandler._issuer_chain_get()) self.assertFalse(mock_pem.called) + @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_name_get') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_post') + @patch('examples.ca_handler.asa_ca_handler.convert_byte_to_string') + @patch('examples.ca_handler.asa_ca_handler.cert_der2pem') + @patch('examples.ca_handler.asa_ca_handler.b64_decode') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._validity_dates_get') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._csr_cn_get') + @patch('examples.ca_handler.asa_ca_handler.csr_pubkey_get') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_chain_get') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_verify') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_verify') + def test_042_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_b64, mock_d2p, mock_b2s, mock_post, mock_profile): + """ test enroll() """ + mock_iv.return_value = None + mock_pv.return_value = None + mock_icg.return_value = 'issuer_chain' + mock_vdg.return_value = ('date1', 'date2') + mock_post.return_value = (200, 'cert') + mock_b2s.return_value = 'bcert' + self.cahandler.header_info_field = 'foo' + mock_profile.return_value = 'profile' + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertEqual((None, 'bcertissuer_chain', 'cert', None), self.cahandler.enroll('csr')) + self.assertIn('INFO:test_a2c:CAhandler._enrollment_dic_create(): profile_name found in header_info: profile', lcm.output) + self.assertTrue(mock_iv.called) + self.assertTrue(mock_pv.called) + self.assertTrue(mock_icg.called) + self.assertTrue(mock_cpg.called) + self.assertTrue(mockccg.called) + self.assertTrue(mock_vdg.called) + self.assertTrue(mock_b64.called) + self.assertTrue(mock_post.called) + self.assertTrue(mock_b2s.called) + self.assertTrue(mock_d2p.called) + self.assertTrue(mock_profile.called) + @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_name_get') @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_post') @patch('examples.ca_handler.asa_ca_handler.convert_byte_to_string') @@ -920,20 +956,7 @@ def test_069_enrollment_dic_create(self, mock_pkg, mock_ccg, mock_vdg, mock_png) self.assertEqual(result, self.cahandler._enrollment_dic_create('csr')) self.assertFalse(mock_png.called) - @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_name_get') - @patch('examples.ca_handler.asa_ca_handler.CAhandler._validity_dates_get') - @patch('examples.ca_handler.asa_ca_handler.CAhandler._csr_cn_get') - @patch('examples.ca_handler.asa_ca_handler.csr_pubkey_get') - def test_070_enrollment_dic_create(self, mock_pkg, mock_ccg, mock_vdg, mock_png): - """ test _enrollment_dic_create()""" - mock_pkg.return_value = 'pubkey' - mock_ccg.return_value = 'cn' - mock_vdg.return_value = ('date1', 'date2') - mock_png.return_value = 'profile_name' - self.cahandler.header_info_field = 'header_field' - result = {'publicKey': 'pubkey', 'profileName': 'profile_name', 'issuerName': None, 'cn': 'cn', 'notBefore': 'date1', 'notAfter': 'date2'} - self.assertEqual(result, self.cahandler._enrollment_dic_create('csr')) - self.assertTrue(mock_png.called) + if __name__ == '__main__': From b69833fb802eb3a2c2b79acb4904553a397deeeb Mon Sep 17 00:00:00 2001 From: grindsa Date: Mon, 15 Jan 2024 16:09:10 +0100 Subject: [PATCH 017/460] [fix] liniting --- examples/ca_handler/asa_ca_handler.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/ca_handler/asa_ca_handler.py b/examples/ca_handler/asa_ca_handler.py index f2161df1..ba3fb457 100644 --- a/examples/ca_handler/asa_ca_handler.py +++ b/examples/ca_handler/asa_ca_handler.py @@ -3,11 +3,11 @@ from __future__ import print_function from typing import Tuple, Dict import os -import requests import json +import requests from requests.auth import HTTPBasicAuth # pylint: disable=C0209, E0401 -from acme_srv.helper import load_config, encode_url, csr_pubkey_get, csr_cn_get, csr_san_get, csr_san_byte_get, uts_now, uts_to_date_utc, b64_decode, cert_der2pem, convert_byte_to_string, cert_ski_get, header_info_get +from acme_srv.helper import load_config, encode_url, csr_pubkey_get, csr_cn_get, csr_san_get, uts_now, uts_to_date_utc, b64_decode, cert_der2pem, convert_byte_to_string, cert_ski_get, header_info_get class CAhandler(object): From 539a877647e8b0b27f84ddb651b2dbf153c24950 Mon Sep 17 00:00:00 2001 From: grindsa Date: Mon, 15 Jan 2024 16:25:47 +0100 Subject: [PATCH 018/460] [fix] md linting --- docs/asa.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/asa.md b/docs/asa.md index 8c8cbec1..bbe030aa 100644 --- a/docs/asa.md +++ b/docs/asa.md @@ -81,4 +81,3 @@ Example for lego: ```bash docker run -i -v $PWD/lego:/.lego/ --rm --name lego goacme/lego -s http:// -a --email "lego@example.com" --user-agent profile_name= -d --http run ``` - From 5670ed24aafd12dccf9305f544fcf63fd2a2986a Mon Sep 17 00:00:00 2001 From: grindsa Date: Mon, 15 Jan 2024 16:44:01 +0100 Subject: [PATCH 019/460] [fix] import statement --- examples/ca_handler/asa_ca_handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/ca_handler/asa_ca_handler.py b/examples/ca_handler/asa_ca_handler.py index ba3fb457..0ef1f997 100644 --- a/examples/ca_handler/asa_ca_handler.py +++ b/examples/ca_handler/asa_ca_handler.py @@ -7,7 +7,7 @@ import requests from requests.auth import HTTPBasicAuth # pylint: disable=C0209, E0401 -from acme_srv.helper import load_config, encode_url, csr_pubkey_get, csr_cn_get, csr_san_get, uts_now, uts_to_date_utc, b64_decode, cert_der2pem, convert_byte_to_string, cert_ski_get, header_info_get +from acme_srv.helper import load_config, encode_url, csr_pubkey_get, csr_cn_get, csr_san_get, uts_now, uts_to_date_utc, b64_decode, cert_der2pem, convert_byte_to_string, cert_ski_get, header_info_get, csr_san_byte_get class CAhandler(object): From f814c124566009086e1f49451328fd54601a73c5 Mon Sep 17 00:00:00 2001 From: grindsa Date: Mon, 15 Jan 2024 17:45:49 +0100 Subject: [PATCH 020/460] [fix] address codesmells --- acme_srv/helper.py | 2 +- examples/ca_handler/asa_ca_handler.py | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/acme_srv/helper.py b/acme_srv/helper.py index 4937ab9c..4239d05a 100644 --- a/acme_srv/helper.py +++ b/acme_srv/helper.py @@ -311,7 +311,7 @@ def cert_san_get(logger: logging.Logger, certificate: str, recode: bool = True) sans.append('IP:{0}'.format(san)) except Exception as err: logger.error('cert_san_get(): Error: {0}'.format(err)) - # sans = cert_san_pyopenssl_get(logger, certificate, recode=recode) + # we may add the routing to get the sanes via pyopenssl here if needed (sans = cert_san_pyopenssl_get(logger, certificate, recode=recode)) logger.debug('cert_san_get() ended') return sans diff --git a/examples/ca_handler/asa_ca_handler.py b/examples/ca_handler/asa_ca_handler.py index 0ef1f997..6a570348 100644 --- a/examples/ca_handler/asa_ca_handler.py +++ b/examples/ca_handler/asa_ca_handler.py @@ -37,7 +37,7 @@ def __enter__(self): def __exit__(self, *args): """ cose the connection at the end of the context """ - def _api_get(self, url: str) -> Dict[str, str]: + def _api_get(self, url: str) -> Tuple(int, Dict[str, str]): """ post data to API """ self.logger.debug('CAhandler._api_get()') headers = {'x-api-key': self.api_key} @@ -48,16 +48,16 @@ def _api_get(self, url: str) -> Dict[str, str]: try: content = api_response.json() except Exception as err_: - self.logger.error('CAhandler._api_get() returned error: {0}'.format(err_)) + self.logger.error('CAhandler._api_get() returned error during json parsing: {0}'.format(err_)) content = str(err_) except Exception as err_: - self.logger.error('CAhandler._api_post() returned error: {0}'.format(err_)) + self.logger.error('CAhandler._api_get() returned error: {0}'.format(err_)) code = 500 content = str(err_) return code, content - def _api_post(self, url: str, data: Dict[str, str]) -> Dict[str, str]: + def _api_post(self, url: str, data: Dict[str, str]) -> Tuple(int, Dict[str, str]): """ post data to API """ self.logger.debug('CAhandler._api_post()') headers = {'x-api-key': self.api_key} @@ -69,7 +69,7 @@ def _api_post(self, url: str, data: Dict[str, str]) -> Dict[str, str]: try: content = api_response.json() except Exception as err_: - self.logger.error('CAhandler._api_post() returned error: {0}'.format(err_)) + self.logger.error('CAhandler._api_post() returned error during json parsing: {0}'.format(err_)) content = str(err_) else: content = None From 1685550f80f60876ab30c9410483961589f5483a Mon Sep 17 00:00:00 2001 From: grindsa Date: Mon, 15 Jan 2024 17:53:25 +0100 Subject: [PATCH 021/460] [fix] address codesmells and bugs in hints --- examples/ca_handler/asa_ca_handler.py | 4 ++-- test/test_asa_ca_handler.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/ca_handler/asa_ca_handler.py b/examples/ca_handler/asa_ca_handler.py index 6a570348..6f2d2570 100644 --- a/examples/ca_handler/asa_ca_handler.py +++ b/examples/ca_handler/asa_ca_handler.py @@ -37,7 +37,7 @@ def __enter__(self): def __exit__(self, *args): """ cose the connection at the end of the context """ - def _api_get(self, url: str) -> Tuple(int, Dict[str, str]): + def _api_get(self, url: str) -> Tuple[int, Dict[str, str]]: """ post data to API """ self.logger.debug('CAhandler._api_get()') headers = {'x-api-key': self.api_key} @@ -57,7 +57,7 @@ def _api_get(self, url: str) -> Tuple(int, Dict[str, str]): return code, content - def _api_post(self, url: str, data: Dict[str, str]) -> Tuple(int, Dict[str, str]): + def _api_post(self, url: str, data: Dict[str, str]) -> Tuple[int, Dict[str, str]]: """ post data to API """ self.logger.debug('CAhandler._api_post()') headers = {'x-api-key': self.api_key} diff --git a/test/test_asa_ca_handler.py b/test/test_asa_ca_handler.py index 7e8d32d3..bad2cf77 100644 --- a/test/test_asa_ca_handler.py +++ b/test/test_asa_ca_handler.py @@ -315,7 +315,7 @@ def test_019__api_post(self, mock_req): mock_req.return_value = mockresponse with self.assertLogs('test_a2c', level='INFO') as lcm: self.assertEqual(('status_code', "'str' object is not callable"), self.cahandler._api_post('url', 'data')) - self.assertIn("ERROR:test_a2c:CAhandler._api_post() returned error: 'str' object is not callable", lcm.output) + self.assertIn("ERROR:test_a2c:CAhandler._api_post() returned error during json parsing: 'str' object is not callable", lcm.output) @patch('requests.post') def test_020__api_post(self, mock_req): @@ -354,7 +354,7 @@ def test_023__api_get(self, mock_req): mock_req.return_value = mockresponse with self.assertLogs('test_a2c', level='INFO') as lcm: self.assertEqual(('status_code', "'str' object is not callable"), self.cahandler._api_get('url')) - self.assertIn("ERROR:test_a2c:CAhandler._api_get() returned error: 'str' object is not callable", lcm.output) + self.assertIn("ERROR:test_a2c:CAhandler._api_get() returned error during json parsing: 'str' object is not callable", lcm.output) @patch('requests.get') def test_024__api_get(self, mock_req): @@ -364,7 +364,7 @@ def test_024__api_get(self, mock_req): mock_req.side_effect = Exception('exc_api_get') with self.assertLogs('test_a2c', level='INFO') as lcm: self.assertEqual((500, 'exc_api_get'), self.cahandler._api_get('url')) - self.assertIn('ERROR:test_a2c:CAhandler._api_post() returned error: exc_api_get', lcm.output) + self.assertIn('ERROR:test_a2c:CAhandler._api_get() returned error: exc_api_get', lcm.output) @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_get') def test_025__issuers_list(self, mock_get): From d11107accde1f21e68cd3e2fe068aec3097a7af0 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 20 Jan 2024 18:25:22 +0100 Subject: [PATCH 022/460] [fix] pylint c0209 formatting --- acme_srv/account.py | 97 +++--- acme_srv/acmechallenge.py | 5 +- acme_srv/authorization.py | 30 +- acme_srv/certificate.py | 185 +++++------ acme_srv/challenge.py | 136 ++++---- acme_srv/directory.py | 6 +- acme_srv/helper.py | 194 +++++------ acme_srv/housekeeping.py | 63 ++-- acme_srv/message.py | 21 +- acme_srv/nonce.py | 19 +- acme_srv/order.py | 92 +++--- acme_srv/renewalinfo.py | 15 +- acme_srv/signature.py | 17 +- acme_srv/trigger.py | 14 +- examples/db_handler/django_handler.py | 98 +++--- examples/db_handler/wsgi_handler.py | 215 ++++++------ examples/django/acme_srv/views.py | 20 +- test/test_account.py | 3 +- test/test_certificate.py | 40 ++- test/test_challenge.py | 12 - test/test_helper.py | 456 +++++++++++++------------- test/test_order.py | 18 +- 22 files changed, 878 insertions(+), 878 deletions(-) diff --git a/acme_srv/account.py b/acme_srv/account.py index e8542b8b..f7fbd37e 100644 --- a/acme_srv/account.py +++ b/acme_srv/account.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- -# pylint: disable=C0209 """ Account class """ from __future__ import print_function import json @@ -58,7 +57,7 @@ def _account_lookup(self, jwk: Dict[str, str]) -> Tuple[int, str, Dict[str, str] try: result = self.dbstore.account_lookup('jwk', json.dumps(jwk)) except Exception as err_: - self.logger.critical('acme2certifier database error in Account._account_lookup(): {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Account._account_lookup(): %s', err_) result = None if result: @@ -72,21 +71,21 @@ def _account_lookup(self, jwk: Dict[str, str]) -> Tuple[int, str, Dict[str, str] message = self.err_msg_dic['accountdoesnotexist'] detail = None - self.logger.debug('Account._acount_lookup() ended with:{0}'.format(code)) + self.logger.debug('Account._acount_lookup() ended with: %s', code) return (code, message, detail) def _account_add_check(self, account_name: str, data_dic: Dict[str, str]) -> Tuple[int, str, str]: """ perform database operation """ - self.logger.debug('Account.account._account_add_check({0})'.format(account_name)) + self.logger.debug('Account.account._account_add_check(%s)', account_name) try: (db_name, new) = self.dbstore.account_add(data_dic) except Exception as err_: - self.logger.critical('Account.account._add(): Database error: {0}'.format(err_)) + self.logger.critical('Account.account._add(): Database error: %s', err_) db_name = None new = False - self.logger.debug('got account_name:{0} new:{1}'.format(db_name, new)) + self.logger.debug('got account_name: %s new: %s', db_name, new) if new: code = 201 @@ -96,7 +95,7 @@ def _account_add_check(self, account_name: str, data_dic: Dict[str, str]) -> Tup message = db_name detail = None - self.logger.debug('Account.account._account_add_check() ended with: {0}'.format(account_name)) + self.logger.debug('Account.account._account_add_check() ended with: %s', account_name) return (code, message, detail) def _account_eab_add(self, payload: Dict[str, str], data_dic: Dict[str, str]) -> Dict[str, str]: @@ -106,7 +105,7 @@ def _account_eab_add(self, payload: Dict[str, str], data_dic: Dict[str, str]) -> if payload and 'externalaccountbinding' in payload and payload['externalaccountbinding']: if 'protected' in payload['externalaccountbinding']: eab_kid = self._eab_kid_get(payload['externalaccountbinding']['protected']) - self.logger.info('add eab_kid: {0} to data_dic'.format(eab_kid)) + self.logger.info('add eab_kid: %s to data_dic', eab_kid) if eab_kid: data_dic['eab_kid'] = eab_kid @@ -115,7 +114,7 @@ def _account_eab_add(self, payload: Dict[str, str], data_dic: Dict[str, str]) -> def _account_add(self, account_name: str, content: Dict[str, str], contact: List[str], payload: Dict[str, str]): """ prepare db insert and call DBstore helper """ - self.logger.debug('Account.account._account_add({0})'.format(account_name)) + self.logger.debug('Account.account._account_add(%s)', account_name) # ecc_only check if self.ecc_only and not content['alg'].startswith('ES'): @@ -137,7 +136,7 @@ def _account_add(self, account_name: str, content: Dict[str, str], contact: List # check code to be returned (code, message, detail) = self._account_add_check(account_name, data_dic) - self.logger.debug('Account.account._account_add() ended with: {0}'.format(account_name)) + self.logger.debug('Account.account._account_add() ended with: %s', account_name) return (code, message, detail) def _add(self, content: Dict[str, str], payload: Dict[str, str], contact: List[str]): @@ -161,7 +160,7 @@ def _add(self, content: Dict[str, str], payload: Dict[str, str], contact: List[s message = self.err_msg_dic['malformed'] detail = 'incomplete protected payload' - self.logger.debug('Account.account._add() ended with:{0}'.format(code)) + self.logger.debug('Account.account._add() ended with: %s', code) return (code, message, detail) def _contact_check(self, content: Dict[str, str]) -> Tuple[int, str, str]: @@ -182,7 +181,7 @@ def _contact_check(self, content: Dict[str, str]) -> Tuple[int, str, str]: message = self.err_msg_dic['invalidcontact'] detail = 'no contacts specified' - self.logger.debug('Account._contact_check() ended with:{0}'.format(code)) + self.logger.debug('Account._contact_check() ended with: %s', code) return (code, message, detail) def _contact_list_build(self, payload: Dict[str, str]) -> List[str]: @@ -206,7 +205,7 @@ def _contacts_update(self, aname: str, payload: Dict[str, str]) -> Tuple[int, st try: result = self.dbstore.account_update(data_dic) except Exception as err_: - self.logger.critical('acme2certifier database error in Account._contacts_update(): {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Account._contacts_update(): %s', err_) result = None if result: @@ -220,11 +219,11 @@ def _contacts_update(self, aname: str, payload: Dict[str, str]) -> Tuple[int, st def _delete(self, aname: str) -> Tuple[int, str, str]: """ delete account """ - self.logger.debug('Account._delete({0})'.format(aname)) + self.logger.debug('Account._delete(%s)', aname) try: result = self.dbstore.account_delete(aname) except Exception as err_: - self.logger.critical('acme2certifier database error in Account._delete(): {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Account._delete(): %s', err_) result = None if result: @@ -236,7 +235,7 @@ def _delete(self, aname: str) -> Tuple[int, str, str]: message = self.err_msg_dic['accountdoesnotexist'] detail = 'deletion failed' - self.logger.debug('Account._delete() ended with:{0}'.format(code)) + self.logger.debug('Account._delete() ended with: %s', code) return (code, message, detail) def _eab_jwk_compare(self, protected: Dict[str, str], payload: Dict[str, str]) -> bool: @@ -253,7 +252,7 @@ def _eab_jwk_compare(self, protected: Dict[str, str], payload: Dict[str, str]) - if jwk_outer == jwk_inner: result = True - self.logger.debug('_eab_jwk_compare() ended with: {0}'.format(result)) + self.logger.debug('_eab_jwk_compare() ended with: %s', result) return result def _eab_kid_get(self, protected: str) -> str: @@ -267,7 +266,7 @@ def _eab_kid_get(self, protected: str) -> str: else: eab_key_id = None - self.logger.debug('_eab_kid_get() ended with: {0}'.format(eab_key_id)) + self.logger.debug('_eab_kid_get() ended with: %s', eab_key_id) return eab_key_id def _eab_verify(self, payload: Dict[str, str]) -> Tuple[int, str, str]: @@ -293,13 +292,13 @@ def _eab_verify(self, payload: Dict[str, str]) -> Tuple[int, str, str]: code = 403 message = self.err_msg_dic['unauthorized'] detail = 'eab signature verification failed' - self.logger.error('Account._eab_check() returned error: {0}'.format(error)) + self.logger.error('Account._eab_check() returned error: %s', error) else: code = 403 message = self.err_msg_dic['unauthorized'] detail = 'eab kid lookup failed' - self.logger.debug('_eab_check() ended with: {0}'.format(code)) + self.logger.debug('_eab_check() ended with: %s', code) return (code, message, detail) def _eab_check(self, protected: Dict[str, str], payload: Dict[str, str]) -> Tuple[int, str, str]: @@ -323,7 +322,7 @@ def _eab_check(self, protected: Dict[str, str], payload: Dict[str, str]) -> Tupl message = self.err_msg_dic['externalaccountrequired'] detail = 'external account binding required' - self.logger.debug('Account._eab_check() ended with:{0}'.format(code)) + self.logger.debug('Account._eab_check() ended with: %s', code) return (code, message, detail) def _eab_signature_verify(self, content: Dict[str, str], mac_key: str) -> Tuple[bool, str]: @@ -337,7 +336,7 @@ def _eab_signature_verify(self, content: Dict[str, str], mac_key: str) -> Tuple[ else: sig_check = False error = None - self.logger.debug('Account._eab_signature_verify() ended with: {0}'.format(sig_check)) + self.logger.debug('Account._eab_signature_verify() ended with: %s', sig_check) return (sig_check, error) def _header_url_compare(self, outer_protected: Dict[str, str], inner_protected: Dict[str, str]) -> Tuple[int, str, str]: @@ -358,7 +357,7 @@ def _header_url_compare(self, outer_protected: Dict[str, str], inner_protected: message = self.err_msg_dic['malformed'] detail = 'url parameter differ in inner and outer jws' - self.logger.debug('Account._header_url_compare() ended with: {0}'.format(code)) + self.logger.debug('Account._header_url_compare() ended with: %s', code) return (code, message, detail) def _info(self, account_obj: Dict[str, str]) -> Dict[str, str]: @@ -374,7 +373,7 @@ def _info(self, account_obj: Dict[str, str]) -> Dict[str, str]: if 'eab_kid' in account_obj and account_obj['eab_kid']: response_dic['eab_kid'] = account_obj['eab_kid'] - self.logger.debug('Account._info() returns: {0}'.format(json.dumps(response_dic))) + self.logger.debug('Account._info() returns: %s', json.dumps(response_dic)) return response_dic def _inner_jws_check(self, outer_protected: Dict[str, str], inner_protected: Dict[str, str]) -> Tuple[int, str, str]: @@ -395,7 +394,7 @@ def _inner_jws_check(self, outer_protected: Dict[str, str], inner_protected: Dic message = self.err_msg_dic['malformed'] detail = 'inner jws is missing jwk' - self.logger.debug('Account._inner_jws_check() ended with: {0}:{1}'.format(code, detail)) + self.logger.debug('Account._inner_jws_check() ended with: %s:%s', code, detail) return (code, message, detail) def _inner_payload_check(self, aname: str, outer_protected: Dict[str, str], inner_payload: Dict[str, str]) -> Tuple[int, str, str]: @@ -425,12 +424,12 @@ def _inner_payload_check(self, aname: str, outer_protected: Dict[str, str], inne message = self.err_msg_dic['malformed'] detail = 'kid is missing in outer header' - self.logger.debug('Account._inner_payload_check() ended with: {0}:{1}'.format(code, detail)) + self.logger.debug('Account._inner_payload_check() ended with: %s:%s', code, detail) return (code, message, detail) def _key_change_validate(self, aname: str, outer_protected: Dict[str, str], inner_protected: Dict[str, str], inner_payload: Dict[str, str]): """ validate key_change before exectution """ - self.logger.debug('Account._key_change_validate({0})'.format(aname)) + self.logger.debug('Account._key_change_validate(%s)', aname) if 'jwk' in inner_protected: # check if we already have the key stored in DB key_exists = self._lookup(json.dumps(inner_protected['jwk']), 'jwk') @@ -448,12 +447,12 @@ def _key_change_validate(self, aname: str, outer_protected: Dict[str, str], inne message = self.err_msg_dic['malformed'] detail = 'inner jws is missing jwk' - self.logger.debug('Account._key_change_validate() ended with: {0}:{1}'.format(code, detail)) + self.logger.debug('Account._key_change_validate() ended with: %s:%s', code, detail) return (code, message, detail) def _key_rollover(self, aname: str, protected: Dict[str, str], inner_protected: Dict[str, str], inner_payload: Dict[str, str]) -> Tuple[int, str, str]: """ key update after key change """ - self.logger.debug('Account._key_rollover({0})'.format(aname)) + self.logger.debug('Account._key_rollover(%s)', aname) (code, message, detail) = self._key_change_validate(aname, protected, inner_protected, inner_payload) if code == 200: @@ -461,7 +460,7 @@ def _key_rollover(self, aname: str, protected: Dict[str, str], inner_protected: try: result = self.dbstore.account_update(data_dic) except Exception as err_: - self.logger.critical('acme2certifier database error in Account._key_change(): {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Account._key_change(): %s', err_) result = None if result: code = 200 @@ -472,12 +471,12 @@ def _key_rollover(self, aname: str, protected: Dict[str, str], inner_protected: message = self.err_msg_dic['serverinternal'] detail = 'key rollover failed' - self.logger.debug('Account._key_rollover() ended with: {0}'.format(code)) + self.logger.debug('Account._key_rollover() ended with: %s', code) return (code, message, detail) def _key_change(self, aname: str, payload: Dict[str, str], protected: Dict[str, str]) -> Tuple[int, str, str]: """ key change for a given account """ - self.logger.debug('Account._key_change({0})'.format(aname)) + self.logger.debug('Account._key_change(%s)', aname) if 'url' in protected: if 'key-change' in protected['url']: @@ -495,7 +494,7 @@ def _key_change(self, aname: str, payload: Dict[str, str], protected: Dict[str, message = self.err_msg_dic['malformed'] detail = 'malformed request' - self.logger.debug('Account._key_change() ended with: {0}'.format(code)) + self.logger.debug('Account._key_change() ended with: %s', code) return (code, message, detail) def _keys_adjust(self, pub_key: Dict[str, str], old_key: Dict[str, str]) -> Tuple[Dict[str, str], Dict[str, str]]: @@ -514,13 +513,13 @@ def _keys_adjust(self, pub_key: Dict[str, str], old_key: Dict[str, str]) -> Tupl def _key_compare(self, aname: str, old_key: Dict[str, str]) -> Tuple[int, str, str]: """ compare key with the one stored in database """ - self.logger.debug('Account._key_compare({0})'.format(aname)) + self.logger.debug('Account._key_compare(%s)', aname) # load current public key from database try: pub_key = self.dbstore.jwk_load(aname) except Exception as err_: - self.logger.critical('acme2certifier database error in Account._key_compare(): {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Account._key_compare(): %s', err_) pub_key = None if old_key and pub_key: @@ -540,7 +539,7 @@ def _key_compare(self, aname: str, old_key: Dict[str, str]) -> Tuple[int, str, s message = self.err_msg_dic['unauthorized'] detail = 'wrong public key' - self.logger.debug('Account._key_compare() ended with: {0}'.format(code)) + self.logger.debug('Account._key_compare() ended with: %s', code) return (code, message, detail) def _config_load(self): @@ -577,11 +576,11 @@ def _config_load(self): def _lookup(self, value: str, field: str = 'name') -> Dict[str, str]: """ lookup account """ - self.logger.debug('Account._lookup({0}:{1})'.format(field, value)) + self.logger.debug('Account._lookup(%s:%s)', field, value) try: result = self.dbstore.account_lookup(field, value) except Exception as err_: - self.logger.critical('acme2certifier database error in Account._lookup(): {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Account._lookup(): %s', err_) result = None return result @@ -618,11 +617,11 @@ def _onlyreturnexisting(self, protected: Dict[str, str], payload: Dict[str, str] message = self.err_msg_dic['serverinternal'] detail = 'onlyReturnExisting without payload' - self.logger.debug('Account.onlyreturnexisting() ended with:{0}'.format(code)) + self.logger.debug('Account.onlyreturnexisting() ended with: %s', code) return (code, message, detail) def _parse_deactivation(self, account_name: str, payload: Dict[str, str]) -> Tuple[int, str, str]: - self.logger.debug('Account._parse_deactivation({0})'.format(account_name)) + self.logger.debug('Account._parse_deactivation(%s)', account_name) data = None # account deactivation if payload['status'].lower() == 'deactivated': @@ -639,7 +638,7 @@ def _parse_deactivation(self, account_name: str, payload: Dict[str, str]) -> Tup def _parse_contacts_update(self, account_name: str, payload: Dict[str, str]) -> Tuple[int, str, str, Dict[str, str]]: """ update contacts """ - self.logger.debug('Account._parse_contacts_update({0})'.format(account_name)) + self.logger.debug('Account._parse_contacts_update(%s)', account_name) data = None (code, message, detail) = self._contacts_update(account_name, payload) if code == 200: @@ -655,7 +654,7 @@ def _parse_contacts_update(self, account_name: str, payload: Dict[str, str]) -> def _parse_query(self, account_name: str) -> Dict[str, str]: """ update contacts """ - self.logger.debug('Account._parse_query({0})'.format(account_name)) + self.logger.debug('Account._parse_query(%s)', account_name) # this is a query for account information account_obj = self._lookup(account_name) @@ -672,7 +671,7 @@ def _tos_check(self, content: Dict[str, str]) -> Tuple[int, str, str]: """ check terms of service """ self.logger.debug('Account._tos_check()') if 'termsofserviceagreed' in content: - self.logger.debug('tos:{0}'.format(content['termsofserviceagreed'])) + self.logger.debug('tos:%s', content['termsofserviceagreed']) if content['termsofserviceagreed']: code = 200 message = None @@ -687,7 +686,7 @@ def _tos_check(self, content: Dict[str, str]) -> Tuple[int, str, str]: message = self.err_msg_dic['useractionrequired'] detail = 'tosfalse' - self.logger.debug('Account._tos_check() ended with:{0}'.format(code)) + self.logger.debug('Account._tos_check() ended with:%s', code) return (code, message, detail) def _new(self, code: int, payload: Dict[str, str], protected: Dict[str, str]) -> Tuple[int, str, str]: @@ -717,7 +716,7 @@ def _new(self, code: int, payload: Dict[str, str], protected: Dict[str, str]) -> # add new account (code, message, detail) = self._add(protected, payload, contact_list) - self.logger.debug('Account._new() ended with: {0}'.format(code)) + self.logger.debug('Account._new() ended with: %s', code) return (code, message, detail) def new(self, content: Dict[str, str]) -> Dict[str, str]: @@ -735,7 +734,7 @@ def new(self, content: Dict[str, str]) -> Dict[str, str]: if code == 201: response_dic['data'] = { 'status': 'valid', - 'orders': '{0}{1}{2}/orders'.format(self.server_name, self.path_dic['acct_path'], message), + 'orders': f'{self.server_name}{self.path_dic['acct_path']}{message}/orders' } if 'contact' in payload: response_dic['data']['contact'] = payload['contact'] @@ -743,7 +742,7 @@ def new(self, content: Dict[str, str]) -> Dict[str, str]: response_dic['data'] = detail response_dic['header'] = {} - response_dic['header']['Location'] = '{0}{1}{2}'.format(self.server_name, self.path_dic['acct_path'], message) + response_dic['header']['Location'] = f'{self.server_name}{self.path_dic['acct_path']}{message}' # add exernal account binding if self.eab_check and 'externalaccountbinding' in payload: @@ -757,7 +756,7 @@ def new(self, content: Dict[str, str]) -> Dict[str, str]: status_dic = {'code': code, 'type': message, 'detail': detail} response_dic = self.message.prepare_response(response_dic, status_dic) - self.logger.debug('Account.new() returns: {0}'.format(json.dumps(response_dic))) + self.logger.debug('Account.new() returns: %s', json.dumps(response_dic)) return response_dic def parse(self, content: Dict[str, str]) -> Dict[str, str]: @@ -795,5 +794,5 @@ def parse(self, content: Dict[str, str]) -> Dict[str, str]: status_dic = {'code': code, 'type': message, 'detail': detail} response_dic = self.message.prepare_response(response_dic, status_dic) - self.logger.debug('Account.account_parse() returns: {0}'.format(json.dumps(response_dic))) + self.logger.debug('Account.account_parse() returns: %s', json.dumps(response_dic)) return response_dic diff --git a/acme_srv/acmechallenge.py b/acme_srv/acmechallenge.py index 5d2a1802..f3176e45 100644 --- a/acme_srv/acmechallenge.py +++ b/acme_srv/acmechallenge.py @@ -1,6 +1,5 @@ # -*- coding: utf-8 -*- """ acmechallenge class """ -# pylint: disable=C0209 from __future__ import print_function from acme_srv.db_handler import DBstore @@ -28,10 +27,10 @@ def lookup(self, path_info: str) -> str: key_authorization = None if path_info: token = path_info.replace('/.well-known/acme-challenge/', '') - self.logger.info('Acmechallenge.lookup() token: {0}'.format(token)) + self.logger.info('Acmechallenge.lookup() token: %s', token) challenge_dic = self.dbstore.cahandler_lookup('name', token) if challenge_dic and 'value1' in challenge_dic: key_authorization = challenge_dic['value1'] - self.logger.debug('Acmechallenge.lookup() ended with: {0}'.format(key_authorization)) + self.logger.debug('Acmechallenge.lookup() ended with: %s', key_authorization) return key_authorization diff --git a/acme_srv/authorization.py b/acme_srv/authorization.py index 1737d7e9..50ec44bf 100644 --- a/acme_srv/authorization.py +++ b/acme_srv/authorization.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """ Order class """ -# pylint: disable=C0209, R0913 +# pylint: disable=R0913 from __future__ import print_function import json from typing import List, Tuple, Dict @@ -40,12 +40,12 @@ def _expiry_update(self, authz_name: str, token: str, expires: int): try: self.dbstore.authorization_update({'name': authz_name, 'token': token, 'expires': expires}) except Exception as err_: - self.logger.error('acme2certifier database error in Authorization._expiry_update({0}) update: {1}'.format(authz_name, err_)) + self.logger.error('acme2certifier database error in Authorization._expiry_update(%s) update: %s', authz_name, err_) self.logger.debug('Authorization._expiry_update() ended') def _authz_lookup(self, authz_name: str, vlist: List[str] = None) -> Dict[str, str]: - self.logger.debug('Authorization._authz_lookup({0})'.format(authz_name)) + self.logger.debug('Authorization._authz_lookup(%s)', authz_name) # lookup authorization based on name try: @@ -54,7 +54,7 @@ def _authz_lookup(self, authz_name: str, vlist: List[str] = None) -> Dict[str, s else: authz = self.dbstore.authorization_lookup('name', authz_name) except Exception as err_: - self.logger.critical('acme2certifier database error in Authorization._authz_lookup({0}) lookup: {1}'.format(authz_name, err_)) + self.logger.critical('acme2certifier database error in Authorization._authz_lookup(%s) lookup: %s', authz_name, err_) authz = None self.logger.debug('Authorization._authz_lookup() ended') @@ -62,7 +62,7 @@ def _authz_lookup(self, authz_name: str, vlist: List[str] = None) -> Dict[str, s def _challengeset_get(self, authz_info_dic: Dict[str, str], authz_name: str, token: str, tnauth: bool, expires: int) -> Dict[str, str]: """ get challenge set """ - self.logger.debug('Authorization._challengeset_get({0})'.format(authz_name)) + self.logger.debug('Authorization._challengeset_get(%s)', authz_name) with Challenge(self.debug, self.server_name, self.logger, expires) as challenge: # get challenge data (either existing or new ones) @@ -109,8 +109,8 @@ def _authz_info(self, url: str) -> Dict[str, str]: """ return authzs information """ self.logger.debug('Authorization._authz_info()') - authz_name = string_sanitize(self.logger, url.replace('{0}{1}'.format(self.server_name, self.path_dic['authz_path']), '')) - self.logger.debug('Authorization._authz_info({0})'.format(authz_name)) + authz_name = string_sanitize(self.logger, url.replace(f'{self.server_name}{self.path_dic["authz_path"]}', '')) + self.logger.debug('Authorization._authz_info(%s)', authz_name) expires = uts_now() + self.validity token = generate_random_string(self.logger, 32) @@ -136,7 +136,7 @@ def _authz_info(self, url: str) -> Dict[str, str]: # get challenge-set authz_info_dic['challenges'] = self._challengeset_get(authz_info_dic, authz_name, token, tnauth, expires) - self.logger.debug('Authorization._authz_info() returns: {0}'.format(json.dumps(authz_info_dic))) + self.logger.debug('Authorization._authz_info() returns: %s', json.dumps(authz_info_dic)) return authz_info_dic def _config_load(self): @@ -150,23 +150,23 @@ def _config_load(self): try: self.validity = int(config_dic['Authorization']['validity']) except Exception: - self.logger.warning('Authorization._config_load(): failed to parse validity: {0}'.format(config_dic['Authorization']['validity'])) + self.logger.warning('Authorization._config_load(): failed to parse validity: %s', config_dic['Authorization']['validity']) if 'Directory' in config_dic and 'url_prefix' in config_dic['Directory']: self.path_dic = {k: config_dic['Directory']['url_prefix'] + v for k, v in self.path_dic.items()} self.logger.debug('Authorization._config_load() ended.') def invalidate(self, timestamp: int = None) -> Tuple[List[str], List[str]]: """ invalidate authorizations """ - self.logger.debug('Authorization.invalidate({0})'.format(timestamp)) + self.logger.debug('Authorization.invalidate(%s)', timestamp) if not timestamp: timestamp = uts_now() - self.logger.debug('Authorization.invalidate(): set timestamp to {0}'.format(timestamp)) + self.logger.debug('Authorization.invalidate(): set timestamp to %s', timestamp) field_list = ['id', 'name', 'expires', 'value', 'created_at', 'token', 'status__id', 'status__name', 'order__id', 'order__name'] try: authz_list = self.dbstore.authorizations_expired_search('expires', timestamp, vlist=field_list, operant='<=') except Exception as err_: - self.logger.critical('acme2certifier database error in Authorization.invalidate(): {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Authorization.invalidate(): %s', err_) authz_list = [] output_list = [] @@ -181,9 +181,9 @@ def invalidate(self, timestamp: int = None) -> Tuple[List[str], List[str]]: try: self.dbstore.authorization_update(data_dic) except Exception as err_: - self.logger.critical('acme2certifier database error in Authorization.invalidate(): {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Authorization.invalidate(): %s', err_) - self.logger.debug('Authorization.invalidate() ended: {0} authorizations identified'.format(len(output_list))) + self.logger.debug('Authorization.invalidate() ended: %s authorizations identified', len(output_list)) return (field_list, output_list) def new_get(self, url: str) -> Dict[str, str]: @@ -224,5 +224,5 @@ def new_post(self, content: str) -> Dict[str, str]: status_dic = {'code': code, 'type': message, 'detail': detail} response_dic = self.message.prepare_response(response_dic, status_dic) - self.logger.debug('Authorization.new_post() returns: {0}'.format(json.dumps(response_dic))) + self.logger.debug('Authorization.new_post() returns: %s', json.dumps(response_dic)) return response_dic diff --git a/acme_srv/certificate.py b/acme_srv/certificate.py index f5257194..680050a5 100644 --- a/acme_srv/certificate.py +++ b/acme_srv/certificate.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# pylint: disable=c0209, r0902, r0912, r0913, r0915 +# pylint: disable=r0902, r0912, r0913, r0915 """ certificate class """ from __future__ import print_function import json @@ -46,7 +46,7 @@ def _account_check(self, account_name: str, certificate: str) -> Dict[str, str]: try: result = self.dbstore.certificate_account_check(account_name, b64_url_recode(self.logger, certificate)) except Exception as err_: - self.logger.critical('acme2certifier database error in Certificate._account_check(): {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Certificate._account_check(): %s', err_) result = None return result @@ -68,7 +68,7 @@ def _authz_check(self, identifier_dic: Dict[str, str], certificate: str) -> List except Exception as err_: # enough to set identifier_list as empty list identifier_status = [] - self.logger.warning('Certificate._authorization_check() error while loading parsing certifcate. Error: {0}'.format(err_)) + self.logger.warning('Certificate._authorization_check() error while loading parsing certifcate. Error: %s', err_) else: try: # get sans @@ -77,13 +77,13 @@ def _authz_check(self, identifier_dic: Dict[str, str], certificate: str) -> List # add common name to SANs cert_cn = cert_cn_get(self.logger, certificate) if not san_list and cert_cn: - san_list.append('DNS:{0}'.format(cert_cn)) + san_list.append(f'DNS:{cert_cn}') identifier_status = self._identifer_status_list(identifiers, san_list) except Exception as err_: # enough to set identifier_list as empty list identifier_status = [] - self.logger.warning('Certificate._authorization_check() error while loading parsing certifcate. Error: {0}'.format(err_)) + self.logger.warning('Certificate._authorization_check() error while loading parsing certifcate. Error: %s', err_) self.logger.debug('Certificate._authz_check() ended') return identifier_status @@ -99,7 +99,7 @@ def _authorization_check(self, order_name: str, certificate: str) -> bool: try: identifier_dic = self.dbstore.order_lookup('name', order_name, ['identifiers']) except Exception as err_: - self.logger.critical('acme2certifier database error in Certificate._authorization_check(): {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Certificate._authorization_check(): %s', err_) identifier_dic = {} if identifier_dic and 'identifiers' in identifier_dic: @@ -110,17 +110,17 @@ def _authorization_check(self, order_name: str, certificate: str) -> bool: if identifier_status and False not in identifier_status: result = True - self.logger.debug('Certificate._authorization_check() ended with {0}'.format(result)) + self.logger.debug('Certificate._authorization_check() ended with %s', result) return result def _cert_reusage_check(self, csr: str) -> Tuple[None, str, str, str]: """ check if an existing certificate an be reused """ - self.logger.debug('Certificate._cert_reusage_check({0})'.format(self.cert_reusage_timeframe)) + self.logger.debug('Certificate._cert_reusage_check(%s)', self.cert_reusage_timeframe) try: result_dic = self.dbstore.certificates_search('csr', csr, ('cert', 'cert_raw', 'expire_uts', 'issue_uts', 'created_at', 'id')) except Exception as err_: - self.logger.critical('acme2certifier database error in Certificate._cert_reusage_check(): {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Certificate._cert_reusage_check(): %s', err_) result_dic = None cert = None @@ -134,7 +134,7 @@ def _cert_reusage_check(self, csr: str) -> Tuple[None, str, str, str]: try: uts_create = date_to_uts_utc(certificate['created_at']) except Exception as _err: - self.logger.error('acme2certifier date_to_uts_utc() error in Certificate._cert_reusage_check(): id:{0}/created_at:{1}'.format(certificate['id'], certificate['created_at'])) + self.logger.error('acme2certifier date_to_uts_utc() error in Certificate._cert_reusage_check(): id:%s/created_at:%s', certificate['id'], certificate['created_at']) uts_create = 0 # check if there certificates within reusage timeframe @@ -143,10 +143,10 @@ def _cert_reusage_check(self, csr: str) -> Tuple[None, str, str, str]: if uts <= certificate['expire_uts']: cert = certificate['cert'] cert_raw = certificate['cert_raw'] - message = 'reused certificate from id: {0}'.format(certificate['id']) + message = f'reused certificate from id: {certificate['id']}' break - self.logger.debug('Certificate._cert_reusage_check() ended with {0}'.format(message)) + self.logger.debug('Certificate._cert_reusage_check() ended with {%s', message) return (None, cert, cert_raw, message) def _config_hooks_load(self, config_dic: Dict[str, str]): @@ -160,7 +160,7 @@ def _config_hooks_load(self, config_dic: Dict[str, str]): # store handler in variable self.hooks = hooks_module.Hooks(self.logger) except Exception as err: - self.logger.critical('Certificate._config_load(): Hooks could not be loaded: {0}'.format(err)) + self.logger.critical('Certificate._config_load(): Hooks could not be loaded: %s', err) self.ignore_pre_hook_failure = config_dic.getboolean('Hooks', 'ignore_pre_hook_failure', fallback=False) self.ignore_post_hook_failure = config_dic.getboolean('Hooks', 'ignore_post_hook_failure', fallback=True) @@ -177,12 +177,12 @@ def _config_parameters_load(self, config_dic: Dict[str, str]): try: self.cert_reusage_timeframe = int(config_dic['Certificate']['cert_reusage_timeframe']) except Exception as err_: - self.logger.error('acme2certifier Certificate._config_load() cert_reusage_timout parsing error: {0}'.format(err_)) + self.logger.error('acme2certifier Certificate._config_load() cert_reusage_timout parsing error: %s', err_) if 'enrollment_timeout' in config_dic['Certificate']: try: self.enrollment_timeout = int(config_dic['Certificate']['enrollment_timeout']) except Exception as err_: - self.logger.error('acme2certifier Certificate._config_load() enrollment_timeout parsing error: {0}'.format(err_)) + self.logger.error('acme2certifier Certificate._config_load() enrollment_timeout parsing error: %s', err_) if 'Directory' in config_dic and 'url_prefix' in config_dic['Directory']: self.path_dic = {k: config_dic['Directory']['url_prefix'] + v for k, v in self.path_dic.items()} @@ -215,7 +215,7 @@ def _config_load(self): # load parametrs self._config_parameters_load(config_dic) - self.logger.debug('ca_handler: {0}'.format(ca_handler_module)) + self.logger.debug('ca_handler: %s', ca_handler_module) self.logger.debug('Certificate._config_load() ended.') def _identifiers_load(self, identifier_dic: Dict[str, str], csr: str) -> List[str]: @@ -236,7 +236,7 @@ def _identifiers_load(self, identifier_dic: Dict[str, str], csr: str) -> List[st identifier_status = self._identifer_tnauth_list(identifier_dic, tnauthlist) except Exception as err_: identifier_status = [] - self.logger.warning('Certificate._csr_check() error while parsing csr.\nerror: {0}'.format(err_)) + self.logger.warning('Certificate._csr_check() error while parsing csr.\nerror: %s', err_) else: # get sans and compare identifiers against san try: @@ -244,9 +244,9 @@ def _identifiers_load(self, identifier_dic: Dict[str, str], csr: str) -> List[st identifier_status = self._identifer_status_list(identifiers, san_list) except Exception as err_: identifier_status = [] - self.logger.warning('Certificate._csr_check() error while checking csr.\nerror: {0}'.format(err_)) + self.logger.warning('Certificate._csr_check() error while checking csr.\nerror: %s', err_) - self.logger.debug('Certificate._identifiers_load() ended with {0}'.format(identifier_status)) + self.logger.debug('Certificate._identifiers_load() ended with %s', identifier_status) return identifier_status def _csr_check(self, certificate_name: str, csr: str) -> bool: @@ -255,7 +255,7 @@ def _csr_check(self, certificate_name: str, csr: str) -> bool: # fetch certificate dictionary from DB certificate_dic = self._info(certificate_name) - self.logger.debug('Certificate._info() ended with:{0}'.format(certificate_dic)) + self.logger.debug('Certificate._info() ended with:%s', certificate_dic) # empty list of statuses identifier_status = [] @@ -265,7 +265,7 @@ def _csr_check(self, certificate_name: str, csr: str) -> bool: try: identifier_dic = self.dbstore.order_lookup('name', certificate_dic['order'], ['identifiers']) except Exception as err_: - self.logger.critical('acme2certifier database error in Certificate._csr_check(): {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Certificate._csr_check(): %s', err_) identifier_dic = {} if identifier_dic and 'identifiers' in identifier_dic: @@ -276,7 +276,7 @@ def _csr_check(self, certificate_name: str, csr: str) -> bool: if identifier_status and False not in identifier_status: csr_check_result = True - self.logger.debug('Certificate._csr_check() ended with {0}'.format(csr_check_result)) + self.logger.debug('Certificate._csr_check() ended with %s', csr_check_result) return csr_check_result def _enroll(self, csr: str, ca_handler: object) -> Tuple[str, str, str, str]: @@ -304,7 +304,7 @@ def _renewal_info_get(self, certificate: str) -> str: renewal_info_hex = certid_asn1_get(self.logger, certificate_list[0], certificate_list[1]) - self.logger.debug('Certificate.certid_asn1_get() ended with {0}'.format(renewal_info_hex)) + self.logger.debug('Certificate.certid_asn1_get() ended with %s', renewal_info_hex) return renewal_info_hex def _store(self, certificate: str, certificate_raw: str, poll_identifier: str, certificate_name: str, order_name: str, csr: str) -> Tuple[int, str]: @@ -322,31 +322,31 @@ def _store(self, certificate: str, certificate_raw: str, poll_identifier: str, c self.hooks.success_hook(certificate_name, order_name, csr, certificate, certificate_raw, poll_identifier) self.logger.debug('Certificate._enroll_and_store: success_hook successful') except Exception as err: - self.logger.error('Certificate._enroll_and_store: success_hook exception: {0}'.format(err)) + self.logger.error('Certificate._enroll_and_store: success_hook exception: %s', err) if not self.ignore_success_hook_failure: error = (None, 'success_hook_error', str(err)) except Exception as err_: result = None - self.logger.critical('acme2certifier database error in Certificate._enroll_and_store(): {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Certificate._enroll_and_store(): %s', err_) self.logger.error('Certificate._store() ended') return (result, error) def _enrollerror_handler(self, error: str, poll_identifier: str, order_name: str, certificate_name: str) -> Tuple[None, str, str]: """ store error message for later analysis """ - self.logger.error('Certificate._enroll_and_store({0})'.format(error)) + self.logger.error('Certificate._enroll_and_store(%s)', error) result = None detail = None try: if not poll_identifier: - self.logger.debug('Certificate._enroll_and_store(): invalidating order as there is no certificate and no poll_identifier: {0}/{1}'.format(error, order_name)) + self.logger.debug('Certificate._enroll_and_store(): invalidating order as there is no certificate and no poll_identifier: %s/%s', error, order_name) self._order_update({'name': order_name, 'status': 'invalid'}) self._store_cert_error(certificate_name, error, poll_identifier) except Exception as err_: result = None - self.logger.critical('acme2certifier database error in Certificate._enroll_and_store() _store_cert_error: {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Certificate._enroll_and_store() _store_cert_error: %s', err_) # cover polling cases if poll_identifier: @@ -354,26 +354,26 @@ def _enrollerror_handler(self, error: str, poll_identifier: str, order_name: str else: error = self.err_msg_dic['serverinternal'] - self.logger.error('Certificate._enroll_and_store() ended with: {0}'.format(result)) + self.logger.error('Certificate._enroll_and_store() ended with: %s', result) return (result, error, detail) def _pre_hooks_process(self, certificate_name: str, order_name: str, csr: str) -> List[str]: - self.logger.debug('Certificate._pre_hooks_process({0}, {1})'.format(certificate_name, order_name)) + self.logger.debug('Certificate._pre_hooks_process(%s, %s)', certificate_name, order_name) hook_error = [] if self.hooks: try: self.hooks.pre_hook(certificate_name, order_name, csr) self.logger.debug('Certificate._enroll_and_store(): pre_hook successful') except Exception as err: - self.logger.error('Certificate._enroll_and_store(): pre_hook exception: {0}'.format(err)) + self.logger.error('Certificate._enroll_and_store(): pre_hook exception: %s', err) if not self.ignore_pre_hook_failure: hook_error = (None, 'pre_hook_error', str(err)) - self.logger.debug('Certificate._pre_hooks_process({0})'.format(hook_error)) + self.logger.debug('Certificate._pre_hooks_process(%s)', hook_error) return hook_error def _post_hooks_process(self, certificate_name: str, order_name: str, csr: str, error: str) -> List[str]: - self.logger.debug('Certificate._pre_hooks_process({0}, {1})'.format(certificate_name, order_name)) + self.logger.debug('Certificate._pre_hooks_process(%s, %s', certificate_name, order_name) hook_error = [] if self.hooks: @@ -381,16 +381,16 @@ def _post_hooks_process(self, certificate_name: str, order_name: str, csr: str, self.hooks.post_hook(certificate_name, order_name, csr, error) self.logger.debug('Certificate._enroll_and_store(): post_hook successful') except Exception as err: - self.logger.error('Certificate._enroll_and_store(): post_hook exception: {0}'.format(err)) + self.logger.error('Certificate._enroll_and_store(): post_hook exception: %s', err) if not self.ignore_post_hook_failure: hook_error = (None, 'post_hook_error', str(err)) - self.logger.debug('Certificate._post_hooks_process({0})'.format(hook_error)) + self.logger.debug('Certificate._post_hooks_process(%s)', hook_error) return hook_error def _enroll_and_store(self, certificate_name: str, csr: str, order_name: str = None) -> Tuple[str, str, str]: """ enroll and store certificate """ - self.logger.debug('Certificate._enroll_and_store({0}, {1}, {2})'.format(certificate_name, order_name, csr)) + self.logger.debug('Certificate._enroll_and_store(%s, %s, %s)',certificate_name, order_name, csr) detail = None error = None @@ -409,19 +409,19 @@ def _enroll_and_store(self, certificate_name: str, csr: str, order_name: str = N if error: return error else: - self.logger.error('acme2certifier enrollment error: {0}'.format(error)) + self.logger.error('acme2certifier enrollment error: %s', error) (result, error, detail) = self._enrollerror_handler(error, poll_identifier, order_name, certificate_name) hook_error = self._post_hooks_process(certificate_name, order_name, csr, error) if hook_error: return hook_error - self.logger.debug('Certificate._enroll_and_store() ended with: {0}:{1}'.format(result, error)) + self.logger.debug('Certificate._enroll_and_store() ended with: %s:%s', result, error) return (result, error, detail) def _identifier_chk(self, cert_type: str, cert_value: str, identifiers: List[str], san_is_in: bool) -> bool: """ check identifier """ - self.logger.debug('Certificate._identifier_chk({0}/{1})'.format(cert_type, cert_value)) + self.logger.debug('Certificate._identifier_chk(%s/%s)', cert_type, cert_value) if cert_type and cert_value: for identifier in identifiers: @@ -430,7 +430,7 @@ def _identifier_chk(self, cert_type: str, cert_value: str, identifiers: List[str san_is_in = True break - self.logger.debug('Certificate._identifier_chk({0})'.format(san_is_in)) + self.logger.debug('Certificate._identifier_chk(%s)', san_is_in) return san_is_in def _identifer_status_list(self, identifiers: List[str], san_list: List[str]) -> List[str]: @@ -443,25 +443,25 @@ def _identifer_status_list(self, identifiers: List[str], san_list: List[str]) -> try: (cert_type, cert_value) = san.lower().split(':', 1) except Exception as err_: - self.logger.error('Error while splitting san {0}: {1}'.format(san, err_)) + self.logger.error('Error while splitting san %s: %s', san, err_) cert_type = None cert_value = None # check identifiers san_is_in = self._identifier_chk(cert_type, cert_value, identifiers, san_is_in) - self.logger.debug('SAN check for {0} against identifiers returned {1}'.format(san.lower(), san_is_in)) + self.logger.debug('SAN check for %s against identifiers returned %s', san.lower(), san_is_in) identifier_status.append(san_is_in) if not identifier_status: identifier_status.append(False) - self.logger.debug('Certificate._identifer_status_list() ended with {0}'.format(identifier_status)) + self.logger.debug('Certificate._identifer_status_list() ended with %s', identifier_status) return identifier_status def _identifier_tnauth_chk(self, identifier: Dict[str, str], tnauthlist: List[str]) -> bool: """ check tnauth identifier against tnauthlist """ - self.logger.debug('Certificate._identifier_tnauth_chk({0})'.format(identifier)) + self.logger.debug('Certificate._identifier_tnauth_chk(%s)', identifier) result = False # get the tnauthlist identifier @@ -470,7 +470,7 @@ def _identifier_tnauth_chk(self, identifier: Dict[str, str], tnauthlist: List[st if 'value' in identifier and identifier['value'] in tnauthlist: result = True - self.logger.debug('Certificate._identifier_tnauth_chk() endedt with {0}'.format(result)) + self.logger.debug('Certificate._identifier_tnauth_chk() endedt with %s', result) return result def _identifer_tnauth_list(self, identifier_dic: Dict[str, str], tnauthlist: List[str]): @@ -492,16 +492,16 @@ def _identifer_tnauth_list(self, identifier_dic: Dict[str, str], tnauthlist: Lis else: identifier_status.append(False) - self.logger.debug('Certificate._identifer_tnauth_list() ended with {0}'.format(identifier_status)) + self.logger.debug('Certificate._identifer_tnauth_list() ended with %s', identifier_status) return identifier_status def _info(self, certificate_name: str, flist: List[str] = ('name', 'csr', 'cert', 'order__name')) -> Dict[str, str]: """ get certificate from database """ - self.logger.debug('Certificate._info({0})'.format(certificate_name)) + self.logger.debug('Certificate._info(%s)', certificate_name) try: result = self.dbstore.certificate_lookup('name', certificate_name, flist) except Exception as err_: - self.logger.critical('acme2certifier database error in Certificate._info(): {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Certificate._info(): %s', err_) result = None return result @@ -546,13 +546,13 @@ def _expiredate_get(self, cert: Dict[str, str], timestamp: int, to_be_cleared: b # expired based on expire_uts from db to_be_cleared = True - self.logger.debug('Certificate._expiredate_get() ended with: to_be_cleared: {0}'.format(to_be_cleared)) + self.logger.debug('Certificate._expiredate_get() ended with: to_be_cleared: %s', to_be_cleared) return to_be_cleared def _invalidation_check(self, cert: Dict[str, str], timestamp: int, purge: bool = False): """ check if cert must be invalidated """ if 'name' in cert: - self.logger.debug('Certificate._invalidation_check({0})'.format(cert['name'])) + self.logger.debug('Certificate._invalidation_check(%s)', cert['name']) else: self.logger.debug('Certificate._invalidation_check()') @@ -575,23 +575,23 @@ def _invalidation_check(self, cert: Dict[str, str], timestamp: int, purge: bool to_be_cleared = True if 'name' in cert: - self.logger.debug('Certificate._invalidation_check({0}) ended with {1}'.format(cert['name'], to_be_cleared)) + self.logger.debug('Certificate._invalidation_check(%s) ended with %s', cert['name'], to_be_cleared) else: - self.logger.debug('Certificate._invalidation_check() ended with {0}'.format(to_be_cleared)) + self.logger.debug('Certificate._invalidation_check() ended with %s', to_be_cleared) return (to_be_cleared, cert) def _order_update(self, data_dic: Dict[str, str]): """ update order based on ordername """ - self.logger.debug('Certificate._order_update({0})'.format(data_dic)) + self.logger.debug('Certificate._order_update(%s)', data_dic) try: self.dbstore.order_update(data_dic) except Exception as err_: - self.logger.critical('acme2certifier database error in Certificate._order_update(): {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Certificate._order_update(): %s', err_) def _revocation_reason_check(self, reason: str) -> str: """ check reason """ - self.logger.debug('Certificate._revocation_reason_check({0})'.format(reason)) + self.logger.debug('Certificate._revocation_reason_check(%s)', reason) # taken from https://tools.ietf.org/html/rfc5280#section-5.3.1 allowed_reasons = { @@ -608,12 +608,12 @@ def _revocation_reason_check(self, reason: str) -> str: } result = allowed_reasons.get(reason, None) - self.logger.debug('Certificate._revocation_reason_check() ended with {0}'.format(result)) + self.logger.debug('Certificate._revocation_reason_check() ended with %s', result) return result def _revocation_request_validate(self, account_name: str, payload: Dict[str, str]) -> Tuple[int, str]: """ check revocaton request for consistency""" - self.logger.debug('Certificate._revocation_request_validate({0})'.format(account_name)) + self.logger.debug('Certificate._revocation_request_validate(%s)', account_name) # set a value to avoid that we are returning none by accident code = 400 @@ -645,12 +645,12 @@ def _revocation_request_validate(self, account_name: str, payload: Dict[str, str else: error = self.err_msg_dic['unauthorized'] - self.logger.debug('Certificate._revocation_request_validate() ended with: {0}, {1}'.format(code, error)) + self.logger.debug('Certificate._revocation_request_validate() ended with: %s, %s', code, error) return (code, error) def _store_cert(self, certificate_name: str, certificate: str, raw: str, issue_uts: int = 0, expire_uts: int = 0, poll_identifier: str = None) -> int: """ get key for a specific account id """ - self.logger.debug('Certificate._store_cert({0})'.format(certificate_name)) + self.logger.debug('Certificate._store_cert(%s)', certificate_name) renewal_info_hex = self._renewal_info_get(certificate) @@ -659,20 +659,20 @@ def _store_cert(self, certificate_name: str, certificate: str, raw: str, issue_u cert_id = self.dbstore.certificate_add(data_dic) except Exception as err_: cert_id = None - self.logger.critical('acme2certifier database error in Certificate._store_cert(): {0}'.format(err_)) - self.logger.debug('Certificate._store_cert({0}) ended'.format(cert_id)) + self.logger.critical('acme2certifier database error in Certificate._store_cert(): %s', err_) + self.logger.debug('Certificate._store_cert(%s) ended', cert_id) return cert_id def _store_cert_error(self, certificate_name: str, error: str, poll_identifier: str) -> int: """ get key for a specific account id """ - self.logger.debug('Certificate._store_cert_error({0})'.format(certificate_name)) + self.logger.debug('Certificate._store_cert_error(%s)', certificate_name) data_dic = {'error': error, 'name': certificate_name, 'poll_identifier': poll_identifier} try: cert_id = self.dbstore.certificate_add(data_dic) except Exception as err_: cert_id = None - self.logger.critical('acme2certifier database error in Certificate._store_cert(): {0}'.format(err_)) - self.logger.debug('Certificate._store_cert_error({0}) ended'.format(cert_id)) + self.logger.critical('acme2certifier database error in Certificate._store_cert(): %s', err_) + self.logger.debug('Certificate._store_cert_error(%s) ended', cert_id) return cert_id def _tnauth_identifier_check(self, identifier_dic: Dict[str, str]) -> int: @@ -685,22 +685,22 @@ def _tnauth_identifier_check(self, identifier_dic: Dict[str, str]) -> int: if 'type' in identifier: if identifier['type'].lower() == 'tnauthlist': tnauthlist_identifer_in = True - self.logger.debug('Certificate._tnauth_identifier_check() ended with: {0}'.format(tnauthlist_identifer_in)) + self.logger.debug('Certificate._tnauth_identifier_check() ended with: %s', tnauthlist_identifer_in) return tnauthlist_identifer_in def certlist_search(self, key: str, value: str, vlist: List[str] = ('name', 'csr', 'cert', 'order__name')) -> Dict[str, str]: """ get certificate from database """ - self.logger.debug('Certificate.certlist_search({0}: {1})'.format(key, value)) + self.logger.debug('Certificate.certlist_search(%s: %s)', key, value) try: result = self.dbstore.certificates_search(key, value, vlist) except Exception as err_: - self.logger.critical('acme2certifier database error in Certificate.certlist_search(): {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Certificate.certlist_search(): %s', err_) result = None return result def _cleanup(self, report_list: List[str], timestamp: int, purge: bool): """ cleanup """ - self.logger.debug('Certificate.cleanup({0},{1})'.format(timestamp, purge)) + self.logger.debug('Certificate.cleanup(%s,%s)', timestamp, purge) if not purge: # we are just modifiying data for cert in report_list: @@ -708,26 +708,26 @@ def _cleanup(self, report_list: List[str], timestamp: int, purge: bool): 'name': cert['name'], 'expire_uts': cert['expire_uts'], 'issue_uts': cert['issue_uts'], - 'cert': 'removed by certificates.cleanup() on {0} '.format(uts_to_date_utc(timestamp)), + 'cert': f'removed by certificates.cleanup() on {uts_to_date_utc(timestamp)}', 'cert_raw': cert['cert_raw'] } try: self.dbstore.certificate_add(data_dic) except Exception as err_: - self.logger.critical('acme2certifier database error in Certificate.cleanup() add: {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Certificate.cleanup() add: %s', err_) else: # delete entries from certificates table for cert in report_list: try: self.dbstore.certificate_delete('id', cert['id']) except Exception as err_: - self.logger.critical('acme2certifier database error in Certificate.cleanup() delete: {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Certificate.cleanup() delete: %s', err_) self.logger.debug('Certificate.cleanup() ended') def cleanup(self, timestamp: int = None, purge: bool = False) -> Tuple[List[str], List[str]]: """ cleanup routine to shrink table-size """ - self.logger.debug('Certificate.cleanup({0},{1})'.format(timestamp, purge)) + self.logger.debug('Certificate.cleanup(%s,%s)', timestamp, purge) field_list = ['id', 'name', 'expire_uts', 'issue_uts', 'cert', 'cert_raw', 'csr', 'created_at', 'order__id', 'order__name'] @@ -735,7 +735,7 @@ def cleanup(self, timestamp: int = None, purge: bool = False) -> Tuple[List[str] try: certificate_list = self.dbstore.certificates_search('expire_uts', timestamp, field_list, '<=') except Exception as err_: - self.logger.critical('acme2certifier database error in Certificate.cleanup() search: {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Certificate.cleanup() search: %s', err_) certificate_list = [] report_list = [] @@ -748,7 +748,7 @@ def cleanup(self, timestamp: int = None, purge: bool = False) -> Tuple[List[str] # cleanup self._cleanup(report_list, timestamp, purge) - self.logger.debug('Certificate.cleanup() ended with: {0} certs'.format(len(report_list))) + self.logger.debug('Certificate.cleanup() ended with: %s certs', len(report_list)) return (field_list, report_list) def _dates_update(self, cert: Dict[str, str]): @@ -770,7 +770,7 @@ def dates_update(self): with Certificate(self.debug, None, self.logger) as certificate: cert_list = certificate.certlist_search('issue_uts', 0, vlist=('id', 'name', 'cert', 'cert_raw', 'issue_uts', 'expire_uts')) - self.logger.debug('Got {0} certificates to be updated...'.format(len(cert_list))) + self.logger.debug('Got {%s} certificates to be updated...', len(cert_list)) for cert in cert_list: self._dates_update(cert) @@ -778,7 +778,7 @@ def dates_update(self): def enroll_and_store(self, certificate_name: str, csr: str, order_name: str = None) -> Tuple[str, str]: """ check csr and trigger enrollment """ - self.logger.debug('Certificate.enroll_and_store({0},{1})'.format(certificate_name, order_name)) + self.logger.debug('Certificate.enroll_and_store(%s, %s)', certificate_name, order_name) # check csr against order csr_check_result = self._csr_check(certificate_name, csr) @@ -792,7 +792,7 @@ def enroll_and_store(self, certificate_name: str, csr: str, order_name: str = No try: (result, error, detail) = enroll_result except Exception as err_: - self.logger.error('acme2certifier database error in Certificate.enroll_and_store(): split of {0} failed with err: {1}'.format(enroll_result, err_)) + self.logger.error('acme2certifier database error in Certificate.enroll_and_store(): split of %s failed with err: %s', enroll_result, err_) result = None error = self.err_msg_dic['serverinternal'] detail = 'unexpected enrollment result' @@ -805,13 +805,14 @@ def enroll_and_store(self, certificate_name: str, csr: str, order_name: str = No error = self.err_msg_dic['badcsr'] detail = 'CSR validation failed' - self.logger.debug('Certificate.enroll_and_store() ended with: {0}:{1}'.format(result, error)) + self.logger.debug('Certificate.enroll_and_store() ended with: %s:%s', result, error) return (error, detail) def new_get(self, url: str) -> Dict[str, str]: """ get request """ - certificate_name = string_sanitize(self.logger, url.replace('{0}{1}'.format(self.server_name, self.path_dic['cert_path']), '')) - self.logger.debug('Certificate.new_get({0})'.format(certificate_name)) + certificate_name = string_sanitize(self.logger, url.replace(f'{self.server_name}{self.path_dic['cert_path']}', '')) + self.logger.debug('Certificate.new_get(%s)', certificate_name) + # fetch certificate dictionary from DB certificate_dic = self._info(certificate_name, ['name', 'csr', 'cert', 'order__name', 'order__status_id']) response_dic = {} @@ -829,7 +830,7 @@ def new_get(self, url: str) -> Dict[str, str]: response_dic['data'] = self.err_msg_dic['serverinternal'] elif certificate_dic['order__status_id'] == 4: # order status is processing - ratelimiting - response_dic['header'] = {'Retry-After': '{0}'.format(self.retry_after)} + response_dic['header'] = {'Retry-After': f'{self.retry_after}'} response_dic['code'] = 403 response_dic['data'] = self.err_msg_dic['ratelimited'] else: @@ -839,13 +840,12 @@ def new_get(self, url: str) -> Dict[str, str]: response_dic['code'] = 500 response_dic['data'] = self.err_msg_dic['serverinternal'] - self.logger.debug('Certificate.new_get({0}) ended'.format(response_dic['code'])) - + self.logger.debug('Certificate.new_get(%s) ended', response_dic['code']) return response_dic def new_post(self, content: str) -> Dict[str, str]: """ post request """ - self.logger.debug('Certificate.new_post({0})') + self.logger.debug('Certificate.new_post()') response_dic = {} # check message @@ -878,7 +878,7 @@ def new_post(self, content: str) -> Dict[str, str]: else: result = 'no code found' - self.logger.debug('Certificate.new_post() ended with: {0}'.format(result)) + self.logger.debug('Certificate.new_post() ended with: %s', result) return response_dic def revoke(self, content: str) -> Dict[str, str]: @@ -912,12 +912,12 @@ def revoke(self, content: str) -> Dict[str, str]: status_dic = {'code': code, 'type': message, 'detail': detail} response_dic = self.message.prepare_response(response_dic, status_dic) - self.logger.debug('Certificate.revoke() ended with: {0}'.format(response_dic)) + self.logger.debug('Certificate.revoke() ended with: %s', response_dic) return response_dic def poll(self, certificate_name: str, poll_identifier: str, csr: str, order_name: str) -> int: """ try to fetch a certificate from CA and store it into database """ - self.logger.debug('Certificate.poll({0}: {1})'.format(certificate_name, poll_identifier)) + self.logger.debug('Certificate.poll(%s: %s)', certificate_name, poll_identifier) with self.cahandler(self.debug, self.logger) as ca_handler: (error, certificate, certificate_raw, poll_identifier, rejected) = ca_handler.poll(certificate_name, poll_identifier, csr) @@ -930,7 +930,7 @@ def poll(self, certificate_name: str, poll_identifier: str, csr: str, order_name try: self.dbstore.order_update({'name': order_name, 'status': 'valid'}) except Exception as err_: - self.logger.critical('acme2certifier database error in Certificate.poll(): {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Certificate.poll(): %s', err_) else: # store error message for later analysis self._store_cert_error(certificate_name, error, poll_identifier) @@ -939,18 +939,19 @@ def poll(self, certificate_name: str, poll_identifier: str, csr: str, order_name try: self.dbstore.order_update({'name': order_name, 'status': 'invalid'}) except Exception as err_: - self.logger.critical('acme2certifier database error in Certificate.poll(): {0}'.format(err_)) - self.logger.debug('Certificate.poll({0}: {1})'.format(certificate_name, poll_identifier)) + self.logger.critical('acme2certifier database error in Certificate.poll(): %s', err_) + self.logger.debug('Certificate.poll(%s: %s)', certificate_name, poll_identifier) return _result def store_csr(self, order_name: str, csr: str, header_info: str) -> str: """ store csr into database """ - self.logger.debug('Certificate.store_csr({0})'.format(order_name)) + self.logger.debug('Certificate.store_csr(%s)', order_name) + certificate_name = generate_random_string(self.logger, 12) data_dic = {'order': order_name, 'csr': csr, 'name': certificate_name, 'header_info': header_info} try: self.dbstore.certificate_add(data_dic) except Exception as err_: - self.logger.critical('Database error in Certificate.store_csr(): {0}'.format(err_)) + self.logger.critical('Database error in Certificate.store_csr(): %s', err_) self.logger.debug('Certificate.store_csr() ended') return certificate_name diff --git a/acme_srv/challenge.py b/acme_srv/challenge.py index a3ca2143..9d960966 100644 --- a/acme_srv/challenge.py +++ b/acme_srv/challenge.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """ Challenge class """ -# pylint: disable=C0209, r0913 +# pylint: disable=r0913 from __future__ import print_function import json from typing import List, Tuple, Dict @@ -43,7 +43,7 @@ def _challengelist_search(self, key: str, value: str, vlist: List = ('name', 'ty try: challenge_list = self.dbstore.challenges_search(key, value, vlist) except Exception as err_: - self.logger.critical('acme2certifier database error in Challenge._challengelist_search(): {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Challenge._challengelist_search(): %s', err_) challenge_list = [] challenge_dic = {} @@ -54,7 +54,7 @@ def _challengelist_search(self, key: str, value: str, vlist: List = ('name', 'ty challenge_dic[challenge['type']]['token'] = challenge['token'] challenge_dic[challenge['type']]['type'] = challenge['type'] challenge_dic[challenge['type']]['url'] = challenge['name'] - challenge_dic[challenge['type']]['url'] = '{0}{1}{2}'.format(self.server_name, self.path_dic['chall_path'], challenge['name']) + challenge_dic[challenge['type']]['url'] = f'{self.server_name}{self.path_dic['chall_path']}{challenge['name']}' challenge_dic[challenge['type']]['name'] = challenge['name'] if 'status__name' in challenge: challenge_dic[challenge['type']]['status'] = challenge['status__name'] @@ -63,12 +63,12 @@ def _challengelist_search(self, key: str, value: str, vlist: List = ('name', 'ty for challenge, challenge_items in challenge_dic.items(): challenge_list.append(challenge_items) - self.logger.debug('Challenge._challengelist_search() ended with: {0}'.format(challenge_list)) + self.logger.debug('Challenge._challengelist_search() ended with: %s', challenge_list) return challenge_list def _challenge_validate(self, pub_key: Dict[str, str], challenge_name: str, challenge_dic: Dict[str, str], payload: Dict[str, str]) -> Tuple[bool, bool]: """ challenge validate """ - self.logger.debug('Challenge._challenge_validate({0})'.format(challenge_name)) + self.logger.debug('Challenge._challenge_validate(%s)', challenge_name) jwk_thumbprint = jwk_thumbprint_get(self.logger, pub_key) for _ele in range(0, 5): @@ -81,31 +81,31 @@ def _challenge_validate(self, pub_key: Dict[str, str], challenge_name: str, chal elif challenge_dic['type'] == 'tkauth-01' and jwk_thumbprint and self.tnauthlist_support: (result, invalid) = self._validate_tkauth_challenge(challenge_name, challenge_dic['authorization__type'], challenge_dic['authorization__value'], challenge_dic['token'], jwk_thumbprint, payload) else: - self.logger.error('unknown challenge type "{0}". Setting check result to False'.format(challenge_dic['type'])) + self.logger.error('unknown challenge type "%s". Setting check result to False', challenge_dic['type']) result = False invalid = True if result or invalid: # break loop if we got any good or bad response break - self.logger.debug('Challenge._challenge_validate() ended with: {0}/{1}'.format(result, invalid)) + self.logger.debug('Challenge._challenge_validate() ended with: %s/%s', result, invalid) return (result, invalid) def _check(self, challenge_name: str, payload: Dict[str, str]) -> Tuple[bool, bool]: """ challenge check """ - self.logger.debug('Challenge._check({0})'.format(challenge_name)) + self.logger.debug('Challenge._check(%s)', challenge_name) try: challenge_dic = self.dbstore.challenge_lookup('name', challenge_name, ['type', 'status__name', 'token', 'authorization__name', 'authorization__type', 'authorization__value', 'authorization__token', 'authorization__order__account__name']) except Exception as err_: - self.logger.critical('acme2certifier database error in Challenge._check() lookup: {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Challenge._check() lookup: %s', err_) challenge_dic = {} if 'type' in challenge_dic and 'authorization__value' in challenge_dic and 'token' in challenge_dic and 'authorization__order__account__name' in challenge_dic: try: pub_key = self.dbstore.jwk_load(challenge_dic['authorization__order__account__name']) except Exception as err_: - self.logger.critical('acme2certifier database error in Challenge._check() jwk: {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Challenge._check() jwk: %s', err_) pub_key = None if pub_key: @@ -117,7 +117,7 @@ def _check(self, challenge_name: str, payload: Dict[str, str]) -> Tuple[bool, bo result = False invalid = False - self.logger.debug('challenge._check() ended with: {0}/{1}'.format(result, invalid)) + self.logger.debug('challenge._check() ended with: %s/%s', result, invalid) return (result, invalid) def _existing_challenge_validate(self, challenge_list: List[str]) -> Dict[str, str]: @@ -134,11 +134,11 @@ def _existing_challenge_validate(self, challenge_list: List[str]) -> Dict[str, s def _info(self, challenge_name): """ get challenge details """ - self.logger.debug('Challenge._info({0})'.format(challenge_name)) + self.logger.debug('Challenge._info(%s)', challenge_name) try: challenge_dic = self.dbstore.challenge_lookup('name', challenge_name, vlist=('type', 'token', 'status__name', 'validated')) except Exception as err_: - self.logger.critical('acme2certifier database error in Challenge._info(): {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Challenge._info(): %s', err_) challenge_dic = {} if 'status' in challenge_dic and challenge_dic['status'] == 'valid': @@ -152,7 +152,7 @@ def _info(self, challenge_name): if 'validated' in challenge_dic: challenge_dic.pop('validated') - self.logger.debug('Challenge._info({0}) ended'.format(challenge_name)) + self.logger.debug('Challenge._info(%s) ended', challenge_name) return challenge_dic def _config_proxy_load(self, config_dic: Dict[str, str]): @@ -163,7 +163,7 @@ def _config_proxy_load(self, config_dic: Dict[str, str]): try: self.proxy_server_list = json.loads(config_dic['DEFAULT']['proxy_server_list']) except Exception as err_: - self.logger.warning('Challenge._config_load() proxy_server_list failed with error: {0}'.format(err_)) + self.logger.warning('Challenge._config_load() proxy_server_list failed with error: %s', err_) self.logger.debug('Challenge._config_proxy_load() ended') @@ -178,12 +178,12 @@ def _config_challenge_load(self, config_dic: Dict[str, str]): try: self.dns_server_list = json.loads(config_dic['Challenge']['dns_server_list']) except Exception as err_: - self.logger.warning('Challenge._config_load() dns_server_list failed with error: {0}'.format(err_)) + self.logger.warning('Challenge._config_load() dns_server_list failed with error: %s', err_) if 'challenge_validation_timeout' in config_dic['Challenge']: try: self.challenge_validation_timeout = int(config_dic['Challenge']['challenge_validation_timeout']) except Exception as err_: - self.logger.warning('Challenge._config_load() failed to load challenge_validation_timeout: {0}'.format(err_)) + self.logger.warning('Challenge._config_load() failed to load challenge_validation_timeout: %s', err_) self.logger.debug('Challenge._config_challenge_load() ended') @@ -208,7 +208,7 @@ def _config_load(self): def _extensions_validate(self, cert: str, extension_value: str, fqdn: str) -> bool: """ validate extension """ - self.logger.debug('Challenge._extensions_validate({0}/{1})'.format(extension_value, fqdn)) + self.logger.debug('Challenge._extensions_validate(%s/%s)', extension_value, fqdn) result = False san_list = cert_san_get(self.logger, cert, recode=False) fqdn_in_san = fqdn_in_san_check(self.logger, san_list, fqdn) @@ -222,12 +222,13 @@ def _extensions_validate(self, cert: str, extension_value: str, fqdn: str) -> bo else: self.logger.debug('fqdn check against san failed') - self.logger.debug('Challenge._extensions_validate() ended with: {0}'.format(result)) + self.logger.debug('Challenge._extensions_validate() ended with: %s', result) return result def _name_get(self, url: str) -> str: """ get challenge """ - self.logger.debug('Challenge.get_name({0})'.format(url)) + self.logger.debug('Challenge.get_name(%s)', url) + url_dic = parse_url(self.logger, url) challenge_name = url_dic['path'].replace(self.path_dic['chall_path'], '') if '/' in challenge_name: @@ -236,7 +237,7 @@ def _name_get(self, url: str) -> str: def _new(self, authz_name: str, mtype: str, token: str = None, value: str = None) -> Dict[str, str]: """ new challenge """ - self.logger.debug('Challenge._new({0}:{2}:{1})'.format(authz_name, mtype, value)) + self.logger.debug('Challenge._new(%s:%s:%s)', authz_name, mtype, value) challenge_name = generate_random_string(self.logger, 12) @@ -255,13 +256,13 @@ def _new(self, authz_name: str, mtype: str, token: str = None, value: str = None try: chid = self.dbstore.challenge_add(value, mtype, data_dic) except Exception as err_: - self.logger.critical('acme2certifier database error in Challenge._new(): {0}, {2}:{1}'.format(err_, mtype, value)) + self.logger.critical('acme2certifier database error in Challenge._new(): %s, %s:%s', err_, value, mtype) chid = None challenge_dic = {} if chid: challenge_dic['type'] = mtype - challenge_dic['url'] = '{0}{1}{2}'.format(self.server_name, self.path_dic['chall_path'], challenge_name) + challenge_dic['url'] = f'{self.server_name}{self.path_dic['chall_path']}{challenge_name}' challenge_dic['token'] = token challenge_dic['status'] = 'pending' if mtype == 'tkauth-01': @@ -275,7 +276,7 @@ def _new(self, authz_name: str, mtype: str, token: str = None, value: str = None def _parse(self, code: int, payload: Dict[str, str], protected: Dict[str, str], challenge_name: str, challenge_dic: Dict[str, str]) -> Tuple[int, str, str, Dict[str, str]]: # pylint: disable=R0913 """ challenge parse """ - self.logger.debug('Challenge._parse({0})'.format(challenge_name)) + self.logger.debug('Challenge._parse(%s)', challenge_name) response_dic = {} message = None @@ -307,28 +308,29 @@ def _parse(self, code: int, payload: Dict[str, str], protected: Dict[str, str], challenge_dic['url'] = protected['url'] response_dic['data'] = challenge_dic response_dic['header'] = {} - response_dic['header']['Link'] = '<{0}{1}>;rel="up"'.format(self.server_name, self.path_dic['authz_path']) + response_dic['header']['Link'] = f'<{self.server_name}{ self.path_dic['authz_path']}>;rel="up"' - self.logger.debug('Challenge._parse() ended with: {0}'.format(code)) + self.logger.debug('Challenge._parse() ended with: %s', code) return (code, message, detail, response_dic) def _update(self, data_dic: Dict[str, str]): """ update challenge """ - self.logger.debug('Challenge._update({0})'.format(data_dic)) + self.logger.debug('Challenge._update(%s)', data_dic) + try: self.dbstore.challenge_update(data_dic) except Exception as err_: - self.logger.critical('acme2certifier database error in Challenge._update(): {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Challenge._update(): %s', err_) self.logger.debug('Challenge._update() ended') def _update_authz(self, challenge_name: str, data_dic: Dict[str, str]): """ update authorizsation based on challenge_name """ - self.logger.debug('Challenge._update_authz({0})'.format(challenge_name)) + self.logger.debug('Challenge._update_authz(%s)', challenge_name) try: # lookup autorization based on challenge_name authz_name = self.dbstore.challenge_lookup('name', challenge_name, ['authorization__name'])['authorization'] except Exception as err_: - self.logger.critical('acme2certifier database error in Challenge._update_authz() lookup: {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Challenge._update_authz() lookup: %s', err_) authz_name = None if authz_name: @@ -337,13 +339,14 @@ def _update_authz(self, challenge_name: str, data_dic: Dict[str, str]): # update authorization self.dbstore.authorization_update(data_dic) except Exception as err_: - self.logger.critical('acme2certifier database error in Challenge._update_authz() upd: {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Challenge._update_authz() upd: %s', err_) self.logger.debug('Challenge._update_authz() ended') def _validate(self, challenge_name: str, payload: Dict[str, str]) -> bool: """ validate challenge""" - self.logger.debug('Challenge._validate({0}: {1})'.format(challenge_name, payload)) + self.logger.debug('Challenge._validate(%s: %s)', challenge_name, payload) + # change state to processing self._update({'name': challenge_name, 'status': 'processing'}) if self.challenge_validation_disable: @@ -367,17 +370,17 @@ def _validate(self, challenge_name: str, payload: Dict[str, str]) -> bool: data_dic = {'name': challenge_name, 'keyauthorization': payload['keyAuthorization']} self._update(data_dic) - self.logger.debug('Challenge._validate() ended with:{0}'.format(challenge_check)) + self.logger.debug('Challenge._validate() ended with:%s', challenge_check) return challenge_check def _validate_alpn_challenge(self, challenge_name: str, id_type: str, id_value: str, token: str, jwk_thumbprint: str) -> Tuple[bool, bool]: """ validate dns challenge """ - self.logger.debug('Challenge._validate_alpn_challenge({0}:{1}:{2})'.format(challenge_name, id_value, token)) + self.logger.debug('Challenge._validate_alpn_challenge(%s:%s:%s)', challenge_name, id_value, token) if id_type == 'dns': # resolve name (response, invalid) = fqdn_resolve(id_value, self.dns_server_list) - self.logger.debug('fqdn_resolve() ended with: {0}/{1}'.format(response, invalid)) + self.logger.debug('fqdn_resolve() ended with: %s/%s', response, invalid) sni = id_value elif id_type == 'ip': (sni, invalid) = ip_validate(self.logger, id_value) @@ -387,9 +390,9 @@ def _validate_alpn_challenge(self, challenge_name: str, id_type: str, id_value: # we are expecting a certifiate extension which is the sha256 hexdigest of token in a byte structure # which is base64 encoded '0420' has been taken from acme_srv.sh sources - sha256_digest = sha256_hash_hex(self.logger, '{0}.{1}'.format(token, jwk_thumbprint)) - extension_value = b64_encode(self.logger, bytearray.fromhex('0420{0}'.format(sha256_digest))) - self.logger.debug('computed value: {0}'.format(extension_value)) + sha256_digest = sha256_hash_hex(self.logger, f'{token}.{jwk_thumbprint}') + extension_value = b64_encode(self.logger, bytearray.fromhex(f'0420{sha256_digest}')) + self.logger.debug('computed value: %s', extension_value) if not invalid: # check if we need to set a proxy @@ -406,26 +409,27 @@ def _validate_alpn_challenge(self, challenge_name: str, id_type: str, id_value: else: result = False - self.logger.debug('Challenge._validate_alpn_challenge() ended with: {0}/{1}'.format(result, invalid)) + self.logger.debug('Challenge._validate_alpn_challenge() ended with: %s/%s', result, invalid) return (result, invalid) def _validate_dns_challenge(self, challenge_name: str, _type: str, fqdn: str, token: str, jwk_thumbprint: str) -> Tuple[bool, bool]: """ validate dns challenge """ - self.logger.debug('Challenge._validate_dns_challenge({0}:{1}:{2})'.format(challenge_name, fqdn, token)) + self.logger.debug('Challenge._validate_dns_challenge(%s:%s:%s)', challenge_name, fqdn, token) # handle wildcard domain fqdn = self._wcd_manipulate(fqdn) # rewrite fqdn to resolve txt record - fqdn = '_acme-challenge.{0}'.format(fqdn) + fqdn = f'_acme-challenge.{fqdn}' # compute sha256 hash - _hash = b64_url_encode(self.logger, sha256_hash(self.logger, '{0}.{1}'.format(token, jwk_thumbprint))) + _hash = b64_url_encode(self.logger, sha256_hash(self.logger, f'{token}.{jwk_thumbprint}')) + # query dns txt_list = txt_get(self.logger, fqdn, self.dns_server_list) # compare computed hash with result from DNS query - self.logger.debug('response_got: {0} response_expected: {1}'.format(txt_list, _hash)) + self.logger.debug('response_got: %s response_expected: %s', txt_list, _hash) if _hash in txt_list: self.logger.debug('validation successful') result = True @@ -433,17 +437,17 @@ def _validate_dns_challenge(self, challenge_name: str, _type: str, fqdn: str, to self.logger.debug('validation not successful') result = False - self.logger.debug('Challenge._validate_dns_challenge() ended with: {0}'.format(result)) + self.logger.debug('Challenge._validate_dns_challenge() ended with: %s', result) return (result, False) def _validate_http_challenge(self, challenge_name: str, id_type: str, id_value: str, token: str, jwk_thumbprint: str) -> Tuple[bool, bool]: """ validate http challenge """ - self.logger.debug('Challenge._validate_http_challenge({0}:{1}:{2})'.format(challenge_name, id_value, token)) + self.logger.debug('Challenge._validate_http_challenge(%s:%s:%s)', challenge_name, id_value, token) if id_type == 'dns': # resolve name (response, invalid) = fqdn_resolve(id_value, self.dns_server_list) - self.logger.debug('fqdn_resolve() ended with: {0}/{1}'.format(response, invalid)) + self.logger.debug('fqdn_resolve() ended with: %s/%s', response, invalid) elif id_type == 'ip': invalid = False (_sni, invalid) = ip_validate(self.logger, id_value) @@ -456,11 +460,11 @@ def _validate_http_challenge(self, challenge_name: str, id_type: str, id_value: proxy_server = proxy_check(self.logger, id_value, self.proxy_server_list) else: proxy_server = None - req = url_get(self.logger, 'http://{0}/.well-known/acme-challenge/{1}'.format(id_value, token), dns_server_list=self.dns_server_list, proxy_server=proxy_server, verify=False, timeout=self.challenge_validation_timeout) + req = url_get(self.logger, f'http://{id_value}/.well-known/acme-challenge/{token}', dns_server_list=self.dns_server_list, proxy_server=proxy_server, verify=False, timeout=self.challenge_validation_timeout) if req: response_got = req.splitlines()[0] - response_expected = '{0}.{1}'.format(token, jwk_thumbprint) - self.logger.debug('response_got: {0} response_expected: {1}'.format(response_got, response_expected)) + response_expected = f'{token}.{jwk_thumbprint}' + self.logger.debug('response_got: %s response_expected: %s', response_got, response_expected) if response_got == response_expected: self.logger.debug('validation successful') result = True @@ -473,21 +477,21 @@ def _validate_http_challenge(self, challenge_name: str, id_type: str, id_value: else: result = False - self.logger.debug('Challenge._validate_http_challenge() ended with: {0}/{1}'.format(result, invalid)) + self.logger.debug('Challenge._validate_http_challenge() ended with: %s/%s', result, invalid) return (result, invalid) def _validate_tkauth_challenge(self, challenge_name: str, _type: str, tnauthlist: str, _token: str, _jwk_thumbprint: str, payload: Dict[str, str]) -> Tuple[bool, bool]: """ validate tkauth challenge """ - self.logger.debug('Challenge._validate_tkauth_challenge({0}:{1}:{2})'.format(challenge_name, tnauthlist, payload)) + self.logger.debug('Challenge._validate_tkauth_challenge(%s:%s:%s)', challenge_name, tnauthlist, payload) result = True invalid = False - self.logger.debug('Challenge._validate_tkauth_challenge() ended with: {0}/{1}'.format(result, invalid)) + self.logger.debug('Challenge._validate_tkauth_challenge() ended with: %s/%s', result, invalid) return (result, invalid) def _validate_tnauthlist_payload(self, payload: Dict[str, str], challenge_dic: Dict[str, str]) -> Tuple[int, str, str]: """ check payload in cae tnauthlist option has been set """ - self.logger.debug('Challenge._validate_tnauthlist_payload({0})'.format(payload)) + self.logger.debug('Challenge._validate_tnauthlist_payload(%s)', payload) code = 400 message = None @@ -513,22 +517,24 @@ def _validate_tnauthlist_payload(self, payload: Dict[str, str], challenge_dic: D code = 200 else: message = self.err_msg_dic['malformed'] - detail = 'invalid challenge: {0}'.format(challenge_dic) + detail = f'invalid challenge: {challenge_dic}' - self.logger.debug('Challenge._validate_tnauthlist_payload() ended with:{0}'.format(code)) + self.logger.debug('Challenge._validate_tnauthlist_payload() ended with:%s', code) return (code, message, detail) def _wcd_manipulate(self, fqdn: str) -> str: """ wildcard domain handling """ - self.logger.debug('Challenge._wc_manipulate() for fqdn: {0}'.format(fqdn)) + self.logger.debug('Challenge._wc_manipulate() for fqdn: %s', fqdn) + if fqdn.startswith('*.'): fqdn = fqdn[2:] - self.logger.debug('Challenge._wc_manipulate() ended with: {0}'.format(fqdn)) + self.logger.debug('Challenge._wc_manipulate() ended with: %s', fqdn) return fqdn def challengeset_get(self, authz_name: str, _auth_status: str, token: str, tnauth: bool, id_type: str = 'dns', id_value: str = None) -> List[str]: """ get the challengeset for an authorization """ - self.logger.debug('Challenge.challengeset_get() for auth: {0}:{1}'.format(authz_name, id_value)) + self.logger.debug('Challenge.challengeset_get() for auth: %s:%s', authz_name, id_value) + # check database if there are exsting challenges for a particular authorization challenge_list = self._challengelist_search('authorization__name', authz_name) @@ -552,7 +558,8 @@ def challengeset_get(self, authz_name: str, _auth_status: str, token: str, tnaut def get(self, url: str) -> Dict[str, str]: """ get challenge details based on get request """ challenge_name = self._name_get(url) - self.logger.debug('Challenge.get({0})'.format(challenge_name)) + self.logger.debug('Challenge.get(%s)', challenge_name) + response_dic = {} response_dic['code'] = 200 response_dic['data'] = self._info(challenge_name) @@ -560,7 +567,8 @@ def get(self, url: str) -> Dict[str, str]: def new_set(self, authz_name: str, token: str, tnauth: bool = False, id_type: str = 'dns', value: str = None) -> List[str]: """ net challenge set """ - self.logger.debug('Challenge.new_set({0}, {1})'.format(authz_name, value)) + self.logger.debug('Challenge.new_set(%s, %s)', authz_name, value) + challenge_list = [] if tnauth: @@ -579,9 +587,9 @@ def new_set(self, authz_name: str, token: str, tnauth: bool = False, id_type: st if challenge_json: challenge_list.append(challenge_json) else: - self.logger.error('ERROR: Empty challenge returned for {0}'.format(challenge_type)) + self.logger.error('ERROR: Empty challenge returned for %s', challenge_type) - self.logger.debug('Challenge._new_set returned ({0})'.format(challenge_list)) + self.logger.debug('Challenge._new_set returned (%s)', challenge_list) return challenge_list def parse(self, content: str) -> Dict[str, str]: @@ -604,7 +612,7 @@ def parse(self, content: str) -> Dict[str, str]: else: code = 400 message = self.err_msg_dic['malformed'] - detail = 'invalid challenge: {0}'.format(challenge_name) + detail = f'invalid challenge: {challenge_name}' else: code = 400 message = self.err_msg_dic['malformed'] @@ -617,5 +625,5 @@ def parse(self, content: str) -> Dict[str, str]: # prepare/enrich response status_dic = {'code': code, 'type': message, 'detail': detail} response_dic = self.message.prepare_response(response_dic, status_dic) - self.logger.debug('challenge.parse() returns: {0}'.format(json.dumps(response_dic))) + self.logger.debug('challenge.parse() returns: %s', json.dumps(response_dic)) return response_dic diff --git a/acme_srv/directory.py b/acme_srv/directory.py index 39dd9aa6..d382a6cb 100644 --- a/acme_srv/directory.py +++ b/acme_srv/directory.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """ Directory class """ -# pylint: disable=c0209, e0401, r0913 +# pylint: disable=e0401, r0913 from __future__ import print_function import uuid from typing import Dict @@ -87,11 +87,11 @@ def directory_get(self) -> Dict[str, str]: if version == self.dbversion: d_dic['meta']['db_check'] = 'OK' else: - self.logger.error('acme2certifier database error: version mismatch: detected: {0}/ expected: {1}'.format(version, __dbversion__)) + self.logger.error('acme2certifier database error: version mismatch: detected: %s/ expected: %s', version, __dbversion__) d_dic['meta']['db_check'] = 'NOK' except Exception as err_: - self.logger.critical('acme2certifier database error in Directory.dbversion_check(): {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Directory.dbversion_check(): %s', err_) d_dic['meta']['db_check'] = 'NOK' # generate random key in json as recommended by LE diff --git a/acme_srv/helper.py b/acme_srv/helper.py index 4239d05a..3b6709dd 100644 --- a/acme_srv/helper.py +++ b/acme_srv/helper.py @@ -1,4 +1,4 @@ -# pylint: disable=c0209, c0302, e0401, r0913 +# pylint: disable=c0302, e0401, r0913 # -*- coding: utf-8 -*- """ helper functions for acme2certifier """ from __future__ import print_function @@ -39,7 +39,7 @@ from .version import __version__ -USER_AGENT = 'acme2certifier/{0}'.format(__version__) +USER_AGENT = f'acme2certifier/{__version__}' def b64decode_pad(logger: logging.Logger, string: str) -> bytes: @@ -86,18 +86,18 @@ def build_pem_file(logger: logging.Logger, existing, certificate, wrap, csr=Fals """ construct pem_file """ logger.debug('build_pem_file()') if csr: - pem_file = '-----BEGIN CERTIFICATE REQUEST-----\n{0}\n-----END CERTIFICATE REQUEST-----\n'.format(textwrap.fill(convert_byte_to_string(certificate), 64)) + pem_file = f'-----BEGIN CERTIFICATE REQUEST-----\n{textwrap.fill(convert_byte_to_string(certificate), 64)}\n-----END CERTIFICATE REQUEST-----\n' else: if existing: if wrap: - pem_file = '{0}-----BEGIN CERTIFICATE-----\n{1}\n-----END CERTIFICATE-----\n'.format(convert_byte_to_string(existing), textwrap.fill(convert_byte_to_string(certificate), 64)) + pem_file = f'{existing}-----BEGIN CERTIFICATE-----\n{textwrap.fill(convert_byte_to_string(certificate), 64)}\n-----END CERTIFICATE-----\n' else: - pem_file = '{0}-----BEGIN CERTIFICATE-----\n{1}\n-----END CERTIFICATE-----\n'.format(convert_byte_to_string(existing), convert_byte_to_string(certificate)) + pem_file = f'{convert_byte_to_string(existing)}-----BEGIN CERTIFICATE-----\n{convert_byte_to_string(certificate)}\n-----END CERTIFICATE-----\n' else: if wrap: - pem_file = '-----BEGIN CERTIFICATE-----\n{0}\n-----END CERTIFICATE-----\n'.format(textwrap.fill(convert_byte_to_string(certificate), 64)) + pem_file = f'-----BEGIN CERTIFICATE-----\n{textwrap.fill(convert_byte_to_string(certificate), 64)}\n-----END CERTIFICATE-----\n' else: - pem_file = '-----BEGIN CERTIFICATE-----\n{0}\n-----END CERTIFICATE-----\n'.format(convert_byte_to_string(certificate)) + pem_file = f'-----BEGIN CERTIFICATE-----\n{convert_byte_to_string(certificate)}\n-----END CERTIFICATE-----\n' return pem_file @@ -117,13 +117,13 @@ def ca_handler_load(logger: logging.Logger, config_dic: Dict) -> importlib.impor spec.loader.exec_module(ca_handler_module) return ca_handler_module except Exception as err_: - logger.critical('Helper.ca_handler_load(): loading CAhandler configured in cfg failed with err: {0}'.format(err_)) + logger.critical('Helper.ca_handler_load(): loading CAhandler configured in cfg failed with err: %s', err_) # if no 'handler_file' provided or loading was unsuccessful, try to load default handler try: ca_handler_module = importlib.import_module('acme_srv.ca_handler') except Exception as err_: - logger.critical('Helper.ca_handler_load(): loading default CAhandler failed with err: {0}'.format(err_)) + logger.critical('Helper.ca_handler_load(): loading default CAhandler failed with err: %s', err_) ca_handler_module = None return ca_handler_module @@ -136,7 +136,7 @@ def config_check(logger: logging.Logger, config_dic: Dict): for section, section_dic in config_dic.items(): for key, value in section_dic.items(): if value.startswith('"') or value.endswith('"'): - logger.warning('config_check(): section {0} option: {1} contains " characters. Check if this is really needed!'.format(section, key)) + logger.warning('config_check(): section %s option: %s contains " characters. Check if this is really needed!', section, key) def eab_handler_load(logger: logging.Logger, config_dic: Dict) -> importlib.import_module: @@ -150,18 +150,18 @@ def eab_handler_load(logger: logging.Logger, config_dic: Dict) -> importlib.impo eab_handler_module = importlib.util.module_from_spec(spec) spec.loader.exec_module(eab_handler_module) except Exception as err_: - logger.critical('Helper.eab_handler_load(): loading EABhandler configured in cfg failed with err: {0}'.format(err_)) + logger.critical('Helper.eab_handler_load(): loading EABhandler configured in cfg failed with err: %s', err_) try: eab_handler_module = importlib.import_module('acme_srv.eab_handler') except Exception as err_: eab_handler_module = None - logger.critical('Helper.eab_handler_load(): loading default EABhandler failed with err: {0}'.format(err_)) + logger.critical('Helper.eab_handler_load(): loading default EABhandler failed with err: %s', err_) else: if 'EABhandler' in config_dic: try: eab_handler_module = importlib.import_module('acme_srv.eab_handler') except Exception as err_: - logger.critical('Helper.eab_handler_load(): loading default EABhandler failed with err: {0}'.format(err_)) + logger.critical('Helper.eab_handler_load(): loading default EABhandler failed with err: %s', err_) eab_handler_module = None else: logger.error('Helper.eab_handler_load(): EABhandler configuration missing in config file') @@ -182,14 +182,15 @@ def hooks_load(logger: logging.Logger, config_dic: Dict) -> importlib.import_mod hooks_module = importlib.util.module_from_spec(spec) spec.loader.exec_module(hooks_module) except Exception as err_: - logger.critical('Helper.hooks_load(): loading Hooks configured in cfg failed with err: {0}'.format(err_)) + logger.critical('Helper.hooks_load(): loading Hooks configured in cfg failed with err: %s', err_) return hooks_module def cert_load(logger: logging.Logger, certificate: str, recode: bool) -> x509.Certificate: """ load certificate object from pem _Format """ - logger.debug('cert_load({0})'.format(recode)) + logger.debug('cert_load(%s)', recode) + if recode: pem_data = convert_string_to_byte(build_pem_file(logger, None, b64_url_recode(logger, certificate), True)) else: @@ -202,9 +203,9 @@ def cert_load(logger: logging.Logger, certificate: str, recode: bool) -> x509.Ce def cert_dates_get(logger: logging.Logger, certificate: str) -> Tuple[int, int]: """ get date number form certificate """ logger.debug('cert_dates_get()') + issue_date = 0 expiration_date = 0 - try: cert = cert_load(logger, certificate, recode=True) issue_date = date_to_uts_utc(cert.not_valid_before, _tformat='%Y-%m-%d %H:%M:%S') @@ -213,7 +214,7 @@ def cert_dates_get(logger: logging.Logger, certificate: str) -> Tuple[int, int]: issue_date = 0 expiration_date = 0 - logger.debug('cert_dates_get() ended with: {0}/{1}'.format(issue_date, expiration_date)) + logger.debug('cert_dates_get() ended with: %s/%s', issue_date, expiration_date) return (issue_date, expiration_date) @@ -229,7 +230,7 @@ def cert_cn_get(logger: logging.Logger, certificate: str) -> str: if attr.oid == x509.NameOID.COMMON_NAME: result = attr.value break - logger.debug('CAhandler.cert_cn_get() ended with: {0}'.format(result)) + logger.debug('CAhandler.cert_cn_get() ended with: %s', result) return result @@ -246,7 +247,7 @@ def cert_issuer_get(logger: logging.Logger, certificate: str) -> str: cert = cert_load(logger, certificate, recode=True) result = cert.issuer.rfc4514_string() - logger.debug('CAhandler.cert_issuer_get() ended with: {0}'.format(result)) + logger.debug('CAhandler.cert_issuer_get() ended with: %s', result) return result @@ -266,7 +267,7 @@ def cert_pubkey_get(logger: logging.Logger, certificate=str) -> str: encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo ) - logger.debug('CAhandler.cert_pubkey_get() ended with: {0}'.format(pubkey_str)) + logger.debug('CAhandler.cert_pubkey_get() ended with: %s', pubkey_str) return convert_byte_to_string(pubkey_str) @@ -297,7 +298,7 @@ def cert_san_pyopenssl_get(logger, certificate, recode=True): def cert_san_get(logger: logging.Logger, certificate: str, recode: bool = True) -> List[str]: """ get subject alternate names from certificate """ - logger.debug('cert_san_get({0})'.format(recode)) + logger.debug('cert_san_get(%s)', recode) cert = cert_load(logger, certificate, recode=recode) sans = [] @@ -305,12 +306,12 @@ def cert_san_get(logger: logging.Logger, certificate: str, recode: bool = True) ext = cert.extensions.get_extension_for_oid(x509.OID_SUBJECT_ALTERNATIVE_NAME) sans_list = ext.value.get_values_for_type(x509.DNSName) for san in sans_list: - sans.append('DNS:{0}'.format(san)) + sans.append(f'DNS:{san}') sans_list = ext.value.get_values_for_type(x509.IPAddress) for san in sans_list: - sans.append('IP:{0}'.format(san)) + sans.append(f'IP:{san}') except Exception as err: - logger.error('cert_san_get(): Error: {0}'.format(err)) + logger.error('cert_san_get(): Error: %s', err) # we may add the routing to get the sanes via pyopenssl here if needed (sans = cert_san_pyopenssl_get(logger, certificate, recode=recode)) logger.debug('cert_san_get() ended') @@ -335,7 +336,7 @@ def cert_ski_pyopenssl_get(logger, certificate: str) -> str: else: logger.error("cert_ski_pyopenssl_get(): No SKI found in certificate") ski_hex = None - logger.debug('cert_ski_pyopenssl_cert() ended with: {0}'.format(ski_hex)) + logger.debug('cert_ski_pyopenssl_cert() ended with: %s', ski_hex) return ski_hex @@ -348,9 +349,9 @@ def cert_ski_get(logger: logging.Logger, certificate: str) -> str: ski = cert.extensions.get_extension_for_oid(x509.OID_SUBJECT_KEY_IDENTIFIER) ski_value = ski.value.digest.hex() except Exception as err: - logger.error('cert_ski_get(): Error: {0}'.format(err)) + logger.error('cert_ski_get(): Error: %s', err) ski_value = cert_ski_pyopenssl_get(logger, certificate) - logger.debug('cert_ski_get() ended with: {0}'.format(ski_value)) + logger.debug('cert_ski_get() ended with: %s', ski_value) return ski_value @@ -364,7 +365,7 @@ def cert_extensions_get(logger: logging.Logger, certificate: str, recode: bool = for extension in cert.extensions: extension_list.append(convert_byte_to_string(base64.b64encode(extension.value.public_bytes()))) - logger.debug('cert_extensions_get() ended with: {0}'.format(extension_list)) + logger.debug('cert_extensions_get() ended with: %s', extension_list) return extension_list @@ -373,10 +374,10 @@ def cert_serial_get(logger: logging.Logger, certificate: str, hexformat: bool = logger.debug('cert_serial_get()') cert = cert_load(logger, certificate, recode=True) if hexformat: - serial_number = '{0:x}'.format(cert.serial_number) + serial_number = f'{cert.serial_number:x}' else: serial_number = cert.serial_number - logger.debug('cert_serial_get() ended with: {0}'.format(serial_number)) + logger.debug('cert_serial_get() ended with: %s', serial_number) return serial_number @@ -402,7 +403,8 @@ def convert_string_to_byte(value: str) -> bytes: def csr_load(logger: logging.Logger, csr: str) -> x509.CertificateSigningRequest: """ load certificate object from pem _Format """ - logger.debug('cert_load({0})') + logger.debug('cert_load()') + pem_data = convert_string_to_byte(build_pem_file(logger, None, b64_url_recode(logger, csr), True, True)) csr_data = x509.load_pem_x509_csr(pem_data) @@ -414,7 +416,6 @@ def csr_cn_get(logger: logging.Logger, csr_pem: str) -> str: logger.debug('CAhandler.csr_cn_get()') csr = csr_load(logger, csr_pem) - # Extract the subject's common name common_name = None for attribute in csr.subject: @@ -422,7 +423,7 @@ def csr_cn_get(logger: logging.Logger, csr_pem: str) -> str: common_name = attribute.value break - logger.debug('CAhandler.csr_cn_get() ended with: {0}'.format(common_name)) + logger.debug('CAhandler.csr_cn_get() ended with: %s', common_name) return common_name @@ -433,7 +434,7 @@ def csr_dn_get(logger: logging.Logger, csr: str) -> str: csr_obj = csr_load(logger, csr) subject = csr_obj.subject.rfc4514_string() - logger.debug('CAhandler.csr_dn_get() ended with: {0}'.format(subject)) + logger.debug('CAhandler.csr_dn_get() ended with: %s', subject) return subject @@ -462,7 +463,7 @@ def csr_pubkey_get(logger, csr, encoding='pem'): ) else: pubkey = None - logger.debug('CAhandler.cert_pubkey_get() ended with: {0}'.format(pubkey)) + logger.debug('CAhandler.cert_pubkey_get() ended with: %s', pubkey) return pubkey @@ -479,15 +480,15 @@ def csr_san_get(logger: logging.Logger, csr: str) -> List[str]: sans_list = ext.value.get_values_for_type(x509.DNSName) for san in sans_list: - sans.append('DNS:{0}'.format(san)) + sans.append(f'DNS:{san}') sans_list = ext.value.get_values_for_type(x509.IPAddress) for san in sans_list: - sans.append('IP:{0}'.format(san)) + sans.append(f'IP:{san}') except Exception as err: - logger.error('csr_san_get(): Error: {0}'.format(err)) + logger.error('csr_san_get(): Error: %s', err) - logger.debug('csr_san_get() ended with: {0}'.format(str(sans))) + logger.debug('csr_san_get() ended with: %s', str(sans)) return sans @@ -524,7 +525,7 @@ def csr_extensions_get(logger: logging.Logger, csr: str) -> List[str]: for extension in csr_obj.extensions: extension_list.append(convert_byte_to_string(base64.b64encode(extension.value.public_bytes()))) - logger.debug('csr_extensions_get() ended with: {0}'.format(extension_list)) + logger.debug('csr_extensions_get() ended with: %s', extension_list) return extension_list @@ -559,7 +560,7 @@ def decode_message(logger: logging.Logger, message: str) -> Tuple[str, str, Dict signature = jwstoken.objects['signature'] result = True except Exception as err: - logger.error('decode_message() err: {0}'.format(err)) + logger.error('decode_message() err: %s', err) error = str(err) protected = {} payload = {} @@ -594,9 +595,9 @@ def fqdn_in_san_check(logger: logging.Logger, san_list: List[str], fqdn: str) -> result = True break except Exception: - logger.error('ERROR: fqdn_in_san_check() SAN split failed: {0}'.format(san)) + logger.error('ERROR: fqdn_in_san_check() SAN split failed: %s', san) - logger.debug('fqdn_in_san_check() ended with: {}'.format(result)) + logger.debug('fqdn_in_san_check() ended with: %s', result) return result @@ -629,9 +630,9 @@ def get_url(environ: Dict[str, str], include_path: bool = False) -> str: proto = 'http' if include_path and 'PATH_INFO' in environ: - result = '{0}://{1}{2}'.format(proto, server_name, html.escape(environ['PATH_INFO'])) + result = f'{proto}://{server_name}{html.escape(environ['PATH_INFO'])}' else: - result = '{0}://{1}'.format(proto, server_name) + result = f'{proto}://{server_name}' return result @@ -645,7 +646,7 @@ def header_info_get(logger: logging.Logger, csr: str, vlist: List[str] = ('id', result = dbstore.certificates_search('csr', csr, vlist) except Exception as err: result = [] - logger.error('Helper.header_info_get(): error: {0}'.format(err)) + logger.error('Helper.header_info_get(): error: %s', err) return list(result) @@ -658,7 +659,7 @@ def load_config(logger: logging.Logger = None, mfilter: str = None, cfg_file: st else: cfg_file = os.path.dirname(__file__) + '/' + 'acme_srv.cfg' if logger: - logger.debug('load_config({1}:{0})'.format(mfilter, cfg_file)) + logger.debug('load_config(%s:%s)', mfilter, cfg_file) config = configparser.ConfigParser(interpolation=None) config.optionxform = str config.read(cfg_file, encoding='utf8') @@ -667,7 +668,7 @@ def load_config(logger: logging.Logger = None, mfilter: str = None, cfg_file: st def parse_url(logger: logging.Logger, url: str) -> Dict[str, str]: """ split url into pieces """ - logger.debug('parse_url({0})'.format(url)) + logger.debug('parse_url(%s)', url) url_dic = { 'proto': urlparse(url).scheme, 'host': urlparse(url).netloc, @@ -678,7 +679,7 @@ def parse_url(logger: logging.Logger, url: str) -> Dict[str, str]: def encode_url(logger: logging.Logger, input_string: str) -> str: """ urlencoding """ - logger.debug('encode_url({0})'.format(input_string)) + logger.debug('encode_url(%s)', input_string) return quote(input_string) @@ -729,7 +730,7 @@ def logger_info(logger: logging.Logger, addr: str, locator: str, dat_dic: Dict[s # remove token from challenge data_dic = _logger_challenges_modify(data_dic) - logger.info('{0} {1} {2}'.format(addr, locator, str(data_dic))) + logger.info('%s %s %s', addr, locator, str(data_dic)) def logger_setup(debug: bool) -> logging.Logger: @@ -757,7 +758,7 @@ def logger_setup(debug: bool) -> logging.Logger: def print_debug(debug: bool, text: str): """ little helper to print debug messages """ if debug: - print('{0}: {1}'.format(datetime.datetime.now(), text)) + print(f'{datetime.datetime.now()}: {text}') def jwk_thumbprint_get(logger: logging.Logger, pub_key: Dict[str, str]) -> str: @@ -768,12 +769,12 @@ def jwk_thumbprint_get(logger: logging.Logger, pub_key: Dict[str, str]) -> str: jwkey = jwk.JWK(**pub_key) thumbprint = jwkey.thumbprint() except Exception as err: - logger.error('jwk_thumbprint_get(): error: {0}'.format(err)) + logger.error('jwk_thumbprint_get(): error: %s', err) thumbprint = None else: thumbprint = None - logger.debug('jwk_thumbprint_get() ended with: {0}'.format(thumbprint)) + logger.debug('jwk_thumbprint_get() ended with: %s', thumbprint) return thumbprint @@ -781,7 +782,7 @@ def sha256_hash(logger: logging.Logger, string: str) -> str: """ hash string """ logger.debug('sha256_hash()') result = hashlib.sha256(string.encode('utf-8')).digest() - logger.debug('sha256_hash() ended with {0} (base64-encoded)'.format(b64_encode(logger, result))) + logger.debug('sha256_hash() ended with %s (base64-encoded)', b64_encode(logger, result)) return result @@ -789,13 +790,13 @@ def sha256_hash_hex(logger: logging.Logger, string: str) -> str: """ hash string """ logger.debug('sha256_hash_hex()') result = hashlib.sha256(string.encode('utf-8')).hexdigest() - logger.debug('sha256_hash_hex() ended with {0}'.format(result)) + logger.debug('sha256_hash_hex() ended with %s', result) return result def signature_check(logger: logging.Logger, message: str, pub_key: str, json_: bool = False) -> Tuple[bool, str]: """ check JWS """ - logger.debug('signature_check({0})'.format(json_)) + logger.debug('signature_check(%s)', json_) result = False error = None @@ -808,7 +809,7 @@ def signature_check(logger: logging.Logger, message: str, pub_key: str, json_: b else: jwkey = jwk.JWK(**pub_key) except Exception as err: - logger.error('load key failed {0}'.format(err)) + logger.error('load key failed %s', err) jwkey = None result = False error = str(err) @@ -821,7 +822,7 @@ def signature_check(logger: logging.Logger, message: str, pub_key: str, json_: b jwstoken.verify(jwkey) result = True except Exception as err: - logger.error('verify failed {0}'.format(err)) + logger.error('verify failed %s', err) error = str(err) else: error = 'No key specified.' @@ -942,7 +943,7 @@ def patched_create_connection(address: List[str], *args, **kwargs): # pragma: n def proxy_check(logger: logging.Logger, fqdn: str, proxy_server_list: Dict[str, str]) -> str: """ check proxy server """ - logger.debug('proxy_check({0})'.format(fqdn)) + logger.debug('proxy_check(%s)', fqdn) # remove leading *. proxy_server_list_new = {k.replace('*.', ''): v for k, v in proxy_server_list.items()} @@ -954,20 +955,20 @@ def proxy_check(logger: logging.Logger, fqdn: str, proxy_server_list: Dict[str, if bool(regex_compiled.search(fqdn)): # parameter is in - set flag accordingly and stop loop proxy = proxy_server_list_new[regex] - logger.debug('proxy_check() match found: fqdn: {0}, regex: {1}'.format(fqdn, regex)) + logger.debug('proxy_check() match found: fqdn: %s, regex: %s', fqdn, regex) break if '*' in proxy_server_list_new.keys() and not proxy: - logger.debug('proxy_check() wildcard match found: fqdn: {0}'.format(fqdn)) + logger.debug('proxy_check() wildcard match found: fqdn: %s', fqdn) proxy = proxy_server_list_new['*'] - logger.debug('proxy_check() ended with {0}'.format(proxy)) + logger.debug('proxy_check() ended with %s', proxy) return proxy def url_get_with_own_dns(logger: logging.Logger, url: str, verify: bool = True) -> str: """ request by using an own dns resolver """ - logger.debug('url_get_with_own_dns({0})'.format(url)) + logger.debug('url_get_with_own_dns(%s)', url) # patch an own connection handler into URL lib # pylint: disable=W0212 connection._orig_create_connection = connection.create_connection @@ -977,7 +978,7 @@ def url_get_with_own_dns(logger: logging.Logger, url: str, verify: bool = True) result = req.text except Exception as err_: result = None - logger.error('url_get_with_own_dns error: {0}'.format(err_)) + logger.error('url_get_with_own_dns error: %s', err_) # cleanup connection.create_connection = connection._orig_create_connection return result @@ -991,7 +992,7 @@ def allowed_gai_family() -> socket.AF_INET: def url_get_with_default_dns(logger: logging.Logger, url: str, proxy_list: Dict[str, str], verify: bool, timeout: int) -> str: """ http get with default dns server """ - logger.debug('url_get_with_default_dns({0}) vrf={1}, timout:{2}'.format(url, verify, timeout)) + logger.debug('url_get_with_default_dns(%s) vrf=%s, timout:%s', url, verify, timeout) # we need to tweak headers and url for ipv6 addresse (headers, url) = v6_adjust(logger, url) @@ -1000,9 +1001,9 @@ def url_get_with_default_dns(logger: logging.Logger, url: str, proxy_list: Dict[ req = requests.get(url, verify=verify, timeout=timeout, headers=headers, proxies=proxy_list) result = req.text except Exception as err_: - logger.debug('url_get({0}): error'.format(err_)) + logger.debug('url_get(%s): error', err_) # force fallback to ipv4 - logger.debug('url_get({0}): fallback to v4'.format(url)) + logger.debug('url_get(%s): fallback to v4', url) old_gai_family = urllib3_cn.allowed_gai_family try: urllib3_cn.allowed_gai_family = allowed_gai_family @@ -1010,7 +1011,7 @@ def url_get_with_default_dns(logger: logging.Logger, url: str, proxy_list: Dict[ result = req.text except Exception as err: result = None - logger.error('url_get error: {0}'.format(err)) + logger.error('url_get error: %s', err) urllib3_cn.allowed_gai_family = old_gai_family return result @@ -1018,7 +1019,7 @@ def url_get_with_default_dns(logger: logging.Logger, url: str, proxy_list: Dict[ def url_get(logger: logging.Logger, url: str, dns_server_list: List[str] = None, proxy_server=None, verify=True, timeout=20) -> str: """ http get """ - logger.debug('url_get({0}) vrf={1}, timout:{2}'.format(url, verify, timeout)) + logger.debug('url_get(%s) vrf=%s, timout:%s', url, verify, timeout) # pylint: disable=w0621 # configure proxy servers if specified if proxy_server: @@ -1030,13 +1031,13 @@ def url_get(logger: logging.Logger, url: str, dns_server_list: List[str] = None, else: result = url_get_with_default_dns(logger, url, proxy_list, verify, timeout) - logger.debug('url_get() ended with: {0}'.format(result)) + logger.debug('url_get() ended with: %s', result) return result def txt_get(logger: logging.Logger, fqdn: str, dns_srv: List[str] = None) -> List[str]: """ dns query to get the TXt record """ - logger.debug('txt_get({0}: {1})'.format(fqdn, dns_srv)) + logger.debug('txt_get(%s: %s)', fqdn, dns_srv) # rewrite dns resolver if configured if dns_srv: @@ -1048,8 +1049,8 @@ def txt_get(logger: logging.Logger, fqdn: str, dns_srv: List[str] = None) -> Lis for rrecord in response: txt_record_list.append(rrecord.strings[0]) except Exception as err_: - logger.error('txt_get() error: {0}'.format(err_)) - logger.debug('txt_get() ended with: {0}'.format(txt_record_list)) + logger.error('txt_get() error: %s', err_) + logger.debug('txt_get() ended with: %s', txt_record_list) return txt_record_list @@ -1093,12 +1094,13 @@ def datestr_to_date(datestr: str, tformat: str = '%Y-%m-%dT%H:%M:%S') -> str: def proxystring_convert(logger: logging.Logger, proxy_server: str) -> Tuple[str, str, str]: """ convert proxy string """ - logger.debug('proxystring_convert({0})'.format(proxy_server)) + logger.debug('proxystring_convert(%s)', proxy_server) + proxy_proto_dic = {'http': socks.PROXY_TYPE_HTTP, 'socks4': socks.PROXY_TYPE_SOCKS4, 'socks5': socks.PROXY_TYPE_SOCKS5} try: (proxy_proto, proxy) = proxy_server.split('://') except Exception: - logger.error('proxystring_convert(): error splitting proxy_server string: {0}'.format(proxy_server)) + logger.error('proxystring_convert(): error splitting proxy_server string: %s', proxy_server) proxy = None proxy_proto = None @@ -1106,7 +1108,7 @@ def proxystring_convert(logger: logging.Logger, proxy_server: str) -> Tuple[str, try: (proxy_addr, proxy_port) = proxy.split(':') except Exception: - logger.error('proxystring_convert(): error splitting proxy into host/port: {0}'.format(proxy)) + logger.error('proxystring_convert(): error splitting proxy into host/port: %s', proxy) proxy_addr = None proxy_port = None else: @@ -1117,25 +1119,25 @@ def proxystring_convert(logger: logging.Logger, proxy_server: str) -> Tuple[str, try: proto_string = proxy_proto_dic[proxy_proto] except Exception: - logger.error('proxystring_convert(): unknown proxy protocol: {0}'.format(proxy_proto)) + logger.error('proxystring_convert(): unknown proxy protocol: %s', proxy_proto) proto_string = None else: - logger.error('proxystring_convert(): proxy_proto ({0}), proxy_addr ({1}) or proxy_port ({2}) missing'.format(proxy_proto, proxy_addr, proxy_port)) + logger.error('proxystring_convert(): proxy_proto (%s), proxy_addr (%s) or proxy_port (%s) missing', proxy_proto, proxy_addr, proxy_port) proto_string = None try: proxy_port = int(proxy_port) except Exception: - logger.error('proxystring_convert(): unknown proxy port: {0}'.format(proxy_port)) + logger.error('proxystring_convert(): unknown proxy port: %s', proxy_port) proxy_port = None - logger.debug('proxystring_convert() ended with {0}, {1}, {2}'.format(proto_string, proxy_addr, proxy_port)) + logger.debug('proxystring_convert() ended with %s, %s, %s', proto_string, proxy_addr, proxy_port) return (proto_string, proxy_addr, proxy_port) def servercert_get(logger: logging.Logger, hostname: str, port: int = 443, proxy_server: str = None, sni: str = None) -> str: """ get server certificate from an ssl connection """ - logger.debug('servercert_get({0}:{1})'.format(hostname, port)) + logger.debug('servercert_get(%s:%s)', hostname, port) pem_cert = None @@ -1167,17 +1169,17 @@ def servercert_get(logger: logging.Logger, hostname: str, port: int = 443, proxy try: sock.connect((hostname, port)) with context.wrap_socket(sock, server_hostname=sni) as sslsock: - logger.debug('servercert_get(): {0}:{1}:{2} version: {3}'.format(hostname, sni, port, sslsock.version())) + logger.debug('servercert_get(): %s:%s:%s version: %s', hostname, sni, port, sslsock.version()) der_cert = sslsock.getpeercert(True) # from binary DER format to PEM if der_cert: pem_cert = ssl.DER_cert_to_PEM_cert(der_cert) except Exception as err_: - logger.error('servercert_get() failed with: {0}'.format(err_)) + logger.error('servercert_get() failed with: %s', err_) pem_cert = None if pem_cert: - logger.debug('servercert_get() ended with: {0}'.format(b64_encode(logger, convert_string_to_byte(pem_cert)))) + logger.debug('servercert_get() ended with: %s', b64_encode(logger, convert_string_to_byte(pem_cert))) else: logger.debug('servercert_get() ended with: None') return pem_cert @@ -1185,7 +1187,7 @@ def servercert_get(logger: logging.Logger, hostname: str, port: int = 443, proxy def validate_csr(logger: logging.Logger, order_dic: Dict[str, str], _csr) -> bool: """ validate certificate signing request against order""" - logger.debug('validate_csr({0})'.format(order_dic)) + logger.debug('validate_csr(%s)', order_dic) return True @@ -1200,14 +1202,14 @@ def validate_email(logger: logging.Logger, contact_list: List[str]) -> bool: contact = contact.replace('mailto:', '') contact = contact.lstrip() tmp_result = bool(re.search(pattern, contact)) - logger.debug('# validate: {0} result: {1}'.format(contact, tmp_result)) + logger.debug('# validate: %s result: %s', contact, tmp_result) if not tmp_result: result = tmp_result else: contact_list = contact_list.replace('mailto:', '') contact_list = contact_list.lstrip() result = bool(re.search(pattern, contact_list)) - logger.debug('# validate: {0} result: {1}'.format(contact_list, result)) + logger.debug('# validate: %s result: %s', contact_list, result) return result @@ -1235,7 +1237,7 @@ def pembundle_to_list(logger: logging.Logger, pem_bundle: str) -> List[str]: pem_data += line + "\n" if pem_data: cert_list.append(pem_data) - logger.debug('pembundle_to_list() returned {0} certificates'.format(len(cert_list))) + logger.debug('pembundle_to_list() returned %s certificates', cert_list) return cert_list @@ -1268,7 +1270,7 @@ def certid_hex_get(logger: logging.Logger, renewal_info: str) -> Tuple[str, str] mda, certid_renewal = renewal_info_hex.split('0420', 1) mda = mda[4:] - logger.debug('certid_hex_get() endet with {0}'.format(certid_renewal)) + logger.debug('certid_hex_get() endet with %s', certid_renewal) return mda, certid_renewal @@ -1283,13 +1285,13 @@ def certid_check(logger: logging.Logger, renewal_info: str, certid_database: str _header, certid_renewal = renewal_info_hex.split('0420', 1) result = certid_renewal == certid_database - logger.debug('certid_check() ended with: {0}'.format(result)) + logger.debug('certid_check() ended with: %s', result) return result def ip_validate(logger: logging.Logger, ip_addr: str) -> Tuple[str, bool]: """ validate ip address """ - logger.debug('ip_validate({0})'.format(ip_addr)) + logger.debug('ip_validate(%s)', ip_addr) try: reverse_pointer = ipaddress.ip_address(ip_addr).reverse_pointer @@ -1297,13 +1299,13 @@ def ip_validate(logger: logging.Logger, ip_addr: str) -> Tuple[str, bool]: except ValueError: reverse_pointer = None invalid = True - logger.debug('ip_validate() ended with: {0}:{1}'.format(reverse_pointer, invalid)) + logger.debug('ip_validate() ended with: %s:%s', reverse_pointer, invalid) return (reverse_pointer, invalid) def v6_adjust(logger: logging.Logger, url: str) -> Tuple[Dict[str, str], str]: """ corner case for v6 addresses """ - logger.debug('v6_adjust({0})'.format(url)) + logger.debug('v6_adjust(%s)', url) headers = {'Connection': 'close', 'Accept-Encoding': 'gzip', 'User-Agent': USER_AGENT} @@ -1312,7 +1314,7 @@ def v6_adjust(logger: logging.Logger, url: str) -> Tuple[Dict[str, str], str]: # adjust headers and url in case we have an ipv6address if ipv6_chk(logger, url_dic['host']): headers['Host'] = url_dic['host'] - url = '{0}://[{1}]/{2}'.format(url_dic['proto'], url_dic['host'], url_dic['path']) + url = f'{url_dic['proto']}://[{url_dic['host']}]/{url_dic['path']}' logger.debug('v6_adjust() ended') return (headers, url) @@ -1320,7 +1322,7 @@ def v6_adjust(logger: logging.Logger, url: str) -> Tuple[Dict[str, str], str]: def ipv6_chk(logger: logging.Logger, address: str) -> bool: """ check if an address is ipv6 """ - logger.debug('ipv6_chk({0})'.format(address)) + logger.debug('ipv6_chk(%s)', address) try: # we need to set a host header and braces for ipv6 headers and @@ -1332,5 +1334,5 @@ def ipv6_chk(logger: logging.Logger, address: str) -> bool: except Exception: result = False - logger.debug('ipv6_chk() ended with {0}'.format(result)) + logger.debug('ipv6_chk() ended with %s', result) return result diff --git a/acme_srv/housekeeping.py b/acme_srv/housekeeping.py index 01649f4c..eb28ef0e 100644 --- a/acme_srv/housekeeping.py +++ b/acme_srv/housekeeping.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- -# pylint: disable=c0209 """ Housekeeping class """ from __future__ import print_function import csv @@ -37,7 +36,7 @@ def _accountlist_get(self) -> Dict[str, str]: try: result = self.dbstore.accountlist_get() except Exception as err_: - self.logger.critical('acme2certifier database error in Housekeeping._accountlist_get(): {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Housekeeping._accountlist_get(): %s', err_) result = None return result @@ -47,7 +46,7 @@ def _certificatelist_get(self) -> Dict[str, str]: try: result = self.dbstore.certificatelist_get() except Exception as err_: - self.logger.critical('acme2certifier database error in Housekeeping.certificatelist_get(): {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Housekeeping.certificatelist_get(): %s', err_) result = None return result @@ -68,7 +67,7 @@ def _cliaccounts_list(self, silent: bool = True) -> Dict[str, str]: try: result = self.dbstore.cliaccountlist_get() except Exception as err_: - self.logger.critical('acme2certifier database error in Housekeeping._cliaccounts_list(): {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Housekeeping._cliaccounts_list(): %s', err_) result = None if result and not silent: self._cliaccounts_format(result) @@ -78,14 +77,14 @@ def _cliaccounts_format(self, result_list: List[str]): """ format cliaccount report """ self.logger.debug('Housekeeping._cliaccounts_format()') try: - print('\n{0}|{1}|{2}|{3}|{4}|{5}'.format('Name'.ljust(15), 'Contact'.ljust(20), 'cliadm'.ljust(6), 'repadm'.ljust(6), 'certadm'.ljust(7), 'Created at'.ljust(20))) + print(f'\n{'Name'.ljust(15)}|{'Contact'.ljust(20)}|{'cliadm'.ljust(6)}|{'repadm'.ljust(6)}|{'certadm'.ljust(7)}|{'Created at'.ljust(20)}') print('-' * 78) for account in sorted(result_list, key=lambda k: k['id']): - print('{0}|{1}|{2}|{3}|{4}|{5}'.format(account['name'][:15].ljust(15), account['contact'][:20].ljust(20), str(bool(account['cliadmin'])).ljust(6), str(bool(account['reportadmin'])).ljust(6), str(bool(account['certificateadmin'])).ljust(7), account['created_at'].ljust(20))) + print(f'{account['name'][:15].ljust(15)}|{account['contact'][:20].ljust(20)}|{str(bool(account['cliadmin'])).ljust(6)}|{str(bool(account['reportadmin'])).ljust(6)}|{str(bool(account['certificateadmin'])).ljust(7)}|{account['created_at'].ljust(20)}') print('\n') except Exception as err: self.logger.error('acme2certifier error in Housekeeping._cliaccounts_format()') - self.logger.error('acme2certifier error in Housekeeping._cliaccounts_format(): {0}'.format(err)) + self.logger.error('acme2certifier error in Housekeeping._cliaccounts_format(): %s', err) def _report_get(self, payload: Dict[str, str]) -> Tuple[Dict[str, str], int, str, str]: """ create report """ @@ -130,7 +129,7 @@ def _clireport_get(self, payload: Dict[str, str], permissions_dic: Dict[str, str message = self.error_msg_dic['unauthorized'] detail = 'No permissions to download reports' - self.logger.debug('Housekeeping._clireport_get() returned with: {0}/{1}'.format(code, detail)) + self.logger.debug('Housekeeping._clireport_get() returned with: %s/%s', code, detail) return (code, message, detail, response_dic) def _config_load(self): @@ -240,7 +239,7 @@ def _data_dic_build(self, config_dic: Dict[str, str]) -> Dict[str, str]: try: data_dic.update(config_dic['permissions']) except Exception as err: - self.logger.error('acme2certifier error in Housekeeping._data_dic_build(): {0}'.format(err)) + self.logger.error('acme2certifier error in Housekeeping._data_dic_build(): %s', err) if 'jwk' in config_dic: data_dic['jwk'] = json.dumps(config_dic['jwk']) @@ -266,12 +265,12 @@ def _fieldlist_normalize(self, field_list: List[str], prefix: str) -> Dict[str, f_list = field.split('__') # items from selected list which do not have a table reference get prefix added if len(f_list) == 1: - new_field = '{0}.{1}'.format(prefix, field) + new_field = f'{prefix}.{field}' elif f_list[-2] == 'status' and len(f_list) >= 3: # status fields have one reference more - new_field = '{0}.{1}.{2}'.format(f_list[-3], f_list[-2], f_list[-1]) + new_field = f'{f_list[-3]}.{f_list[-2]}.{f_list[-1]}' else: - new_field = '{0}.{1}'.format(f_list[-2], f_list[-1]) + new_field = f'{f_list[-2]}.{f_list[-1]}' field_dic[field] = new_field return field_dic @@ -430,7 +429,7 @@ def _to_list(self, field_list: List[str], cert_list: List[str]) -> List[str]: # append list to output csv_list.append(tmp_list) - self.logger.debug('Housekeeping._to_list() ended with {0} entries'.format(len(csv_list))) + self.logger.debug('Housekeeping._to_list() ended with %s entries', len(csv_list)) return csv_list def accountreport_get(self, report_format: str = 'csv', report_name: str = None, nested: bool = False) -> List[str]: @@ -445,18 +444,18 @@ def accountreport_get(self, report_format: str = 'csv', report_name: str = None, account_list = self._convert_data(account_list) if account_list: - self.logger.debug('output to dump: {0}.{1}'.format(report_name, report_format)) + self.logger.debug('output to dump: %s.%s', report_name, report_format) if report_format == 'csv': self.logger.debug('Housekeeping.certreport_get() dump in csv-format') csv_list = self._to_list(field_list, account_list) account_list = csv_list if report_name: - self._csv_dump('{0}.{1}'.format(report_name, report_format), csv_list) + self._csv_dump(f'{report_name}.{report_format}', csv_list) elif report_format == 'json': if nested: account_list = self._to_acc_json(account_list) if report_name: - self._json_dump('{0}.{1}'.format(report_name, report_format), account_list) + self._json_dump(f'{report_name}.{report_format}', account_list) return account_list @@ -478,17 +477,17 @@ def certreport_get(self, report_format: str = 'csv', report_name: str = None) -> field_list.insert(8, 'certificate.expire_date') if cert_list: - self.logger.debug('Prepare output in: {0} format'.format(report_format)) + self.logger.debug('Prepare output in: %s format', report_format) if report_format == 'csv': self.logger.debug('Housekeeping.certreport_get(): Dump in csv-format') csv_list = self._to_list(field_list, cert_list) cert_list = csv_list if report_name: - self._csv_dump('{0}.{1}'.format(report_name, report_format), csv_list) + self._csv_dump(f'{report_name}.{report_format}', csv_list) elif report_format == 'json': self.logger.debug('Housekeeping.certreport_get(): Dump in json-format') if report_name: - self._json_dump('{0}.{1}'.format(report_name, report_format), cert_list) + self._json_dump(f'{report_name}.{report_format}', cert_list) else: self.logger.info('Housekeeping.certreport_get(): No dump just return report') @@ -519,10 +518,10 @@ def certificates_cleanup(self, uts: int = None, purge: bool = False, report_form if report_format == 'csv': self.logger.debug('Housekeeping.certificates_cleanup(): Dump in csv-format') csv_list = self._to_list(field_list, cert_list) - self._csv_dump('{0}.{1}'.format(report_name, report_format), csv_list) + self._csv_dump(f'{report_name}.{report_format}', csv_list) elif report_format == 'json': self.logger.debug('Housekeeping.certificates_cleanup(): Dump in json-format') - self._json_dump('{0}.{1}'.format(report_name, report_format), cert_list) + self._json_dump(f'{report_name}.{report_format}', cert_list) else: self.logger.debug('Housekeeping.certificates_cleanup(): No dump just return report') else: @@ -554,13 +553,13 @@ def cli_usermgr(self, config_dic: Dict[str, str]) -> int: self.logger.error('acme2certifier error in Housekeeping.cli_usermgr(): data incomplete') except Exception as err_: - self.logger.critical('acme2certifier database error in Housekeeping.cli_usermgr(): {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Housekeeping.cli_usermgr(): %s', err_) return result def authorizations_invalidate(self, uts: int = uts_now(), report_format: str = 'csv', report_name: str = None): """ authorizations cleanup based on expiry date """ - self.logger.debug('Housekeeping.authorization_invalidate({0})'.format(uts)) + self.logger.debug('Housekeeping.authorization_invalidate(%s)', uts) with Authorization(self.debug, None, self.logger) as authorization: # get expired orders @@ -576,10 +575,10 @@ def authorizations_invalidate(self, uts: int = uts_now(), report_format: str = ' if report_format == 'csv': self.logger.debug('Housekeeping.authorizations_invalidate(): Dump in csv-format') csv_list = self._to_list(field_list, authorization_list) - self._csv_dump('{0}.{1}'.format(report_name, report_format), csv_list) + self._csv_dump(f'{report_name}.{report_format}', csv_list) elif report_format == 'json': self.logger.debug('Housekeeping.authorizations_invalidate(): Dump in json-format') - self._json_dump('{0}.{1}'.format(report_name, report_format), authorization_list) + self._json_dump(f'{report_name}.{report_format}', authorization_list) else: self.logger.debug('Housekeeping.authorizations_invalidate(): No dump just return report') else: @@ -587,25 +586,25 @@ def authorizations_invalidate(self, uts: int = uts_now(), report_format: str = ' def dbversion_check(self, version: str = None): """ check database version """ - self.logger.debug('Housekeeping.dbversion_check({0})'.format(version)) + self.logger.debug('Housekeeping.dbversion_check(%s)', version) if version: try: (result, script_name) = self.dbstore.dbversion_get() except Exception as err_: - self.logger.critical('acme2certifier database error in Housekeeping.dbversion_check(): {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Housekeeping.dbversion_check(): %s', err_) result = None script_name = 'handler specific migration' if result != version: - self.logger.critical('acme2certifier database version mismatch in: version is {0} but should be {1}. Please run the "{2}" script'.format(result, version, script_name)) + self.logger.critical('acme2certifier database version mismatch in: version is %s but should be %s. Please run the "%s" script', result, version, script_name) else: - self.logger.debug('acme2certifier database version: {0} is upto date'.format(version)) + self.logger.debug('acme2certifier database version: %s is upto date', version) else: self.logger.critical('acme2certifier database version could not be verified in Housekeeping.dbversion_check()') def orders_invalidate(self, uts: int = uts_now(), report_format: str = 'csv', report_name: str = None) -> List[str]: """ orders cleanup based on expiry date""" - self.logger.debug('Housekeeping.orders_invalidate({0})'.format(uts)) + self.logger.debug('Housekeeping.orders_invalidate(%s)', uts) with Order(self.debug, None, self.logger) as order: # get expired orders @@ -621,10 +620,10 @@ def orders_invalidate(self, uts: int = uts_now(), report_format: str = 'csv', re if report_format == 'csv': self.logger.debug('Housekeeping.orders_invalidate(): Dump in csv-format') csv_list = self._to_list(field_list, order_list) - self._csv_dump('{0}.{1}'.format(report_name, report_format), csv_list) + self._csv_dump(f'{report_name}.{report_format}', csv_list) elif report_format == 'json': self.logger.debug('Housekeeping.orders_invalidate(): Dump in json-format') - self._json_dump('{0}.{1}'.format(report_name, report_format), order_list) + self._json_dump(f'{report_name}.{report_format}', order_list) else: self.logger.debug('Housekeeping.orders_invalidate(): No dump just return report') else: diff --git a/acme_srv/message.py b/acme_srv/message.py index fd8dbad7..5e8aae1a 100644 --- a/acme_srv/message.py +++ b/acme_srv/message.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# pylint: disable=c0209 +# pylint: disable=r0913 """ message class """ from __future__ import print_function import json @@ -49,7 +49,7 @@ def _name_rev_get(self, content: Dict[str, str]) -> str: try: account_list = self.dbstore.account_lookup('jwk', json.dumps(content['jwk'])) except Exception as err_: - self.logger.critical('acme2certifier database error in Message._name_rev_get(): {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Message._name_rev_get(): %s', err_) account_list = [] if account_list: if 'name' in account_list: @@ -59,7 +59,7 @@ def _name_rev_get(self, content: Dict[str, str]) -> str: else: kid = None - self.logger.debug('Message._name_rev_get() ended with kid: {0}'.format(kid)) + self.logger.debug('Message._name_rev_get() ended with kid: %s', kid) return kid def _name_get(self, content: Dict[str, str]) -> str: @@ -67,19 +67,19 @@ def _name_get(self, content: Dict[str, str]) -> str: self.logger.debug('Message._name_get()') if 'kid' in content: - self.logger.debug('kid: {0}'.format(content['kid'])) - kid = content['kid'].replace('{0}{1}'.format(self.server_name, self.path_dic['acct_path']), '') + self.logger.debug('kid: %s', content['kid']) + kid = content['kid'].replace(f'{self.server_name}{self.path_dic['acct_path']}', '') if '/' in kid: kid = None elif 'jwk' in content and 'url' in content: - if content['url'] == '{0}{1}'.format(self.server_name, self.path_dic['revocation_path']): + if content['url'] == f'{self.server_name}{self.path_dic['revocation_path']}': # this is needed for cases where we get a revocation message signed with account key but account name is missing kid = self._name_rev_get(content) else: kid = None else: kid = None - self.logger.debug('Message._name_get() returns: {0}'.format(kid)) + self.logger.debug('Message._name_get() returns: %s', kid) return kid def _check(self, skip_nonce_check: bool, skip_signature_check: bool, content: str, protected: Dict[str, str], use_emb_key: bool) -> Tuple[int, str, str, str]: @@ -114,13 +114,14 @@ def _check(self, skip_nonce_check: bool, skip_signature_check: bool, content: st message = error detail = error_detail - self.logger.debug('Message._check() ended with: {0}'.format(code)) + self.logger.debug('Message._check() ended with: %s', code) return (code, message, detail, account_name) # pylint: disable=R0914 def check(self, content: str, use_emb_key: bool = False, skip_nonce_check: bool = False) -> Tuple[int, str, str, Dict[str, str], Dict[str, str], str]: """ validate message """ self.logger.debug('Message.check()') + # disable signature check if paramter has been set if self.disable_dic['signature_check_disable']: self.logger.error('**** SIGNATURE_CHECK_DISABLE!!! Severe security issue ****') @@ -139,7 +140,7 @@ def check(self, content: str, use_emb_key: bool = False, skip_nonce_check: bool message = 'urn:ietf:params:acme:error:malformed' detail = error_detail - self.logger.debug('Message.check() ended with:{0}'.format(code)) + self.logger.debug('Message.check() ended with:%s', code) return (code, message, detail, protected, payload, account_name) def cli_check(self, content: str) -> Tuple[int, str, str, Dict[str, str], Dict[str, str], str, Dict[str, str]]: @@ -171,7 +172,7 @@ def cli_check(self, content: str) -> Tuple[int, str, str, Dict[str, str], Dict[s message = 'urn:ietf:params:acme:error:malformed' detail = error_detail - self.logger.debug('Message.check() ended with:{0}'.format(code)) + self.logger.debug('Message.check() ended with:%s', code) return (code, message, detail, protected, payload, account_name, permissions) def prepare_response(self, response_dic: Dict[str, str], status_dic: Dict[str, str], add_nonce: bool = True) -> Dict[str, str]: diff --git a/acme_srv/nonce.py b/acme_srv/nonce.py index 78243389..63924ac1 100644 --- a/acme_srv/nonce.py +++ b/acme_srv/nonce.py @@ -1,6 +1,5 @@ # -*- coding: utf-8 -*- """ Nonce class """ -# pylint: disable=c0209 from __future__ import print_function import uuid from typing import Tuple, Dict @@ -24,19 +23,19 @@ def __exit__(self, *args): def _check_and_delete(self, nonce: str) -> Tuple[int, str, str]: """ check if nonce exists and delete it """ - self.logger.debug('Nonce.nonce._check_and_delete({0})'.format(nonce)) + self.logger.debug('Nonce.nonce._check_and_delete(%s)', nonce) try: nonce_chk_result = self.dbstore.nonce_check(nonce) except Exception as err_: - self.logger.critical('acme2certifier database error during nonce_check() in Nonce._check_and_delete(): {0}'.format(err_)) + self.logger.critical('acme2certifier database error during nonce_check() in Nonce._check_and_delete(): %s', err_) nonce_chk_result = False if nonce_chk_result: try: self.dbstore.nonce_delete(nonce) except Exception as err_: - self.logger.critical('acme2certifier database error during nonce_delete() in Nonce._check_and_delete(): {0}'.format(err_)) + self.logger.critical('acme2certifier database error during nonce_delete() in Nonce._check_and_delete(): %s', err_) code = 200 message = None detail = None @@ -44,7 +43,7 @@ def _check_and_delete(self, nonce: str) -> Tuple[int, str, str]: code = 400 message = 'urn:ietf:params:acme:error:badNonce' detail = nonce - self.logger.debug('Nonce._check_and_delete() ended with:{0}'.format(code)) + self.logger.debug('Nonce._check_and_delete() ended with:%s', code) return (code, message, detail) def _new(self) -> str: @@ -61,18 +60,18 @@ def check(self, protected_decoded: Dict[str, str]) -> Tuple[int, str, str]: code = 400 message = 'urn:ietf:params:acme:error:badNonce' detail = 'NONE' - self.logger.debug('Nonce.check_nonce() ended with:{0}'.format(code)) + self.logger.debug('Nonce.check_nonce() ended with:%s', code) return (code, message, detail) def generate_and_add(self) -> str: """ generate new nonce and store it """ self.logger.debug('Nonce.nonce_generate_and_add()') nonce = self._new() - self.logger.debug('got nonce: {0}'.format(nonce)) - # self.logger.critical('foo') + + self.logger.debug('got nonce: %s', nonce) try: _id = self.dbstore.nonce_add(nonce) # lgtm [py/unused-local-variable] except Exception as err_: - self.logger.critical('acme2certifier database error in Nonce.generate_and_add(): {0}'.format(err_)) - self.logger.debug('Nonce.generate_and_add() ended with:{0}'.format(nonce)) + self.logger.critical('acme2certifier database error in Nonce.generate_and_add(): %s', err_) + self.logger.debug('Nonce.generate_and_add() ended with:%s', nonce) return nonce diff --git a/acme_srv/order.py b/acme_srv/order.py index b83bba2d..c89817af 100644 --- a/acme_srv/order.py +++ b/acme_srv/order.py @@ -1,6 +1,5 @@ # -*- coding: utf-8 -*- """ Order class """ -# pylint: disable=c0209 from __future__ import print_function import json from typing import List, Tuple, Dict @@ -38,7 +37,7 @@ def __exit__(self, *args): """ cose the connection at the end of the context """ def _auth_add(self, oid: str, payload: Dict[str, str], auth_dic: Dict[str, str]) -> str: - self.logger.debug('Order._auth_add({0})'.format(oid)) + self.logger.debug('Order._auth_add(%s)', oid) if oid: error = None @@ -57,16 +56,17 @@ def _auth_add(self, oid: str, payload: Dict[str, str], auth_dic: Dict[str, str]) auth['status'] = 'valid' self.dbstore.authorization_update(auth) except Exception as err_: - self.logger.critical('acme2certifier database error in Order._add() authz: {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Order._add() authz: %s', err_) else: error = self.error_msg_dic['malformed'] - self.logger.debug('Order._auth_add() ended with {0}'.format(error)) + self.logger.debug('Order._auth_add() ended with %s', error) return error def _add(self, payload: Dict[str, str], aname: str) -> Tuple[str, str, Dict[str, str], int]: """ add order request to database """ - self.logger.debug('Order._add({0})'.format(aname)) + self.logger.debug('Order._add(%s)', aname) + error = None auth_dic = {} order_name = generate_random_string(self.logger, 12) @@ -91,7 +91,7 @@ def _add(self, payload: Dict[str, str], aname: str) -> Tuple[str, str, Dict[str, # add order to db oid = self.dbstore.order_add(data_dic) except Exception as err_: - self.logger.critical('acme2certifier database error in Order._add() order: {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Order._add() order: %s', err_) oid = None if not error: @@ -111,7 +111,7 @@ def _config_headerinfo_config_load(self, config_dic: Dict[str, str]): try: self.header_info_list = json.loads(config_dic['Order']['header_info_list']) except Exception as err_: - self.logger.warning('Order._config_orderconfig_load() header_info_list failed with error: {0}'.format(err_)) + self.logger.warning('Order._config_orderconfig_load() header_info_list failed with error: %s', err_) self.logger.debug('Order._config_headerinfo_config_load() ended') @@ -130,12 +130,12 @@ def _config_orderconfig_load(self, config_dic: Dict[str, str]): try: self.retry_after = int(config_dic['Order']['retry_after_timeout']) except Exception: - self.logger.warning('Order._config_load(): failed to parse retry_after: {0}'.format(config_dic['Order']['retry_after_timeout'])) + self.logger.warning('Order._config_load(): failed to parse retry_after: %s', config_dic['Order']['retry_after_timeout']) if 'validity' in config_dic['Order']: try: self.validity = int(config_dic['Order']['validity']) except Exception: - self.logger.warning('Order._config_load(): failed to parse validity: {0}'.format(config_dic['Order']['validity'])) + self.logger.warning('Order._config_load(): failed to parse validity: %s', config_dic['Order']['validity']) self.logger.debug('Order._config_orderconfig_load() ended') @@ -153,7 +153,7 @@ def _config_load(self): try: self.authz_validity = int(config_dic['Authorization']['validity']) except Exception: - self.logger.warning('Order._config_load(): failed to parse authz validity: {0}'.format(config_dic['Authorization']['validity'])) + self.logger.warning('Order._config_load(): failed to parse authz validity: %s', config_dic['Authorization']['validity']) if 'Directory' in config_dic and 'url_prefix' in config_dic['Directory']: self.path_dic = {k: config_dic['Directory']['url_prefix'] + v for k, v in self.path_dic.items()} @@ -162,7 +162,8 @@ def _config_load(self): def _name_get(self, url: str) -> str: """ get ordername """ - self.logger.debug('Order._name_get({0})'.format(url)) + self.logger.debug('Order._name_get(%s)', url) + url_dic = parse_url(self.logger, url) order_name = url_dic['path'].replace(self.path_dic['order_path'], '') if '/' in order_name: @@ -172,7 +173,8 @@ def _name_get(self, url: str) -> str: def _identifiers_check(self, identifiers_list: List[str]) -> str: """ check validity of identifers in order """ - self.logger.debug('Order._identifiers_check({0})'.format(identifiers_list)) + self.logger.debug('Order._identifiers_check(%s)', identifiers_list) + error = None allowed_identifers = ['dns', 'ip'] @@ -191,16 +193,16 @@ def _identifiers_check(self, identifiers_list: List[str]) -> str: else: error = self.error_msg_dic['malformed'] - self.logger.debug('Order._identifiers_check() done with {0}:'.format(error)) + self.logger.debug('Order._identifiers_check() done with %s:', error) return error def _info(self, order_name: str) -> Dict[str, str]: """ list details of an order """ - self.logger.debug('Order._info({0})'.format(order_name)) + self.logger.debug('Order._info(%s)', order_name) try: result = self.dbstore.order_lookup('name', order_name) except Exception as err_: - self.logger.critical('acme2certifier database error in Order._info(): {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Order._info(): %s', err_) result = None return result @@ -218,7 +220,7 @@ def _header_info_lookup(self, header: str) -> str: if header_info_dic: result = json.dumps(header_info_dic) - self.logger.debug('Order._header_info_lookup() ended with: {0} keys in dic'.format(len(header_info_dic.keys()))) + self.logger.debug('Order._header_info_lookup() ended with: %s keys in dic', len(header_info_dic.keys())) return result def _finalize(self, order_name: str, payload: Dict[str, str], header: str = None) -> Tuple[int, str, str, str]: @@ -267,7 +269,8 @@ def _finalize(self, order_name: str, payload: Dict[str, str], header: str = None def _process(self, order_name: str, protected: Dict[str, str], payload: Dict[str, str], header: str = None) -> Tuple[int, str, str, str]: """ process order """ - self.logger.debug('Order._process({0})'.format(order_name)) + self.logger.debug('Order._process({%s)', order_name) + certificate_name = None message = None detail = None @@ -283,7 +286,7 @@ def _process(self, order_name: str, protected: Dict[str, str], payload: Dict[str try: cert_dic = self.dbstore.certificate_lookup('order__name', order_name) except Exception as err_: - self.logger.critical('acme2certifier database error in Order._process(): {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Order._process(): %s', err_) cert_dic = {} if cert_dic: # we found a cert in the database @@ -295,12 +298,12 @@ def _process(self, order_name: str, protected: Dict[str, str], payload: Dict[str message = self.error_msg_dic['malformed'] detail = 'url is missing in protected' - self.logger.debug('Order._process() ended with order:{0} {1}:{2}:{3}'.format(order_name, code, message, detail)) + self.logger.debug('Order._process() ended with order:%s %s:%s:%s', order_name, code, message, detail) return (code, message, detail, certificate_name) def _csr_process(self, order_name: str, csr: str, header_info: str) -> Tuple[int, str, str]: """ process certificate signing request """ - self.logger.debug('Order._csr_process({0})'.format(order_name)) + self.logger.debug('Order._csr_process(%s)', order_name) order_dic = self._info(order_name) @@ -327,18 +330,19 @@ def _csr_process(self, order_name: str, csr: str, header_info: str) -> Tuple[int else: code = 400 message = self.error_msg_dic['unauthorized'] - detail = 'order: {0} not found'.format(order_name) + detail = f'order: {order_name} not found' - self.logger.debug('Order._csr_process() ended with order:{0} {1}:{2}:{3}'.format(order_name, code, message, detail)) + self.logger.debug('Order._csr_process() ended with order:%s %s:{%s:%s', order_name, code, message, detail) return (code, message, detail) def _update(self, data_dic: Dict[str, str]): """ update order based on ordername """ - self.logger.debug('Order._update({0})'.format(data_dic)) + self.logger.debug('Order._update(%s)', data_dic) + try: self.dbstore.order_update(data_dic) except Exception as err_: - self.logger.critical('acme2certifier database error in Order._update(): {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Order._update(): %s', err_) def _order_dic_create(self, tmp_dic: Dict[str, str]) -> Dict[str, str]: """ create order dictionary """ @@ -357,19 +361,19 @@ def _order_dic_create(self, tmp_dic: Dict[str, str]) -> Dict[str, str]: try: order_dic['identifiers'] = json.loads(tmp_dic['identifiers']) except Exception: - self.logger.error('Order._order_dic_create(): error while parsing the identifier {0}'.format(tmp_dic['identifiers'])) + self.logger.error('Order._order_dic_create(): error while parsing the identifier %s', tmp_dic['identifiers']) self.logger.debug('Order._order_dic_create() ended') return order_dic def _authz_list_lookup(self, order_name: str) -> List[str]: """ lookup authorization list """ - self.logger.debug('Order._authz_list_lookup({0})'.format(order_name)) + self.logger.debug('Order._authz_list_lookup(%s)', order_name) try: authz_list = self.dbstore.authorization_lookup('order__name', order_name, ['name', 'status__name']) except Exception as err_: - self.logger.critical('acme2certifier database error in Order._authz_list_lookup(): {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Order._authz_list_lookup(): %s', err_) authz_list = [] self.logger.debug('Order._authz_list_lookup() ended') @@ -380,7 +384,7 @@ def _validity_list_create(self, authz_list: List[str], order_dic: Dict[str, str] validity_list = [] for authz in authz_list: if 'name' in authz: - order_dic["authorizations"].append('{0}{1}{2}'.format(self.server_name, self.path_dic['authz_path'], authz['name'])) + order_dic["authorizations"].append(f'{self.server_name}{self.path_dic['authz_path']}{authz['name']}') if 'status__name' in authz: if authz['status__name'] == 'valid': validity_list.append(True) @@ -396,7 +400,7 @@ def _validity_list_create(self, authz_list: List[str], order_dic: Dict[str, str] def _lookup(self, order_name: str) -> Dict[str, str]: """ sohw order details based on ordername """ - self.logger.debug('Order._validity_list_create({0})'.format(order_name)) + self.logger.debug('Order._validity_list_create(%s)', order_name) order_dic = {} tmp_dic = self._info(order_name) @@ -417,16 +421,16 @@ def _lookup(self, order_name: str) -> Dict[str, str]: def invalidate(self, timestamp: int = None) -> Tuple[List[str], List[str]]: """ invalidate orders """ - self.logger.debug('Order.invalidate({0})'.format(timestamp)) + self.logger.debug('Order.invalidate(%s)', timestamp) if not timestamp: timestamp = uts_now() - self.logger.debug('Order.invalidate(): set timestamp to {0}'.format(timestamp)) + self.logger.debug('Order.invalidate(): set timestamp to %s', timestamp) field_list = ['id', 'name', 'expires', 'identifiers', 'created_at', 'status__id', 'status__name', 'account__id', 'account__name', 'account__contact'] try: order_list = self.dbstore.orders_invalid_search('expires', timestamp, vlist=field_list, operant='<=') except Exception as err_: - self.logger.critical('acme2certifier database error in Order._invalidate() search: {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Order._invalidate() search: %s', err_) order_list = [] output_list = [] for order in order_list: @@ -438,9 +442,9 @@ def invalidate(self, timestamp: int = None) -> Tuple[List[str], List[str]]: try: self.dbstore.order_update(data_dic) except Exception as err_: - self.logger.critical('acme2certifier database error in Order._invalidate() upd: {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Order._invalidate() upd: %s', err_) - self.logger.debug('Order.invalidate() ended: {0} orders identified'.format(len(output_list))) + self.logger.debug('Order.invalidate() ended: %s orders identified', len(output_list)) return (field_list, output_list) def new(self, content: str) -> Dict[str, str]: @@ -455,15 +459,15 @@ def new(self, content: str) -> Dict[str, str]: if not error: code = 201 response_dic['header'] = {} - response_dic['header']['Location'] = '{0}{1}{2}'.format(self.server_name, self.path_dic['order_path'], order_name) + response_dic['header']['Location'] = f'{self.server_name}{self.path_dic['order_path']}{ order_name}' response_dic['data'] = {} response_dic['data']['identifiers'] = [] response_dic['data']['authorizations'] = [] response_dic['data']['status'] = 'pending' response_dic['data']['expires'] = expires - response_dic['data']['finalize'] = '{0}{1}{2}/finalize'.format(self.server_name, self.path_dic['order_path'], order_name) + response_dic['data']['finalize'] = f'{self.server_name}{self.path_dic['order_path']}{order_name}/finalize' for auth_name, value in auth_dic.items(): - response_dic['data']['authorizations'].append('{0}{1}{2}'.format(self.server_name, self.path_dic['authz_path'], auth_name)) + response_dic['data']['authorizations'].append(f'{self.server_name}{self.path_dic['authz_path']}{auth_name}') response_dic['data']['identifiers'].append(value) else: code = 400 @@ -473,7 +477,7 @@ def new(self, content: str) -> Dict[str, str]: status_dic = {'code': code, 'type': message, 'detail': detail} response_dic = self.message.prepare_response(response_dic, status_dic) - self.logger.debug('Order.new() returns: {0}'.format(json.dumps(response_dic))) + self.logger.debug('Order.new() returns: %s', json.dumps(response_dic)) return response_dic def _parse(self, protected: Dict[str, str], payload: Dict[str, str], header: str = None) -> Tuple[int, str, str, str, str]: @@ -501,7 +505,7 @@ def _parse(self, protected: Dict[str, str], payload: Dict[str, str], header: str message = self.error_msg_dic['malformed'] detail = 'url is missing in protected' - self.logger.debug('Order._parse() ended with code: {0}'.format(code)) + self.logger.debug('Order._parse() ended with code: %s', code) return (code, message, detail, certificate_name, order_name) def parse(self, content: str, header: str = None) -> Dict[str, str]: @@ -524,20 +528,20 @@ def parse(self, content: str, header: str = None) -> Dict[str, str]: if code == 200: # create response response_dic['header'] = {} - response_dic['header']['Location'] = '{0}{1}{2}'.format(self.server_name, self.path_dic['order_path'], order_name) + response_dic['header']['Location'] = f'{self.server_name}{self.path_dic['order_path']}{order_name}' response_dic['data'] = self._lookup(order_name) if 'status' in response_dic['data'] and response_dic['data']['status'] == 'processing': # set retry header as cert issuane is not completed. - response_dic['header']['Retry-After'] = '{0}'.format(self.retry_after) - response_dic['data']['finalize'] = '{0}{1}{2}/finalize'.format(self.server_name, self.path_dic['order_path'], order_name) + response_dic['header']['Retry-After'] = f'{self.retry_after}' + response_dic['data']['finalize'] = f'{self.server_name}{self.path_dic['order_path']}{order_name}/finalize' # add the path to certificate if order-status is ready # if certificate_name: if certificate_name and 'status' in response_dic['data'] and response_dic['data']['status'] == 'valid': - response_dic['data']['certificate'] = '{0}{1}{2}'.format(self.server_name, self.path_dic['cert_path'], certificate_name) + response_dic['data']['certificate'] = f'{self.server_name}{self.path_dic['cert_path']}{certificate_name}' # prepare/enrich response status_dic = {'code': code, 'type': message, 'detail': detail} response_dic = self.message.prepare_response(response_dic, status_dic) - self.logger.debug('Order.parse() returns: {0}'.format(json.dumps(response_dic))) + self.logger.debug('Order.parse() returns: %s', json.dumps(response_dic)) return response_dic diff --git a/acme_srv/renewalinfo.py b/acme_srv/renewalinfo.py index 27699834..d7f1e601 100644 --- a/acme_srv/renewalinfo.py +++ b/acme_srv/renewalinfo.py @@ -1,6 +1,5 @@ # -*- coding: utf-8 -*- """ Nonce class """ -# pylint: disable=c0209 from __future__ import print_function from typing import Dict from acme_srv.db_handler import DBstore @@ -44,13 +43,13 @@ def _config_load(self): try: self.renewaltreshold_pctg = float(config_dic['Renewalinfo']['renewaltreshold_pctg']) except Exception as err_: - self.logger.error('acme2certifier Renewalinfo._config_load() renewaltreshold_pctg parsing error: {0}'.format(err_)) + self.logger.error('acme2certifier Renewalinfo._config_load() renewaltreshold_pctg parsing error: %s', err_) if 'retry_after_timeout' in config_dic['Renewalinfo']: try: self.retry_after_timeout = int(config_dic['Renewalinfo']['retry_after_timeout']) except Exception as err_: - self.logger.error('acme2certifier Renewalinfo._config_load() retry_after_timeout parsing error: {0}'.format(err_)) + self.logger.error('acme2certifier Renewalinfo._config_load() retry_after_timeout parsing error: %s', err_) def _lookup(self, certid_hex: str) -> Dict[str, str]: """ lookup expiry dates based on renewal info """ @@ -59,7 +58,7 @@ def _lookup(self, certid_hex: str) -> Dict[str, str]: try: result_dic = self.dbstore.certificate_lookup('renewal_info', certid_hex, ('id', 'name', 'cert', 'cert_raw', 'expire_uts', 'issue_uts', 'created_at')) except Exception as err_: - self.logger.critical('acme2certifier database error in Renewalinfo._lookup(): {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Renewalinfo._lookup(): %s', err_) result_dic = None return result_dic @@ -102,13 +101,13 @@ def renewalinfo_string_get(self, url: str) -> str: self.logger.debug('Renewalinfo.renewal_string_get()') # we need to workaround a strange issue in win-acme - url = url.replace('{0}{1}'.format(self.server_name, self.path_dic['renewalinfo'].rstrip('/')), '') + url = url.replace(f'{self.server_name}{self.path_dic['renewalinfo'].rstrip('/')}', '') url = url.lstrip('/') # sanitize renewal_info string renewalinfo_string = string_sanitize(self.logger, url) - self.logger.debug('Renewalinfo.renewal_string_get() - renewalinfo_string: {0}'.format(renewalinfo_string)) + self.logger.debug('Renewalinfo.renewal_string_get() - renewalinfo_string: %s', renewalinfo_string) return renewalinfo_string def get(self, url: str) -> Dict[str, str]: @@ -130,7 +129,7 @@ def get(self, url: str) -> Dict[str, str]: # filter certificate and decode it response_dic['data'] = rewalinfo_dic # order status is processing - ratelimiting - response_dic['header'] = {'Retry-After': '{0}'.format(self.retry_after_timeout)} + response_dic['header'] = {'Retry-After': f'{self.retry_after_timeout}'.format()} else: response_dic['code'] = 404 response_dic['data'] = self.err_msg_dic['malformed'] @@ -142,7 +141,7 @@ def get(self, url: str) -> Dict[str, str]: def update(self, content: str) -> Dict[str, str]: """ update renewalinfo request """ - self.logger.debug('Renewalinfo.update({0})') + self.logger.debug('Renewalinfo.update()') # check message (code, _message, _detail, _protected, payload, _account_name) = self.message.check(content) diff --git a/acme_srv/signature.py b/acme_srv/signature.py index fa6ae983..7d717208 100644 --- a/acme_srv/signature.py +++ b/acme_srv/signature.py @@ -1,6 +1,5 @@ # -*- coding: utf-8 -*- """ Signature class """ -# pylint: disable=c0209 from __future__ import print_function from typing import Tuple, Dict from acme_srv.helper import signature_check, load_config, error_dic_get @@ -25,27 +24,27 @@ def __init__(self, debug: bool = False, srv_name: str = None, logger: object = N def _cli_jwk_load(self, kid: int) -> Dict[str, str]: """ get key for a specific account id """ - self.logger.debug('Signature._cli_jwk_load({0})'.format(kid)) + self.logger.debug('Signature._cli_jwk_load(%s)', kid) try: result = self.dbstore.cli_jwk_load(kid) except Exception as err_: - self.logger.critical('acme2certifier database error in Signature._cli_jwk_load(): {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Signature._cli_jwk_load(): %s', err_) result = None return result def _jwk_load(self, kid: str) -> Dict[str, str]: """ get key for a specific account id """ - self.logger.debug('Signature._jwk_load({0})'.format(kid)) + self.logger.debug('Signature._jwk_load(%s)', kid) try: result = self.dbstore.jwk_load(kid) except Exception as err_: - self.logger.critical('acme2certifier database error in Signature._jwk_load(): {0}'.format(err_)) + self.logger.critical('acme2certifier database error in Signature._jwk_load(): %s', err_) result = None return result def cli_check(self, aname: str, content: str) -> Tuple[str, str, None]: """ signature check against cli key """ - self.logger.debug('Signature.cli_check({0})'.format(aname)) + self.logger.debug('Signature.cli_check(%s)', aname) result = False error = None @@ -62,12 +61,12 @@ def cli_check(self, aname: str, content: str) -> Tuple[str, str, None]: else: error = self.err_msg_dic['malformed'] - self.logger.debug('Signature.cli_check() ended with: {0}:{1}'.format(result, error)) + self.logger.debug('Signature.cli_check() ended with: %s:%s', result, error) return (result, error, None) def check(self, aname: str, content: str, use_emb_key: bool = False, protected: Dict[str, str] = None) -> Tuple[str, str, None]: """ signature check """ - self.logger.debug('Signature.check({0})'.format(aname)) + self.logger.debug('Signature.check(%s)', aname) result = False if content: error = None @@ -90,7 +89,7 @@ def check(self, aname: str, content: str, use_emb_key: bool = False, protected: else: error = self.err_msg_dic['malformed'] - self.logger.debug('Signature.check() ended with: {0}:{1}'.format(result, error)) + self.logger.debug('Signature.check() ended with: %s:%s', result, error) return (result, error, None) def eab_check(self, content: str, mac_key: str) -> Tuple[str, str]: diff --git a/acme_srv/trigger.py b/acme_srv/trigger.py index b175d05e..f7e46521 100644 --- a/acme_srv/trigger.py +++ b/acme_srv/trigger.py @@ -44,7 +44,7 @@ def _certname_lookup(self, cert_pem: str) -> List[str]: csr_pubkey = csr_pubkey_get(self.logger, cert['csr']) if csr_pubkey == cert_pubkey: result_list.append({'cert_name': cert['name'], 'order_name': cert['order__name']}) - self.logger.debug('Trigger._certname_lookup() ended with: {0}'.format(result_list)) + self.logger.debug('Trigger._certname_lookup() ended with: %s', result_list) return result_list @@ -61,9 +61,9 @@ def _config_load(self): try: self.cahandler = ca_handler_module.CAhandler except Exception as err_: - self.logger.critical('Certificate._config_load(): loading CAhandler failed with err: {0}'.format(err_)) + self.logger.critical('Certificate._config_load(): loading CAhandler failed with err: %s', err_) - self.logger.debug('ca_handler: {0}'.format(ca_handler_module)) + self.logger.debug('ca_handler: %s', ca_handler_module) self.logger.debug('Certificate._config_load() ended.') def _cert_store(self, cert_bundle: str, cert_raw: str) -> Tuple[int, str, str]: @@ -82,13 +82,13 @@ def _cert_store(self, cert_bundle: str, cert_raw: str) -> Tuple[int, str, str]: try: self.dbstore.certificate_add(data_dic) except Exception as err_: - self.logger.critical('acme2certifier database error in trigger._payload_process() add: {0}'.format(err_)) + self.logger.critical('acme2certifier database error in trigger._payload_process() add: %s', err_) if 'order_name' in cert and cert['order_name']: try: # update order status to 5 (valid) self.dbstore.order_update({'name': cert['order_name'], 'status': 'valid'}) except Exception as err_: - self.logger.critical('acme2certifier database error in trigger._payload_process() upd: {0}'.format(err_)) + self.logger.critical('acme2certifier database error in trigger._payload_process() upd: %s', err_) code = 200 message = 'OK' detail = None @@ -118,7 +118,7 @@ def _payload_process(self, payload: str) -> Tuple[int, str, str]: message = 'payload malformed' detail = None - self.logger.debug('Trigger._payload_process() ended with: {0} {1}'.format(code, message)) + self.logger.debug('Trigger._payload_process() ended with: %s %s', code, message) return (code, message, detail) def parse(self, content: str) -> Dict[str, str]: @@ -151,5 +151,5 @@ def parse(self, content: str) -> Dict[str, str]: if detail: response_dic['data']['detail'] = detail - self.logger.debug('Trigger.parse() returns: {0}'.format(json.dumps(response_dic))) + self.logger.debug('Trigger.parse() returns: %s', json.dumps(response_dic)) return response_dic diff --git a/examples/db_handler/django_handler.py b/examples/db_handler/django_handler.py index d2ba7ff8..b8a487b3 100644 --- a/examples/db_handler/django_handler.py +++ b/examples/db_handler/django_handler.py @@ -1,7 +1,7 @@ #!/usr/bin/python # -*- coding: utf-8 -*- """ django handler for acme2certifier """ -# pylint: disable=c0209, c0413, c0415, c0401, e0401, e1123, r0904, w0611 +# pylint: disable=c0413, c0415, c0401, e0401, e1123, r0904, w0611 from __future__ import print_function import os import sys @@ -35,37 +35,37 @@ def __init__(self, _debug: bool = False, logger: object = None): def _account_getinstance(self, aname: str) -> QuerySet[Account]: """ get account instance """ - self.logger.debug('DBStore._account_getinstance({0})'.format(aname)) + self.logger.debug('DBStore._account_getinstance(%s)', aname) return Account.objects.get(name=aname) def _authorization_getinstance(self, name: str) -> QuerySet[Authorization]: """ get authorization instance """ - self.logger.debug('DBStore._authorization_getinstance({0})'.format(name)) + self.logger.debug('DBStore._authorization_getinstance(%s)', name) return Authorization.objects.get(name=name) def _modify_key(self, mkey: str, operant: str) -> str: """ quick hack """ - self.logger.debug('DBStore._modify_key({0}/{1})'.format(mkey, operant)) + self.logger.debug('DBStore._modify_key(%s/%s)', mkey, operant) if operant == '<=': - mkey = '{0}__lte'.format(mkey) + mkey = f'{mkey}__lte' - self.logger.debug('DBStore._modify_key() ended with: {0}'.format(mkey)) + self.logger.debug('DBStore._modify_key() ended with: %s', mkey) return mkey def _order_getinstance(self, value: str = id, mkey: id = 'id') -> QuerySet[Order]: """ get order instance """ - self.logger.debug('DBStore._order_getinstance({0}:{1})'.format(mkey, value)) + self.logger.debug('DBStore._order_getinstance(%s:%s)', mkey, value) return Order.objects.get(**{mkey: value}) def _status_getinstance(self, value: str, mkey: str = 'id') -> QuerySet[Status]: """ get account instance """ - self.logger.debug('DBStore._status_getinstance({0}:{1})'.format(mkey, value)) + self.logger.debug('DBStore._status_getinstance(%s:%s)', mkey, value) return Status.objects.get(**{mkey: value}) def account_add(self, data_dic: Dict[str, str]) -> Tuple[str, bool]: """ add account in database """ - self.logger.debug('DBStore.account_add({0})'.format(data_dic)) + self.logger.debug('DBStore.account_add(%s)', data_dic) account_list = self.account_lookup('jwk', data_dic['jwk']) if account_list: created = False @@ -78,7 +78,7 @@ def account_add(self, data_dic: Dict[str, str]) -> Tuple[str, bool]: def account_lookup(self, mkey: str, value: str) -> Dict[str, str]: """ search account for a given id """ - self.logger.debug('DBStore.account_lookup({0}:{1})'.format(mkey, value)) + self.logger.debug('DBStore.account_lookup(%s:%s)', mkey, value) account_dict = Account.objects.filter(**{mkey: value}).values('id', 'jwk', 'name', 'contact', 'alg', 'created_at')[:1] if account_dict: result = account_dict[0] @@ -88,16 +88,16 @@ def account_lookup(self, mkey: str, value: str) -> Dict[str, str]: def account_delete(self, aname): """ add account in database """ - self.logger.debug('DBStore.account_delete({0})'.format(aname)) + self.logger.debug('DBStore.account_delete(%s)', aname) result = Account.objects.filter(name=aname).delete() return result def account_update(self, data_dic: Dict[str, str]) -> int: """ update existing account """ - self.logger.debug('DBStore.account_update({0})'.format(data_dic)) + self.logger.debug('DBStore.account_update(%s)', data_dic) obj, _created = Account.objects.update_or_create(name=data_dic['name'], defaults=data_dic) obj.save() - self.logger.debug('acct_id({0})'.format(obj.id)) + self.logger.debug('acct_id(%s)', obj.id) return obj.id def accountlist_get(self) -> Tuple[List[str], QuerySet[Account]]: @@ -116,7 +116,7 @@ def accountlist_get(self) -> Tuple[List[str], QuerySet[Account]]: def authorization_add(self, data_dic: Dict[str, str]) -> int: """ add authorization to database """ - self.logger.debug('DBStore.authorization_add({0})'.format(data_dic)) + self.logger.debug('DBStore.authorization_add(%s)', data_dic) # get some instance for DB insert if 'order' in data_dic: @@ -127,18 +127,18 @@ def authorization_add(self, data_dic: Dict[str, str]) -> int: # add authorization obj, _created = Authorization.objects.update_or_create(name=data_dic['name'], defaults=data_dic) obj.save() - self.logger.debug('auth_id({0})'.format(obj.id)) + self.logger.debug('auth_id(%s)', obj.id) return obj.id def authorization_lookup(self, mkey: str, value: str, vlist: List[str] = ('type', 'value')) -> QuerySet[Authorization]: """ search account for a given id """ - self.logger.debug('authorization_lookup({0}:{1}:{2})'.format(mkey, value, vlist)) + self.logger.debug('authorization_lookup(%s:%s:%s)', mkey, value, vlist) authz_list = Authorization.objects.filter(**{mkey: value}).values(*vlist)[::1] return authz_list def authorizations_expired_search(self, mkey: str, value: str, vlist: List[str] = ('id', 'name', 'expires', 'identifiers', 'created_at', 'status__id', 'status__name', 'account__id', 'account__name', 'acccount__contact'), operant: str = 'LIKE') -> QuerySet[Authorization]: """ search order table for a certain key/value pair """ - self.logger.debug('DBStore.authorizations_invalid_search(column:{0}, pattern:{1})'.format(mkey, value)) + self.logger.debug('DBStore.authorizations_invalid_search(column:%s, pattern:%s)', mkey, value) mkey = self._modify_key(mkey, operant) @@ -147,7 +147,7 @@ def authorizations_expired_search(self, mkey: str, value: str, vlist: List[str] def authorization_update(self, data_dic: Dict[str, str]) -> int: """ update existing authorization """ - self.logger.debug('DBStore.authorization_update({0})'.format(data_dic)) + self.logger.debug('DBStore.authorization_update(%s)', data_dic) # get some instance for DB insert if 'status' in data_dic: data_dic['status'] = self._status_getinstance(data_dic['status'], 'name') @@ -163,12 +163,12 @@ def authorization_update(self, data_dic: Dict[str, str]) -> int: obj, _created = Authorization.objects.update_or_create(name=data_dic['name'], defaults=data_dic) obj.save() - self.logger.debug('auth_id({0})'.format(obj.id)) + self.logger.debug('auth_id(%s)', obj.id) return obj.id def cahandler_add(self, data_dic: Dict[str, str]) -> Tuple[str, bool]: """ add cahandler to database """ - self.logger.debug('DBStore.cahandler_add({0})'.format(data_dic)) + self.logger.debug('DBStore.cahandler_add(%s)', data_dic) cahandler_list = self.cahandler_lookup('name', data_dic['name']) if cahandler_list: created = False @@ -181,7 +181,7 @@ def cahandler_add(self, data_dic: Dict[str, str]) -> Tuple[str, bool]: def cahandler_lookup(self, mkey: str, value: str) -> Dict[str, str]: """ search cahandler for a given id """ - self.logger.debug('DBStore.cahandler_lookup({0}:{1})'.format(mkey, value)) + self.logger.debug('DBStore.cahandler_lookup(%s:%s)', mkey, value) cahandler_dict = Cahandler.objects.filter(**{mkey: value}).values('name', 'value1', 'value2', 'created_at')[:1] if cahandler_dict: result = cahandler_dict[0] @@ -191,7 +191,7 @@ def cahandler_lookup(self, mkey: str, value: str) -> Dict[str, str]: def challenge_add(self, value: str, mtype: str, data_dic: Dict[str, str]) -> int: """ add challenge to database """ - self.logger.debug('DBStore.challenge_add({0}:{1})'.format(value, mtype)) + self.logger.debug('DBStore.challenge_add(%s:%s)', value, mtype) # get order instance for DB insert data_dic['authorization'] = self._authorization_getinstance(data_dic['authorization']) @@ -208,8 +208,8 @@ def challenge_add(self, value: str, mtype: str, data_dic: Dict[str, str]) -> int obj, _created = Challenge.objects.update_or_create(name=data_dic['name'], defaults=data_dic) obj.save() - self.logger.debug('cid({0})'.format(obj.id)) - self.logger.debug('DBStore.challenge_add({0}:{1}:{2})'.format(value, mtype, obj.id)) + self.logger.debug('cid(%s)', obj.id) + self.logger.debug('DBStore.challenge_add(%s:%s:%s)', value, mtype, obj.id) return obj.id def certificate_add(self, data_dic: Dict[str, str]) -> int: @@ -222,12 +222,12 @@ def certificate_add(self, data_dic: Dict[str, str]) -> int: # add certificate/CSR obj, _created = Certificate.objects.update_or_create(name=data_dic['name'], defaults=data_dic) obj.save() - self.logger.debug('DBStore.certificate_add() ended with :{0}'.format(obj.id)) + self.logger.debug('DBStore.certificate_add() ended with :%s', obj.id) return obj.id def certificate_account_check(self, account_name: str, certificate: str) -> str: """ check issuer against certificate """ - self.logger.debug('DBStore.certificate_account_check({0})'.format(account_name)) + self.logger.debug('DBStore.certificate_account_check(%s)', account_name) result = None certificate_list = self.certificate_lookup('cert_raw', certificate, ['name', 'order__name', 'order__account__name']) @@ -241,12 +241,12 @@ def certificate_account_check(self, account_name: str, certificate: str) -> str: # no account name given (message signed with domain key result = certificate_list['order'] - self.logger.debug('DBStore.certificate_account_check() ended with: {0}'.format(result)) + self.logger.debug('DBStore.certificate_account_check() ended with: %s', result) return result def certificate_delete(self, mkey: str, value: str) -> QuerySet[Certificate]: """ delete certificate from table """ - self.logger.debug('DBStore.certificate_delete({0}:{1})'.format(mkey, value)) + self.logger.debug('DBStore.certificate_delete(%s:%s)', mkey, value) Certificate.objects.filter(**{mkey: value}).delete() def certificatelist_get(self) -> Tuple[List[str], List[QuerySet[Certificate]]]: @@ -261,7 +261,7 @@ def certificatelist_get(self) -> Tuple[List[str], List[QuerySet[Certificate]]]: def certificate_lookup(self, mkey: str, value: str, vlist: List[str] = ('name', 'csr', 'cert', 'order__name')) -> Dict[str, str]: """ search certificate based on "something" """ - self.logger.debug('DBStore.certificate_lookup({0}:{1})'.format(mkey, value)) + self.logger.debug('DBStore.certificate_lookup(%s:%s)', mkey, value) certificate_list = Certificate.objects.filter(**{mkey: value}).values(*vlist)[:1] if certificate_list: result = certificate_list[0] @@ -270,18 +270,18 @@ def certificate_lookup(self, mkey: str, value: str, vlist: List[str] = ('name', del result['order__name'] else: result = None - self.logger.debug('DBStore.certificate_lookup() ended with: {0}'.format(result)) + self.logger.debug('DBStore.certificate_lookup() ended with: %s', result) return result def certificates_search(self, mkey: str, value: str, vlist: List[str] = ('name', 'csr', 'cert', 'order__name'), operator=None) -> QuerySet[Certificate]: """ search certificate based on "something" """ - self.logger.debug('DBStore.certificates_search({0}:{1})'.format(mkey, value)) + self.logger.debug('DBStore.certificates_search(%s:%s)', mkey, value) mkey = self._modify_key(mkey, operator) return Certificate.objects.filter(**{mkey: value}).values(*vlist) def challenge_lookup(self, mkey: str, value: str, vlist: List[str] = ('type', 'token', 'status__name')) -> Dict[str, str]: """ search account for a given id """ - self.logger.debug('DBStore.challenge_lookup({0}:{1})'.format(mkey, value)) + self.logger.debug('DBStore.challenge_lookup(%s:%s)', mkey, value) challenge_list = Challenge.objects.filter(**{mkey: value}).values(*vlist)[:1] if challenge_list: result = challenge_list[0] @@ -297,12 +297,12 @@ def challenge_lookup(self, mkey: str, value: str, vlist: List[str] = ('type', 't def challenges_search(self, mkey: str, value: str, vlist: List[str] = ('name', 'type', 'cert', 'status__name', 'token')) -> QuerySet[Challenge]: """ search challenges based on "something" """ - self.logger.debug('DBStore.challenges_search({0}:{1})'.format(mkey, value)) + self.logger.debug('DBStore.challenges_search(%s:%s)', mkey, value) return Challenge.objects.filter(**{mkey: value}).values(*vlist) def challenge_update(self, data_dic: Dict[str, str]): """ update challenge """ - self.logger.debug('challenge_update({0})'.format(data_dic)) + self.logger.debug('challenge_update(%s)', data_dic) # replace orderstatus with an instance if 'status' in data_dic: data_dic['status'] = self._status_getinstance(data_dic['status'], 'name') @@ -311,20 +311,20 @@ def challenge_update(self, data_dic: Dict[str, str]): def cli_jwk_load(self, aname: str) -> Dict[str, str]: """ looad account informatino and build jwk key dictionary from cliaccounts teable """ - self.logger.debug('DBStore.cli_jwk_load({0})'.format(aname)) + self.logger.debug('DBStore.cli_jwk_load(%s)', aname) account_dict = Cliaccount.objects.filter(name=aname).values('jwk')[:1] jwk_dict = {} if account_dict: try: jwk_dict = json.loads(account_dict[0]['jwk'].decode()) except Exception as _err: - self.logger.error('DBStore.cli_jwk_load(): error: {0}'.format(_err)) + self.logger.error('DBStore.cli_jwk_load(): error: %s', _err) jwk_dict = json.loads(account_dict[0]['jwk']) return jwk_dict def cli_permissions_get(self, aname: str) -> Dict[str, str]: """ looad account informations and build jwk key dictionary from cliaccounts teable """ - self.logger.debug('DBStore.cli_jwk_load({0})'.format(aname)) + self.logger.debug('DBStore.cli_jwk_load(%s)', aname) account_dict = Cliaccount.objects.filter(name=aname).values('reportadmin', 'cliadmin', 'certificateadmin')[:1] permissions_dict = {} if account_dict: @@ -339,12 +339,12 @@ def dbversion_get(self) -> Tuple[Dict[str, str], str]: result = version_list[0] else: result = None - self.logger.debug('DBStore.dbversion_get() ended with {0}'.format(result)) + self.logger.debug('DBStore.dbversion_get() ended with %s', result) return (result, 'tools/django_update.py') def hkparameter_add(self, data_dic: Dict[str, str]): """ add housekeeping paramter to database """ - self.logger.debug('DBStore.hkparameter_add({0})'.format(data_dic)) + self.logger.debug('DBStore.hkparameter_add(%s)', data_dic) obj, _created = Housekeeping.objects.update_or_create(name=data_dic['name'], defaults=data_dic) obj.save() @@ -356,12 +356,12 @@ def hkparameter_get(self, parameter: str) -> str: result = result_list[0] else: result = None - self.logger.debug('DBStore.hkparameter_get() ended with {0}'.format(result)) + self.logger.debug('DBStore.hkparameter_get() ended with %s', result) return result def jwk_load(self, aname: str) -> Dict[str, str]: """ looad account informatino and build jwk key dictionary """ - self.logger.debug('DBStore.jwk_load({0})'.format(aname)) + self.logger.debug('DBStore.jwk_load(%s)', aname) account_dict = Account.objects.filter(name=aname).values('jwk', 'alg')[:1] jwk_dict = {} if account_dict: @@ -376,7 +376,7 @@ def nonce_add(self, nonce: str) -> int: """ check if nonce is in datbase in: nonce return: rowid """ - self.logger.debug('DBStore.nonce_add({0})'.format(nonce)) + self.logger.debug('DBStore.nonce_add(%s)', nonce) obj = Nonce(nonce=nonce) obj.save() return obj.id @@ -385,19 +385,19 @@ def nonce_check(self, nonce: str) -> bool: """ ceck if nonce is in datbase in: nonce return: true in case nonce exit, otherwise false """ - self.logger.debug('DBStore.nonce_check({0})'.format(nonce)) + self.logger.debug('DBStore.nonce_check(%s)', nonce) nonce_list = Nonce.objects.filter(nonce=nonce).values('nonce')[:1] return bool(nonce_list) def nonce_delete(self, nonce: str): """ delete nonce from datbase in: nonce """ - self.logger.debug('DBStore.nonce_delete({0})'.format(nonce)) + self.logger.debug('DBStore.nonce_delete(%s)', nonce) Nonce.objects.filter(nonce=nonce).delete() def order_add(self, data_dic: Dict[str, str]) -> int: """ add order to database """ - self.logger.debug('DBStore.order_add({0})'.format(data_dic)) + self.logger.debug('DBStore.order_add(%s)', data_dic) # replace accountid with instance data_dic['account'] = self._account_getinstance(data_dic['account']) @@ -405,12 +405,12 @@ def order_add(self, data_dic: Dict[str, str]) -> int: data_dic['status'] = self._status_getinstance(data_dic['status'], 'id') obj, _created = Order.objects.update_or_create(name=data_dic['name'], defaults=data_dic) obj.save() - self.logger.debug('order_id({0})'.format(obj.id)) + self.logger.debug('order_id(%s)', obj.id) return obj.id def order_lookup(self, mkey: str, value: str, vlist: List[str] = ('name', 'notbefore', 'notafter', 'identifiers', 'status__name', 'account__name', 'expires')) -> Dict[str, str]: """ search orders for a given ordername """ - self.logger.debug('order_lookup({0}:{1})'.format(mkey, value)) + self.logger.debug('order_lookup(%s:%s)', mkey, value) order_list = Order.objects.filter(**{mkey: value}).values(*vlist)[:1] if order_list: result = order_list[0] @@ -426,7 +426,7 @@ def order_lookup(self, mkey: str, value: str, vlist: List[str] = ('name', 'notbe def order_update(self, data_dic: Dict[str, str]): """ update order """ - self.logger.debug('order_update({0})'.format(data_dic)) + self.logger.debug('order_update(%s)', data_dic) # replace orderstatus with an instance if 'status' in data_dic: data_dic['status'] = self._status_getinstance(data_dic['status'], 'name') @@ -435,6 +435,6 @@ def order_update(self, data_dic: Dict[str, str]): def orders_invalid_search(self, mkey: str, value: str, vlist: List[str] = ('id', 'name', 'expires', 'identifiers', 'created_at', 'status__id', 'status__name', 'account__id', 'account__name', 'acccount__contact'), operant='LIKE') -> QuerySet[Order]: """ search order table for a certain key/value pair """ - self.logger.debug('DBStore.orders_search(column:{0}, pattern:{1})'.format(mkey, value)) + self.logger.debug('DBStore.orders_search(column:%s, pattern:%s)', mkey, value) mkey = self._modify_key(mkey, operant) return Order.objects.filter(**{mkey: value}, status__id__gt=1).values(*vlist) diff --git a/examples/db_handler/wsgi_handler.py b/examples/db_handler/wsgi_handler.py index 53704522..ab71f338 100644 --- a/examples/db_handler/wsgi_handler.py +++ b/examples/db_handler/wsgi_handler.py @@ -1,5 +1,5 @@ +# pylint: disable=c0302, r0904, w0102 # -*- coding: utf-8 -*- -# pylint: disable=c0209, c0302, r0904, r0915 """ wsgi handler for acme2certifier """ from __future__ import print_function import sqlite3 @@ -46,26 +46,26 @@ def __init__(self, debug: bool = False, logger: object = None, db_name: str = No def _account_search(self, column: str, string: str) -> List[str]: """ search account table for a certain key/value pair """ - self.logger.debug('DBStore._account_search(column:{0}, pattern:{1})'.format(column, string)) + self.logger.debug('DBStore._account_search(column:%s, pattern:%s)', column, string) self._db_open() try: - pre_statement = 'SELECT * from account WHERE {0} LIKE ?'.format(column) + pre_statement = f'SELECT * from account WHERE {column} LIKE ?' self.cursor.execute(pre_statement, [string]) result = self.cursor.fetchone() except Exception as err: - self.logger.error('DBStore._account_search(column:{0}, pattern:{1}) failed with err: {2}'.format(column, string, err)) + self.logger.error('DBStore._account_search(column:%s, pattern:%s) failed with err: %s', column, string, err) self._db_close() - self.logger.debug('DBStore._account_search() ended with: {0}'.format(bool(result))) + self.logger.debug('DBStore._account_search() ended with: %s', bool(result)) return result def _authorization_search(self, column: str, string: str) -> List[str]: """ search account table for a certain key/value pair """ - self.logger.debug('DBStore._authorization_search(column:{0}, pattern:{1})'.format(column, string)) + self.logger.debug('DBStore._authorization_search(column:%s, pattern:%s)', column, string) if column == 'name': self.logger.debug('rename name to authorization.name') column = 'authorization.name' self._db_open() - pre_statement = '''SELECT + pre_statement = f'''SELECT authorization.*, orders.id as orders__id, orders.name as order__name, @@ -76,34 +76,33 @@ def _authorization_search(self, column: str, string: str) -> List[str]: LEFT JOIN orders on orders.id = authorization.order_id LEFT JOIN status on status.id = authorization.status_id LEFT JOIN account on account.id = orders.account_id - WHERE {0} LIKE ?'''.format(column) + WHERE {column} LIKE ?''' try: self.cursor.execute(pre_statement, [string]) result = self.cursor.fetchall() except Exception as err: - self.logger.error('DBStore._authorization_search(column:{0}, pattern:{1}) failed with err: {2}'.format(column, string, err)) + self.logger.error('DBStore._authorization_search(column:%s, pattern:%s) failed with err: %s', column, string, err) self._db_close() self.logger.debug('DBStore._authorization_search() ended') return result def _cahandler_search(self, column: str, string: str) -> List[str]: """ search cahandler table for a certain key/value pair """ - self.logger.debug('DBStore._cahandler_search(column:{0}, pattern:{1})'.format(column, string)) + self.logger.debug('DBStore._cahandler_search(column:%s, pattern:%s)', column, string) self._db_open() - pre_statement = '''SELECT cahandler.* from cahandler WHERE {0} LIKE ?'''.format(column) + pre_statement = f'''SELECT cahandler.* from cahandler WHERE {column} LIKE ?''' try: self.cursor.execute(pre_statement, [string]) result = self.cursor.fetchone() except Exception as err: - self.logger.error('DBStore._cahandler_search(column:{0}, pattern:{1}) failed with err: {2}'.format(column, string, err)) + self.logger.error('DBStore._cahandler_search(column:%s, pattern:%s) failed with err: %s', column, string, err) result = None self._db_close() self.logger.debug('DBStore._cahandler_search() ended') return result def _certificate_account_check(self, account_name: str, certificate_dic: Dict[str, str], order_dic: Dict[str, str]) -> List[str]: - self.logger.debug('DBStore._certificate_account_check({0})'.format(account_name)) - + self.logger.debug('DBStore._certificate_account_check(%s)', account_name) result = None if account_name: # if there is an acoount name validate it against the account_name from db-query @@ -116,13 +115,12 @@ def _certificate_account_check(self, account_name: str, certificate_dic: Dict[st # no account name given (message signed with domain key) result = certificate_dic['order__name'] self.logger.debug('message signed with domain key') - - self.logger.debug('DBStore._certificate_account_check() ended with: {0}'.format(result)) + self.logger.debug('DBStore._certificate_account_check() ended with: %s', result) return result def _certificate_insert(self, data_dic: Dict[str, str]) -> int: """ insert certificate """ - self.logger.debug('_certificate_insert() for {0}'.format(data_dic['name'])) + self.logger.debug('_certificate_insert() for %s', data_dic['name']) # change order name to id but tackle cases where we cannot do this try: data_dic['order'] = dict_from_row(self._order_search('name', data_dic['order']))['id'] @@ -139,15 +137,14 @@ def _certificate_insert(self, data_dic: Dict[str, str]) -> int: else: self.cursor.execute('''INSERT INTO Certificate(name, csr, order_id, header_info) VALUES(:name, :csr, :order, :header_info)''', data_dic) self._db_close() - self.logger.debug('insert new entry for {0}'.format(data_dic['name'])) + self.logger.debug('insert new entry for %s', data_dic['name']) rid = self.cursor.lastrowid - self.logger.debug('_certificate_insert() ended with: {0}'.format(rid)) + self.logger.debug('_certificate_insert() ended with: %s', rid) return rid def _certificate_update(self, data_dic: Dict[str, str], exists: Dict[str, str]) -> int: - self.logger.debug('_certificate_update() for {0} id:{1}'.format(data_dic['name'], dict_from_row(exists)['id'])) - + self.logger.debug('_certificate_update() for %s id:%s', data_dic['name'], dict_from_row(exists)['id']) self._db_open() if 'error' in data_dic: self.cursor.execute('''UPDATE Certificate SET error = :error, poll_identifier = :poll_identifier WHERE name = :name''', data_dic) @@ -162,20 +159,18 @@ def _certificate_update(self, data_dic: Dict[str, str], exists: Dict[str, str]) self.cursor.execute('''UPDATE Certificate SET cert = :cert, cert_raw = :cert_raw, issue_uts = :issue_uts, expire_uts = :expire_uts, renewal_info = :renewal_info, poll_identifier = :poll_identifier, replaced = :replaced, header_info = :header_info WHERE name = :name''', data_dic) self._db_close() rid = dict_from_row(exists)['id'] - - self.logger.debug('_certificate_update() ended with: {0}'.format(rid)) + self.logger.debug('_certificate_update() ended with: %s', rid) return rid def _certificate_search(self, column: str, string: str) -> Dict[str, str]: """ search certificate table for a certain key/value pair """ - self.logger.debug('DBStore._certificate_search(column:{0}, pattern:{1})'.format(column, string)) + self.logger.debug('DBStore._certificate_search(column:%s, pattern:%s)', column, string) self._db_open() - if column != 'order__name': - column = 'certificate.{0}'.format(column) - self.logger.debug('modified column to {0}'.format(column)) + column = f'certificate.{column}' + self.logger.debug(f'modified column to {column}') - pre_statement = '''SELECT certificate.*, + pre_statement = f'''SELECT certificate.*, orders.id as order__id, orders.name as order__name, orders.status_id as order__status_id, @@ -183,18 +178,18 @@ def _certificate_search(self, column: str, string: str) -> Dict[str, str]: from certificate INNER JOIN orders on orders.id = certificate.order_id INNER JOIN account on account.id = orders.account_id - WHERE {0} LIKE ?'''.format(column) + WHERE {column} LIKE ?''' self.cursor.execute(pre_statement, [string]) result = self.cursor.fetchone() self._db_close() - self.logger.debug('DBStore._certificate_search() ended with: {0}'.format(bool(result))) + self.logger.debug('DBStore._certificate_search() ended with: %s', bool(result)) return result def _challenge_search(self, column: str, string: str) -> List[str]: """ search challenge table for a certain key/value pair """ - self.logger.debug('DBStore._challenge_search(column:{0}, pattern:{1})'.format(column, string)) + self.logger.debug('DBStore._challenge_search(column:%s, pattern:%s)', column, string) self._db_open() - pre_statement = ''' + pre_statement = f''' SELECT challenge.*, status.id as status__id, @@ -211,29 +206,29 @@ def _challenge_search(self, column: str, string: str) -> List[str]: INNER JOIN authorization on authorization.id = challenge.authorization_id INNER JOIN orders on orders.id = authorization.order_id INNER JOIN account on account.id = orders.account_id - WHERE challenge.{0} LIKE ?'''.format(column) + WHERE challenge.{column} LIKE ?''' try: self.cursor.execute(pre_statement, [string]) result = self.cursor.fetchone() except Exception as err: - self.logger.error('DBStore._challenge_search(column:{0}, pattern:{1}) failed with err: {2}'.format(column, string, err)) + self.logger.error('DBStore._challenge_search(column:%s, pattern:%s) failed with err: %s', column, string, err) self._db_close() self.logger.debug('DBStore._challenge_search() ended') return result def _cliaccount_search(self, column: str, string: str) -> Dict[str, str]: """ search account table for a certain key/value pair """ - self.logger.debug('DBStore._cliaccount_search(column:{0}, pattern:{1})'.format(column, string)) + self.logger.debug('DBStore._cliaccount_search(column:%s, pattern:%s)', column, string) self._db_open() try: - pre_statement = 'SELECT * from cliaccount WHERE {0} LIKE ?'.format(column) + pre_statement = f'SELECT * from cliaccount WHERE {column} LIKE ?' self.cursor.execute(pre_statement, [string]) result = self.cursor.fetchone() except Exception as err: - self.logger.error('DBStore._cliaccount_search(column:{0}, pattern:{1}) failed with err: {2}'.format(column, string, err)) + self.logger.error('DBStore._cliaccount_search(column:%s, pattern:%s) failed with err: %s', column, string, err) result = None self._db_close() - self.logger.debug('DBStore._account_search() ended with: {0}'.format(bool(result))) + self.logger.debug('DBStore._account_search() ended with: %s', bool(result)) return result def _db_close(self): @@ -245,7 +240,7 @@ def _db_close(self): def _db_create(self): """ create the database if dos not exist """ - self.logger.debug('DBStore._db_create({0})'.format(self.db_name)) + self.logger.debug('DBStore._db_create(%s)', self.db_name) self._db_open() # create nonce table self.logger.debug('create nonce') @@ -304,7 +299,7 @@ def _db_create(self): END ''') - self.cursor.execute('''INSERT OR IGNORE INTO housekeeping (name, value) VALUES ("dbversion", "{0}")'''.format(__dbversion__)) + self.cursor.execute(f'''INSERT OR IGNORE INTO housekeeping (name, value) VALUES ("dbversion", "{__dbversion__}")''') self.cursor.execute(''' CREATE TABLE "cahandler" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(15) NOT NULL UNIQUE, "value1" text, "value2" text, "created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL) ''') @@ -455,7 +450,7 @@ def _db_update_status(self): self.logger.debug('DBStore._db_update_status()') # add additional values to status table - pre_statement = 'SELECT * from status WHERE status.{0} LIKE ?'.format('name') + pre_statement = 'SELECT * from status WHERE status.name LIKE ?' self.cursor.execute(pre_statement, ['deactivated']) if not self.cursor.fetchone(): self.logger.info('adding additional status') @@ -466,10 +461,10 @@ def _db_update_status(self): def _order_search(self, column: str, string: str) -> List[str]: """ search order table for a certain key/value pair """ - self.logger.debug('DBStore._order_search(column:{0}, pattern:{1})'.format(column, string)) + self.logger.debug('DBStore._order_search(column:%s, pattern:%s)', column, string) self._db_open() - pre_statement = ''' + pre_statement = f''' SELECT orders.*, status.name as status__name, @@ -479,21 +474,21 @@ def _order_search(self, column: str, string: str) -> List[str]: from orders INNER JOIN status on status.id = orders.status_id INNER JOIN account on account.id = orders.account_id - WHERE orders.{0} LIKE ?'''.format(column) + WHERE orders.{column} LIKE ?''' try: self.cursor.execute(pre_statement, [string]) result = self.cursor.fetchone() except Exception as err: - self.logger.error('DBStore._order_search(column:{0}, pattern:{1}) failed with err: {2}'.format(column, string, err)) + self.logger.error('DBStore._order_search(column:%s, pattern:%s) failed with err: %s', column, string, err) self._db_close() self.logger.debug('DBStore._order_search() ended') return result def _status_search(self, column: str, string: str) -> Tuple[str, bool]: """ search status table for a certain key/value pair """ - self.logger.debug('DBStore._status_search(column:{0}, pattern:{1})'.format(column, string)) + self.logger.debug('DBStore._status_search(column:%s, pattern:%s)', column, string) self._db_open() - pre_statement = 'SELECT * from status WHERE status.{0} LIKE ?'.format(column) + pre_statement = f'SELECT * from status WHERE status.{column} LIKE ?' self.cursor.execute(pre_statement, [string]) result = self.cursor.fetchone() self._db_close() @@ -502,7 +497,7 @@ def _status_search(self, column: str, string: str) -> Tuple[str, bool]: def account_add(self, data_dic): """ add account in database """ - self.logger.debug('DBStore.account_add({0})'.format(data_dic)) + self.logger.debug('DBStore.account_add(%s)', data_dic) # add eab_kid field if not existing if 'eab_kid' not in data_dic: @@ -516,7 +511,7 @@ def account_add(self, data_dic): if bool(exists): # update aname = exists[1] - self.logger.debug('account exists: {0} id: {1}'.format(aname, exists[0])) + self.logger.debug('account exists: %s id: %s', aname, exists[0]) self.cursor.execute('''UPDATE ACCOUNT SET alg = :alg, jwk = :jwk, contact = :contact WHERE jwk = :jwk''', data_dic) else: # insert @@ -530,7 +525,7 @@ def account_add(self, data_dic): def account_delete(self, aname: str) -> bool: """ add account in database """ - self.logger.debug('DBStore.account_delete({0})'.format(aname)) + self.logger.debug('DBStore.account_delete(%s)', aname) self._db_open() pre_statement = 'DELETE FROM account WHERE name LIKE ?' self.cursor.execute(pre_statement, [aname]) @@ -541,7 +536,7 @@ def account_delete(self, aname: str) -> bool: def account_lookup(self, column: str, string: str) -> Dict[str, str]: """ lookup account table for a certain key/value pair and return id""" - self.logger.debug('DBStore.account_lookup(column:{0}, pattern:{1})'.format(column, string)) + self.logger.debug('DBStore.account_lookup(column:%s, pattern:%s)', column, string) try: result = dict_from_row(self._account_search(column, string)) except Exception as _err: @@ -553,7 +548,7 @@ def account_lookup(self, column: str, string: str) -> Dict[str, str]: def account_update(self, data_dic: Dict[str, str]) -> List[str]: """ update existing account """ - self.logger.debug('DBStore.account_update({0})'.format(data_dic)) + self.logger.debug('DBStore.account_update(%s)', data_dic) try: lookup = dict_from_row(self._account_search('name', data_dic['name'])) @@ -647,17 +642,17 @@ def accountlist_get(self) -> Tuple[List[str], List[str]]: def authorization_add(self, data_dic: Dict[str, str]) -> int: """ add authorization to database """ - self.logger.debug('DBStore.authorization_add({0})'.format(data_dic)) + self.logger.debug('DBStore.authorization_add(%s)', data_dic) self._db_open() self.cursor.execute('''INSERT INTO authorization(name, order_id, type, value) VALUES(:name, :order, :type, :value)''', data_dic) rid = self.cursor.lastrowid self._db_close() - self.logger.debug('DBStore.authorization_add() ended with: {0}'.format(rid)) + self.logger.debug('DBStore.authorization_add() ended with: %s', rid) return rid def authorization_lookup(self, column: str, string: str, vlist: List[str] = ('type', 'value')) -> List[str]: """ search account for a given id """ - self.logger.debug('DBStore.authorization_lookup(column:{0}, pattern:{1})'.format(column, string)) + self.logger.debug('DBStore.authorization_lookup(column:%s, pattern:%s)', column, string) try: lookup = self._authorization_search(column, string) @@ -676,9 +671,9 @@ def authorization_lookup(self, column: str, string: str, vlist: List[str] = ('ty def authorizations_expired_search(self, column: str, string: str, vlist: List[str] = ('id', 'name', 'expires', 'value', 'created_at', 'token', 'status__id', 'status__name', 'order__id', 'order__name'), operant='LIKE') -> List[str]: """ search order table for a certain key/value pair """ - self.logger.debug('DBStore.authorizations_expired_search(column:{0}, pattern:{1})'.format(column, string)) + self.logger.debug('DBStore.authorizations_expired_search(column:%s, pattern:%s)', column, string) self._db_open() - pre_statement = '''SELECT + pre_statement = f'''SELECT authorization.*, status.name as status__name, status.id as status__id, @@ -687,7 +682,7 @@ def authorizations_expired_search(self, column: str, string: str, vlist: List[st FROM authorization LEFT JOIN status on status.id = authorization.status_id LEFT JOIN orders on orders.id = authorization.order_id - WHERE status__name NOT LIKE 'expired' AND authorization.{0} {1} ?'''.format(column, operant) + WHERE status__name NOT LIKE 'expired' AND authorization.{column} {operant} ?''' self.cursor.execute(pre_statement, [string]) rows = self.cursor.fetchall() @@ -707,7 +702,7 @@ def authorizations_expired_search(self, column: str, string: str, vlist: List[st def authorization_update(self, data_dic: Dict[str, str]) -> List[str]: """ update existing authorization """ - self.logger.debug('DBStore.authorization_update({0})'.format(data_dic)) + self.logger.debug('DBStore.authorization_update(%s)', data_dic) lookup = self._authorization_search('name', data_dic['name']) if lookup: @@ -733,7 +728,7 @@ def authorization_update(self, data_dic: Dict[str, str]) -> List[str]: def certificate_account_check(self, account_name: str, certificate: str) -> List[str]: """ check issuer against certificate """ - self.logger.debug('DBStore.certificate_account_check({0})'.format(account_name)) + self.logger.debug('DBStore.certificate_account_check(%s)', account_name) # search certificate table to get the order-id certificate_dic = self.certificate_lookup('cert_raw', certificate, ['name', 'order__name']) @@ -751,12 +746,12 @@ def certificate_account_check(self, account_name: str, certificate: str) -> List else: self.logger.debug('order_dic empty') - self.logger.debug('DBStore.certificate_account_check() ended with: {0}'.format(result)) + self.logger.debug('DBStore.certificate_account_check() ended with: %s', result) return result def cahandler_add(self, data_dic: Dict[str, str]) -> int: """ add cahandler values to database """ - self.logger.debug('DBStore.cahandler_add({0})'.format(data_dic)) + self.logger.debug('DBStore.cahandler_add(%s)', data_dic) if 'value2' not in data_dic: data_dic['value2'] = '' @@ -765,7 +760,7 @@ def cahandler_add(self, data_dic: Dict[str, str]) -> int: self._db_open() if bool(exists): # update - self.logger.debug('parameter existss: {0} id: {1}'.format('name', data_dic['name'])) + self.logger.debug(f'parameter exists: name id: {data_dic['name']}') self.cursor.execute('''UPDATE CAHANDLER SET name = :name, value1 = :value1, 'value2' = :value2 WHERE name = :name''', data_dic) rid = exists['id'] else: @@ -774,12 +769,12 @@ def cahandler_add(self, data_dic: Dict[str, str]) -> int: rid = self.cursor.lastrowid self._db_close() - self.logger.debug('DBStore.authorization_add() ended with: {0}'.format(rid)) + self.logger.debug('DBStore.authorization_add() ended with: %s', rid) return rid def cahandler_lookup(self, column: str, string: str, vlist: List[str] = ['name', 'value1', 'value2', 'created_at']) -> Dict[str, str]: """ lookup ca handler """ - self.logger.debug('DBStore.cahandler_lookup(column:{0}, pattern:{1})'.format(column, string)) + self.logger.debug('DBStore.cahandler_lookup(column:%s, pattern:%s)', column, string) try: lookup = dict_from_row(self._cahandler_search(column, string)) @@ -798,13 +793,13 @@ def cahandler_lookup(self, column: str, string: str, vlist: List[str] = ['name', def cliaccount_add(self, data_dic: Dict[str, str]) -> int: """ add cli user """ - self.logger.debug('DBStore.cliuser_add({0})'.format(data_dic['name'])) + self.logger.debug('DBStore.cliuser_add(%s)', data_dic['name']) exists = self._cliaccount_search('name', data_dic['name']) rid = None self._db_open() if bool(exists): - self.logger.debug('cliaccount existss: {0} id: {1}'.format('name', data_dic['name'])) + self.logger.debug('cliaccount exists: name id: %s', data_dic['name']) if 'contact' not in data_dic: data_dic['contact'] = exists['contact'] if 'jwk' not in data_dic: @@ -815,19 +810,19 @@ def cliaccount_add(self, data_dic: Dict[str, str]) -> int: self.cursor.execute('''INSERT INTO cliaccount(name, jwk, contact, reportadmin, cliadmin, certificateadmin) VALUES(:name, :jwk, :contact, :reportadmin, :cliadmin, :certificateadmin)''', data_dic) rid = self.cursor.lastrowid self._db_close() - self.logger.debug('DBStore.cliaccount_add() ended with: {0}'.format(rid)) + self.logger.debug('DBStore.cliaccount_add() ended with: %s', rid) return rid def cliaccount_delete(self, data_dic: Dict[str, str]): """ add cli user """ - self.logger.debug('DBStore.cliaccount_delete({0})'.format(data_dic['name'])) + self.logger.debug('DBStore.cliaccount_delete(%s)', data_dic['name']) exists = self._cliaccount_search('name', data_dic['name']) if exists: self._db_open() self.cursor.execute('''DELETE FROM cliaccount WHERE name=:name''', data_dic) self._db_close() else: - self.logger.error('DBStore.cliaccount_delete() failed for kid: {0}'.format(data_dic['name'])) + self.logger.error('DBStore.cliaccount_delete() failed for kid: %s', data_dic['name']) self.logger.debug('DBStore.cliaccount_delete() ended') def cliaccountlist_get(self) -> List[str]: @@ -857,7 +852,7 @@ def cliaccountlist_get(self) -> List[str]: def certificate_add(self, data_dic: Dict[str, str]) -> int: """ add csr/certificate to database """ - self.logger.debug('DBStore.certificate_add({0})'.format(data_dic['name'])) + self.logger.debug('DBStore.certificate_add(%s)', data_dic['name']) # check if we alredy have an entry for the key exists = self._certificate_search('name', data_dic['name']) @@ -873,14 +868,14 @@ def certificate_add(self, data_dic: Dict[str, str]) -> int: else: rid = self._certificate_insert(data_dic) - self.logger.debug('DBStore.certificate_add() ended with: {0}'.format(rid)) + self.logger.debug('DBStore.certificate_add() ended with: %s', rid) return rid def certificate_delete(self, mkey: str, string: str) -> Tuple[List[str], List[str]]: """ delete certificate from table """ - self.logger.debug('DBStore.certificate_delete({0}:{1})'.format(mkey, string)) + self.logger.debug('DBStore.certificate_delete(%s:%s)', mkey, string) self._db_open() - pre_statement = '''DELETE from certificate WHERE {0} = ?'''.format(mkey) + pre_statement = f'''DELETE from certificate WHERE {mkey} = ?''' self.cursor.execute(pre_statement, [string]) self._db_close() @@ -930,7 +925,7 @@ def certificatelist_get(self) -> Tuple[List[str], List[str]]: def certificate_lookup(self, column: str, string: str, vlist: List[str] = ('name', 'csr', 'cert', 'order__name')) -> Dict[str, str]: """ search certificate based on "something" """ - self.logger.debug('DBstore.certificate_lookup({0}:{1})'.format(column, string)) + self.logger.debug('DBstore.certificate_lookup(%s:%s)', column, string) try: lookup = dict_from_row(self._certificate_search(column, string)) @@ -946,19 +941,19 @@ def certificate_lookup(self, column: str, string: str, vlist: List[str] = ('name else: result = {} - self.logger.debug('DBStore.certificate_lookup() ended with: {0}'.format(result)) + self.logger.debug('DBStore.certificate_lookup() ended with: %s', result) return result def certificates_search(self, column: str, string: str, vlist: List[str] = ('name', 'csr', 'cert', 'order__name'), operant='LIKE') -> List[str]: """ search certificate table for a certain key/value pair """ - self.logger.debug('DBStore.certificates_search(column:{0}, pattern:{1})'.format(column, string)) + self.logger.debug('DBStore.certificates_search(column:%s, pattern:%s)', column, string) self._db_open() if column == 'order__status_id': column = 'orders.status_id' - self.logger.debug('modified column to {0}'.format(column)) + self.logger.debug('modified column to %s', column) - pre_statement = '''SELECT certificate.*, + pre_statement = f'''SELECT certificate.*, orders.id as order__id, orders.name as order__name, orders.status_id as order__status_id, @@ -966,7 +961,7 @@ def certificates_search(self, column: str, string: str, vlist: List[str] = ('nam from certificate INNER JOIN orders on orders.id = certificate.order_id INNER JOIN account on account.id = orders.account_id - WHERE {0} {1} ?'''.format(column, operant) + WHERE {column} {operant} ?''' self.cursor.execute(pre_statement, [string]) rows = self.cursor.fetchall() @@ -987,10 +982,10 @@ def certificates_search(self, column: str, string: str, vlist: List[str] = ('nam def challenges_search(self, column: str, string: str, vlist: List[str] = ('name', 'type', 'status__name', 'token')) -> List[str]: """ search challenge table for a certain key/value pair """ - self.logger.debug('DBStore._challenge_search(column:{0}, pattern:{1})'.format(column, string)) + self.logger.debug('DBStore._challenge_search(column:%s, pattern:%s)', column, string) self._db_open() - pre_statement = ''' + pre_statement = f''' SELECT challenge.*, status.id as status__id, @@ -1007,7 +1002,7 @@ def challenges_search(self, column: str, string: str, vlist: List[str] = ('name' INNER JOIN authorization on authorization.id = challenge.authorization_id INNER JOIN orders on orders.id = authorization.order_id INNER JOIN account on account.id = orders.account_id - WHERE {0} LIKE ?'''.format(column) + WHERE {column} LIKE ?''' self.cursor.execute(pre_statement, [string]) rows = self.cursor.fetchall() @@ -1028,7 +1023,7 @@ def challenges_search(self, column: str, string: str, vlist: List[str] = ('name' def challenge_add(self, value: str, mtype: str, data_dic: Dict[str, str]) -> int: """ add challenge to database """ - self.logger.debug('DBStore.challenge_add({0}:{1})'.format(value, mtype)) + self.logger.debug('DBStore.challenge_add(%s:%s)', value, mtype) authorization = self.authorization_lookup('name', data_dic['authorization'], ['id']) if "status" not in data_dic: @@ -1046,7 +1041,7 @@ def challenge_add(self, value: str, mtype: str, data_dic: Dict[str, str]) -> int def challenge_lookup(self, column: str, string: str, vlist: List[str] = ('type', 'token', 'status__name')) -> Dict[str, str]: """ search account for a given id """ - self.logger.debug('DBStore.challenge_lookup({0}:{1})'.format(column, string)) + self.logger.debug('DBStore.challenge_lookup(%s:%s)', column, string) try: lookup = dict_from_row(self._challenge_search(column, string)) @@ -1063,12 +1058,12 @@ def challenge_lookup(self, column: str, string: str, vlist: List[str] = ('type', else: result[ele] = lookup[ele] - self.logger.debug('DBStore.challenge_lookup() ended with:{0}'.format(result)) + self.logger.debug('DBStore.challenge_lookup() ended with:%s', result) return result def challenge_update(self, data_dic: Dict[str, str]): """ update challenge """ - self.logger.debug('DBStore.challenge_update({0})'.format(data_dic)) + self.logger.debug('DBStore.challenge_update(%s)', data_dic) lookup = self._challenge_search('name', data_dic['name']) lookup = dict_from_row(lookup) @@ -1090,17 +1085,17 @@ def challenge_update(self, data_dic: Dict[str, str]): def cli_jwk_load(self, aname: str) -> Dict[str, str]: """ looad cliaccount information and build jwk key dictionary """ - self.logger.debug('DBStore.cli_jwk_load({0})'.format(aname)) + self.logger.debug('DBStore.cli_jwk_load(%s)', aname) account_list = self._cliaccount_search('name', aname) jwk_dict = {} if account_list: jwk_dict = json.loads(account_list[2]) - self.logger.debug('DBStore.jwk_load() ended with: {0}'.format(jwk_dict)) + self.logger.debug('DBStore.jwk_load() ended with: %s', jwk_dict) return jwk_dict def cli_permissions_get(self, aname: str) -> Dict[str, str]: """ looad cliaccount information and build jwk key dictionary """ - self.logger.debug('DBStore.cli_jwk_load({0})'.format(aname)) + self.logger.debug('DBStore.cli_jwk_load(%s)', aname) account_list = self._cliaccount_search('name', aname) account_dic = {} if account_list: @@ -1141,9 +1136,9 @@ def db_update(self): self._db_update_cliaccount() # version update - self.logger.info('update dbversion to {0}'.format(__dbversion__)) - self.cursor.execute('''INSERT OR IGNORE INTO housekeeping (name, value) VALUES ("dbversion", "{0}")'''.format(__dbversion__)) - self.cursor.execute('''UPDATE housekeeping SET value = "{0}" WHERE name="dbversion"'''.format(__dbversion__)) + self.logger.info(f'update dbversion to {__dbversion__}') + self.cursor.execute(f'''INSERT OR IGNORE INTO housekeeping (name, value) VALUES ("dbversion", "{__dbversion__}")''') + self.cursor.execute(f'''UPDATE housekeeping SET value = "{__dbversion__}" WHERE name="dbversion"''') self._db_close() self.logger.debug('DBStore.db_update() ended') @@ -1152,7 +1147,7 @@ def dbversion_get(self) -> Tuple[List[str], str]: """ get db version from housekeeping table """ self.logger.debug('DBStore.dbversion_get()') self._db_open() - pre_statement = 'SELECT value from housekeeping WHERE housekeeping.{0} LIKE ?'.format('name') + pre_statement = 'SELECT value from housekeeping WHERE housekeeping.name LIKE ?' self.cursor.execute(pre_statement, ['dbversion']) query = list(self.cursor.fetchone()) if query: @@ -1161,7 +1156,7 @@ def dbversion_get(self) -> Tuple[List[str], str]: self.logger.error('DBStore.dbversion_get() lookup failed') result = None self._db_close() - self.logger.debug('DBStore.dbversion_get() ended with {0}'.format(result)) + self.logger.debug('DBStore.dbversion_get() ended with %s', result) return (result, 'tools/db_update.py') def hkparameter_add(self, data_dic: Dict[str, str]) -> Tuple[str, bool]: @@ -1173,7 +1168,7 @@ def hkparameter_add(self, data_dic: Dict[str, str]) -> Tuple[str, bool]: self._db_open() if bool(exists): # update - self.logger.debug('parameter exists: {0}'.format(data_dic['name'])) + self.logger.debug(f'parameter exists: {data_dic['name']}') self.cursor.execute('''UPDATE HOUSEKEEPING SET name = :name, value = :value WHERE name = :name''', data_dic) else: # insert @@ -1188,7 +1183,7 @@ def hkparameter_get(self, parameter: str) -> List[str]: """ get parameter from housekeeping table """ self.logger.debug('DBStore.hkparameter_get()') self._db_open() - pre_statement = 'SELECT value from housekeeping WHERE housekeeping.{0} LIKE ?'.format('name') + pre_statement = 'SELECT value from housekeeping WHERE housekeeping.name LIKE ?' self.cursor.execute(pre_statement, [parameter]) try: query = list(self.cursor.fetchone()) @@ -1200,25 +1195,25 @@ def hkparameter_get(self, parameter: str) -> List[str]: else: result = None self._db_close() - self.logger.debug('DBStore.hkparameter_get() ended with {0}'.format(result)) + self.logger.debug('DBStore.hkparameter_get() ended with %s', result) return result def jwk_load(self, aname: str) -> Dict[str, str]: """ looad account informatino and build jwk key dictionary """ - self.logger.debug('DBStore.jwk_load({0})'.format(aname)) + self.logger.debug('DBStore.jwk_load(%s)', aname) account_list = self._account_search('name', aname) jwk_dict = {} if account_list: jwk_dict = json.loads(account_list[3]) jwk_dict['alg'] = account_list[2] - self.logger.debug('DBStore.jwk_load() ended with: {0}'.format(jwk_dict)) + self.logger.debug('DBStore.jwk_load() ended with: %s', jwk_dict) return jwk_dict def nonce_add(self, nonce: str) -> int: """ check if nonce is in datbase in: nonce return: rowid """ - self.logger.debug('DBStore.nonce_add({0})'.format(nonce)) + self.logger.debug('DBStore.nonce_add(%s)', nonce) self._db_open() self.cursor.execute('''INSERT INTO nonce(nonce) VALUES(:nonce)''', {'nonce': nonce}) rid = self.cursor.lastrowid @@ -1230,7 +1225,7 @@ def nonce_check(self, nonce: str) -> bool: """ ceck if nonce is in datbase in: nonce return: true in case nonce exit, otherwise false """ - self.logger.debug('DBStore.nonce_check({0})'.format(nonce)) + self.logger.debug('DBStore.nonce_check(%s)', nonce) self._db_open() self.cursor.execute('''SELECT nonce FROM nonce WHERE nonce=:nonce''', {'nonce': nonce}) result = bool(self.cursor.fetchone()) @@ -1241,7 +1236,7 @@ def nonce_check(self, nonce: str) -> bool: def nonce_delete(self, nonce: str): """ delete nonce from datbase in: nonce """ - self.logger.debug('DBStore.nonce_delete({0})'.format(nonce)) + self.logger.debug('DBStore.nonce_delete(%s)', nonce) self._db_open() self.cursor.execute('''DELETE FROM nonce WHERE nonce=:nonce''', {'nonce': nonce}) self._db_close() @@ -1249,7 +1244,7 @@ def nonce_delete(self, nonce: str): def order_add(self, data_dic: Dict[str, str]) -> int: """ add order to database """ - self.logger.debug('DBStore.order_add({0})'.format(data_dic)) + self.logger.debug('DBStore.order_add(%s)', data_dic) if 'notbefore' not in data_dic: data_dic['notbefore'] = '' @@ -1270,7 +1265,7 @@ def order_add(self, data_dic: Dict[str, str]) -> int: def order_lookup(self, column: str, string: str, vlist: List[str] = ('notbefore', 'notafter', 'identifiers', 'expires', 'status__name')) -> Dict[str, str]: """ search orders for a given ordername """ - self.logger.debug('order_lookup({0}:{1})'.format(column, string)) + self.logger.debug('order_lookup(%s:%s)', column, string) try: lookup = dict_from_row(self._order_search(column, string)) @@ -1290,12 +1285,12 @@ def order_lookup(self, column: str, string: str, vlist: List[str] = ('notbefore' else: result[ele] = lookup[ele] - self.logger.debug('DBStore.order_lookup() ended with: {0}'.format(result)) + self.logger.debug('DBStore.order_lookup() ended with: %s', result) return result def order_update(self, data_dic: Dict[str, str]): """ update order """ - self.logger.debug('order_update({0})'.format(data_dic)) + self.logger.debug('order_update(%s)', data_dic) if 'status' in data_dic: data_dic['status'] = dict_from_row(self._status_search('name', data_dic['status']))['id'] self._db_open() @@ -1305,10 +1300,10 @@ def order_update(self, data_dic: Dict[str, str]): def orders_invalid_search(self, column: str, string: str, vlist: List[str] = ('id', 'name', 'expires', 'identifiers', 'created_at', 'status__id', 'status__name', 'account__id', 'account__name', 'account__contact'), operant='LIKE') -> List[str]: """ search order table for a certain key/value pair """ - self.logger.debug('DBStore.orders_search(column:{0}, pattern:{1})'.format(column, string)) + self.logger.debug('DBStore.orders_search(column:%s, pattern:%s)', column, string) self._db_open() - pre_statement = '''SELECT + pre_statement = f'''SELECT orders.*, status.name as status__name, status.id as status__id, @@ -1318,7 +1313,7 @@ def orders_invalid_search(self, column: str, string: str, vlist: List[str] = ('i FROM orders LEFT JOIN status on status.id = orders.status_id LEFT JOIN account on account.id = orders.account_id - WHERE orders.status_id > 1 AND orders.{0} {1} ?'''.format(column, operant) + WHERE orders.status_id > 1 AND orders.{column} {operant} ?''' self.cursor.execute(pre_statement, [string]) rows = self.cursor.fetchall() diff --git a/examples/django/acme_srv/views.py b/examples/django/acme_srv/views.py index 394d3cfd..58d19e4e 100644 --- a/examples/django/acme_srv/views.py +++ b/examples/django/acme_srv/views.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- -# pylint: disable=C0209, E0611, E0401 """ acme app main view """ from __future__ import unicode_literals, print_function from django.http import HttpResponse, HttpResponseNotFound @@ -54,20 +53,15 @@ def pretty_request(request): if not header.startswith('HTTP'): continue header = '-'.join([h.capitalize() for h in header[5:].lower().split('_')]) - headers += '{}: {}\n'.format(header, value) + headers += f'{header}: {value}\n' return ( - '{method} HTTP/1.1\n' - 'Content-Length: {content_length}\n' - 'Content-Type: {content_type}\n' - '{headers}\n\n' - '{body}' - ).format( - method=request.method, - content_length=request.META['CONTENT_LENGTH'], - content_type=request.META['CONTENT_TYPE'], - headers=headers, - body=request.body, ) + f'{request.method} HTTP/1.1\n' + f'Content-Length: {request.META['CONTENT_LENGTH']}\n' + f'Content-Type: {request.META['CONTENT_TYPE']}\n' + f'{headers}\n\n' + f'{request.body}' + ) def directory(request): diff --git a/test/test_account.py b/test/test_account.py index 379c6568..19439b7c 100644 --- a/test/test_account.py +++ b/test/test_account.py @@ -1285,7 +1285,7 @@ def test_126_config_load(self, mock_load_cfg, mock_eab): self.assertTrue(self.account.eab_check) self.assertTrue(self.account.eab_handler) - @patch('importlib.import_module') + @patch('acme_srv.account.eab_handler_load') @patch('acme_srv.account.load_config') def test_127_config_load(self, mock_load_cfg, mock_imp): """ test _config_load account with contact_check_disable True """ @@ -1294,6 +1294,7 @@ def test_127_config_load(self, mock_load_cfg, mock_imp): mock_load_cfg.return_value = parser mock_imp.return_value = Mock() self.account._config_load() + self.account._config_load() self.assertFalse(self.account.inner_header_nonce_allow) self.assertFalse(self.account.ecc_only) self.assertFalse(self.account.tos_check_disable) diff --git a/test/test_certificate.py b/test/test_certificate.py index c4c5a087..6e11cf98 100644 --- a/test/test_certificate.py +++ b/test/test_certificate.py @@ -1817,8 +1817,9 @@ def test_164__cert_reusage_check(self, mock_uts): self.assertEqual((None, None, None, None), self.certificate._cert_reusage_check('csr')) self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Certificate._cert_reusage_check(): ex_cert_reusage', lcm.output) + @patch('acme_srv.certificate.ca_handler_load') @patch('acme_srv.certificate.load_config') - def test_165_config_load(self, mock_load_cfg): + def test_165_config_load(self, mock_load_cfg, mock_handler): """ test _config_load empty dictionary """ mock_load_cfg.return_value = {} self.certificate._config_load() @@ -1840,8 +1841,9 @@ def test_166_config_load(self, mock_load_cfg): self.assertTrue(self.certificate.ignore_post_hook_failure) self.assertFalse(self.certificate.ignore_success_hook_failure) + @patch('acme_srv.certificate.ca_handler_load') @patch('acme_srv.certificate.load_config') - def test_167_config_load(self, mock_load_cfg): + def test_167_config_load(self, mock_load_cfg, mock_hand): """ test _config_load missing ca_handler """ parser = configparser.ConfigParser() parser['Order'] = {'tnauthlist_support': False} @@ -1854,8 +1856,9 @@ def test_167_config_load(self, mock_load_cfg): self.assertFalse(self.certificate.ignore_success_hook_failure) self.assertFalse(self.certificate.cn2san_add) + @patch('acme_srv.certificate.ca_handler_load') @patch('acme_srv.certificate.load_config') - def test_168_config_load(self, mock_load_cfg): + def test_168_config_load(self, mock_load_cfg, mock_hand): """ test _config_load missing ca_handler """ parser = configparser.ConfigParser() parser['Order'] = {'tnauthlist_support': True} @@ -1902,7 +1905,7 @@ def test_170_config_load(self, mock_load_cfg, mock_handler): self.assertFalse(self.certificate.ignore_success_hook_failure) self.assertTrue(self.certificate.cn2san_add) - @patch('importlib.import_module') + @patch('acme_srv.certificate.ca_handler_load') @patch('acme_srv.certificate.load_config') def test_171_config_load(self, mock_load_cfg, mock_imp): """ test _config_load missing ca_handler """ @@ -1918,8 +1921,9 @@ def test_171_config_load(self, mock_load_cfg, mock_imp): self.assertFalse(self.certificate.ignore_success_hook_failure) self.assertFalse(self.certificate.cn2san_add) + @patch('acme_srv.certificate.ca_handler_load') @patch('acme_srv.certificate.load_config') - def test_172_config_load(self, mock_load_cfg): + def test_172_config_load(self, mock_load_cfg, mock_handler): """ test _config_load missing ca_handler """ parser = configparser.ConfigParser() parser['Directory'] = {'foo': 'bar', 'url_prefix': 'url_prefix'} @@ -1933,7 +1937,7 @@ def test_172_config_load(self, mock_load_cfg): self.assertFalse(self.certificate.ignore_success_hook_failure) self.assertFalse(self.certificate.cn2san_add) - @patch('importlib.import_module') + @patch('acme_srv.certificate.ca_handler_load') @patch('acme_srv.certificate.load_config') def test_173_config_load(self, mock_load_cfg, mock_imp): """ test _config_load ca_handler but no handler_file """ @@ -1951,8 +1955,9 @@ def test_173_config_load(self, mock_load_cfg, mock_imp): self.assertFalse(self.certificate.ignore_success_hook_failure) self.assertFalse(self.certificate.cn2san_add) + @patch('acme_srv.certificate.ca_handler_load') @patch('acme_srv.certificate.load_config') - def test_174_config_load(self, mock_load_cfg): + def test_174_config_load(self, mock_load_cfg, mock_handler): """ test _config_load no cert_reusage_timeframe """ parser = configparser.ConfigParser() parser['Certificate'] = {'foo': 'bar'} @@ -1966,8 +1971,9 @@ def test_174_config_load(self, mock_load_cfg): self.assertFalse(self.certificate.ignore_success_hook_failure) self.assertFalse(self.certificate.cn2san_add) + @patch('acme_srv.certificate.ca_handler_load') @patch('acme_srv.certificate.load_config') - def test_175_config_load(self, mock_load_cfg): + def test_175_config_load(self, mock_load_cfg, mock_handler): """ test _config_load cert_reusage_timeframe 120 """ parser = configparser.ConfigParser() parser['Certificate'] = {'cert_reusage_timeframe': 1200} @@ -1980,8 +1986,9 @@ def test_175_config_load(self, mock_load_cfg): self.assertFalse(self.certificate.ignore_success_hook_failure) self.assertFalse(self.certificate.cn2san_add) + @patch('acme_srv.certificate.ca_handler_load') @patch('acme_srv.certificate.load_config') - def test_176_config_load(self, mock_load_cfg): + def test_176_config_load(self, mock_load_cfg, mock_handler): """ test _config_load cert_reusage_timeframe 0 """ parser = configparser.ConfigParser() parser['Certificate'] = {'cert_reusage_timeframe': 0} @@ -1994,8 +2001,9 @@ def test_176_config_load(self, mock_load_cfg): self.assertFalse(self.certificate.ignore_success_hook_failure) self.assertFalse(self.certificate.cn2san_add) + @patch('acme_srv.certificate.ca_handler_load') @patch('acme_srv.certificate.load_config') - def test_177_config_load(self, mock_load_cfg): + def test_177_config_load(self, mock_load_cfg, mock_handler): """ test _config_load cert_reusage_timeframe text """ parser = configparser.ConfigParser() parser['Certificate'] = {'cert_reusage_timeframe': 'aaa'} @@ -2010,8 +2018,9 @@ def test_177_config_load(self, mock_load_cfg): self.assertFalse(self.certificate.ignore_success_hook_failure) self.assertFalse(self.certificate.cn2san_add) + @patch('acme_srv.certificate.ca_handler_load') @patch('acme_srv.certificate.load_config') - def test_178_config_load(self, mock_load_cfg): + def test_178_config_load(self, mock_load_cfg, mock_handler): """ test _config_load enrollment_timeout 120 """ parser = configparser.ConfigParser() parser['Certificate'] = {'enrollment_timeout': 120} @@ -2024,8 +2033,9 @@ def test_178_config_load(self, mock_load_cfg): self.assertFalse(self.certificate.ignore_success_hook_failure) self.assertFalse(self.certificate.cn2san_add) + @patch('acme_srv.certificate.ca_handler_load') @patch('acme_srv.certificate.load_config') - def test_179_config_load(self, mock_load_cfg): + def test_179_config_load(self, mock_load_cfg, mock_handler): """ test _config_load certificate text """ parser = configparser.ConfigParser() parser['Certificate'] = {'enrollment_timeout': 'aaa'} @@ -2040,9 +2050,10 @@ def test_179_config_load(self, mock_load_cfg): self.assertFalse(self.certificate.ignore_success_hook_failure) self.assertFalse(self.certificate.cn2san_add) + @patch('acme_srv.certificate.ca_handler_load') @patch('acme_srv.certificate.hooks_load') @patch('acme_srv.certificate.load_config') - def test_180_config_load(self, mock_load_cfg, mock_hooks): + def test_180_config_load(self, mock_load_cfg, mock_hooks, mock_handler): """ test _config_load hooks_load() returns None """ parser = configparser.ConfigParser() parser['Certificate'] = {'enrollment_timeout': 120} @@ -2056,9 +2067,10 @@ def test_180_config_load(self, mock_load_cfg, mock_hooks): self.assertFalse(self.certificate.ignore_success_hook_failure) self.assertFalse(self.certificate.cn2san_add) + @patch('acme_srv.certificate.ca_handler_load') @patch('acme_srv.certificate.hooks_load') @patch('acme_srv.certificate.load_config') - def test_181_config_load(self, mock_load_cfg, mock_hooks): + def test_181_config_load(self, mock_load_cfg, mock_hooks, mock_handler): """ test _config_load hooks_load() returns module """ parser = configparser.ConfigParser() parser['Certificate'] = {'enrollment_timeout': 120} diff --git a/test/test_challenge.py b/test/test_challenge.py index 7a207553..9bae1d87 100644 --- a/test/test_challenge.py +++ b/test/test_challenge.py @@ -1229,17 +1229,5 @@ def test_119_challengeset_get(self, mock_chsearch, mock_val, mock_set): self.assertFalse(mock_set.called) self.assertFalse(mock_val.called) - #@patch('acme_srv.challenge.Challenge.new_set') - #@patch('acme_srv.challenge.Challenge._existing_challenge_validate') - #@patch('acme_srv.challenge.Challenge._challengelist_search') - #def test_097_challengeset_get(self, mock_chsearch, mock_val, mock_set): - # """ test challengeset_get - challenge_list returned autzstatus pending """ - # mock_chsearch.return_value = [{'name': 'name1', 'foo': 'bar'}] - # mock_val.return_value = True - # mock_set.return_value = 'new_set' - # self.assertEqual([{'foo': 'bar'}], self.challenge.challengeset_get('authz_name', 'pending', 'token', 'tnauth')) - # self.assertFalse(mock_set.called) - # self.assertTrue(mock_val.called) - if __name__ == '__main__': unittest.main() diff --git a/test/test_helper.py b/test/test_helper.py index 6c955abc..a79bf8e0 100644 --- a/test/test_helper.py +++ b/test/test_helper.py @@ -527,7 +527,7 @@ def test_053_helper_cert_san_pyopenssl_get(self): self.assertEqual(['DNS:foo.example.com'], self.cert_san_pyopenssl_get(self.logger, cert, recode=False)) - def test_051_helper_cert_san_get(self): + def test_054_helper_cert_san_get(self): """ test cert_san_get for a single SAN and recode = False""" cert = """-----BEGIN X509 CERTIFICATE----- MIIE2zCCAsOgAwIBAgIPAXI102H4bCWEkhD2SaLsMA0GCSqGSIb3DQEBDQUAMDIx @@ -561,7 +561,7 @@ def test_051_helper_cert_san_get(self): self.assertEqual(['DNS:foo1.bar.local'], self.cert_san_get(self.logger, cert, recode=False)) @patch('acme_srv.helper.cert_load') - def test_052_helper_cert_san_get(self, mock_certload): + def test_055_helper_cert_san_get(self, mock_certload): """ test cert_san_get for a single SAN and recode = False""" cert = "cert" mock_certload.return_value = 'mock_csrload' @@ -569,38 +569,38 @@ def test_052_helper_cert_san_get(self, mock_certload): self.assertFalse(self.cert_san_get(self.logger, cert, recode=False)) self.assertIn("ERROR:test_a2c:cert_san_get(): Error: 'str' object has no attribute 'extensions'", lcm.output) - def test_053_helper_build_pem_file(self): + def test_056_helper_build_pem_file(self): """ test build_pem_file without exsting content """ existing = None cert = 'cert' self.assertEqual('-----BEGIN CERTIFICATE-----\ncert\n-----END CERTIFICATE-----\n', self.build_pem_file(self.logger, existing, cert, True)) - def test_054_helper_build_pem_file(self): + def test_057_helper_build_pem_file(self): """ test build_pem_file with exsting content """ existing = 'existing' cert = 'cert' self.assertEqual('existing-----BEGIN CERTIFICATE-----\ncert\n-----END CERTIFICATE-----\n', self.build_pem_file(self.logger, existing, cert, True)) - def test_055_helper_build_pem_file(self): + def test_058_helper_build_pem_file(self): """ test build_pem_file with long cert (to test wrap) """ existing = None cert = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' self.assertEqual('-----BEGIN CERTIFICATE-----\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\naaaaaaaaa\n-----END CERTIFICATE-----\n', self.build_pem_file(self.logger, existing, cert, True)) - def test_056_helper_build_pem_file(self): + def test_059_helper_build_pem_file(self): """ test build_pem_file with long cert (to test wrap) """ existing = None cert = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' self.assertEqual('-----BEGIN CERTIFICATE-----\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n-----END CERTIFICATE-----\n', self.build_pem_file(self.logger, existing, cert, False)) - def test_057_helper_build_pem_file(self): + def test_060_helper_build_pem_file(self): """ test build_pem_file with long cert (to test wrap) """ existing = 'existing' cert = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' self.assertEqual('existing-----BEGIN CERTIFICATE-----\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n-----END CERTIFICATE-----\n', self.build_pem_file(self.logger, existing, cert, False)) - def test_058_helper_build_pem_file(self): + def test_061_helper_build_pem_file(self): """ test build_pem_file for CSR """ existing = None csr = 'MIIClzCCAX8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBvH7P73CwR7AF/WGeTfIDLlMWD6VZV3CTZBF0AwNMTFU/zbdAX8r63pzElX/5C5ZVsc36XHqdAJcioJlI33uE3RhOSvDyOcDgWlnPK9gj2soQ7enizGqd1u7hf6C3IwFtc4uGNOU3Z/tnTzVdYiCSKS+5lTZfMxn4FtEUN+w90NHBvC+AlTo3Gl0gqbYOZgg/UwWj60u7S2gBzSeb2/w62Z7bz+SknGZbeI4ySo30ET6oCSCAUN42jE+1dHI/Y+tGBtqP3h7W7OezKeLsJjD9r07U0+uMoVCY9oKTyT0gK8+gsde0tpt6QKa93HJGUPAP9ehrKCl335QcJESFw67/AgMBAAGgOTA3BgkqhkiG9w0BCQ4xKjAoMAsGA1UdDwQEAwIF4DAZBgNVHREEEjAQgg5mb28xLmJhci5sb2NhbDANBgkqhkiG9w0BAQsFAAOCAQEAf4cdGpYHLqX+06BFF7+NqXLmKvc7n66vAfevLN75eu/pCXhhRSdpXvcYm+mAVEXJCPaG2kFGt6wfBvVWoVX/91d+OuAtiUHmhY95Oi7g3RF3ThCrvT2mR4zsNiKgC34jXbl9489iIiFRBQXkq2fLwN5JwBYutUENwkDIeApRRbmUzTDbar1xoBAQ3GjVtOAEjHc/3S1yyKkCpM6Qkg8uWOJAXw9INJqH6x55nMZrvTUuXkURc/mvhV+bp2vdKoigGvfa3VVfoAI0BZLQMohQ9QLKoNQsKxEs3JidvpZrl3o23LMGEPoJs3zIuowTa217PHwdBw4UwtD7KxJK/+344A==' @@ -623,59 +623,59 @@ def test_058_helper_build_pem_file(self): """ self.assertEqual(result, self.build_pem_file(self.logger, existing, csr, False, True)) - def test_059_helper_b64_decode(self): + def test_062_helper_b64_decode(self): """ test bas64 decoder for string value""" self.assertEqual('test', self.b64_decode(self.logger, 'dGVzdA==')) - def test_060_helper_b64_decode(self): + def test_063_helper_b64_decode(self): """ test bas64 decoder for byte value """ self.assertEqual('test', self.b64_decode(self.logger, b'dGVzdA==')) - def test_061_helper_date_to_datestr(self): + def test_064_helper_date_to_datestr(self): """ convert dateobj to date-string with default format""" self.assertEqual('2019-10-27T00:00:00Z', self.date_to_datestr(datetime.date(2019, 10, 27))) - def test_062_helper_date_to_datestr(self): + def test_065_helper_date_to_datestr(self): """ convert dateobj to date-string with a predefined format""" self.assertEqual('2019.10.27', self.date_to_datestr(datetime.date(2019, 10, 27), '%Y.%m.%d')) - def test_063_helper_date_to_datestr(self): + def test_066_helper_date_to_datestr(self): """ convert dateobj to date-string for an knvalid date""" self.assertEqual(None, self.date_to_datestr('foo', '%Y.%m.%d')) - def test_064_helper_datestr_to_date(self): + def test_067_helper_datestr_to_date(self): """ convert datestr to date with default format""" self.assertEqual(datetime.datetime(2019, 11, 27, 0, 1, 2), self.datestr_to_date('2019-11-27T00:01:02')) - def test_065_helper_datestr_to_date(self): + def test_068_helper_datestr_to_date(self): """ convert datestr to date with predefined format""" self.assertEqual(datetime.datetime(2019, 11, 27, 0, 0, 0), self.datestr_to_date('2019.11.27', '%Y.%m.%d')) - def test_066_helper_datestr_to_date(self): + def test_069_helper_datestr_to_date(self): """ convert datestr to date with invalid format""" self.assertEqual(None, self.datestr_to_date('foo', '%Y.%m.%d')) - def test_067_helper_dkeys_lower(self): + def test_070_helper_dkeys_lower(self): """ dkeys_lower with a simple string """ tree = 'fOo' self.assertEqual('fOo', self.dkeys_lower(tree)) - def test_068_helper_dkeys_lower(self): + def test_071_helper_dkeys_lower(self): """ dkeys_lower with a simple list """ tree = ['fOo', 'bAr'] self.assertEqual(['fOo', 'bAr'], self.dkeys_lower(tree)) - def test_069_helper_dkeys_lower(self): + def test_072_helper_dkeys_lower(self): """ dkeys_lower with a simple dictionary """ tree = {'kEy': 'vAlUe'} self.assertEqual({'key': 'vAlUe'}, self.dkeys_lower(tree)) - def test_070_helper_dkeys_lower(self): + def test_073_helper_dkeys_lower(self): """ dkeys_lower with a nested dictionary containg strings, list and dictionaries""" tree = {'kEy1': 'vAlUe2', 'keys2': ['lIsT2', {'kEyS3': 'vAlUe3', 'kEyS4': 'vAlUe3'}], 'keys4': {'kEyS4': 'vAluE5', 'kEyS5': 'vAlUE6'}} self.assertEqual({'key1': 'vAlUe2', 'keys2': ['lIsT2', {'keys3': 'vAlUe3', 'keys4': 'vAlUe3'}], 'keys4': {'keys5': 'vAlUE6', 'keys4': 'vAluE5'}}, self.dkeys_lower(tree)) - def test_071_helper_cert_pubkey_get(self): + def test_074_helper_cert_pubkey_get(self): """ test get public_key from certificate """ cert = """ -----BEGIN X509 CERTIFICATE----- @@ -719,7 +719,7 @@ def test_071_helper_cert_pubkey_get(self): """ self.assertEqual(pub_key, self.cert_pubkey_get(self.logger, cert)) - def test_072_helper_csr_pubkey_get(self): + def test_075_helper_csr_pubkey_get(self): """ test get public_key from certificate """ csr = """MIIClzCCAX8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBvH7P73CwR7AF/WGeTfIDLlMWD6VZV3CTZBF0AwNMTFU/zbdAX8r63pzElX/5C5ZVsc36XHqdAJcioJlI33uE3RhOSvDyOcDgWlnPK9gj2soQ7enizGqd1u7hf6C3IwFtc4uGNOU3Z/tnTzVdYiCSKS+5lTZfMxn4FtEUN+w90NHBvC+AlTo3Gl0gqbYOZgg/UwWj60u7S2gBzSeb2/w62Z7bz+SknGZbeI4ySo30ET6oCSCAUN42jE+1dHI/Y+tGBtqP3h7W7OezKeLsJjD9r07U0+uMoVCY9oKTyT0gK8+gsde0tpt6QKa93HJGUPAP9ehrKCl335QcJESFw67/AgMBAAGgOTA3BgkqhkiG9w0BCQ4xKjAoMAsGA1UdDwQEAwIF4DAZBgNVHREEEjAQgg5mb28xLmJhci5sb2NhbDANBgkqhkiG9w0BAQsFAAOCAQEAf4cdGpYHLqX+06BFF7+NqXLmKvc7n66vAfevLN75eu/pCXhhRSdpXvcYm+mAVEXJCPaG2kFGt6wfBvVWoVX/91d+OuAtiUHmhY95Oi7g3RF3ThCrvT2mR4zsNiKgC34jXbl9489iIiFRBQXkq2fLwN5JwBYutUENwkDIeApRRbmUzTDbar1xoBAQ3GjVtOAEjHc/3S1yyKkCpM6Qkg8uWOJAXw9INJqH6x55nMZrvTUuXkURc/mvhV+bp2vdKoigGvfa3VVfoAI0BZLQMohQ9QLKoNQsKxEs3JidvpZrl3o23LMGEPoJs3zIuowTa217PHwdBw4UwtD7KxJK/+344A==""" @@ -735,7 +735,7 @@ def test_072_helper_csr_pubkey_get(self): """ self.assertEqual(pub_key, self.csr_pubkey_get(self.logger, csr)) - def test_073_helper_csr_pubkey_get(self): + def test_076_helper_csr_pubkey_get(self): """ test get public_key from certificate """ csr = """MIIClzCCAX8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBvH7P73CwR7AF/WGeTfIDLlMWD6VZV3CTZBF0AwNMTFU/zbdAX8r63pzElX/5C5ZVsc36XHqdAJcioJlI33uE3RhOSvDyOcDgWlnPK9gj2soQ7enizGqd1u7hf6C3IwFtc4uGNOU3Z/tnTzVdYiCSKS+5lTZfMxn4FtEUN+w90NHBvC+AlTo3Gl0gqbYOZgg/UwWj60u7S2gBzSeb2/w62Z7bz+SknGZbeI4ySo30ET6oCSCAUN42jE+1dHI/Y+tGBtqP3h7W7OezKeLsJjD9r07U0+uMoVCY9oKTyT0gK8+gsde0tpt6QKa93HJGUPAP9ehrKCl335QcJESFw67/AgMBAAGgOTA3BgkqhkiG9w0BCQ4xKjAoMAsGA1UdDwQEAwIF4DAZBgNVHREEEjAQgg5mb28xLmJhci5sb2NhbDANBgkqhkiG9w0BAQsFAAOCAQEAf4cdGpYHLqX+06BFF7+NqXLmKvc7n66vAfevLN75eu/pCXhhRSdpXvcYm+mAVEXJCPaG2kFGt6wfBvVWoVX/91d+OuAtiUHmhY95Oi7g3RF3ThCrvT2mR4zsNiKgC34jXbl9489iIiFRBQXkq2fLwN5JwBYutUENwkDIeApRRbmUzTDbar1xoBAQ3GjVtOAEjHc/3S1yyKkCpM6Qkg8uWOJAXw9INJqH6x55nMZrvTUuXkURc/mvhV+bp2vdKoigGvfa3VVfoAI0BZLQMohQ9QLKoNQsKxEs3JidvpZrl3o23LMGEPoJs3zIuowTa217PHwdBw4UwtD7KxJK/+344A==""" @@ -751,155 +751,155 @@ def test_073_helper_csr_pubkey_get(self): """ self.assertEqual(pub_key, self.csr_pubkey_get(self.logger, csr, encoding='pem')) - def test_074_helper_csr_pubkey_get(self): + def test_077_helper_csr_pubkey_get(self): """ test get public_key from certificate """ csr = """MIIClzCCAX8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBvH7P73CwR7AF/WGeTfIDLlMWD6VZV3CTZBF0AwNMTFU/zbdAX8r63pzElX/5C5ZVsc36XHqdAJcioJlI33uE3RhOSvDyOcDgWlnPK9gj2soQ7enizGqd1u7hf6C3IwFtc4uGNOU3Z/tnTzVdYiCSKS+5lTZfMxn4FtEUN+w90NHBvC+AlTo3Gl0gqbYOZgg/UwWj60u7S2gBzSeb2/w62Z7bz+SknGZbeI4ySo30ET6oCSCAUN42jE+1dHI/Y+tGBtqP3h7W7OezKeLsJjD9r07U0+uMoVCY9oKTyT0gK8+gsde0tpt6QKa93HJGUPAP9ehrKCl335QcJESFw67/AgMBAAGgOTA3BgkqhkiG9w0BCQ4xKjAoMAsGA1UdDwQEAwIF4DAZBgNVHREEEjAQgg5mb28xLmJhci5sb2NhbDANBgkqhkiG9w0BAQsFAAOCAQEAf4cdGpYHLqX+06BFF7+NqXLmKvc7n66vAfevLN75eu/pCXhhRSdpXvcYm+mAVEXJCPaG2kFGt6wfBvVWoVX/91d+OuAtiUHmhY95Oi7g3RF3ThCrvT2mR4zsNiKgC34jXbl9489iIiFRBQXkq2fLwN5JwBYutUENwkDIeApRRbmUzTDbar1xoBAQ3GjVtOAEjHc/3S1yyKkCpM6Qkg8uWOJAXw9INJqH6x55nMZrvTUuXkURc/mvhV+bp2vdKoigGvfa3VVfoAI0BZLQMohQ9QLKoNQsKxEs3JidvpZrl3o23LMGEPoJs3zIuowTa217PHwdBw4UwtD7KxJK/+344A==""" pub_key = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwbx+z+9wsEewBf1hnk3yAy5TFg+lWVdwk2QRdAMDTExVP823QF/K+t6cxJV/+QuWVbHN+lx6nQCXIqCZSN97hN0YTkrw8jnA4FpZzyvYI9rKEO3p4sxqndbu4X+gtyMBbXOLhjTlN2f7Z081XWIgkikvuZU2XzMZ+BbRFDfsPdDRwbwvgJU6NxpdIKm2DmYIP1MFo+tLu0toAc0nm9v8Otme28/kpJxmW3iOMkqN9BE+qAkggFDeNoxPtXRyP2PrRgbaj94e1uznsyni7CYw/a9O1NPrjKFQmPaCk8k9ICvPoLHXtLabekCmvdxyRlDwD/Xoaygpd9+UHCREhcOu/wIDAQAB' self.assertEqual(pub_key, self.csr_pubkey_get(self.logger, csr, encoding='base64der')) - def test_075_helper_csr_pubkey_get(self): + def test_078_helper_csr_pubkey_get(self): """ test get public_key from certificate """ csr = """MIIClzCCAX8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBvH7P73CwR7AF/WGeTfIDLlMWD6VZV3CTZBF0AwNMTFU/zbdAX8r63pzElX/5C5ZVsc36XHqdAJcioJlI33uE3RhOSvDyOcDgWlnPK9gj2soQ7enizGqd1u7hf6C3IwFtc4uGNOU3Z/tnTzVdYiCSKS+5lTZfMxn4FtEUN+w90NHBvC+AlTo3Gl0gqbYOZgg/UwWj60u7S2gBzSeb2/w62Z7bz+SknGZbeI4ySo30ET6oCSCAUN42jE+1dHI/Y+tGBtqP3h7W7OezKeLsJjD9r07U0+uMoVCY9oKTyT0gK8+gsde0tpt6QKa93HJGUPAP9ehrKCl335QcJESFw67/AgMBAAGgOTA3BgkqhkiG9w0BCQ4xKjAoMAsGA1UdDwQEAwIF4DAZBgNVHREEEjAQgg5mb28xLmJhci5sb2NhbDANBgkqhkiG9w0BAQsFAAOCAQEAf4cdGpYHLqX+06BFF7+NqXLmKvc7n66vAfevLN75eu/pCXhhRSdpXvcYm+mAVEXJCPaG2kFGt6wfBvVWoVX/91d+OuAtiUHmhY95Oi7g3RF3ThCrvT2mR4zsNiKgC34jXbl9489iIiFRBQXkq2fLwN5JwBYutUENwkDIeApRRbmUzTDbar1xoBAQ3GjVtOAEjHc/3S1yyKkCpM6Qkg8uWOJAXw9INJqH6x55nMZrvTUuXkURc/mvhV+bp2vdKoigGvfa3VVfoAI0BZLQMohQ9QLKoNQsKxEs3JidvpZrl3o23LMGEPoJs3zIuowTa217PHwdBw4UwtD7KxJK/+344A==""" pub_key = b'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwbx+z+9wsEewBf1hnk3yAy5TFg+lWVdwk2QRdAMDTExVP823QF/K+t6cxJV/+QuWVbHN+lx6nQCXIqCZSN97hN0YTkrw8jnA4FpZzyvYI9rKEO3p4sxqndbu4X+gtyMBbXOLhjTlN2f7Z081XWIgkikvuZU2XzMZ+BbRFDfsPdDRwbwvgJU6NxpdIKm2DmYIP1MFo+tLu0toAc0nm9v8Otme28/kpJxmW3iOMkqN9BE+qAkggFDeNoxPtXRyP2PrRgbaj94e1uznsyni7CYw/a9O1NPrjKFQmPaCk8k9ICvPoLHXtLabekCmvdxyRlDwD/Xoaygpd9+UHCREhcOu/wIDAQAB' self.assertEqual(pub_key, base64.b64encode(self.csr_pubkey_get(self.logger, csr, encoding='der'))) - def test_076_helper_csr_pubkey_get(self): + def test_079_helper_csr_pubkey_get(self): """ test get public_key from certificate """ csr = """MIIClzCCAX8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBvH7P73CwR7AF/WGeTfIDLlMWD6VZV3CTZBF0AwNMTFU/zbdAX8r63pzElX/5C5ZVsc36XHqdAJcioJlI33uE3RhOSvDyOcDgWlnPK9gj2soQ7enizGqd1u7hf6C3IwFtc4uGNOU3Z/tnTzVdYiCSKS+5lTZfMxn4FtEUN+w90NHBvC+AlTo3Gl0gqbYOZgg/UwWj60u7S2gBzSeb2/w62Z7bz+SknGZbeI4ySo30ET6oCSCAUN42jE+1dHI/Y+tGBtqP3h7W7OezKeLsJjD9r07U0+uMoVCY9oKTyT0gK8+gsde0tpt6QKa93HJGUPAP9ehrKCl335QcJESFw67/AgMBAAGgOTA3BgkqhkiG9w0BCQ4xKjAoMAsGA1UdDwQEAwIF4DAZBgNVHREEEjAQgg5mb28xLmJhci5sb2NhbDANBgkqhkiG9w0BAQsFAAOCAQEAf4cdGpYHLqX+06BFF7+NqXLmKvc7n66vAfevLN75eu/pCXhhRSdpXvcYm+mAVEXJCPaG2kFGt6wfBvVWoVX/91d+OuAtiUHmhY95Oi7g3RF3ThCrvT2mR4zsNiKgC34jXbl9489iIiFRBQXkq2fLwN5JwBYutUENwkDIeApRRbmUzTDbar1xoBAQ3GjVtOAEjHc/3S1yyKkCpM6Qkg8uWOJAXw9INJqH6x55nMZrvTUuXkURc/mvhV+bp2vdKoigGvfa3VVfoAI0BZLQMohQ9QLKoNQsKxEs3JidvpZrl3o23LMGEPoJs3zIuowTa217PHwdBw4UwtD7KxJK/+344A==""" pub_key = b'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwbx+z+9wsEewBf1hnk3yAy5TFg+lWVdwk2QRdAMDTExVP823QF/K+t6cxJV/+QuWVbHN+lx6nQCXIqCZSN97hN0YTkrw8jnA4FpZzyvYI9rKEO3p4sxqndbu4X+gtyMBbXOLhjTlN2f7Z081XWIgkikvuZU2XzMZ+BbRFDfsPdDRwbwvgJU6NxpdIKm2DmYIP1MFo+tLu0toAc0nm9v8Otme28/kpJxmW3iOMkqN9BE+qAkggFDeNoxPtXRyP2PrRgbaj94e1uznsyni7CYw/a9O1NPrjKFQmPaCk8k9ICvPoLHXtLabekCmvdxyRlDwD/Xoaygpd9+UHCREhcOu/wIDAQAB' self.assertFalse(self.csr_pubkey_get(self.logger, csr, encoding='unk')) - def test_077_helper_convert_byte_to_string(self): + def test_080_helper_convert_byte_to_string(self): """ convert byte2string for a string value """ self.assertEqual('foo', self.convert_byte_to_string('foo')) - def test_078_helper_convert_byte_to_string(self): + def test_081_helper_convert_byte_to_string(self): """ convert byte2string for a string value """ self.assertEqual('foo', self.convert_byte_to_string('foo')) - def test_079_helper_convert_byte_to_string(self): + def test_082_helper_convert_byte_to_string(self): """ convert byte2string for a string value """ self.assertNotEqual('foo', self.convert_byte_to_string('foobar')) - def test_080_helper_convert_byte_to_string(self): + def test_083_helper_convert_byte_to_string(self): """ convert byte2string for a string value """ self.assertNotEqual('foo', self.convert_byte_to_string(b'foobar')) - def test_081_helper_b64_url_encode(self): + def test_084_helper_b64_url_encode(self): """ test b64_url_encode of string """ self.assertEqual(b'c3RyaW5n', self.b64_url_encode(self.logger, 'string')) - def test_082_helper_b64_url_encode(self): + def test_085_helper_b64_url_encode(self): """ test b64_url_encode of byte """ self.assertEqual(b'Ynl0ZQ', self.b64_url_encode(self.logger, b'byte')) - def test_083_helper_csr_cn_get(self): + def test_086_helper_csr_cn_get(self): """ get cn of csr """ csr = 'MIIClzCCAX8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0lk4lyEIa0VL/u5ic01Zo/o+gyYqFpU7xe+nbFgiKA+R1rqrzP/sR6xjHqS0Rkv/BcBXf81sp/+iDmwIQLVlBTkKdimqVHCJMAbTL8ZNpcLDaRUce4liyX1cmczPTSqI/kcyEr8tKpYN+KzvKZZsNx2Pbgu7y7/70P2uSywiW+sqYZ+X28KGFxq6wwENzJtweDVsbWql9LLtw6daF41UQg10auNlRL1nhW0SlWZh1zPPW/0sa6C3xX28jjVh843b4ekkRNLXSEYQMTi0qYR2LomQ5aTlQ/hellf17UknfN2aA2RH5D7Ek+mndj/rH21bxQg26KRmHlaJld9K1IfvJAgMBAAGgOTA3BgkqhkiG9w0BCQ4xKjAoMAsGA1UdDwQEAwIF4DAZBgNVHREEEjAQgg5mb28xLmJhci5sb2NhbDANBgkqhkiG9w0BAQsFAAOCAQEAl3egrkO3I94IpxxfSJmVetd7s9uW3lSBqh9OiypFevQO7ZgUxau+k05NKTUNpSq3W9H/lRr5AG5x3/VX8XZVbcLKXQ0d6e38uXBAUFQQJmjBVYqd8KcMfqLeFFUBsLcG04yek2tNIbhXZfBtw9UYO27Y5ktMgWjAz2VskIXl3E2L0b8tGnSKDoMB07IVpYB9bHfHX4o+ccIgq1HxyYT1d+eVIQuSHHxR7j7Wkgb8RG9bCWpVWaYWKWU0Inh3gMnP06kPBJ9nOB4adgC3Hz37ab/0KpmBuQBEgmMfINwV/OpJVv2Su1FYK+uX7E1qUGae6QDsfg0Yor9uP0Vkv4b1NA==' self.assertEqual('foo1.bar.local', self.csr_cn_get(self.logger, csr)) - def test_084_helper_csr_cn_get(self): + def test_087_helper_csr_cn_get(self): """ get cn of csr """ csr = b'MIIClzCCAX8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0lk4lyEIa0VL/u5ic01Zo/o+gyYqFpU7xe+nbFgiKA+R1rqrzP/sR6xjHqS0Rkv/BcBXf81sp/+iDmwIQLVlBTkKdimqVHCJMAbTL8ZNpcLDaRUce4liyX1cmczPTSqI/kcyEr8tKpYN+KzvKZZsNx2Pbgu7y7/70P2uSywiW+sqYZ+X28KGFxq6wwENzJtweDVsbWql9LLtw6daF41UQg10auNlRL1nhW0SlWZh1zPPW/0sa6C3xX28jjVh843b4ekkRNLXSEYQMTi0qYR2LomQ5aTlQ/hellf17UknfN2aA2RH5D7Ek+mndj/rH21bxQg26KRmHlaJld9K1IfvJAgMBAAGgOTA3BgkqhkiG9w0BCQ4xKjAoMAsGA1UdDwQEAwIF4DAZBgNVHREEEjAQgg5mb28xLmJhci5sb2NhbDANBgkqhkiG9w0BAQsFAAOCAQEAl3egrkO3I94IpxxfSJmVetd7s9uW3lSBqh9OiypFevQO7ZgUxau+k05NKTUNpSq3W9H/lRr5AG5x3/VX8XZVbcLKXQ0d6e38uXBAUFQQJmjBVYqd8KcMfqLeFFUBsLcG04yek2tNIbhXZfBtw9UYO27Y5ktMgWjAz2VskIXl3E2L0b8tGnSKDoMB07IVpYB9bHfHX4o+ccIgq1HxyYT1d+eVIQuSHHxR7j7Wkgb8RG9bCWpVWaYWKWU0Inh3gMnP06kPBJ9nOB4adgC3Hz37ab/0KpmBuQBEgmMfINwV/OpJVv2Su1FYK+uX7E1qUGae6QDsfg0Yor9uP0Vkv4b1NA==' self.assertEqual('foo1.bar.local', self.csr_cn_get(self.logger, csr)) - def test_085_helper_convert_string_to_byte(self): + def test_088_helper_convert_string_to_byte(self): """ convert string value to byte """ value = 'foo.bar' self.assertEqual(b'foo.bar', self.convert_string_to_byte(value)) - def test_086_helper_convert_string_to_byte(self): + def test_089_helper_convert_string_to_byte(self): """ convert string value to byte """ value = b'foo.bar' self.assertEqual(b'foo.bar', self.convert_string_to_byte(value)) - def test_087_helper_convert_string_to_byte(self): + def test_090_helper_convert_string_to_byte(self): """ convert string value to byte """ value = b'' self.assertEqual(b'', self.convert_string_to_byte(value)) - def test_088_helper_convert_string_to_byte(self): + def test_091_helper_convert_string_to_byte(self): """ convert string value to byte """ value = '' self.assertEqual(b'', self.convert_string_to_byte(value)) - def test_089_helper_convert_string_to_byte(self): + def test_092_helper_convert_string_to_byte(self): """ convert string value to byte """ value = None self.assertFalse(self.convert_string_to_byte(value)) - def test_090_helper_get_url(self): + def test_093_helper_get_url(self): """ get_url https """ data_dic = {'HTTP_HOST': 'http_host', 'SERVER_PORT': '443', 'PATH_INFO': 'path_info'} self.assertEqual('https://http_host', self.get_url(data_dic, False)) - def test_091_helper_get_url(self): + def test_094_helper_get_url(self): """ get_url http """ data_dic = {'HTTP_HOST': 'http_host', 'SERVER_PORT': '80', 'PATH_INFO': 'path_info'} self.assertEqual('http://http_host', self.get_url(data_dic, False)) - def test_092_helper_get_url(self): + def test_095_helper_get_url(self): """ get_url http wsgi.scheme """ data_dic = {'HTTP_HOST': 'http_host', 'SERVER_PORT': '80', 'PATH_INFO': 'path_info', 'wsgi.url_scheme': 'wsgi.url_scheme'} self.assertEqual('wsgi.url_scheme://http_host', self.get_url(data_dic, False)) - def test_093_helper_get_url(self): + def test_096_helper_get_url(self): """ get_url https include_path true bot no pathinfo""" data_dic = {'HTTP_HOST': 'http_host', 'SERVER_PORT': '443'} self.assertEqual('https://http_host', self.get_url(data_dic, True)) - def test_094_helper_get_url(self): + def test_097_helper_get_url(self): """ get_url https and path info""" data_dic = {'HTTP_HOST': 'http_host', 'SERVER_PORT': '443', 'PATH_INFO': 'path_info'} self.assertEqual('https://http_hostpath_info', self.get_url(data_dic, True)) - def test_095_helper_get_url(self): + def test_098_helper_get_url(self): """ get_url wsgi.url and pathinfo """ data_dic = {'HTTP_HOST': 'http_host', 'SERVER_PORT': '80', 'PATH_INFO': 'path_info', 'wsgi.url_scheme': 'wsgi.url_scheme'} self.assertEqual('wsgi.url_scheme://http_hostpath_info', self.get_url(data_dic, True)) - def test_096_helper_get_url(self): + def test_099_helper_get_url(self): """ get_url http and pathinfo""" data_dic = {'HTTP_HOST': 'http_host', 'SERVER_PORT': '80', 'PATH_INFO': 'path_info'} self.assertEqual('http://http_hostpath_info', self.get_url(data_dic, True)) - def test_097_helper_get_url(self): + def test_100_helper_get_url(self): """ get_url without hostinfo """ data_dic = {'SERVER_PORT': '80', 'PATH_INFO': 'path_info'} self.assertEqual('http://localhost', self.get_url(data_dic, False)) - def test_098_helper_get_url(self): + def test_101_helper_get_url(self): """ get_url without SERVER_PORT """ data_dic = {'HTTP_HOST': 'http_host'} self.assertEqual('http://http_host', self.get_url(data_dic, True)) @patch('acme_srv.helper.requests.get') - def test_099_helper_url_get(self, mock_request): + def test_102_helper_url_get(self, mock_request): """ successful url get without dns servers """ mock_request.return_value.text = 'foo' self.assertEqual('foo', self.url_get(self.logger, 'url')) @patch('acme_srv.helper.requests.get') - def test_100_helper_url_get(self, mock_request): + def test_103_helper_url_get(self, mock_request): """ successful url get without dns servers """ mock_request.return_value.text = 'foo' self.assertEqual('foo', self.url_get(self.logger, 'url', 'dns', 'proxy')) @patch('acme_srv.helper.requests.get') - def test_101_helper_url_get(self, mock_request): + def test_104_helper_url_get(self, mock_request): """ unsuccessful url get without dns servers """ # this is stupid but triggrs an expeption mock_request.return_value = {'foo': 'foo'} self.assertEqual(None, self.url_get(self.logger, 'url')) @patch('acme_srv.helper.url_get_with_own_dns') - def test_102_helper_url_get(self, mock_request): + def test_105_helper_url_get(self, mock_request): """ successful url get with dns servers """ mock_request.return_value = 'foo' self.assertEqual('foo', self.url_get(self.logger, 'url', 'dns')) @patch('acme_srv.helper.requests.get', side_effect=Mock(side_effect=Exception('foo'))) - def test_103_helper_url_get(self, mock_request): + def test_106_helper_url_get(self, mock_request): """ unsuccessful url_get """ # mock_request.return_value.text = 'foo' with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -907,7 +907,7 @@ def test_103_helper_url_get(self, mock_request): self.assertIn('ERROR:test_a2c:url_get error: foo', lcm.output) @patch('acme_srv.helper.requests.get') - def test_104_helper_url_get(self, mock_request): + def test_107_helper_url_get(self, mock_request): """ unsuccessful url_get fallback to v4""" object = Mock() object.text = 'foo' @@ -915,84 +915,84 @@ def test_104_helper_url_get(self, mock_request): self.assertEqual('foo', self.url_get(self.logger, 'url')) @patch('acme_srv.helper.requests.get') - def test_105_helper_url_get_with_own_dns(self, mock_request): + def test_108_helper_url_get_with_own_dns(self, mock_request): """ successful url_get_with_own_dns get with dns servers """ mock_request.return_value.text = 'foo' self.assertEqual('foo', self.url_get_with_own_dns(self.logger, 'url')) @patch('acme_srv.helper.requests.get') - def test_106_helper_url_get_with_own_dns(self, mock_request): + def test_109_helper_url_get_with_own_dns(self, mock_request): """ successful url_get_with_own_dns get with dns servers """ mock_request.return_value = {'foo': 'foo'} self.assertEqual(None, self.url_get_with_own_dns(self.logger, 'url')) @patch('acme_srv.helper.load_config') - def test_107_helper_dns_server_list_load(self, mock_load_config): + def test_110_helper_dns_server_list_load(self, mock_load_config): """ successful dns_server_list_load with empty config file """ mock_load_config.return_value = {} self.assertEqual(['9.9.9.9', '8.8.8.8'], self.dns_server_list_load()) @patch('acme_srv.helper.load_config') - def test_108_helper_dns_server_list_load(self, mock_load_config): + def test_111_helper_dns_server_list_load(self, mock_load_config): """ successful dns_server_list_load with empty Challenge section """ mock_load_config.return_value = {'Challenge': {}} self.assertEqual(['9.9.9.9', '8.8.8.8'], self.dns_server_list_load()) @patch('acme_srv.helper.load_config') - def test_109_helper_dns_server_list_load(self, mock_load_config): + def test_112_helper_dns_server_list_load(self, mock_load_config): """ successful dns_server_list_load with wrong Challenge section """ mock_load_config.return_value = {'Challenge': {'foo': 'bar'}} self.assertEqual(['9.9.9.9', '8.8.8.8'], self.dns_server_list_load()) @patch('acme_srv.helper.load_config') - def test_110_helper_dns_server_list_load(self, mock_load_config): + def test_113_helper_dns_server_list_load(self, mock_load_config): """ successful dns_server_list_load with wrong json format """ mock_load_config.return_value = {'Challenge': {'dns_server_list': 'bar'}} self.assertEqual(['9.9.9.9', '8.8.8.8'], self.dns_server_list_load()) @patch('acme_srv.helper.load_config') - def test_111_helper_dns_server_list_load(self, mock_load_config): + def test_114_helper_dns_server_list_load(self, mock_load_config): """ successful dns_server_list_load with wrong json format """ mock_load_config.return_value = {'Challenge': {'dns_server_list': '["foo", "bar"]'}} self.assertEqual(['foo', 'bar'], self.dns_server_list_load()) - def test_112_helper_csr_san_get(self): + def test_115_helper_csr_san_get(self): """ get sans but no csr """ csr = None self.assertEqual([], self.csr_san_get(self.logger, csr)) - def test_113_helper_csr_san_get(self): + def test_116_helper_csr_san_get(self): """ get sans but one san with == """ csr = 'MIIClzCCAX8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDMwfxxbCCTsZY8mTFZkoQ5cAJyQZLUiz34sDDRvEpI9ZzdNNm2AEZR7AgKNuBkLwzUzY5iQ182huNzYJYZZEvYX++ocF2ngapTMQgfB+bWS5bpWIdjnAcz1/86jmJgTciwL25dSnEWL17Yn3pAWweoewr730rq/PMyIbviQrasksnSo7abe2mctxkHjHb5sZ+Z1yRTN6ir/bObXmxr+vHeeD2vLRv4Hd5XaA1d+k31J2FVMnrn5OpWbxGHo49zd0xdy2mgTdZ9UraLaQnyGlkjYzV0rqHIAIm8HOUjGN5U75/rlOPF0x62FCICZU/z1AgRvugaA5eO8zTSQJiMiBe3AgMBAAGgOTA3BgkqhkiG9w0BCQ4xKjAoMAsGA1UdDwQEAwIF4DAZBgNVHREEEjAQgg5mb28xLmJhci5sb2NhbDANBgkqhkiG9w0BAQsFAAOCAQEANAXOIkv0CovmdzyoAv1dsiK0TK2XHBdBTEPFDsrT7MnrIXOFS4FnDrg8zpn7QBzBRTl3HaKN8fnpIHkA/6ZRDqaEJq0AeskjxIg9LKDBBx5TEdgPh1CwruRWLlXtrqU7XXQmk0wLIo/kfaDRcTjyJ3yHTEK06mCAaws0sTKlTw2D4pIiDRp8zbLHeSEUX5UKOSGbLSSUY/F2XwgPB8nC2BCD/gkvHRR+dMQSdOCiS9GLwZdYAAyESw6WhmGPjmVbeTRgSt/9//yx3JKQgkFYmpSMLKR2G525M+l1qfku/4b0iMOa4vQjFRj5AXZH0SBpAKtvnFxUpP6P9mTE7+akOQ==' self.assertEqual(['DNS:foo1.bar.local'], self.csr_san_get(self.logger, csr)) - def test_114_helper_csr_san_get(self): + def test_117_helper_csr_san_get(self): """ get sans but one san without == """ csr = 'MIIClzCCAX8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDMwfxxbCCTsZY8mTFZkoQ5cAJyQZLUiz34sDDRvEpI9ZzdNNm2AEZR7AgKNuBkLwzUzY5iQ182huNzYJYZZEvYX++ocF2ngapTMQgfB+bWS5bpWIdjnAcz1/86jmJgTciwL25dSnEWL17Yn3pAWweoewr730rq/PMyIbviQrasksnSo7abe2mctxkHjHb5sZ+Z1yRTN6ir/bObXmxr+vHeeD2vLRv4Hd5XaA1d+k31J2FVMnrn5OpWbxGHo49zd0xdy2mgTdZ9UraLaQnyGlkjYzV0rqHIAIm8HOUjGN5U75/rlOPF0x62FCICZU/z1AgRvugaA5eO8zTSQJiMiBe3AgMBAAGgOTA3BgkqhkiG9w0BCQ4xKjAoMAsGA1UdDwQEAwIF4DAZBgNVHREEEjAQgg5mb28xLmJhci5sb2NhbDANBgkqhkiG9w0BAQsFAAOCAQEANAXOIkv0CovmdzyoAv1dsiK0TK2XHBdBTEPFDsrT7MnrIXOFS4FnDrg8zpn7QBzBRTl3HaKN8fnpIHkA/6ZRDqaEJq0AeskjxIg9LKDBBx5TEdgPh1CwruRWLlXtrqU7XXQmk0wLIo/kfaDRcTjyJ3yHTEK06mCAaws0sTKlTw2D4pIiDRp8zbLHeSEUX5UKOSGbLSSUY/F2XwgPB8nC2BCD/gkvHRR+dMQSdOCiS9GLwZdYAAyESw6WhmGPjmVbeTRgSt/9//yx3JKQgkFYmpSMLKR2G525M+l1qfku/4b0iMOa4vQjFRj5AXZH0SBpAKtvnFxUpP6P9mTE7+akOQ' self.assertEqual(['DNS:foo1.bar.local'], self.csr_san_get(self.logger, csr)) - def test_115_helper_csr_san_get(self): + def test_118_helper_csr_san_get(self): """ get sans but two sans """ csr = 'MIICpzCCAY8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDMwfxxbCCTsZY8mTFZkoQ5cAJyQZLUiz34sDDRvEpI9ZzdNNm2AEZR7AgKNuBkLwzUzY5iQ182huNzYJYZZEvYX++ocF2ngapTMQgfB+bWS5bpWIdjnAcz1/86jmJgTciwL25dSnEWL17Yn3pAWweoewr730rq/PMyIbviQrasksnSo7abe2mctxkHjHb5sZ+Z1yRTN6ir/bObXmxr+vHeeD2vLRv4Hd5XaA1d+k31J2FVMnrn5OpWbxGHo49zd0xdy2mgTdZ9UraLaQnyGlkjYzV0rqHIAIm8HOUjGN5U75/rlOPF0x62FCICZU/z1AgRvugaA5eO8zTSQJiMiBe3AgMBAAGgSTBHBgkqhkiG9w0BCQ4xOjA4MAsGA1UdDwQEAwIF4DApBgNVHREEIjAggg5mb28xLmJhci5sb2NhbIIOZm9vMi5iYXIubG9jYWwwDQYJKoZIhvcNAQELBQADggEBADeuf4J8Xziw2OuvLNnLOSgHQl2HdMFtRdgJoun7zPobsP3L3qyXLvvhJcQsIJggu5ZepnHGrCxroSbtRSO65GtLQA0Rq3DCGcPIC1fe9AYrqoynx8bWt2Hd+PyDrBppHVoQzj6yNCt6XNSDs04BMtjs9Pu4DD6DDHmxFMVNdHXea2Rms7C5nLQvXgw7yOF3Zk1vEu7Kue7d3zZMhN+HwwrNEA7RGAEzHHlCv5LL4Mw+kf6OJ8nf/WDiLDKEQIh6bnOuB42Y2wUMpzui8Uur0VJO+twY46MvjiVMMBZE3aPJU33eNPAQVC7GinStn+zQIJA5AADdcO8Lk1qdtaDiGp8' self.assertEqual(['DNS:foo1.bar.local', 'DNS:foo2.bar.local'], self.csr_san_get(self.logger, csr)) - def test_116_helper_csr_san_get(self): + def test_119_helper_csr_san_get(self): """ get sans but three sans """ csr = 'MIICtzCCAZ8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDMwfxxbCCTsZY8mTFZkoQ5cAJyQZLUiz34sDDRvEpI9ZzdNNm2AEZR7AgKNuBkLwzUzY5iQ182huNzYJYZZEvYX++ocF2ngapTMQgfB+bWS5bpWIdjnAcz1/86jmJgTciwL25dSnEWL17Yn3pAWweoewr730rq/PMyIbviQrasksnSo7abe2mctxkHjHb5sZ+Z1yRTN6ir/bObXmxr+vHeeD2vLRv4Hd5XaA1d+k31J2FVMnrn5OpWbxGHo49zd0xdy2mgTdZ9UraLaQnyGlkjYzV0rqHIAIm8HOUjGN5U75/rlOPF0x62FCICZU/z1AgRvugaA5eO8zTSQJiMiBe3AgMBAAGgWTBXBgkqhkiG9w0BCQ4xSjBIMAsGA1UdDwQEAwIF4DA5BgNVHREEMjAwgg5mb28xLmJhci5sb2NhbIIOZm9vMi5iYXIubG9jYWyCDmZvbzMuYmFyLmxvY2FsMA0GCSqGSIb3DQEBCwUAA4IBAQAQRkub6G4uijaXOYpCkoz40I+SVRsbRDgnMNjsooZz1+7DVglFjrr6Pb0PPTOvOxtmbHP2KK0WokDn4LqOD2t0heuI+KPQy7m/ROpOB/YZOzTWEB8yS4vjkf/RFiJ7fnCAc8vA+3K/mBVb+89F8w/KlyPmpg1GK7UNgjEa5bnznTox8q12CocCJVykPEiC8AT/VPWUOPfg6gs+V6LO8R73VRPMVy0ttYKGX80ob+KczDTMUhoxXg8OG+G+bXXU+4Tu4l+nQWf2lFejECi/vNKzUT90IbcGJwyk7rc4Q7BJ/t/5nMo+vuV9f+2HI7qakHcw6u9RGylL4OYDf1CrqF1R' self.assertEqual(['DNS:foo1.bar.local', 'DNS:foo2.bar.local', 'DNS:foo3.bar.local'], self.csr_san_get(self.logger, csr)) - def test_117_helper_csr_san_get(self): + def test_120_helper_csr_san_get(self): """ get sans but three sans """ csr = 'MIIBFjCBvQIBADAYMRYwFAYDVQQDEw1mb28uYmFyLmxvY2FsMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAETOQukalTTCD8y7zoAsmxeAWlbi9oZtzh7XQc7A7KF4fZLP3pYjoZG6s+sXCp7bUpKhuIejrDRp1cFE5NlEK8jaBDMEEGCSqGSIb3DQEJDjE0MDIwMAYDVR0RBCkwJ4INZm9vLmJhci5sb2NhbIcEwKgOg4cQ/oAAAAAAAAACFV3//sABAjAKBggqhkjOPQQDAgNIADBFAiBKUb5r/8aSN4/utaDoi0vIcaASVZz8p1nSJ1YWSCkIpAIhAI20iVBu5j0tBmTc3uRzKIYTqsnXpH0UV8bcONy4m1Sa' self.assertEqual(['DNS:foo.bar.local', 'IP:192.168.14.131', 'IP:fe80::215:5dff:fec0:102'], self.csr_san_get(self.logger, csr)) - def test_118_helper_csr_san_byte_get(self): + def test_121_helper_csr_san_byte_get(self): """ get sans but two sans """ csr = 'MIICpzCCAY8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDMwfxxbCCTsZY8mTFZkoQ5cAJyQZLUiz34sDDRvEpI9ZzdNNm2AEZR7AgKNuBkLwzUzY5iQ182huNzYJYZZEvYX++ocF2ngapTMQgfB+bWS5bpWIdjnAcz1/86jmJgTciwL25dSnEWL17Yn3pAWweoewr730rq/PMyIbviQrasksnSo7abe2mctxkHjHb5sZ+Z1yRTN6ir/bObXmxr+vHeeD2vLRv4Hd5XaA1d+k31J2FVMnrn5OpWbxGHo49zd0xdy2mgTdZ9UraLaQnyGlkjYzV0rqHIAIm8HOUjGN5U75/rlOPF0x62FCICZU/z1AgRvugaA5eO8zTSQJiMiBe3AgMBAAGgSTBHBgkqhkiG9w0BCQ4xOjA4MAsGA1UdDwQEAwIF4DApBgNVHREEIjAggg5mb28xLmJhci5sb2NhbIIOZm9vMi5iYXIubG9jYWwwDQYJKoZIhvcNAQELBQADggEBADeuf4J8Xziw2OuvLNnLOSgHQl2HdMFtRdgJoun7zPobsP3L3qyXLvvhJcQsIJggu5ZepnHGrCxroSbtRSO65GtLQA0Rq3DCGcPIC1fe9AYrqoynx8bWt2Hd+PyDrBppHVoQzj6yNCt6XNSDs04BMtjs9Pu4DD6DDHmxFMVNdHXea2Rms7C5nLQvXgw7yOF3Zk1vEu7Kue7d3zZMhN+HwwrNEA7RGAEzHHlCv5LL4Mw+kf6OJ8nf/WDiLDKEQIh6bnOuB42Y2wUMpzui8Uur0VJO+twY46MvjiVMMBZE3aPJU33eNPAQVC7GinStn+zQIJA5AADdcO8Lk1qdtaDiGp8' self.assertEqual('MCCCDmZvbzEuYmFyLmxvY2Fsgg5mb28yLmJhci5sb2NhbA==', self.csr_san_byte_get(self.logger, csr)) @patch('acme_srv.helper.csr_load') - def test_119_helper_csr_san_get(self, mock_csrload): + def test_122_helper_csr_san_get(self, mock_csrload): """ get sans but three sans """ csr = 'csr' mock_csrload.return_value = 'mock_csrload' @@ -1000,140 +1000,140 @@ def test_119_helper_csr_san_get(self, mock_csrload): self.assertEqual([], self.csr_san_get(self.logger, csr)) self.assertIn("ERROR:test_a2c:csr_san_get(): Error: 'str' object has no attribute 'extensions'", lcm.output) - def test_120_helper_csr_extensions_get(self): + def test_123_helper_csr_extensions_get(self): """ get sns in hex """ csr = 'MIIClzCCAX8CAQAwGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDMwfxxbCCTsZY8mTFZkoQ5cAJyQZLUiz34sDDRvEpI9ZzdNNm2AEZR7AgKNuBkLwzUzY5iQ182huNzYJYZZEvYX++ocF2ngapTMQgfB+bWS5bpWIdjnAcz1/86jmJgTciwL25dSnEWL17Yn3pAWweoewr730rq/PMyIbviQrasksnSo7abe2mctxkHjHb5sZ+Z1yRTN6ir/bObXmxr+vHeeD2vLRv4Hd5XaA1d+k31J2FVMnrn5OpWbxGHo49zd0xdy2mgTdZ9UraLaQnyGlkjYzV0rqHIAIm8HOUjGN5U75/rlOPF0x62FCICZU/z1AgRvugaA5eO8zTSQJiMiBe3AgMBAAGgOTA3BgkqhkiG9w0BCQ4xKjAoMAsGA1UdDwQEAwIF4DAZBgNVHREEEjAQgg5mb28xLmJhci5sb2NhbDANBgkqhkiG9w0BAQsFAAOCAQEANAXOIkv0CovmdzyoAv1dsiK0TK2XHBdBTEPFDsrT7MnrIXOFS4FnDrg8zpn7QBzBRTl3HaKN8fnpIHkA/6ZRDqaEJq0AeskjxIg9LKDBBx5TEdgPh1CwruRWLlXtrqU7XXQmk0wLIo/kfaDRcTjyJ3yHTEK06mCAaws0sTKlTw2D4pIiDRp8zbLHeSEUX5UKOSGbLSSUY/F2XwgPB8nC2BCD/gkvHRR+dMQSdOCiS9GLwZdYAAyESw6WhmGPjmVbeTRgSt/9//yx3JKQgkFYmpSMLKR2G525M+l1qfku/4b0iMOa4vQjFRj5AXZH0SBpAKtvnFxUpP6P9mTE7+akOQ' self.assertEqual(['AwIF4A==', 'MBCCDmZvbzEuYmFyLmxvY2Fs'], self.csr_extensions_get(self.logger, csr)) - def test_121_helper_csr_extensions_get(self): + def test_124_helper_csr_extensions_get(self): """ get tnauth identifier """ csr = 'MIICuzCCAaMCAQAwHjEcMBoGA1UEAwwTY2VydC5zdGlyLmJhci5sb2NhbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALsLm4zgkl2lEx2EHy1ENfh3cYB79Xb5sD3ehkY+1pXphIWoM9KYVqHKOurModjsh75YjRBSilRfTFSk6kCUahTJyeCbM6Vzl75CcZy7poUxiK+u80JMU/xymUsrqY4GZlh2/XtFMxXHUSf3bhKZAIjBNugsvR/sHtEvJ6RJiuYqHMWUzZ/Vby5L0ywNl+LPSY7AVTUAZ0lKrnUCP4dHnbjwjf+nPi7vT6G0yrEg0qPOYXtJOXdf7vvjLi8J+ap758NtG2qapLdbToIPr0uOEvMO6zs8z1bIyjOHU3kzlpKHzDsPYy8txxKC/3Rae7sKB9gWm8WUxFBmuA7gaFDGQAECAwEAAaBYMFYGCSqGSIb3DQEJDjFJMEcwCwYDVR0PBAQDAgXgMB4GA1UdEQQXMBWCE2NlcnQuc3Rpci5iYXIubG9jYWwwGAYIKwYBBQUHARoEDDAKoAgWBjEyMzQ1NjANBgkqhkiG9w0BAQsFAAOCAQEAjyhJfgb/zJBMYp6ylRtEXgtBpsX9ePUL/iLgIDMcGtwaFm3pkQOSBr4xiTxftnqN77SlC8UEu7PDR73JX6iqLNJWucPlhAXVrr367ygO8GGLrtGddClZmo0lhRBRErgpagWB/jFkbL8afPGJwgQQXF0KWFMcajAPiIl1l6M0w11KqJ23Pwrmi7VJHzIgh4ys0D2UrX7KuV4PIOOmG0s7jTfBSB+yUH2zwVzOAzbr3wrD1WubD7hRaHDUi4bn4DRbquQOzbqfTI6QhetUcNpq4DwhBRcnZwUMJUIcxLAsFnDgGSW+dmJe6JH8MsS+8ZmOLllyQxWzYEVquQQvxFVTZA' self.assertEqual(['AwIF4A==', 'MBWCE2NlcnQuc3Rpci5iYXIubG9jYWw=', 'MAqgCBYGMTIzNDU2'], self.csr_extensions_get(self.logger, csr)) - def test_122_helper_validate_email(self): + def test_125_helper_validate_email(self): """ validate email containing "-" in domain """ self.assertTrue(self.validate_email(self.logger, 'foo@example-example.com')) - def test_123_helper_validate_email(self): + def test_126_helper_validate_email(self): """ validate email containing "-" in user""" self.assertTrue(self.validate_email(self.logger, 'foo-foo@example.com')) - def test_124_helper_get_url(self): + def test_127_helper_get_url(self): """ get_url with xforwarded https """ data_dic = {'HTTP_X_FORWARDED_PROTO': 'https', 'HTTP_HOST': 'http_host', 'SERVER_PORT': '443', 'PATH_INFO': 'path_info'} self.assertEqual('https://http_host', self.get_url(data_dic, False)) - def test_125_helper_get_url(self): + def test_128_helper_get_url(self): """ get_url with xforwarded http """ data_dic = {'HTTP_X_FORWARDED_PROTO': 'http', 'HTTP_HOST': 'http_host', 'SERVER_PORT': '443', 'PATH_INFO': 'path_info'} self.assertEqual('http://http_host', self.get_url(data_dic, False)) - def test_126_helper_validate_email(self): + def test_129_helper_validate_email(self): """ validate email containing first letter of domain cannot be a number""" self.assertFalse(self.validate_email(self.logger, 'foo@1example.com')) - def test_127_helper_validate_email(self): + def test_130_helper_validate_email(self): """ validate email containing last letter of domain cannot - """ self.assertFalse(self.validate_email(self.logger, 'foo@example-.com')) - def test_128_helper_cert_dates_get(self): + def test_131_helper_cert_dates_get(self): """ get issuing and expiration date from rsa certificate """ cert = 'MIIElTCCAn2gAwIBAgIRAKD_ulfqPUn-ggOUHOxjp40wDQYJKoZIhvcNAQELBQAwSDELMAkGA1UEBhMCREUxDzANBgNVBAgMBkJlcmxpbjEXMBUGA1UECgwOQWNtZTJDZXJ0aWZpZXIxDzANBgNVBAMMBnN1Yi1jYTAeFw0yMDA1MjcxMjMwMjNaFw0yMDA2MjYxMjMwMjNaMBkxFzAVBgNVBAMMDmZvbzEuYmFyLmxvY2FsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwbx-z-9wsEewBf1hnk3yAy5TFg-lWVdwk2QRdAMDTExVP823QF_K-t6cxJV_-QuWVbHN-lx6nQCXIqCZSN97hN0YTkrw8jnA4FpZzyvYI9rKEO3p4sxqndbu4X-gtyMBbXOLhjTlN2f7Z081XWIgkikvuZU2XzMZ-BbRFDfsPdDRwbwvgJU6NxpdIKm2DmYIP1MFo-tLu0toAc0nm9v8Otme28_kpJxmW3iOMkqN9BE-qAkggFDeNoxPtXRyP2PrRgbaj94e1uznsyni7CYw_a9O1NPrjKFQmPaCk8k9ICvPoLHXtLabekCmvdxyRlDwD_Xoaygpd9-UHCREhcOu_wIDAQABo4GoMIGlMAsGA1UdDwQEAwIF4DAZBgNVHREEEjAQgg5mb28xLmJhci5sb2NhbDAdBgNVHQ4EFgQUqy5KOBlkyX29l4EHTCSzhZuDg-EwDgYDVR0PAQH_BAQDAgWgMB8GA1UdIwQYMBaAFBs0P896R0FUZHfnxMJL52ftKQOkMAwGA1UdEwEB_wQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMA0GCSqGSIb3DQEBCwUAA4ICAQB7pQpILzxqcU2RKlr17rcne6NSJTUJnNXALeUFy5PrnjjJY1_B1cKaWluk3p7AMFvUjBpcucGCfEDudW290AQxYjrvl8_ePkzRzEkAo76L7ZqED5upYBZVn_3lA5Alr8L67UC0bDMhKTsy8WJzhWHQlMb37_YFUvtNPoI_MI09Q842VXeNQz5UDZmW9qhyeDIkf6fwOAO66VnGTLuUm2LGQZ-St2GauxR0ZUcRtMJoc-c7WOdHs8DlUCoFtglrzVH98501Sx749CG4nkJr4QNDpkw2hAhlo4Cxzp6PlljPNSgM9MsqqVdrgqDteDM_n-yrVFGezCik4QexDkWARPutRLQtpbhudExVnoFM68ihZ0y3oeDjgUBLybBQpcBAsBqiJ66Q8HTZRSqO9zlKW5Vm1KwAVDh_qgELxvqd0wIVkyxBKPta2l1fvb5YBiVqo4JyNcCTnoBS1emO4vk8XjroKijwLnU0cEXwHrY4JF1uU_kOtoZMGPul5EuBMcODLs7JJ3_IqJd8quI7Vf5zSsaB6nSzQ8XmiQiVogKflBeLl7AWmYCiL-FLP_q4dSJmvdr6fPMNy4-cfDO4Awc8RNfv-VjF5Mq57X1IXJrWKkat4lCEoPMq5WRJV8uVm6XNdwvUJxgCYR9mfol7T6imODDd7BNV4dKYvyteoS0auC0iww' self.assertEqual((1590582623, 1593174623), self.cert_dates_get(self.logger, cert)) - def test_129_helper_cert_dates_get(self): + def test_132_helper_cert_dates_get(self): """ get issuing and expiration date no certificate """ cert = None self.assertEqual((0, 0), self.cert_dates_get(self.logger, cert)) - def test_130_helper_cert_dates_get(self): + def test_133_helper_cert_dates_get(self): """ get issuing and expiration date damaged certificate """ cert = 'foo' self.assertEqual((0, 0), self.cert_dates_get(self.logger, cert)) - def test_131_helper_cert_dates_get(self): + def test_134_helper_cert_dates_get(self): """ get issuing and expiration date ecc certificate """ cert = 'MIIDozCCAYugAwIBAgIIMMxkE7mRR+YwDQYJKoZIhvcNAQELBQAwKjEXMBUGA1UECxMOYWNtZTJjZXJ0aWZpZXIxDzANBgNVBAMTBnN1Yi1jYTAeFw0yMDA3MTEwNDUzMTFaFw0yMTA3MTEwNDUzMTFaMBkxFzAVBgNVBAMMDmZvbzEuYmFyLmxvY2FsMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAER/KMoV5+zQgegqYue2ztPK2nZVpK2vxb02UzwyHw4ebhJ2gBobI23lSBRa1so1ug0kej7U+ohm5aGFdNxLM0G6OBqDCBpTALBgNVHQ8EBAMCBeAwGQYDVR0RBBIwEIIOZm9vMS5iYXIubG9jYWwwHQYDVR0OBBYEFCSaU743wU8jMETIO381r13tVLdMMA4GA1UdDwEB/wQEAwIFoDAfBgNVHSMEGDAWgBS/3o6OBiIiq61DyN3UT6irSEE+1TAMBgNVHRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATANBgkqhkiG9w0BAQsFAAOCAgEAmmhHuBhXNM2Azv53rCKY72yTQIoDVHjYrAvTmS6NsJzYflEOMkI7FCes64dWp54BerSD736Yax67b4XmLXc/+T41d7QAcnhY5xvLJiMpSsW37icHcLZpjlOrYDoRmny2U7n6t1aQ03nwgV+BgdaUQYLkUZuczs4kdqH1c9Ot9CCRTHpqSWlmWzGeRgt2uT4gKhFESP9lzx37YwKBHulBGthv1kcAaz8w8iPXBg01OEDiraXCBZFoYDEpDi2w2Y6ChCr7sNsY7aJ3a+2iHGYlktXEntk78S+g00HW61G9oLoRgeqEH3L6qVIpnswPAU/joub0YhNBIUFenCj8c3HMBgMcczzdZL+qStdymhpVkZetzXtMTKtgmxhkRzAOQUBBcHFc+wM97FqC0S4HJAuoHQ4EJ46MxwZH0jBVqcqCPMSaJ88uV902+VGGXrnxMR8RbGWLoCmsYb1ISmBUt+31PjMCYbXKwLmzvbRpO7XAQimvtOqoufl5yeRUJRLcUS6Let0QzU196/nZ789d7Etep7RjDYQm7/QhiWH197yKZ5/mUxqfyHDQ3hk5iX7S/gbo1jQXElEv5tB8Ozs+zVQmB2bXpN8c+8XUaZnwvYC2y+0LAQN4z7xilReCaasxQSsEOLCrlsannkGV704HYnnaKBS2tI948QotHnADHdfHl3o' self.assertEqual((1594443191, 1625979191), self.cert_dates_get(self.logger, cert)) @patch('dns.resolver.Resolver') - def test_132_helper_fqdn_resolve(self, mock_resolve): + def test_135_helper_fqdn_resolve(self, mock_resolve): """ successful dns-query returning covering github """ mock_resolve.return_value.query.return_value = ['foo'] self.assertEqual((None, False), self.fqdn_resolve('foo', dnssrv='10.0.0.1')) @patch('dns.resolver.Resolver') - def test_133_helper_fqdn_resolve(self, mock_resolve): + def test_136_helper_fqdn_resolve(self, mock_resolve): """ successful dns-query returning covering github """ mock_resolve.return_value.resolve.return_value = ['foo'] self.assertEqual(('foo', False), self.fqdn_resolve('foo.bar.local', dnssrv='10.0.0.1')) @patch('dns.resolver.Resolver') - def test_134_helper_fqdn_resolve(self, mock_resolve): + def test_137_helper_fqdn_resolve(self, mock_resolve): """ successful dns-query returning covering github """ mock_resolve.return_value.resolve.return_value = ['foo'] self.assertEqual((None, False), self.fqdn_resolve('foo')) @patch('dns.resolver.Resolver') - def test_135_helper_fqdn_resolve(self, mock_resolve): + def test_138_helper_fqdn_resolve(self, mock_resolve): """ successful dns-query returning one value """ mock_resolve.return_value.resolve.return_value = ['foo'] self.assertEqual(('foo', False), self.fqdn_resolve('foo.bar.local')) @patch('dns.resolver.Resolver') - def test_136_helper_fqdn_resolve(self, mock_resolve): + def test_139_helper_fqdn_resolve(self, mock_resolve): """ successful dns-query returning two values """ mock_resolve.return_value.resolve.return_value = ['bar', 'foo'] self.assertEqual(('bar', False), self.fqdn_resolve('foo.bar.local')) @patch('dns.resolver.Resolver.resolve', side_effect=Mock(side_effect=dns.resolver.NXDOMAIN)) - def test_137_helper_fqdn_resolve(self, mock_resolve): + def test_140_helper_fqdn_resolve(self, mock_resolve): """ catch NXDOMAIN """ self.assertEqual((None, True), self.fqdn_resolve('foo.bar.local')) @patch('dns.resolver.Resolver.resolve', side_effect=Mock(side_effect=dns.resolver.NoAnswer)) - def test_138_helper_fqdn_resolve(self, mock_resolve): + def test_141_helper_fqdn_resolve(self, mock_resolve): """ catch NoAnswer """ self.assertEqual((None, True), self.fqdn_resolve('foo.bar.local')) @patch('dns.resolver.Resolver.resolve', side_effect=Mock(side_effect=dns.resolver.NoNameservers)) - def test_139_helper_fqdn_resolve(self, mock_resolve): + def test_142_helper_fqdn_resolve(self, mock_resolve): """ catch other dns related execption """ self.assertEqual((None, False), self.fqdn_resolve('foo.bar.local')) @patch('dns.resolver.Resolver.resolve', side_effect=Mock(side_effect=Exception('foo'))) - def test_140_helper_fqdn_resolve(self, mock_resolve): + def test_143_helper_fqdn_resolve(self, mock_resolve): """ catch other execption """ self.assertEqual((None, False), self.fqdn_resolve('foo.bar.local')) @patch('dns.resolver.Resolver.resolve', side_effect=[Mock(side_effect=dns.resolver.NXDOMAIN), ['foo']]) - def test_141_helper_fqdn_resolve(self, mock_resolve): + def test_144_helper_fqdn_resolve(self, mock_resolve): """ catch NXDOMAIN on v4 and fine in v6 """ self.assertEqual(('foo', False), self.fqdn_resolve('foo.bar.local')) @patch('dns.resolver.Resolver.resolve', side_effect=[Mock(side_effect=dns.resolver.NoAnswer), ['foo']]) - def test_142_helper_fqdn_resolve(self, mock_resolve): + def test_145_helper_fqdn_resolve(self, mock_resolve): """ catch NoAnswer on v4 and fine in v6 """ self.assertEqual(('foo', False), self.fqdn_resolve('foo.bar.local')) @patch('dns.resolver.Resolver.resolve', side_effect=[Mock(side_effect=dns.resolver.NoNameservers), ['foo']]) - def test_143_helper_fqdn_resolve(self, mock_resolve): + def test_146_helper_fqdn_resolve(self, mock_resolve): """ catch other dns related execption on v4 and fine in v6 """ self.assertEqual(('foo', False), self.fqdn_resolve('foo.bar.local')) @patch('dns.resolver.Resolver.resolve', side_effect=[Mock(side_effect=Exception('foo')), ['foo']]) - def test_144_helper_fqdn_resolve(self, mock_resolve): + def test_147_helper_fqdn_resolve(self, mock_resolve): """ catch other execption when resolving v4 but fine in v6""" self.assertEqual(('foo', False), self.fqdn_resolve('foo.bar.local')) - def test_145_helper_signature_check(self): + def test_148_helper_signature_check(self): """ sucessful validation symmetric key""" mkey = '{"k": "ZndUSkZvVldvMEFiRzQ5VWNCdERtNkNBNnBTcTl4czNKVEVxdUZiaEdpZXZNUVJBVmRuSFREcDJYX2s3X0NxTA", "kty": "oct"}' message = '{"payload": "eyJlIjogIkFRQUIiLCAia3R5IjogIlJTQSIsICJuIjogIm5kN3ZWUTNraW4zS3BKdTd6RUZNTlVPb0ZIQmVDUWRFRTUyOF9iOHo2djNDNnYtQS0zeUdBcTFWTjZmRTluUXdYSmNlZ2ZNdm1MczlCVVllVjZ2M1FzdGhkVFRCdW5FS1l0TVVZUVRmNkpwaHNEb1pHTkt1dnpCY2ZxSlN2TXpCNHdwa3hORm1Pa2M1QVhwRzhnQWJiTTRuS3JDQkdCQ21lZ2RJUEc3U0g3Mk9tejN6YjIwemZfZlo4dHVoUzk1eUJKdndKRjhZRGtCdDViWUV5ZnQ4aVoyWVFGVmRZZW5FMDhKOGRBUGNVQy1HYld6NmJXUm9Xc0xOT21VNkVjSndsSV9tRXRqazA5aTNlVEhOa2Vna3NrZUJOeXhlSkdtaVRtMHRtS1MwOEVvY0VQTDA1UktxSm9XNnhVcHNITDcwSzdzUVRaUDBHSUY1VXBwSkZXMnlVdyJ9", "protected": "eyJ1cmwiOiAiaHR0cDovL2FjbWUtc3J2LmJhci5sb2NhbC9hY21lL25ld2FjY291bnQiLCAiYWxnIjogIkhTMjU2IiwgImtpZCI6ICJiYXIifQ", "signature": "VXYLfPuoClsn_rhPPV8qjspZV1Q7HyX8rXv6odWYnLI"}' self.assertEqual((True, None), self.signature_check(self.logger, message, mkey, json_=True)) - def test_146_helper_signature_check(self): + def test_149_helper_signature_check(self): """ sucessful validation wrong symmetric key""" mkey = '{"k": "ZndUSkZvVldvMEFiRzQ5VWNCdERtNkNBNnBTcTl4czNKVEVxdUZiaEdpZXZNUVJBVmRuSFREcDJYX2s3X0NxvA", "kty": "oct"}' message = '{"payload": "eyJlIjogIkFRQUIiLCAia3R5IjogIlJTQSIsICJuIjogIm5kN3ZWUTNraW4zS3BKdTd6RUZNTlVPb0ZIQmVDUWRFRTUyOF9iOHo2djNDNnYtQS0zeUdBcTFWTjZmRTluUXdYSmNlZ2ZNdm1MczlCVVllVjZ2M1FzdGhkVFRCdW5FS1l0TVVZUVRmNkpwaHNEb1pHTkt1dnpCY2ZxSlN2TXpCNHdwa3hORm1Pa2M1QVhwRzhnQWJiTTRuS3JDQkdCQ21lZ2RJUEc3U0g3Mk9tejN6YjIwemZfZlo4dHVoUzk1eUJKdndKRjhZRGtCdDViWUV5ZnQ4aVoyWVFGVmRZZW5FMDhKOGRBUGNVQy1HYld6NmJXUm9Xc0xOT21VNkVjSndsSV9tRXRqazA5aTNlVEhOa2Vna3NrZUJOeXhlSkdtaVRtMHRtS1MwOEVvY0VQTDA1UktxSm9XNnhVcHNITDcwSzdzUVRaUDBHSUY1VXBwSkZXMnlVdyJ9", "protected": "eyJ1cmwiOiAiaHR0cDovL2FjbWUtc3J2LmJhci5sb2NhbC9hY21lL25ld2FjY291bnQiLCAiYWxnIjogIkhTMjU2IiwgImtpZCI6ICJiYXIifQ", "signature": "VXYLfPuoClsn_rhPPV8qjspZV1Q7HyX8rXv6odWYnLI"}' @@ -1144,7 +1144,7 @@ def test_146_helper_signature_check(self): error = 'Verification failed for all signatures["Failed: [InvalidJWSSignature(\'Verification failed\')]"]' self.assertEqual((False, error), self.signature_check(self.logger, message, mkey, json_=True)) - def test_147_helper_signature_check(self): + def test_150_helper_signature_check(self): """ sucessful validation wrong symmetric key without json_ flag set """ mkey = '{"k": "ZndUSkZvVldvMEFiRzQ5VWNCdERtNkNBNnBTcTl4czNKVEVxdUZiaEdpZXZNUVJBVmRuSFREcDJYX2s3X0NxvA", "kty": "oct"}' message = '{"payload": "eyJlIjogIkFRQUIiLCAia3R5IjogIlJTQSIsICJuIjogIm5kN3ZWUTNraW4zS3BKdTd6RUZNTlVPb0ZIQmVDUWRFRTUyOF9iOHo2djNDNnYtQS0zeUdBcTFWTjZmRTluUXdYSmNlZ2ZNdm1MczlCVVllVjZ2M1FzdGhkVFRCdW5FS1l0TVVZUVRmNkpwaHNEb1pHTkt1dnpCY2ZxSlN2TXpCNHdwa3hORm1Pa2M1QVhwRzhnQWJiTTRuS3JDQkdCQ21lZ2RJUEc3U0g3Mk9tejN6YjIwemZfZlo4dHVoUzk1eUJKdndKRjhZRGtCdDViWUV5ZnQ4aVoyWVFGVmRZZW5FMDhKOGRBUGNVQy1HYld6NmJXUm9Xc0xOT21VNkVjSndsSV9tRXRqazA5aTNlVEhOa2Vna3NrZUJOeXhlSkdtaVRtMHRtS1MwOEVvY0VQTDA1UktxSm9XNnhVcHNITDcwSzdzUVRaUDBHSUY1VXBwSkZXMnlVdyJ9", "protected": "eyJ1cmwiOiAiaHR0cDovL2FjbWUtc3J2LmJhci5sb2NhbC9hY21lL25ld2FjY291bnQiLCAiYWxnIjogIkhTMjU2IiwgImtpZCI6ICJiYXIifQ", "signature": "VXYLfPuoClsn_rhPPV8qjspZV1Q7HyX8rXv6odWYnLI"}' @@ -1154,61 +1154,61 @@ def test_147_helper_signature_check(self): error = 'jwcrypto.jwk.JWK() argument after ** must be a mapping, not str' self.assertEqual((False, error), self.signature_check(self.logger, message, mkey)) - def test_148_helper_signature_check(self): + def test_151_helper_signature_check(self): """ sucessful validation invalid key """ mkey = 'invalid key' message = '{"payload": "eyJlIjogIkFRQUIiLCAia3R5IjogIlJTQSIsICJuIjogIm5kN3ZWUTNraW4zS3BKdTd6RUZNTlVPb0ZIQmVDUWRFRTUyOF9iOHo2djNDNnYtQS0zeUdBcTFWTjZmRTluUXdYSmNlZ2ZNdm1MczlCVVllVjZ2M1FzdGhkVFRCdW5FS1l0TVVZUVRmNkpwaHNEb1pHTkt1dnpCY2ZxSlN2TXpCNHdwa3hORm1Pa2M1QVhwRzhnQWJiTTRuS3JDQkdCQ21lZ2RJUEc3U0g3Mk9tejN6YjIwemZfZlo4dHVoUzk1eUJKdndKRjhZRGtCdDViWUV5ZnQ4aVoyWVFGVmRZZW5FMDhKOGRBUGNVQy1HYld6NmJXUm9Xc0xOT21VNkVjSndsSV9tRXRqazA5aTNlVEhOa2Vna3NrZUJOeXhlSkdtaVRtMHRtS1MwOEVvY0VQTDA1UktxSm9XNnhVcHNITDcwSzdzUVRaUDBHSUY1VXBwSkZXMnlVdyJ9", "protected": "eyJ1cmwiOiAiaHR0cDovL2FjbWUtc3J2LmJhci5sb2NhbC9hY21lL25ld2FjY291bnQiLCAiYWxnIjogIkhTMjU2IiwgImtpZCI6ICJiYXIifQ", "signature": "VXYLfPuoClsn_rhPPV8qjspZV1Q7HyX8rXv6odWYnLI"}' self.assertEqual((False, ''), self.signature_check(self.logger, message, mkey, json_=True)) - def test_149_fqdn_in_san_check(self): + def test_152_fqdn_in_san_check(self): """ successful check one entry one match """ fqdn = 'foo.bar.local' san_list = ['DNS:foo.bar.local'] self.assertTrue(self.fqdn_in_san_check(self.logger, san_list, fqdn)) - def test_150_fqdn_in_san_check(self): + def test_153_fqdn_in_san_check(self): """ successful check two entries one match """ fqdn = 'foo.bar.local' san_list = ['DNS:foo1.bar.local', 'DNS:foo.bar.local'] self.assertTrue(self.fqdn_in_san_check(self.logger, san_list, fqdn)) - def test_151_fqdn_in_san_check(self): + def test_154_fqdn_in_san_check(self): """ successful check two entries no DNS one match """ fqdn = 'foo.bar.local' san_list = ['IP: 10.0.0.l', 'DNS:foo.bar.local'] self.assertTrue(self.fqdn_in_san_check(self.logger, san_list, fqdn)) - def test_152_fqdn_in_san_check(self): + def test_155_fqdn_in_san_check(self): """ successful check no fqdn """ fqdn = None san_list = ['IP: 10.0.0.l', 'DNS:foo.bar.local'] self.assertFalse(self.fqdn_in_san_check(self.logger, san_list, fqdn)) - def test_153_fqdn_in_san_check(self): + def test_156_fqdn_in_san_check(self): """ successful check no fqdn """ fqdn = '' san_list = ['IP: 10.0.0.l', 'DNS:foo.bar.local'] self.assertFalse(self.fqdn_in_san_check(self.logger, san_list, fqdn)) - def test_154_fqdn_in_san_check(self): + def test_157_fqdn_in_san_check(self): """ successful check blank fqdn """ fqdn = ' ' san_list = ['IP: 10.0.0.l', 'DNS:foo.bar.local'] self.assertFalse(self.fqdn_in_san_check(self.logger, san_list, fqdn)) - def test_155_fqdn_in_san_check(self): + def test_158_fqdn_in_san_check(self): """ successful check empty san_list """ fqdn = 'foo.bar.local' san_list = [] self.assertFalse(self.fqdn_in_san_check(self.logger, san_list, fqdn)) - def test_156_fqdn_in_san_check(self): + def test_159_fqdn_in_san_check(self): """ successful check two entries one match """ fqdn = 'foo.bar.local' san_list = ['foo1.bar.local', 'DNS:foo.bar.local'] self.assertTrue(self.fqdn_in_san_check(self.logger, san_list, fqdn)) - def test_157_fqdn_in_san_check(self): + def test_160_fqdn_in_san_check(self): """ successful check two entries one match """ fqdn = 'foo.bar.local' san_list = ['foo1.bar.local'] @@ -1216,42 +1216,42 @@ def test_157_fqdn_in_san_check(self): self.assertFalse(self.fqdn_in_san_check(self.logger, san_list, fqdn)) self.assertIn('ERROR:test_a2c:ERROR: fqdn_in_san_check() SAN split failed: foo1.bar.local', lcm.output) - def test_158_sha256_hash_hex(self): + def test_161_sha256_hash_hex(self): """ sha256 digest as hex file """ self.assertEqual('2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae', self.sha256_hash_hex(self.logger, 'foo')) - def test_159_sha256_hash_hex(self): + def test_162_sha256_hash_hex(self): """ sha256 digest as hex file """ self.assertEqual('fcde2b2edba56bf408601fb721fe9b5c338d10ee429ea04fae5511b68fbf8fb9', self.sha256_hash_hex(self.logger, 'bar')) - def test_160_sha256_hash(self): + def test_163_sha256_hash(self): """ sha256 digest """ self.assertEqual(b'LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564', self.b64_url_encode(self.logger, self.sha256_hash(self.logger, 'foo'))) - def test_161_sha256_hash(self): + def test_164_sha256_hash(self): """ sha256 digest """ self.assertEqual(b'_N4rLtula_QIYB-3If6bXDONEO5CnqBPrlURto-_j7k', self.b64_url_encode(self.logger, self.sha256_hash(self.logger, 'bar'))) - def test_162_b64_encode(self): + def test_165_b64_encode(self): """ base64 encode string """ self.assertEqual('Zm9v', self.b64_encode(self.logger, b'foo')) - def test_163_b64_encode(self): + def test_166_b64_encode(self): """ base64 encode string """ self.assertEqual('YmFyMQ==', self.b64_encode(self.logger, b'bar1')) - def test_164_b64_encode(self): + def test_167_b64_encode(self): """ base64 encode string """ self.assertEqual('YmFyMTI=', self.b64_encode(self.logger, b'bar12')) - def test_165_cert_der2pem(self): + def test_168_cert_der2pem(self): """ test cert_der2pem """ b64 = 'MIIETjCCAjagAwIBAgIRAIG11e4S8ErJuwCYAKsoU3UwDQYJKoZIhvcNAQELBQAwETEPMA0GA1UEAxMGc3ViLWNhMB4XDTIxMDYxMjA2MjMzOFoXDTIzMDYwMjA2MjMzOFowGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0lk4lyEIa0VL/u5ic01Zo/o+gyYqFpU7xe+nbFgiKA+R1rqrzP/sR6xjHqS0Rkv/BcBXf81sp/+iDmwIQLVlBTkKdimqVHCJMAbTL8ZNpcLDaRUce4liyX1cmczPTSqI/kcyEr8tKpYN+KzvKZZsNx2Pbgu7y7/70P2uSywiW+sqYZ+X28KGFxq6wwENzJtweDVsbWql9LLtw6daF41UQg10auNlRL1nhW0SlWZh1zPPW/0sa6C3xX28jjVh843b4ekkRNLXSEYQMTi0qYR2LomQ5aTlQ/hellf17UknfN2aA2RH5D7Ek+mndj/rH21bxQg26KRmHlaJld9K1IfvJAgMBAAGjgZgwgZUwCwYDVR0PBAQDAgXgMBkGA1UdEQQSMBCCDmZvbzEuYmFyLmxvY2FsMB0GA1UdDgQWBBReDKlEWwro02ljWMCi10HMqhDmbzAfBgNVHSMEGDAWgBSDJ855iatD1k7LCUzmM5yhe4IzeDAMBgNVHRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATANBgkqhkiG9w0BAQsFAAOCAgEAhv7Jco6VjT25FuyOz/C0N5+q2M8sqjcDDYMwUTKXVkIc7/lSsubL8z64eS4I5iBecNOlPXASMoMe0KbdrvzqItYgeisC08rnWQayuDr/dj2Y/v4WptZdTPc0pWZQ7LUSxcZaydMFsIKxtfO2HR84DqrUbpvDfVSP7/UiN2O0TbSBiEC6Xayu6IudGZ9naHTAXzTau6SejcbH+0jWZsDXd1SbDPd3a+ZcHbDLIZAzsjcurleDPS54PIXjblOgMrsheDq/wzxKtvLOZEe8Gr6THwtX6uS0oQ72BFNGfZVVPFiL/q0Dvj2FveBtv7k14QcBqHutE4pEpYb/kcU7cxCVgGlUw8Q8trYQhBB37X9dOHjC2G8cyCeyVr+xfUE12wTKZDRIXjG3FMpKgeB4oNYPWA5m/1GBOGddhmogIB8GXeenDcAjBdVOFuuOrMInHLnLD9w7iEiopfx+six3Nxpo3thDV4xdiTZsWp9ojZhQzW8haEQleJ3Xyl65UuZKHyrRJ0OWR4LRkNwJitG5F0MYg8bjgik/cHTwzIB0HXgnaVeMBJY3sOkvCpAlTGZe1GL9foWIeFkprPG4cePrjtC3Mn8rHH0pIi1mdkcAIdexYdg/qlroKk2ROLXnX5LHmrM1CDZQphgyzLETdwXQdTBOJvc8FsDPhp5p+iqgT2e16QI=' result = b'-----BEGIN CERTIFICATE-----\nMIIETjCCAjagAwIBAgIRAIG11e4S8ErJuwCYAKsoU3UwDQYJKoZIhvcNAQELBQAw\nETEPMA0GA1UEAxMGc3ViLWNhMB4XDTIxMDYxMjA2MjMzOFoXDTIzMDYwMjA2MjMz\nOFowGTEXMBUGA1UEAwwOZm9vMS5iYXIubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUA\nA4IBDwAwggEKAoIBAQC0lk4lyEIa0VL/u5ic01Zo/o+gyYqFpU7xe+nbFgiKA+R1\nrqrzP/sR6xjHqS0Rkv/BcBXf81sp/+iDmwIQLVlBTkKdimqVHCJMAbTL8ZNpcLDa\nRUce4liyX1cmczPTSqI/kcyEr8tKpYN+KzvKZZsNx2Pbgu7y7/70P2uSywiW+sqY\nZ+X28KGFxq6wwENzJtweDVsbWql9LLtw6daF41UQg10auNlRL1nhW0SlWZh1zPPW\n/0sa6C3xX28jjVh843b4ekkRNLXSEYQMTi0qYR2LomQ5aTlQ/hellf17UknfN2aA\n2RH5D7Ek+mndj/rH21bxQg26KRmHlaJld9K1IfvJAgMBAAGjgZgwgZUwCwYDVR0P\nBAQDAgXgMBkGA1UdEQQSMBCCDmZvbzEuYmFyLmxvY2FsMB0GA1UdDgQWBBReDKlE\nWwro02ljWMCi10HMqhDmbzAfBgNVHSMEGDAWgBSDJ855iatD1k7LCUzmM5yhe4Iz\neDAMBgNVHRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAN\nBgkqhkiG9w0BAQsFAAOCAgEAhv7Jco6VjT25FuyOz/C0N5+q2M8sqjcDDYMwUTKX\nVkIc7/lSsubL8z64eS4I5iBecNOlPXASMoMe0KbdrvzqItYgeisC08rnWQayuDr/\ndj2Y/v4WptZdTPc0pWZQ7LUSxcZaydMFsIKxtfO2HR84DqrUbpvDfVSP7/UiN2O0\nTbSBiEC6Xayu6IudGZ9naHTAXzTau6SejcbH+0jWZsDXd1SbDPd3a+ZcHbDLIZAz\nsjcurleDPS54PIXjblOgMrsheDq/wzxKtvLOZEe8Gr6THwtX6uS0oQ72BFNGfZVV\nPFiL/q0Dvj2FveBtv7k14QcBqHutE4pEpYb/kcU7cxCVgGlUw8Q8trYQhBB37X9d\nOHjC2G8cyCeyVr+xfUE12wTKZDRIXjG3FMpKgeB4oNYPWA5m/1GBOGddhmogIB8G\nXeenDcAjBdVOFuuOrMInHLnLD9w7iEiopfx+six3Nxpo3thDV4xdiTZsWp9ojZhQ\nzW8haEQleJ3Xyl65UuZKHyrRJ0OWR4LRkNwJitG5F0MYg8bjgik/cHTwzIB0HXgn\naVeMBJY3sOkvCpAlTGZe1GL9foWIeFkprPG4cePrjtC3Mn8rHH0pIi1mdkcAIdex\nYdg/qlroKk2ROLXnX5LHmrM1CDZQphgyzLETdwXQdTBOJvc8FsDPhp5p+iqgT2e1\n6QI=\n-----END CERTIFICATE-----\n' der = self.b64_decode(self.logger, b64) self.assertEqual(result, self.cert_der2pem(der)) - def test_166_cert_pem2der(self): + def test_169_cert_pem2der(self): """ test cert_der2pem """ cert = """-----BEGIN CERTIFICATE----- MIIEZDCCAkygAwIBAgIIe941mx0FQtAwDQYJKoZIhvcNAQELBQAwKjEXMBUGA1UE @@ -1282,7 +1282,7 @@ def test_166_cert_pem2der(self): result = 'MIIEZDCCAkygAwIBAgIIe941mx0FQtAwDQYJKoZIhvcNAQELBQAwKjEXMBUGA1UECxMOYWNtZTJjZXJ0aWZpZXIxDzANBgNVBAMTBnN1Yi1jYTAeFw0yMTA0MDkxNTUyMDBaFw0yNjA0MDkxNTUyMDBaMBgxFjAUBgNVBAMTDWVzdGNsaWVudC5lc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDAn6IqwTE1RvZUm3gelpu4tmrdFj8Ub98J1YeQz7qrew5iA81NeH9tR484edjcY0ieOt3e1MfxJoziWtaeqxpsfytmVB/i+850kVZmvRCR1jhW/4AzidkVBMQiCR5erPmmheeCxbKkto0rHb7ziRA+F8/fZLKfLNsahEQPxDuMItyQFCOQFHh8Hfuend2NgsQKeZ1r5Czf3n5Q6NFff7HG+MDeNDNdPB3ShgcvvNCFUS1z615/GIItfSqcWTAVaJ7436cA7yy5y4+0SvjfXYtHYfythBj/5UqlUmjni8Irj5K8uEtb1YUujmvlTTbzPkhYqIkSoyr7t21Dz+gcYn49AgMBAAGjgZ8wgZwwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUN3Z0iLv1FE17DCDBfpxW2P+5+kIwCwYDVR0PBAQDAgO4MBMGA1UdJQQMMAoGCCsGAQUFBwMCMBgGA1UdEQQRMA+CDWVzdGNsaWVudC5lc3QwEQYJYIZIAYb4QgEBBAQDAgWgMB4GCWCGSAGG+EIBDQQRFg94Y2EgY2VydGlmaWNhdGUwDQYJKoZIhvcNAQELBQADggIBACMAHHH4/0eAXbS/uKsIjLN1QPnnzgjxC0xoUon8UVM0PUMH+FMg6rs21Xyl5tn5iItmvKI9c3akAZ00RUQKVdmJVFRUKywmfF7n5epBpXtWJrSH817NT9GOp+PO5VUTDV5VkvpVLoy7WzThrheLKz1nC1dWowRz86tcBLAsC1zT17fsNZXQDuv4LiQQXs7QKhUU75r1IxrdBPeBQSP5skGpWxm8sapQSfOALoXu1pSoGIr6tqvNGuEoZGvUuWeQHG/G8c2ufL+6lEzZBBCd6e2tErkqD/vqfCRzbLcGgSPX0HVWdkjH09nHWXI5UhNr2YgGF7YvSTKWJfbDVlTql1BuSn2yTQtDk4E8k9BLr8WfqFSZvYrivT9Ax1n3BD9jvQL5+QRdioH1kqNGMme0Pb43pHciX4hu9L5rGenZRmxeGXZ78uSOR+n2bGxAMw1OY7Rx/lsNSKWDSN+7xIrwjjXO5Uthev1ecrLAK2+EpjITa6Y85ms39V4ypCEdujkKEBeVxuN8DdMJ2GaFGluSRZeYZ0LAPfYr5sp6G6904WF+PcT0WjGenH4PJLXrAttbhhvQxXU0Q8s2CUwUHy5OT/DW3POq7WETc+zmFGwZqiP3W9gmN0hHXsKqkNmz2RYgoH57lPS1PJb0klGUNHG98CtsmlhrivhSTJWqSIOfyKGF' self.assertEqual(result, self.b64_encode(self.logger, self.cert_pem2der(cert))) - def test_167_helper_cert_extensions_get(self): + def test_170_helper_cert_extensions_get(self): """ test cert_san_get for a single SAN and recode = False""" cert = """-----BEGIN CERTIFICATE----- MIIEZDCCAkygAwIBAgIIe941mx0FQtAwDQYJKoZIhvcNAQELBQAwKjEXMBUGA1UE @@ -1312,47 +1312,47 @@ def test_167_helper_cert_extensions_get(self): -----END CERTIFICATE-----""" self.assertEqual(['MAA=', 'BBQ3dnSIu/UUTXsMIMF+nFbY/7n6Qg==', 'AwIDuA==', 'MAoGCCsGAQUFBwMC', 'MA+CDWVzdGNsaWVudC5lc3Q=', 'AwIFoA==', 'Fg94Y2EgY2VydGlmaWNhdGU='], self.cert_extensions_get(self.logger, cert, recode=False)) - def test_168_helper_cert_extensions_get(self): + def test_171_helper_cert_extensions_get(self): """ test cert_san_get for a single SAN and recode = True""" cert = "MIIEZDCCAkygAwIBAgIIe941mx0FQtAwDQYJKoZIhvcNAQELBQAwKjEXMBUGA1UECxMOYWNtZTJjZXJ0aWZpZXIxDzANBgNVBAMTBnN1Yi1jYTAeFw0yMTA0MDkxNTUyMDBaFw0yNjA0MDkxNTUyMDBaMBgxFjAUBgNVBAMTDWVzdGNsaWVudC5lc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDAn6IqwTE1RvZUm3gelpu4tmrdFj8Ub98J1YeQz7qrew5iA81NeH9tR484edjcY0ieOt3e1MfxJoziWtaeqxpsfytmVB/i+850kVZmvRCR1jhW/4AzidkVBMQiCR5erPmmheeCxbKkto0rHb7ziRA+F8/fZLKfLNsahEQPxDuMItyQFCOQFHh8Hfuend2NgsQKeZ1r5Czf3n5Q6NFff7HG+MDeNDNdPB3ShgcvvNCFUS1z615/GIItfSqcWTAVaJ7436cA7yy5y4+0SvjfXYtHYfythBj/5UqlUmjni8Irj5K8uEtb1YUujmvlTTbzPkhYqIkSoyr7t21Dz+gcYn49AgMBAAGjgZ8wgZwwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUN3Z0iLv1FE17DCDBfpxW2P+5+kIwCwYDVR0PBAQDAgO4MBMGA1UdJQQMMAoGCCsGAQUFBwMCMBgGA1UdEQQRMA+CDWVzdGNsaWVudC5lc3QwEQYJYIZIAYb4QgEBBAQDAgWgMB4GCWCGSAGG+EIBDQQRFg94Y2EgY2VydGlmaWNhdGUwDQYJKoZIhvcNAQELBQADggIBACMAHHH4/0eAXbS/uKsIjLN1QPnnzgjxC0xoUon8UVM0PUMH+FMg6rs21Xyl5tn5iItmvKI9c3akAZ00RUQKVdmJVFRUKywmfF7n5epBpXtWJrSH817NT9GOp+PO5VUTDV5VkvpVLoy7WzThrheLKz1nC1dWowRz86tcBLAsC1zT17fsNZXQDuv4LiQQXs7QKhUU75r1IxrdBPeBQSP5skGpWxm8sapQSfOALoXu1pSoGIr6tqvNGuEoZGvUuWeQHG/G8c2ufL+6lEzZBBCd6e2tErkqD/vqfCRzbLcGgSPX0HVWdkjH09nHWXI5UhNr2YgGF7YvSTKWJfbDVlTql1BuSn2yTQtDk4E8k9BLr8WfqFSZvYrivT9Ax1n3BD9jvQL5+QRdioH1kqNGMme0Pb43pHciX4hu9L5rGenZRmxeGXZ78uSOR+n2bGxAMw1OY7Rx/lsNSKWDSN+7xIrwjjXO5Uthev1ecrLAK2+EpjITa6Y85ms39V4ypCEdujkKEBeVxuN8DdMJ2GaFGluSRZeYZ0LAPfYr5sp6G6904WF+PcT0WjGenH4PJLXrAttbhhvQxXU0Q8s2CUwUHy5OT/DW3POq7WETc+zmFGwZqiP3W9gmN0hHXsKqkNmz2RYgoH57lPS1PJb0klGUNHG98CtsmlhrivhSTJWqSIOfyKGF" self.assertEqual(['MAA=', 'BBQ3dnSIu/UUTXsMIMF+nFbY/7n6Qg==', 'AwIDuA==', 'MAoGCCsGAQUFBwMC', 'MA+CDWVzdGNsaWVudC5lc3Q=', 'AwIFoA==', 'Fg94Y2EgY2VydGlmaWNhdGU='], self.cert_extensions_get(self.logger, cert, recode=True)) - def test_169_csr_dn_get(self): + def test_172_csr_dn_get(self): """" test csr_dn_get """ csr = 'MIICjDCCAXQCAQAwFzEVMBMGA1UEAwwMdGVzdF9yZXF1ZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy6VRYaXuLS/DPa+pf5IEwycpjPfZ2vTFlvjvhwu9A3yaQQn4kD33Fu4p+zorIVmsjgpkUel2104lxFeSV081YKGzOtsajzaIRZhF7mHG5aVA8cahVPHlnxT06kO8F545ZsxE6T22tCbrLJpZk4hcaQUmGcZDWZqI7CXhbi1LSuIVIAAF0lTGMsanIM97ZEtA9mhtxFd7TsLlJpmls1l8MTavFcBtAZXqAsi4LnzEbozSjaLnuXsTe7tPmOS0uOLX+EcTAH/SxkbIg3whehTzC/sVmz5STbpklq3QuudtUl/509fpSa/UQ+WFOUUC3GhiiMM813ZsbAnt1BJepKtrfQIDAQABoDAwLgYJKoZIhvcNAQkOMSEwHzAdBgNVHREEFjAUghJ0ZXN0X3JlcXVlc3QubG9jYWwwDQYJKoZIhvcNAQELBQADggEBAFcKxjJXHBVjzqF3e6fCkDbF1JnVtNyDxZB+h4b5lI7SIuA9O/+0hcl/njeFB1gJbRODws10kKkiAYLXvS/fsLJg1gdyFPmDiCd2nJhDUCBcGmVYraGhV45x67jcUmoeqSSj5KyUY9zI+v3nANvZMf+g31ORtW8PuspkiiLJiyuGzFS67DGovbcBRrM67IApO7p04VwLA0hssFUa+wF9PUWIyu9TLx+w0rNYcp3d1wkJ905TB8gwOKXeB0RwkporlOF3KEcT+ueKZE04867bjZ/ZpiuIDFnO23MsUKLKU9ebWgwYN/xzxA8sroM69y+Acpt9Zwn3vRjVlT92Ztl218Q=' self.assertEqual('CN=test_request', self.csr_dn_get(self.logger, csr)) - def test_170_logger_setup(self): + def test_173_logger_setup(self): """ logger setup """ self.assertTrue(self.logger_setup(False)) - def test_171_logger_setup(self): + def test_174_logger_setup(self): """ logger setup """ self.assertTrue(self.logger_setup(True)) @patch('acme_srv.helper.load_config') - def test_172_logger_setup(self, mock_load_cfg): + def test_175_logger_setup(self, mock_load_cfg): """ logger setup """ mock_load_cfg.return_value = {'Helper': {'log_format': 'foo'}} self.assertTrue(self.logger_setup(True)) @patch('configparser.RawConfigParser') - def test_173_load_config(self, mock_parser): + def test_176_load_config(self, mock_parser): """ load config """ self.assertTrue(self.load_config(None, None, None)) @patch('configparser.RawConfigParser') - def test_174_load_config(self, mock_parser): + def test_177_load_config(self, mock_parser): """ load config """ self.assertTrue(self.load_config(self.logger, None, None)) @patch.dict('os.environ', {'ACME_SRV_CONFIGFILE': 'ACME_SRV_CONFIGFILE'}) @patch('configparser.RawConfigParser') - def test_175_load_config(self, mock_parser): + def test_178_load_config(self, mock_parser): """ load config """ self.assertTrue(self.load_config(None, None, None)) - def test_176_logger_info(self): + def test_179_logger_info(self): """ logger info """ addr = 'addr' url = 'url' @@ -1361,7 +1361,7 @@ def test_176_logger_info(self): self.logger_info(self.logger, addr, url, data_dic) self.assertIn("INFO:test_a2c:addr url {'foo': 'bar'}", lcm.output) - def test_177_logger_info(self): + def test_180_logger_info(self): """ logger info replace remove Nonce in header """ addr = 'addr' url = 'url' @@ -1370,7 +1370,7 @@ def test_177_logger_info(self): self.logger_info(self.logger, addr, url, data_dic) self.assertIn("INFO:test_a2c:addr url {'foo': 'bar', 'header': {'Replay-Nonce': '- modified -'}}", lcm.output) - def test_178_logger_info(self): + def test_181_logger_info(self): """ logger info replace remnove cert """ addr = 'addr' url = '/acme/cert/secret' @@ -1379,7 +1379,7 @@ def test_178_logger_info(self): self.logger_info(self.logger, addr, url, data_dic) self.assertIn("INFO:test_a2c:addr /acme/cert/secret {'foo': 'bar', 'data': ' - certificate - '}", lcm.output) - def test_179_logger_info(self): + def test_182_logger_info(self): """ logger info replace remove token """ addr = 'addr' url = 'url' @@ -1388,7 +1388,7 @@ def test_179_logger_info(self): self.logger_info(self.logger, addr, url, data_dic) self.assertIn("INFO:test_a2c:addr url {'foo': 'bar', 'data': {'token': '- modified -'}}", lcm.output) - def test_180_logger_info(self): + def test_183_logger_info(self): """ logger info replace remove single token in challenges """ addr = 'addr' url = 'url' @@ -1397,7 +1397,7 @@ def test_180_logger_info(self): self.logger_info(self.logger, addr, url, data_dic) self.assertIn("INFO:test_a2c:addr url {'foo': 'bar', 'data': {'challenges': [{'foo1': 'bar1', 'token': '- modified - '}]}}", lcm.output) - def test_181_logger_info(self): + def test_184_logger_info(self): """ logger info replace remove two token in challenges """ addr = 'addr' url = 'url' @@ -1407,31 +1407,31 @@ def test_181_logger_info(self): self.assertIn("INFO:test_a2c:addr url {'foo': 'bar', 'data': {'challenges': [{'foo1': 'bar1', 'token': '- modified - '}, {'foo2': 'bar2', 'token': '- modified - '}]}}", lcm.output) @patch('builtins.print') - def test_182_print_debug(self, mock_print): + def test_185_print_debug(self, mock_print): """ test print_debug """ self.print_debug(False, 'test') self.assertFalse(mock_print.called) @patch('builtins.print') - def test_183_print_debug(self, mock_print): + def test_186_print_debug(self, mock_print): """ test print_debug """ self.print_debug(True, 'test') self.assertTrue(mock_print.called) - def test_184_jwk_thumbprint_get(self): + def test_187_jwk_thumbprint_get(self): """ test jwk_thumbprint_get with empty pubkey """ pub_key = None self.assertFalse(self.jwk_thumbprint_get(self.logger, pub_key)) @patch('jwcrypto.jwk.JWK') - def test_185_jwk_thumbprint_get(self, mock_jwk): + def test_188_jwk_thumbprint_get(self, mock_jwk): """ test jwk_thumbprint_get with pubkey """ pub_key = {'pub_key': 'pub_key'} mock_jwk = Mock() self.assertTrue(self.jwk_thumbprint_get(self.logger, pub_key)) @patch('jwcrypto.jwk.JWK') - def test_186_jwk_thumbprint_get(self, mock_jwk): + def test_189_jwk_thumbprint_get(self, mock_jwk): """ test jwk_thumbprint_get with pubkey """ pub_key = {'pub_key': 'pub_key'} mock_jwk.side_effect = Exception('exc_jwk_jwk') @@ -1440,11 +1440,11 @@ def test_186_jwk_thumbprint_get(self, mock_jwk): self.assertIn('ERROR:test_a2c:jwk_thumbprint_get(): error: exc_jwk_jwk', lcm.output) @patch('socket.AF_INET') - def test_187_allowed_gai_family(self, mock_sock): + def test_190_allowed_gai_family(self, mock_sock): """ test allowed_gai_family """ self.assertTrue(self.allowed_gai_family()) - def test_188_validate_csr(self): + def test_191_validate_csr(self): """ patched_create_connection """ self.assertTrue(self.validate_csr(self.logger, 'oder_dic', 'csr')) @@ -1452,7 +1452,7 @@ def test_188_validate_csr(self): @patch('ssl.DER_cert_to_PEM_cert') @patch('ssl.SSLContext.wrap_socket') @patch('socks.socksocket') - def test_189_servercert_get(self, mock_sock, mock_context, mock_cert, mock_convert): + def test_192_servercert_get(self, mock_sock, mock_context, mock_cert, mock_convert): """ test servercert get """ mock_convert.return_value = ('proxy_proto', 'proxy_addr', 'proxy_port') mock_sock = Mock() @@ -1466,7 +1466,7 @@ def test_189_servercert_get(self, mock_sock, mock_context, mock_cert, mock_conve @patch('ssl.SSLContext.wrap_socket') @patch('socket.socket') @patch('socks.socksocket') - def test_190_servercert_get(self, mock_sock, mock_ssock, mock_context, mock_cert, mock_convert, mock_ipchk): + def test_193_servercert_get(self, mock_sock, mock_ssock, mock_context, mock_cert, mock_convert, mock_ipchk): """ test servercert get ippv6 """ mock_convert.return_value = ('proxy_proto', 'proxy_addr', 'proxy_port') mock_ipchk.return_value = True @@ -1481,7 +1481,7 @@ def test_190_servercert_get(self, mock_sock, mock_ssock, mock_context, mock_cert @patch('ssl.SSLContext.wrap_socket') @patch('socket.socket') @patch('socks.socksocket') - def test_191_servercert_get(self, mock_sock, mock_ssock, mock_context, mock_cert, mock_convert): + def test_194_servercert_get(self, mock_sock, mock_ssock, mock_context, mock_cert, mock_convert): """ test servercert get with proxy """ mock_convert.return_value = ('proxy_proto', 'proxy_addr', 'proxy_port') mock_context = Mock() @@ -1493,7 +1493,7 @@ def test_191_servercert_get(self, mock_sock, mock_ssock, mock_context, mock_cert @patch('ssl.DER_cert_to_PEM_cert') @patch('ssl.SSLContext.wrap_socket') @patch('socks.socksocket') - def test_192_servercert_get(self, mock_sock, mock_context, mock_cert): + def test_195_servercert_get(self, mock_sock, mock_context, mock_cert): """ test servercert exception """ mock_sock = Mock() mock_context.side_effect = Exception('exc_warp_sock') @@ -1505,7 +1505,7 @@ def test_192_servercert_get(self, mock_sock, mock_context, mock_cert): @patch('dns.resolver.Resolver') @patch('dns.resolver.resolve') - def test_193_txt_get(self, mock_resolve, mock_res): + def test_196_txt_get(self, mock_resolve, mock_res): """ successful dns-query returning one txt record """ resp_obj = Mock() resp_obj.strings = ['foo', 'bar'] @@ -1514,7 +1514,7 @@ def test_193_txt_get(self, mock_resolve, mock_res): self.assertTrue(mock_res.called) @patch('dns.resolver.resolve') - def test_194_txt_get(self, mock_resolve): + def test_197_txt_get(self, mock_resolve): """ successful dns-query returning one txt record """ resp_obj = Mock() resp_obj.strings = ['foo', 'bar'] @@ -1522,7 +1522,7 @@ def test_194_txt_get(self, mock_resolve): self.assertEqual(['foo'], self.txt_get(self.logger, 'foo')) @patch('dns.resolver.resolve') - def test_195_txt_get(self, mock_resolve): + def test_198_txt_get(self, mock_resolve): """ successful dns-query returning one txt record """ resp_obj1 = Mock() resp_obj1.strings = ['foo1', 'bar1'] @@ -1532,136 +1532,136 @@ def test_195_txt_get(self, mock_resolve): self.assertEqual(['foo1', 'foo2'], self.txt_get(self.logger, 'foo')) @patch('dns.resolver.resolve') - def test_196_txt_get(self, mock_resolve): + def test_199_txt_get(self, mock_resolve): """ successful dns-query returning one txt record """ mock_resolve.side_effect = Exception('mock_resolve') with self.assertLogs('test_a2c', level='INFO') as lcm: self.assertFalse(self.txt_get(self.logger, 'foo')) self.assertIn('ERROR:test_a2c:txt_get() error: mock_resolve', lcm.output) - def test_197_proxystring_convert(self): + def test_200_proxystring_convert(self): """ convert proxy_string http """ self.assertEqual((3, 'proxy', 8080), self.proxystring_convert(self.logger, 'http://proxy:8080')) - def test_198_proxystring_convert(self): + def test_201_proxystring_convert(self): """ convert proxy_string socks4 """ self.assertEqual((1, 'proxy', 8080), self.proxystring_convert(self.logger, 'socks4://proxy:8080')) - def test_199_proxystring_convert(self): + def test_202_proxystring_convert(self): """ convert proxy_string socks5 """ self.assertEqual((2, 'proxy', 8080), self.proxystring_convert(self.logger, 'socks5://proxy:8080')) - def test_200_proxystring_convert(self): + def test_203_proxystring_convert(self): """ convert proxy_string unknown protocol """ with self.assertLogs('test_a2c', level='INFO') as lcm: self.assertEqual((None, 'proxy', 8080), self.proxystring_convert(self.logger, 'unk://proxy:8080')) self.assertIn('ERROR:test_a2c:proxystring_convert(): unknown proxy protocol: unk', lcm.output) - def test_201_proxystring_convert(self): + def test_204_proxystring_convert(self): """ convert proxy_string unknown protocol """ with self.assertLogs('test_a2c', level='INFO') as lcm: self.assertEqual((3, 'proxy', None), self.proxystring_convert(self.logger, 'http://proxy:ftp')) self.assertIn('ERROR:test_a2c:proxystring_convert(): unknown proxy port: ftp', lcm.output) - def test_202_proxystring_convert(self): + def test_205_proxystring_convert(self): """ convert proxy_string porxy sting without protocol """ with self.assertLogs('test_a2c', level='INFO') as lcm: self.assertEqual((None, None, None), self.proxystring_convert(self.logger, 'proxy')) self.assertIn('ERROR:test_a2c:proxystring_convert(): error splitting proxy_server string: proxy', lcm.output) self.assertIn('ERROR:test_a2c:proxystring_convert(): proxy_proto (None), proxy_addr (None) or proxy_port (None) missing', lcm.output) - def test_203_proxystring_convert(self): + def test_206_proxystring_convert(self): """ convert proxy_string porxy sting without port """ with self.assertLogs('test_a2c', level='INFO') as lcm: self.assertEqual((None, None, None), self.proxystring_convert(self.logger, 'http://proxy')) self.assertIn('ERROR:test_a2c:proxystring_convert(): error splitting proxy into host/port: proxy', lcm.output) self.assertIn('ERROR:test_a2c:proxystring_convert(): proxy_proto (http), proxy_addr (None) or proxy_port (None) missing', lcm.output) - def test_204_proxy_check(self): + def test_207_proxy_check(self): """ check proxy for empty list """ fqdn = 'foo.bar.local' proxy_list = {} self.assertFalse(self.proxy_check(self.logger, fqdn, proxy_list)) - def test_205_proxy_check(self): + def test_208_proxy_check(self): """ check proxy - no match """ fqdn = 'foo.bar.local' proxy_list = {'foo1.bar.local': 'proxy_match'} self.assertFalse(self.proxy_check(self.logger, fqdn, proxy_list)) - def test_206_proxy_check(self): + def test_209_proxy_check(self): """ check proxy - single entry """ fqdn = 'foo.bar.local' proxy_list = {'foo.bar.local': 'proxy_match'} self.assertEqual('proxy_match', self.proxy_check(self.logger, fqdn, proxy_list)) - def test_207_proxy_check(self): + def test_210_proxy_check(self): """ check proxy - multiple entry """ fqdn = 'foo.bar.local' proxy_list = {'bar.bar.local': 'proxy_nomatch', 'foo.bar.local': 'proxy_match'} self.assertEqual('proxy_match', self.proxy_check(self.logger, fqdn, proxy_list)) - def test_208_proxy_check(self): + def test_211_proxy_check(self): """ check proxy - multiple entrie domain match""" fqdn = 'foo.bar.local' proxy_list = {'bar.bar.local': 'proxy_nomatch', 'bar.local$': 'proxy_match'} self.assertEqual('proxy_match', self.proxy_check(self.logger, fqdn, proxy_list)) - def test_209_proxy_check(self): + def test_212_proxy_check(self): """ check proxy for empty list multiple entrie domain match""" fqdn = 'foo.bar.local' proxy_list = {'bar.local$': 'proxy_nomatch', 'foo.bar.local$': 'proxy_match'} self.assertEqual('proxy_match', self.proxy_check(self.logger, fqdn, proxy_list)) - def test_210_proxy_check(self): + def test_213_proxy_check(self): """ check proxy - multiple entrie domain match""" fqdn = 'foo.bar.local' proxy_list = {'bar.local$': 'proxy_match', 'foo1.bar.local$': 'proxy_nomatch'} self.assertEqual('proxy_match', self.proxy_check(self.logger, fqdn, proxy_list)) - def test_211_proxy_check(self): + def test_214_proxy_check(self): """ check proxy - wildcard """ fqdn = 'foo.bar.local' proxy_list = {'foo1.bar.local$': 'proxy_nomatch', '*.bar.local$': 'proxy_match'} self.assertEqual('proxy_match', self.proxy_check(self.logger, fqdn, proxy_list)) - def test_212_proxy_check(self): + def test_215_proxy_check(self): """ check proxy - wildcard """ fqdn = 'foo.bar.local' proxy_list = {'.local$': 'proxy_nomatch', '*.bar.local$': 'proxy_match'} self.assertEqual('proxy_match', self.proxy_check(self.logger, fqdn, proxy_list)) - def test_213_proxy_check(self): + def test_216_proxy_check(self): """ check proxy - wildcard """ fqdn = 'local' proxy_list = {'local$': 'proxy_match', '*.bar.local$': 'proxy_no_match'} self.assertEqual('proxy_match', self.proxy_check(self.logger, fqdn, proxy_list)) - def test_214_proxy_check(self): + def test_217_proxy_check(self): """ check proxy - wildcard """ fqdn = 'foo.bar.local' proxy_list = {'*': 'wildcard', 'notlocal$': 'proxy_no_match', '*.notbar.local$': 'proxy_no_match'} self.assertEqual('wildcard', self.proxy_check(self.logger, fqdn, proxy_list)) - def test_215_handle_exception(self): + def test_218_handle_exception(self): """ test exception handler """ exc_type = FakeDBStore exc_value = Mock() exc_traceback = Mock() self.handle_exception(exc_type, exc_value, exc_traceback) - def test_216_proxy_check(self): + def test_219_proxy_check(self): """ check proxy - wildcard """ fqdn = 'foo.bar.local' proxy_list = {'*.bar.local$': 'proxy_match'} self.assertEqual('proxy_match', self.proxy_check(self.logger, fqdn, proxy_list)) - def test_217_ca_handler_load(self): + def test_220_ca_handler_load(self): """ test ca_handler_load """ config_dic = {'foo': 'bar'} self.assertFalse(self.ca_handler_load(self.logger, config_dic)) - def test_218_ca_handler_load(self): + def test_221_ca_handler_load(self): """ test ca_handler_load """ config_dic = {'foo': 'bar'} with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -1669,7 +1669,7 @@ def test_218_ca_handler_load(self): self.assertIn('ERROR:test_a2c:Helper.ca_handler_load(): CAhandler configuration missing in config file', lcm.output) @patch('importlib.import_module') - def test_219_ca_handler_load(self, mock_imp): + def test_222_ca_handler_load(self, mock_imp): """ test ca_handler_load """ config_dic = {'CAhandler': {'foo': 'bar'}} mock_imp.side_effect = Exception('exc_mock_imp') @@ -1678,14 +1678,14 @@ def test_219_ca_handler_load(self, mock_imp): self.assertIn('CRITICAL:test_a2c:Helper.ca_handler_load(): loading default CAhandler failed with err: exc_mock_imp', lcm.output) @patch('importlib.import_module') - def test_220_ca_handler_load(self, mock_imp): + def test_223_ca_handler_load(self, mock_imp): """ test ca_handler_load """ config_dic = {'CAhandler': {'foo': 'bar'}} mock_imp.return_value = 'foo' self.assertEqual('foo', self.ca_handler_load(self.logger, config_dic)) @patch('importlib.util') - def test_221_ca_handler_load(self, mock_util): + def test_224_ca_handler_load(self, mock_util): """ test ca_handler_load """ config_dic = {'CAhandler': {'handler_file': 'foo'}} mock_util.module_from_spec = Mock(return_value='foo') @@ -1693,7 +1693,7 @@ def test_221_ca_handler_load(self, mock_util): @patch('importlib.import_module') @patch('importlib.util') - def test_222_ca_handler_load(self, mock_util, mock_imp): + def test_225_ca_handler_load(self, mock_util, mock_imp): """ test ca_handler_load """ config_dic = {'CAhandler': {'handler_file': 'foo'}} mock_util.module_from_spec.side_effect = Exception('exc_mock_util') @@ -1704,7 +1704,7 @@ def test_222_ca_handler_load(self, mock_util, mock_imp): @patch('importlib.import_module') @patch('importlib.util') - def test_223_ca_handler_load(self, mock_util, mock_imp): + def test_226_ca_handler_load(self, mock_util, mock_imp): """ test ca_handler_load """ config_dic = {'CAhandler': {'handler_file': 'foo'}} mock_util.module_from_spec.side_effect = Exception('exc_mock_util') @@ -1713,7 +1713,7 @@ def test_223_ca_handler_load(self, mock_util, mock_imp): self.assertFalse(self.ca_handler_load(self.logger, config_dic)) self.assertIn('CRITICAL:test_a2c:Helper.ca_handler_load(): loading default CAhandler failed with err: exc_mock_imp', lcm.output) - def test_224_eab_handler_load(self): + def test_227_eab_handler_load(self): """ test eab_handler_load """ config_dic = {'foo': 'bar'} with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -1721,7 +1721,7 @@ def test_224_eab_handler_load(self): self.assertIn('ERROR:test_a2c:Helper.eab_handler_load(): EABhandler configuration missing in config file', lcm.output) @patch('importlib.import_module') - def test_225_eab_handler_load(self, mock_imp): + def test_228_eab_handler_load(self, mock_imp): """ test eab_handler_load """ config_dic = {'EABhandler': {'foo': 'bar'}} mock_imp.side_effect = Exception('exc_mock_imp') @@ -1730,14 +1730,14 @@ def test_225_eab_handler_load(self, mock_imp): self.assertIn('CRITICAL:test_a2c:Helper.eab_handler_load(): loading default EABhandler failed with err: exc_mock_imp', lcm.output) @patch('importlib.import_module') - def test_226_eab_handler_load(self, mock_imp): + def test_229_eab_handler_load(self, mock_imp): """ test eab_handler_load """ config_dic = {'EABhandler': {'foo': 'bar'}} mock_imp.return_value = 'foo' self.assertEqual('foo', self.eab_handler_load(self.logger, config_dic)) @patch('importlib.util') - def test_227_eab_handler_load(self, mock_util): + def test_230_eab_handler_load(self, mock_util): """ test eab_handler_load """ config_dic = {'EABhandler': {'eab_handler_file': 'foo'}} mock_util.module_from_spec = Mock(return_value='foo') @@ -1745,7 +1745,7 @@ def test_227_eab_handler_load(self, mock_util): @patch('importlib.import_module') @patch('importlib.util') - def test_228_eab_handler_load(self, mock_util, mock_imp): + def test_231_eab_handler_load(self, mock_util, mock_imp): """ test eab_handler_load """ config_dic = {'EABhandler': {'eab_handler_file': 'foo'}} mock_util.module_from_spec.side_effect = Exception('exc_mock_util') @@ -1756,7 +1756,7 @@ def test_228_eab_handler_load(self, mock_util, mock_imp): @patch('importlib.import_module') @patch('importlib.util') - def test_229_eab_handler_load(self, mock_util, mock_imp): + def test_232_eab_handler_load(self, mock_util, mock_imp): """ test eab_handler_load """ config_dic = {'EABhandler': {'eab_handler_file': 'foo'}} mock_util.module_from_spec.side_effect = Exception('exc_mock_util') @@ -1765,18 +1765,18 @@ def test_229_eab_handler_load(self, mock_util, mock_imp): self.assertFalse(self.eab_handler_load(self.logger, config_dic)) self.assertIn('CRITICAL:test_a2c:Helper.eab_handler_load(): loading default EABhandler failed with err: exc_mock_imp', lcm.output) - def test_230_hooks_load(self): + def test_233_hooks_load(self): """ test hooks load with empty config_dic """ config_dic = {} self.assertFalse(self.hooks_load(self.logger, config_dic)) - def test_231_hooks_load(self): + def test_234_hooks_load(self): """ test hooks load with hooks but no hooks_file in config_dic """ config_dic = {'Hooks': {'foo': 'bar'}} self.assertFalse(self.hooks_load(self.logger, config_dic)) @patch('importlib.util') - def test_232_hooks_load(self, mock_util): + def test_235_hooks_load(self, mock_util): """ test hooks load with hooks but no hooks_file in config_dic """ config_dic = {'Hooks': {'hooks_file': 'bar'}} mock_util.module_from_spec = Mock(return_value='foo') @@ -1785,7 +1785,7 @@ def test_232_hooks_load(self, mock_util): self.assertTrue(mock_util.module_from_spec.called) @patch('importlib.util') - def test_233_hooks_load(self, mock_util): + def test_236_hooks_load(self, mock_util): """ test hooks load with hooks but no hooks_file in config_dic """ config_dic = {'Hooks': {'hooks_file': 'bar'}} mock_util.module_from_spec = Exception('exc_mock_util') @@ -1793,7 +1793,7 @@ def test_233_hooks_load(self, mock_util): self.assertFalse(self.hooks_load(self.logger, config_dic)) self.assertIn("CRITICAL:test_a2c:Helper.hooks_load(): loading Hooks configured in cfg failed with err: 'Exception' object is not callable", lcm.output) - def test_234_error_dic_get(self): + def test_237_error_dic_get(self): """ test error_dic_get """ result = { 'badcsr': 'urn:ietf:params:acme:error:badCSR', @@ -1812,64 +1812,64 @@ def test_234_error_dic_get(self): 'badrevocationreason': 'urn:ietf:params:acme:error:badRevocationReason'} self.assertEqual(result, self.error_dic_get(self.logger)) - def test_235_logger_nonce_modify(self): + def test_238_logger_nonce_modify(self): """ test _logger_nonce_modify() """ data_dic = {'foo': 'bar'} self.assertEqual({'foo': 'bar'}, self.logger_nonce_modify(data_dic)) - def test_236_logger_nonce_modify(self): + def test_239_logger_nonce_modify(self): """ test _logger_nonce_modify() """ data_dic = {'foo': 'bar', 'header': {'foo': 'bar'}} self.assertEqual({'foo': 'bar', 'header': {'foo': 'bar'}}, self.logger_nonce_modify(data_dic)) - def test_237_logger_nonce_modify(self): + def test_240_logger_nonce_modify(self): """ test _logger_nonce_modify() """ data_dic = {'foo': 'bar', 'header': {'Replay-Nonce': 'bar'}} self.assertEqual({'foo': 'bar', 'header': {'Replay-Nonce': '- modified -'}}, self.logger_nonce_modify(data_dic)) - def test_238_logger_certificate_modify(self): + def test_241_logger_certificate_modify(self): """ test _logger_certificate_modify() """ data_dic = {'data': 'bar'} self.assertEqual({'data': 'bar'}, self.logger_certificate_modify(data_dic, 'locator')) - def test_239_logger_certificate_modify(self): + def test_242_logger_certificate_modify(self): """ test _logger_certificate_modify() """ data_dic = {'data': 'bar'} self.assertEqual({'data': ' - certificate - '}, self.logger_certificate_modify(data_dic, 'foo/acme/cert')) - def test_240_logger_token_modify(self): + def test_243_logger_token_modify(self): """ test _logger_token_modify() """ data_dic = {'data': 'bar'} self.assertEqual({'data': 'bar'}, self.logger_token_modify(data_dic)) - def test_241_logger_token_modify(self): + def test_244_logger_token_modify(self): """ test _logger_token_modify() """ data_dic = {'data': {'token': 'token'}} self.assertEqual({'data': {'token': '- modified -'}}, self.logger_token_modify(data_dic)) - def test_242_logger_challenges_modify(self): + def test_245_logger_challenges_modify(self): """ test _logger_challenges_modify() """ data_dic = {'data': 'bar'} self.assertEqual({'data': 'bar'}, self.logger_challenges_modify(data_dic)) - def test_243_logger_challenges_modify(self): + def test_246_logger_challenges_modify(self): """ test _logger_challenges_modify() """ data_dic = {'data': {'challenges': [{'token': 'token1'}]}} self.assertEqual({'data': {'challenges': [{'token': '- modified - '}]}}, self.logger_challenges_modify(data_dic)) - def test_244_logger_challenges_modify(self): + def test_247_logger_challenges_modify(self): """ test _logger_challenges_modify() """ data_dic = {'data': {'challenges': [{'token': 'token1'}, {'token': 'token2'}]}} self.assertEqual({'data': {'challenges': [{'token': '- modified - '}, {'token': '- modified - '}]}}, self.logger_challenges_modify(data_dic)) - def test_245_config_check(self): + def test_248_config_check(self): """ test config check """ config_dic = {'foo': {'bar': '"foobar"'}} with self.assertLogs('test_a2c', level='INFO') as lcm: self.config_check(self.logger, config_dic) self.assertIn('WARNING:test_a2c:config_check(): section foo option: bar contains " characters. Check if this is really needed!', lcm.output) - def test_246_helper_cert_cn_get(self): + def test_249_helper_cert_cn_get(self): """ get cn of csr """ cert = """MIIDDTCCAfWgAwIBAgIBCjANBgkqhkiG9w0BAQsFADAaMRgwFgYDVQQDEw9mb28u ZXhhbXBsZS5jb20wHhcNMTkwMTIwMTY1OTIwWhcNMTkwMjE5MTY1OTIwWjAaMRgw @@ -1890,64 +1890,64 @@ def test_246_helper_cert_cn_get(self): t+eRUDECE+0UnjyeCjTn3EU=""" self.assertEqual('foo.example.com', self.cert_cn_get(self.logger, cert)) - def test_247_logger_challenges_modify(self): + def test_250_logger_challenges_modify(self): """ test string_sanitize() """ unsafe_string = 'foo' self.assertEqual('foo', self.string_sanitize(self.logger, unsafe_string)) - def test_248_logger_challenges_modify(self): + def test_251_logger_challenges_modify(self): """ test string_sanitize() """ unsafe_string = 'foo\n;' self.assertEqual('foo;', self.string_sanitize(self.logger, unsafe_string)) - def test_249_logger_challenges_modify(self): + def test_252_logger_challenges_modify(self): """ test string_sanitize() """ unsafe_string = 'fooö' self.assertEqual('foo', self.string_sanitize(self.logger, unsafe_string)) - def test_250_logger_challenges_modify(self): + def test_253_logger_challenges_modify(self): """ test string_sanitize() """ unsafe_string = 'fooö' self.assertEqual('foo', self.string_sanitize(self.logger, unsafe_string)) - def test_251_logger_challenges_modify(self): + def test_254_logger_challenges_modify(self): """ test string_sanitize() """ unsafe_string = 'foo ' self.assertEqual('foo ', self.string_sanitize(self.logger, unsafe_string)) - def test_252_logger_challenges_modify(self): + def test_255_logger_challenges_modify(self): """ test string_sanitize() """ unsafe_string = 'foo\u0009' self.assertEqual('foo ', self.string_sanitize(self.logger, unsafe_string)) - def test_253_pembundle_to_list(self): + def test_256_pembundle_to_list(self): """ bundle to list """ pembundle_to_list = 'foo' self.assertFalse(self.pembundle_to_list(self.logger, pembundle_to_list)) - def test_254_pembundle_to_list(self): + def test_257_pembundle_to_list(self): """ bundle to list """ pembundle_to_list = '-----BEGIN CERTIFICATE-----foo' self.assertEqual(['-----BEGIN CERTIFICATE-----foo\n'], self.pembundle_to_list(self.logger, pembundle_to_list)) - def test_255_pembundle_to_list(self): + def test_258_pembundle_to_list(self): """ bundle to list """ pembundle_to_list = '-----BEGIN CERTIFICATE-----foo\n-----BEGIN CERTIFICATE-----foo1' self.assertEqual(['-----BEGIN CERTIFICATE-----foo\n', '-----BEGIN CERTIFICATE-----foo1\n'], self.pembundle_to_list(self.logger, pembundle_to_list)) - def test_256_certid_check(self): + def test_259_certid_check(self): """ test certid_check """ certid = 'e181efbe6f7ae3ea71c78fc99e4226d7185715be3d289eaa56801dff4696ca4d0420ae0dcf53345691826b81d093e9c7588c35dd5ec5eacf5b1b2606330515d5faf402082cca85f640d54142' renewal_info = 'MFswCwYJYIZIAWUDBAIBBCDhge--b3rj6nHHj8meQibXGFcVvj0onqpWgB3_RpbKTQQgrg3PUzRWkYJrgdCT6cdYjDXdXsXqz1sbJgYzBRXV-vQCCCzKhfZA1UFC' self.assertTrue(self.certid_check(self.logger, renewal_info, certid)) - def test_257_certid_check(self): + def test_260_certid_check(self): """ test certid_check """ certid = 'false' renewal_info = 'MFswCwYJYIZIAWUDBAIBBCDhge--b3rj6nHHj8meQibXGFcVvj0onqpWgB3_RpbKTQQgrg3PUzRWkYJrgdCT6cdYjDXdXsXqz1sbJgYzBRXV-vQCCCzKhfZA1UFC' self.assertFalse(self.certid_check(self.logger, renewal_info, certid)) - def test_258_certid_asn1_get(self): + def test_261_certid_asn1_get(self): """ test certid_asn1_get()""" cert_pem = '''-----BEGIN CERTIFICATE----- @@ -2006,51 +2006,51 @@ def test_258_certid_asn1_get(self): result = 'e181efbe6f7ae3ea71c78fc99e4226d7185715be3d289eaa56801dff4696ca4d0420ae0dcf53345691826b81d093e9c7588c35dd5ec5eacf5b1b2606330515d5faf402082cca85f640d54142' self.assertEqual(result, self.certid_asn1_get(self.logger, cert_pem, issuer_pem)) - def test_259_certid_hex_get(self): + def test_262_certid_hex_get(self): """ test certid_check """ certid = 'false' renewal_info = 'MFswCwYJYIZIAWUDBAIBBCDhge--b3rj6nHHj8meQibXGFcVvj0onqpWgB3_RpbKTQQgrg3PUzRWkYJrgdCT6cdYjDXdXsXqz1sbJgYzBRXV-vQCCCzKhfZA1UFC' self.assertEqual(('300b0609608648016503040201', 'e181efbe6f7ae3ea71c78fc99e4226d7185715be3d289eaa56801dff4696ca4d0420ae0dcf53345691826b81d093e9c7588c35dd5ec5eacf5b1b2606330515d5faf402082cca85f640d54142'), self.certid_hex_get(self.logger, renewal_info)) @patch('acme_srv.helper.USER_AGENT', 'FOOBAR') - def test_260_v6_adjust(self): + def test_263_v6_adjust(self): """ test v6_adjust() """ url = 'http://www.foo.bar' self.assertEqual(({'Connection': 'close', 'Accept-Encoding': 'gzip', 'User-Agent': 'FOOBAR'}, 'http://www.foo.bar'), self.v6_adjust(self.logger, url)) @patch('acme_srv.helper.USER_AGENT', 'FOOBAR') - def test_261_v6_adjust(self): + def test_264_v6_adjust(self): """ test v6_adjust() """ url = 'http://192.168.123.10' self.assertEqual(({'Connection': 'close', 'Accept-Encoding': 'gzip', 'User-Agent': 'FOOBAR'}, 'http://192.168.123.10'), self.v6_adjust(self.logger, url)) @patch('acme_srv.helper.USER_AGENT', 'FOOBAR') - def test_262_v6_adjust(self): + def test_265_v6_adjust(self): """ test v6_adjust() """ url = 'http://fe80::215:5dff:fec0:102' self.assertEqual(({'Connection': 'close', 'Accept-Encoding': 'gzip', 'User-Agent': 'FOOBAR', 'Host': 'fe80::215:5dff:fec0:102'}, 'http://[fe80::215:5dff:fec0:102]/'), self.v6_adjust(self.logger, url)) - def test_263_ipv6_chk(self): + def test_266_ipv6_chk(self): """ test ipv6_chk()""" addr_obj = 'fe80::215:5dff:fec0:102' self.assertTrue(self.ipv6_chk(self.logger, addr_obj)) - def test_264_ipv6_chk(self): + def test_267_ipv6_chk(self): """ test ipv6_chk()""" addr_obj = 'foo.bar.local' self.assertFalse(self.ipv6_chk(self.logger, addr_obj)) - def test_265_ipv6_chk(self): + def test_268_ipv6_chk(self): """ test ipv6_chk()""" addr_obj = '192.168.123.10' self.assertFalse(self.ipv6_chk(self.logger, addr_obj)) - def test_266_ipv6_chk(self): + def test_269_ipv6_chk(self): """ test ipv6_chk()""" addr_obj = None self.assertFalse(self.ipv6_chk(self.logger, addr_obj)) - def test_267_header_info_get(self): + def test_270_header_info_get(self): """ header_info_get () """ models_mock = MagicMock() models_mock.DBstore().certificates_search.return_value = ('foo', 'bar') @@ -2058,7 +2058,7 @@ def test_267_header_info_get(self): patch.dict('sys.modules', modules).start() self.assertEqual(['foo', 'bar'], self.header_info_get(self.logger, 'csr')) - def test_268_header_info_get(self): + def test_271_header_info_get(self): """ header_info_get () """ models_mock = MagicMock() models_mock.DBstore().certificates_search.side_effect = Exception('mock_search') @@ -2068,34 +2068,34 @@ def test_268_header_info_get(self): self.assertFalse(self.header_info_get(self.logger, 'csr')) self.assertIn('ERROR:test_a2c:Helper.header_info_get(): error: mock_search', lcm.output) - def test_269_encode_url(self): + def test_272_encode_url(self): # Test with a simple URL url = "www.example.com" self.assertEqual(url, self.encode_url(self.logger, url)) - def test_270_encode_url(self): + def test_273_encode_url(self): # Test with a URL containing spaces url = "www.example.com/hello world" self.assertEqual('www.example.com/hello%20world', self.encode_url(self.logger, url)) - def test_271_encode_url(self): + def test_274_encode_url(self): # Test with a URL containing special characters url = "www.example.com/hello@world?foo=bar&bar=foo" self.assertEqual('www.example.com/hello%40world%3Ffoo%3Dbar%26bar%3Dfoo', self.encode_url(self.logger, url)) - def test_272_uts_now(self): + def test_275_uts_now(self): """ test uts_now() """ self.assertIsInstance(self.uts_now(), int) - def test_273_ip_validate(self): + def test_276_ip_validate(self): """ test ip validate """ self.assertEqual(('1.0.0.10.in-addr.arpa', False), self.ip_validate(self.logger, '10.0.0.1')) - def test_274_ip_validate(self): + def test_277_ip_validate(self): """ test ip validate """ self.assertEqual((None, True), self.ip_validate(self.logger, '1000.0.0.1')) - def test_257_cert_ski_get(self): + def test_278_cert_ski_get(self): """ test cert_san_get for a multiple SAN of type DNS""" cert = """MIIDIzCCAgugAwIBAgICBZgwDQYJKoZIhvcNAQELBQAwGjEYMBYGA1UEAxMPZm9v LmV4YW1wbGUuY29tMB4XDTE5MDEyMDE3MDkxMVoXDTE5MDIxOTE3MDkxMVowGjEY @@ -2116,7 +2116,7 @@ def test_257_cert_ski_get(self): NWQddOR8IHg+v6lWc9BtuuKK5ubsg6XOiEjhhr42AKViKalX1i4+""" self.assertEqual('a5627a4a430d7632610ca6fb1311e422d7b52c9c', self.cert_ski_get(self.logger, cert)) - def test_258_cert_ski_pyopenssl_get(self): + def test_279_cert_ski_pyopenssl_get(self): """ test cert_san_get for a multiple SAN of type DNS""" cert = """MIIDIzCCAgugAwIBAgICBZgwDQYJKoZIhvcNAQELBQAwGjEYMBYGA1UEAxMPZm9v LmV4YW1wbGUuY29tMB4XDTE5MDEyMDE3MDkxMVoXDTE5MDIxOTE3MDkxMVowGjEY @@ -2139,7 +2139,7 @@ def test_258_cert_ski_pyopenssl_get(self): @patch('acme_srv.helper.cert_ski_pyopenssl_get') @patch('acme_srv.helper.cert_load') - def test_259cert_ski_get(self, mock_load, mock_ski): + def test_280_ski_get(self, mock_load, mock_ski): """ test cert_ski_get() """ cert = 'cert' mock_ski.return_value = 'mock_ski' @@ -2148,7 +2148,7 @@ def test_259cert_ski_get(self, mock_load, mock_ski): self.assertTrue(mock_ski.called) @patch('OpenSSL.crypto.load_certificate') - def test_260cert_ski_get(self, mock_load): + def test_281_ski_get(self, mock_load): """ test cert_ski_get() """ cert = 'cert' mock_load.get_extension_count.return_value = 2 diff --git a/test/test_order.py b/test/test_order.py index 09e0fe5b..ef0caa12 100644 --- a/test/test_order.py +++ b/test/test_order.py @@ -1066,7 +1066,7 @@ def test_107_config_load(self, mock_load_cfg): @patch('acme_srv.order.DBstore.authorization_add') @patch('acme_srv.order.generate_random_string') - def test_106__auth_add(self, mock_name, mock_order_add): + def test_108__auth_add(self, mock_name, mock_order_add): """ test _auth_add() """ mock_name.return_value = 'name' auth_dic = {} @@ -1075,7 +1075,7 @@ def test_106__auth_add(self, mock_name, mock_order_add): self.assertFalse(mock_order_add.called) @patch('acme_srv.order.generate_random_string') - def test_107__auth_add(self, mock_name): + def test_109__auth_add(self, mock_name): """ test _auth_add() """ mock_name.return_value = 'name' auth_dic = {} @@ -1086,7 +1086,7 @@ def test_107__auth_add(self, mock_name): self.assertFalse(self.order.dbstore.authorization_update.called) @patch('acme_srv.order.generate_random_string') - def test_108__auth_add(self, mock_name): + def test_110__auth_add(self, mock_name): """ test _auth_add() """ mock_name.return_value = 'name' auth_dic = {} @@ -1097,37 +1097,37 @@ def test_108__auth_add(self, mock_name): self.assertTrue(self.order.dbstore.authorization_add.called) self.assertTrue(self.order.dbstore.authorization_update.called) - def test_109__header_info_lookup(self): + def test_111__header_info_lookup(self): """ test _header_info_lookup() """ header = {'foo1': 'bar1', 'foo2': 'bar2'} self.order.header_info_list = ['foo1', 'foo2'] self.assertEqual('{"foo1": "bar1", "foo2": "bar2"}', self.order._header_info_lookup(header)) - def test_110__header_info_lookup(self): + def test_112__header_info_lookup(self): """ test _header_info_lookup() """ header = {'foo1': 'bar1', 'foo2': 'bar2'} self.order.header_info_list = ['foo2'] self.assertEqual('{"foo2": "bar2"}', self.order._header_info_lookup(header)) - def test_111__header_info_lookup(self): + def test_113__header_info_lookup(self): """ test _header_info_lookup() """ header = {'foo1': 'bar1', 'foo2': 'bar2'} self.order.header_info_list = ['foo1'] self.assertEqual('{"foo1": "bar1"}', self.order._header_info_lookup(header)) - def test_112__header_info_lookup(self): + def test_114__header_info_lookup(self): """ test _header_info_lookup() """ header = {'foo1': 'bar1', 'foo2': 'bar2'} self.order.header_info_list = ['foo1', 'foo3'] self.assertEqual('{"foo1": "bar1"}', self.order._header_info_lookup(header)) - def test_113__header_info_lookup(self): + def test_115__header_info_lookup(self): """ test _header_info_lookup() """ header = None self.order.header_info_list = ['foo1', 'foo3'] self.assertFalse(self.order._header_info_lookup(header)) - def test_114__header_info_lookup(self): + def test_116__header_info_lookup(self): """ test _header_info_lookup() """ header = {'foo1': 'bar1', 'foo2': 'bar2'} self.order.header_info_list = False From 6ce1581cd5825bceff8820fa2fbd50acf9745b4d Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 20 Jan 2024 19:00:49 +0100 Subject: [PATCH 023/460] [fix] f-string doublequoting --- acme_srv/account.py | 4 ++-- acme_srv/certificate.py | 6 +++--- acme_srv/challenge.py | 6 +++--- acme_srv/helper.py | 4 ++-- acme_srv/housekeeping.py | 4 ++-- acme_srv/message.py | 4 ++-- acme_srv/order.py | 14 +++++++------- acme_srv/renewalinfo.py | 2 +- examples/django/acme_srv/views.py | 4 ++-- 9 files changed, 24 insertions(+), 24 deletions(-) diff --git a/acme_srv/account.py b/acme_srv/account.py index f7fbd37e..36d722f3 100644 --- a/acme_srv/account.py +++ b/acme_srv/account.py @@ -734,7 +734,7 @@ def new(self, content: Dict[str, str]) -> Dict[str, str]: if code == 201: response_dic['data'] = { 'status': 'valid', - 'orders': f'{self.server_name}{self.path_dic['acct_path']}{message}/orders' + 'orders': f'{self.server_name}{self.path_dic["acct_path"]}{message}/orders' } if 'contact' in payload: response_dic['data']['contact'] = payload['contact'] @@ -742,7 +742,7 @@ def new(self, content: Dict[str, str]) -> Dict[str, str]: response_dic['data'] = detail response_dic['header'] = {} - response_dic['header']['Location'] = f'{self.server_name}{self.path_dic['acct_path']}{message}' + response_dic['header']['Location'] = f'{self.server_name}{self.path_dic["acct_path"]}{message}' # add exernal account binding if self.eab_check and 'externalaccountbinding' in payload: diff --git a/acme_srv/certificate.py b/acme_srv/certificate.py index 680050a5..e1f6ffbd 100644 --- a/acme_srv/certificate.py +++ b/acme_srv/certificate.py @@ -143,7 +143,7 @@ def _cert_reusage_check(self, csr: str) -> Tuple[None, str, str, str]: if uts <= certificate['expire_uts']: cert = certificate['cert'] cert_raw = certificate['cert_raw'] - message = f'reused certificate from id: {certificate['id']}' + message = f'reused certificate from id: {certificate["id"]}' break self.logger.debug('Certificate._cert_reusage_check() ended with {%s', message) @@ -390,7 +390,7 @@ def _post_hooks_process(self, certificate_name: str, order_name: str, csr: str, def _enroll_and_store(self, certificate_name: str, csr: str, order_name: str = None) -> Tuple[str, str, str]: """ enroll and store certificate """ - self.logger.debug('Certificate._enroll_and_store(%s, %s, %s)',certificate_name, order_name, csr) + self.logger.debug('Certificate._enroll_and_store(%s, %s, %s)', certificate_name, order_name, csr) detail = None error = None @@ -810,7 +810,7 @@ def enroll_and_store(self, certificate_name: str, csr: str, order_name: str = No def new_get(self, url: str) -> Dict[str, str]: """ get request """ - certificate_name = string_sanitize(self.logger, url.replace(f'{self.server_name}{self.path_dic['cert_path']}', '')) + certificate_name = string_sanitize(self.logger, url.replace(f'{self.server_name}{self.path_dic["cert_path"]}', '')) self.logger.debug('Certificate.new_get(%s)', certificate_name) # fetch certificate dictionary from DB diff --git a/acme_srv/challenge.py b/acme_srv/challenge.py index 9d960966..9382f12f 100644 --- a/acme_srv/challenge.py +++ b/acme_srv/challenge.py @@ -54,7 +54,7 @@ def _challengelist_search(self, key: str, value: str, vlist: List = ('name', 'ty challenge_dic[challenge['type']]['token'] = challenge['token'] challenge_dic[challenge['type']]['type'] = challenge['type'] challenge_dic[challenge['type']]['url'] = challenge['name'] - challenge_dic[challenge['type']]['url'] = f'{self.server_name}{self.path_dic['chall_path']}{challenge['name']}' + challenge_dic[challenge['type']]['url'] = f"{self.server_name}{self.path_dic['chall_path']}{challenge['name']}" challenge_dic[challenge['type']]['name'] = challenge['name'] if 'status__name' in challenge: challenge_dic[challenge['type']]['status'] = challenge['status__name'] @@ -262,7 +262,7 @@ def _new(self, authz_name: str, mtype: str, token: str = None, value: str = None challenge_dic = {} if chid: challenge_dic['type'] = mtype - challenge_dic['url'] = f'{self.server_name}{self.path_dic['chall_path']}{challenge_name}' + challenge_dic['url'] = f'{self.server_name}{self.path_dic["chall_path"]}{challenge_name}' challenge_dic['token'] = token challenge_dic['status'] = 'pending' if mtype == 'tkauth-01': @@ -308,7 +308,7 @@ def _parse(self, code: int, payload: Dict[str, str], protected: Dict[str, str], challenge_dic['url'] = protected['url'] response_dic['data'] = challenge_dic response_dic['header'] = {} - response_dic['header']['Link'] = f'<{self.server_name}{ self.path_dic['authz_path']}>;rel="up"' + response_dic['header']['Link'] = f'<{self.server_name}{self.path_dic["authz_path"]}>;rel="up"' self.logger.debug('Challenge._parse() ended with: %s', code) return (code, message, detail, response_dic) diff --git a/acme_srv/helper.py b/acme_srv/helper.py index 3b6709dd..2f3bb51f 100644 --- a/acme_srv/helper.py +++ b/acme_srv/helper.py @@ -630,7 +630,7 @@ def get_url(environ: Dict[str, str], include_path: bool = False) -> str: proto = 'http' if include_path and 'PATH_INFO' in environ: - result = f'{proto}://{server_name}{html.escape(environ['PATH_INFO'])}' + result = f'{proto}://{server_name}{html.escape(environ["PATH_INFO"])}' else: result = f'{proto}://{server_name}' return result @@ -1314,7 +1314,7 @@ def v6_adjust(logger: logging.Logger, url: str) -> Tuple[Dict[str, str], str]: # adjust headers and url in case we have an ipv6address if ipv6_chk(logger, url_dic['host']): headers['Host'] = url_dic['host'] - url = f'{url_dic['proto']}://[{url_dic['host']}]/{url_dic['path']}' + url = f"{url_dic['proto']}://[{url_dic['host']}]/{url_dic['path']}" logger.debug('v6_adjust() ended') return (headers, url) diff --git a/acme_srv/housekeeping.py b/acme_srv/housekeeping.py index eb28ef0e..fd41a71e 100644 --- a/acme_srv/housekeeping.py +++ b/acme_srv/housekeeping.py @@ -77,10 +77,10 @@ def _cliaccounts_format(self, result_list: List[str]): """ format cliaccount report """ self.logger.debug('Housekeeping._cliaccounts_format()') try: - print(f'\n{'Name'.ljust(15)}|{'Contact'.ljust(20)}|{'cliadm'.ljust(6)}|{'repadm'.ljust(6)}|{'certadm'.ljust(7)}|{'Created at'.ljust(20)}') + print(f"\n{'Name'.ljust(15)}|{'Contact'.ljust(20)}|{'cliadm'.ljust(6)}|{'repadm'.ljust(6)}|{'certadm'.ljust(7)}|{'Created at'.ljust(20)}") print('-' * 78) for account in sorted(result_list, key=lambda k: k['id']): - print(f'{account['name'][:15].ljust(15)}|{account['contact'][:20].ljust(20)}|{str(bool(account['cliadmin'])).ljust(6)}|{str(bool(account['reportadmin'])).ljust(6)}|{str(bool(account['certificateadmin'])).ljust(7)}|{account['created_at'].ljust(20)}') + print(f"{account['name'][:15].ljust(15)}|{account['contact'][:20].ljust(20)}|{str(bool(account['cliadmin'])).ljust(6)}|{str(bool(account['reportadmin'])).ljust(6)}|{str(bool(account['certificateadmin'])).ljust(7)}|{account['created_at'].ljust(20)}") print('\n') except Exception as err: self.logger.error('acme2certifier error in Housekeeping._cliaccounts_format()') diff --git a/acme_srv/message.py b/acme_srv/message.py index 5e8aae1a..a79ac775 100644 --- a/acme_srv/message.py +++ b/acme_srv/message.py @@ -68,11 +68,11 @@ def _name_get(self, content: Dict[str, str]) -> str: if 'kid' in content: self.logger.debug('kid: %s', content['kid']) - kid = content['kid'].replace(f'{self.server_name}{self.path_dic['acct_path']}', '') + kid = content['kid'].replace(f'{self.server_name}{self.path_dic["acct_path"]}', '') if '/' in kid: kid = None elif 'jwk' in content and 'url' in content: - if content['url'] == f'{self.server_name}{self.path_dic['revocation_path']}': + if content['url'] == f'{self.server_name}{self.path_dic["revocation_path"]}': # this is needed for cases where we get a revocation message signed with account key but account name is missing kid = self._name_rev_get(content) else: diff --git a/acme_srv/order.py b/acme_srv/order.py index c89817af..ad732d38 100644 --- a/acme_srv/order.py +++ b/acme_srv/order.py @@ -384,7 +384,7 @@ def _validity_list_create(self, authz_list: List[str], order_dic: Dict[str, str] validity_list = [] for authz in authz_list: if 'name' in authz: - order_dic["authorizations"].append(f'{self.server_name}{self.path_dic['authz_path']}{authz['name']}') + order_dic["authorizations"].append(f'{self.server_name}{self.path_dic["authz_path"]}{authz["name"]}') if 'status__name' in authz: if authz['status__name'] == 'valid': validity_list.append(True) @@ -459,15 +459,15 @@ def new(self, content: str) -> Dict[str, str]: if not error: code = 201 response_dic['header'] = {} - response_dic['header']['Location'] = f'{self.server_name}{self.path_dic['order_path']}{ order_name}' + response_dic['header']['Location'] = f'{self.server_name}{self.path_dic["order_path"]}{order_name}' response_dic['data'] = {} response_dic['data']['identifiers'] = [] response_dic['data']['authorizations'] = [] response_dic['data']['status'] = 'pending' response_dic['data']['expires'] = expires - response_dic['data']['finalize'] = f'{self.server_name}{self.path_dic['order_path']}{order_name}/finalize' + response_dic['data']['finalize'] = f'{self.server_name}{self.path_dic["order_path"]}{order_name}/finalize' for auth_name, value in auth_dic.items(): - response_dic['data']['authorizations'].append(f'{self.server_name}{self.path_dic['authz_path']}{auth_name}') + response_dic['data']['authorizations'].append(f'{self.server_name}{self.path_dic["authz_path"]}{auth_name}') response_dic['data']['identifiers'].append(value) else: code = 400 @@ -528,16 +528,16 @@ def parse(self, content: str, header: str = None) -> Dict[str, str]: if code == 200: # create response response_dic['header'] = {} - response_dic['header']['Location'] = f'{self.server_name}{self.path_dic['order_path']}{order_name}' + response_dic['header']['Location'] = f'{self.server_name}{self.path_dic["order_path"]}{order_name}' response_dic['data'] = self._lookup(order_name) if 'status' in response_dic['data'] and response_dic['data']['status'] == 'processing': # set retry header as cert issuane is not completed. response_dic['header']['Retry-After'] = f'{self.retry_after}' - response_dic['data']['finalize'] = f'{self.server_name}{self.path_dic['order_path']}{order_name}/finalize' + response_dic['data']['finalize'] = f'{self.server_name}{self.path_dic["order_path"]}{order_name}/finalize' # add the path to certificate if order-status is ready # if certificate_name: if certificate_name and 'status' in response_dic['data'] and response_dic['data']['status'] == 'valid': - response_dic['data']['certificate'] = f'{self.server_name}{self.path_dic['cert_path']}{certificate_name}' + response_dic['data']['certificate'] = f'{self.server_name}{self.path_dic["cert_path"]}{certificate_name}' # prepare/enrich response status_dic = {'code': code, 'type': message, 'detail': detail} diff --git a/acme_srv/renewalinfo.py b/acme_srv/renewalinfo.py index d7f1e601..4c0d9344 100644 --- a/acme_srv/renewalinfo.py +++ b/acme_srv/renewalinfo.py @@ -101,7 +101,7 @@ def renewalinfo_string_get(self, url: str) -> str: self.logger.debug('Renewalinfo.renewal_string_get()') # we need to workaround a strange issue in win-acme - url = url.replace(f'{self.server_name}{self.path_dic['renewalinfo'].rstrip('/')}', '') + url = url.replace(f'{self.server_name}{self.path_dic["renewalinfo"].rstrip("/")}', '') url = url.lstrip('/') # sanitize renewal_info string diff --git a/examples/django/acme_srv/views.py b/examples/django/acme_srv/views.py index 58d19e4e..26317485 100644 --- a/examples/django/acme_srv/views.py +++ b/examples/django/acme_srv/views.py @@ -57,8 +57,8 @@ def pretty_request(request): return ( f'{request.method} HTTP/1.1\n' - f'Content-Length: {request.META['CONTENT_LENGTH']}\n' - f'Content-Type: {request.META['CONTENT_TYPE']}\n' + f'Content-Length: {request.META["CONTENT_LENGTH"]}\n' + f'Content-Type: {request.META["CONTENT_TYPE"]}\n' f'{headers}\n\n' f'{request.body}' ) From 7b703ceb40a0cf39b7210be1831a04d736c05c38 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 20 Jan 2024 19:07:37 +0100 Subject: [PATCH 024/460] [iix] f-string doublequoting in db_handler --- examples/db_handler/wsgi_handler.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/db_handler/wsgi_handler.py b/examples/db_handler/wsgi_handler.py index ab71f338..53a53d24 100644 --- a/examples/db_handler/wsgi_handler.py +++ b/examples/db_handler/wsgi_handler.py @@ -760,7 +760,7 @@ def cahandler_add(self, data_dic: Dict[str, str]) -> int: self._db_open() if bool(exists): # update - self.logger.debug(f'parameter exists: name id: {data_dic['name']}') + self.logger.debug(f'parameter exists: name id: {data_dic["name"]}') self.cursor.execute('''UPDATE CAHANDLER SET name = :name, value1 = :value1, 'value2' = :value2 WHERE name = :name''', data_dic) rid = exists['id'] else: @@ -1168,7 +1168,7 @@ def hkparameter_add(self, data_dic: Dict[str, str]) -> Tuple[str, bool]: self._db_open() if bool(exists): # update - self.logger.debug(f'parameter exists: {data_dic['name']}') + self.logger.debug(f'parameter exists: {data_dic["name"]}') self.cursor.execute('''UPDATE HOUSEKEEPING SET name = :name, value = :value WHERE name = :name''', data_dic) else: # insert From d803e3eac1b9a71b7f2354f8e2e113ffb6b60e0b Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 21 Jan 2024 08:58:49 +0100 Subject: [PATCH 025/460] [fix] c0209 refactoring in tools and eab_handlers --- examples/acme2certifier_wsgi.py | 38 ++++----- examples/django/acme2certifier/urls.py | 35 +++------ examples/django/acme_srv/tests.py | 1 + examples/eab_handler/file_handler.py | 8 +- examples/eab_handler/skeleton_eab_handler.py | 2 +- examples/hooks/exception_test_hooks.py | 8 +- examples/hooks/skeleton_hooks.py | 2 +- examples/soap/mock_soap_srv.py | 42 +++++----- tools/a2c_cli.py | 83 ++++++++++---------- tools/cliuser_mgmt.py | 4 +- tools/invalidator.py | 6 +- tools/report_generator.py | 16 ++-- 12 files changed, 115 insertions(+), 130 deletions(-) diff --git a/examples/acme2certifier_wsgi.py b/examples/acme2certifier_wsgi.py index ee0aacf6..4d354f7f 100644 --- a/examples/acme2certifier_wsgi.py +++ b/examples/acme2certifier_wsgi.py @@ -1,6 +1,6 @@ #!/usr/bin/python # -*- coding: utf-8 -*- -# pylint: disable=E0401, R1705, C0209 +# pylint: disable=E0401, R1705 """ wsgi based acme server """ from __future__ import print_function import re @@ -48,7 +48,7 @@ def err_wrong_request_mothod(start_response): """ this is the error response for a wrong reqest method """ - start_response('405 {0}'.format(HTTP_CODE_DIC[405]), [('Content-Type', CONTENT_TYPE_JSON)]) + start_response(f'405 {HTTP_CODE_DIC[405]}', [('Content-Type', CONTENT_TYPE_JSON)]) def handle_exception(exc_type, exc_value, exc_traceback): @@ -114,7 +114,7 @@ def acct(environ, start_response): # create header headers = create_header(response_dic) - start_response('{0} {1}'.format(response_dic['code'], HTTP_CODE_DIC[response_dic['code']]), headers) + start_response(f'{response_dic["code"]} {HTTP_CODE_DIC[response_dic["code"]]}', headers) return [json.dumps(response_dic['data']).encode('utf-8')] @@ -124,9 +124,9 @@ def acmechallenge_serve(environ, start_response): key_authorization = acmechallenge.lookup(environ['PATH_INFO']) if not key_authorization: key_authorization = 'NOT FOUND' - start_response('404 {0}'.format(HTTP_CODE_DIC[404]), [('Content-Type', 'text/html')]) + start_response(f'404 {HTTP_CODE_DIC[404]}', [('Content-Type', 'text/html')]) else: - start_response('200 {0}'.format(HTTP_CODE_DIC[200]), [('Content-Type', 'text/html')]) + start_response(f'200 {HTTP_CODE_DIC[200]}', [('Content-Type', 'text/html')]) # logging logger_info(LOGGER, environ['REMOTE_ADDR'], environ['PATH_INFO'], {}) return [key_authorization.encode('utf-8')] @@ -148,7 +148,7 @@ def authz(environ, start_response): # create header headers = create_header(response_dic) - start_response('{0} {1}'.format(response_dic['code'], HTTP_CODE_DIC[response_dic['code']]), headers) + start_response(f'{response_dic["code"]} {HTTP_CODE_DIC[response_dic["code"]]}', headers) # logging logger_info(LOGGER, environ['REMOTE_ADDR'], environ['PATH_INFO'], response_dic) @@ -168,7 +168,7 @@ def newaccount(environ, start_response): # create header headers = create_header(response_dic) - start_response('{0} {1}'.format(response_dic['code'], HTTP_CODE_DIC[response_dic['code']]), headers) + start_response(f'{response_dic["code"]} {HTTP_CODE_DIC[response_dic["code"]]}', headers) # logging logger_info(LOGGER, environ['REMOTE_ADDR'], environ['PATH_INFO'], response_dic) @@ -197,7 +197,7 @@ def cert(environ, start_response): response_dic = certificate.new_post(request_body) # create header headers = create_header(response_dic, False) - start_response('{0} {1}'.format(response_dic['code'], HTTP_CODE_DIC[response_dic['code']]), headers) + start_response(f'{response_dic["code"]} {HTTP_CODE_DIC[response_dic["code"]]}', headers) # logging logger_info(LOGGER, environ['REMOTE_ADDR'], environ['PATH_INFO'], response_dic) @@ -209,7 +209,7 @@ def cert(environ, start_response): # create header headers = create_header(response_dic) # create the response - start_response('{0} {1}'.format(response_dic['code'], HTTP_CODE_DIC[response_dic['code']]), headers) + start_response(f'{response_dic["code"]} {HTTP_CODE_DIC[response_dic["code"]]}', headers) # logging logger_info(LOGGER, environ['REMOTE_ADDR'], environ['PATH_INFO'], response_dic) @@ -231,7 +231,7 @@ def chall(environ, start_response): # create header headers = create_header(response_dic) - start_response('{0} {1}'.format(response_dic['code'], HTTP_CODE_DIC[response_dic['code']]), headers) + start_response(f'{response_dic["code"]} {HTTP_CODE_DIC[response_dic["code"]]}', headers) # logging logger_info(LOGGER, environ['REMOTE_ADDR'], environ['PATH_INFO'], response_dic) @@ -244,7 +244,7 @@ def chall(environ, start_response): # generate header headers = [('Content-Type', CONTENT_TYPE_JSON)] # create the response - start_response('{0} {1}'.format(response_dic['code'], HTTP_CODE_DIC[response_dic['code']]), headers) + start_response(f'{response_dic["code"]} {HTTP_CODE_DIC[response_dic["code"]]}', headers) # logging logger_info(LOGGER, environ['REMOTE_ADDR'], environ['PATH_INFO'], response_dic) @@ -260,7 +260,7 @@ def newnonce(environ, start_response): """ generate a new nonce """ if environ['REQUEST_METHOD'] in ['HEAD', 'GET']: nonce = Nonce(DEBUG, LOGGER) - headers = [('Content-Type', 'text/plain'), ('Replay-Nonce', '{0}'.format(nonce.generate_and_add()))] + headers = [('Content-Type', 'text/plain'), ('Replay-Nonce', f'{nonce.generate_and_add()}')] status = '200 OK' if environ['REQUEST_METHOD'] == 'HEAD' else '204 No content' start_response(status, headers) return [] @@ -278,7 +278,7 @@ def neworders(environ, start_response): # create header headers = create_header(response_dic) - start_response('{0} {1}'.format(response_dic['code'], HTTP_CODE_DIC[response_dic['code']]), headers) + start_response(f'{response_dic["code"]} {HTTP_CODE_DIC[response_dic["code"]]}', headers) # logging logger_info(LOGGER, environ['REMOTE_ADDR'], environ['PATH_INFO'], response_dic) @@ -298,7 +298,7 @@ def order(environ, start_response): # create header headers = create_header(response_dic) - start_response('{0} {1}'.format(response_dic['code'], HTTP_CODE_DIC[response_dic['code']]), headers) + start_response(f'{response_dic["code"]} {HTTP_CODE_DIC[response_dic["code"]]}', headers) # logging logger_info(LOGGER, environ['REMOTE_ADDR'], environ['PATH_INFO'], response_dic) @@ -317,7 +317,7 @@ def renewalinfo(environ, start_response): response_dic = renewalinfo_.update(request_body) # create header headers = create_header(response_dic, False) - start_response('{0} {1}'.format(response_dic['code'], HTTP_CODE_DIC[response_dic['code']]), headers) + start_response(f'{response_dic["code"]} {HTTP_CODE_DIC[response_dic["code"]]}', headers) # logging logger_info(LOGGER, environ['REMOTE_ADDR'], environ['PATH_INFO'], response_dic) @@ -329,7 +329,7 @@ def renewalinfo(environ, start_response): # create header headers = create_header(response_dic) # create the response - start_response('{0} {1}'.format(response_dic['code'], HTTP_CODE_DIC[response_dic['code']]), headers) + start_response(f'{response_dic["code"]} {HTTP_CODE_DIC[response_dic["code"]]}', headers) # logging logger_info(LOGGER, environ['REMOTE_ADDR'], environ['PATH_INFO'], response_dic) @@ -354,7 +354,7 @@ def revokecert(environ, start_response): # create header headers = create_header(response_dic) - start_response('{0} {1}'.format(response_dic['code'], HTTP_CODE_DIC[response_dic['code']]), headers) + start_response(f'{response_dic["code"]} {HTTP_CODE_DIC[response_dic["code"]]}', headers) # logging logger_info(LOGGER, environ['REMOTE_ADDR'], environ['PATH_INFO'], response_dic) @@ -376,7 +376,7 @@ def trigger(environ, start_response): # create header headers = create_header(response_dic) - start_response('{0} {1}'.format(response_dic['code'], HTTP_CODE_DIC[response_dic['code']]), headers) + start_response(f'{response_dic["code"]} {HTTP_CODE_DIC[response_dic["code"]]}', headers) # logging logger_info(LOGGER, environ['REMOTE_ADDR'], environ['PATH_INFO'], response_dic) @@ -399,7 +399,7 @@ def housekeeping(environ, start_response): # create header headers = create_header(response_dic) - start_response('{0} {1}'.format(response_dic['code'], HTTP_CODE_DIC[response_dic['code']]), headers) + start_response(f'{response_dic["code"]} {HTTP_CODE_DIC[response_dic["code"]]}', headers) # logging logger_info(LOGGER, environ['REMOTE_ADDR'], environ['PATH_INFO'], '****') diff --git a/examples/django/acme2certifier/urls.py b/examples/django/acme2certifier/urls.py index a37c1eb6..e65626e7 100644 --- a/examples/django/acme2certifier/urls.py +++ b/examples/django/acme2certifier/urls.py @@ -1,19 +1,4 @@ -"""acme2certifier URL Configuration - -The `urlpatterns` list routes URLs to views. For more information please see: - https://docs.djangoproject.com/en/1.11/topics/http/urls/ -Examples: -Function views - 1. Add an import: from my_app import views - 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') -Class-based views - 1. Add an import: from other_app.views import Home - 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') -Including another URLconf - 1. Import the include() function: from django.conf.urls import url, include - 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) -""" -# pylint: disable=C0330 +"""acme2certifier URL Configuration""" from django.conf.urls import include, url from django.contrib import admin from acme_srv import views @@ -24,22 +9,22 @@ # check ifwe need to prefix the url if 'Directory' in CONFIG and 'url_prefix' in CONFIG['Directory']: - prefix = CONFIG['Directory']['url_prefix'] + '/' - if prefix.startswith('/'): - prefix = prefix.lstrip('/') + PREFIX = CONFIG['Directory']['url_prefix'] + '/' + if PREFIX.startswith('/'): + PREFIX = PREFIX.lstrip('/') else: - prefix = '' + PREFIX = '' urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^$', views.directory, name='index'), url(r'^directory$', views.directory, name='directory'), - url(r'^{0}get_servername$'.format(prefix), views.servername_get, name='servername_get'), - url(r'^{0}trigger$'.format(prefix), views.trigger, name='trigger'), - url(r'^{0}housekeeping$'.format(prefix), views.housekeeping, name='housekeeping'), - url(r'^{0}acme/'.format(prefix), include('acme_srv.urls')) + url(rf'^{PREFIX}get_servername$', views.servername_get, name='servername_get'), + url(rf'^{PREFIX}trigger$', views.trigger, name='trigger'), + url(rf'^{PREFIX}housekeeping$', views.housekeeping, name='housekeeping'), + url(rf'^{PREFIX}acme/', include('acme_srv.urls')) ] # check if we need to activate the url pattern for challenge verification if 'CAhandler' in CONFIG and 'acme_url' in CONFIG['CAhandler']: - urlpatterns.append(url(r'^{0}.well-known/acme-challenge/'.format(prefix), views.acmechallenge_serve, name='acmechallenge_serve')) + urlpatterns.append(url(rf'^{PREFIX}.well-known/acme-challenge/', views.acmechallenge_serve, name='acmechallenge_serve')) diff --git a/examples/django/acme_srv/tests.py b/examples/django/acme_srv/tests.py index a83eb721..ed46e7f4 100644 --- a/examples/django/acme_srv/tests.py +++ b/examples/django/acme_srv/tests.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +""" tester """ from __future__ import unicode_literals # Create your tests here. diff --git a/examples/eab_handler/file_handler.py b/examples/eab_handler/file_handler.py index 9d9d7c02..482e8c83 100644 --- a/examples/eab_handler/file_handler.py +++ b/examples/eab_handler/file_handler.py @@ -3,7 +3,7 @@ """ eab file handler """ from __future__ import print_function import csv -# pylint: disable=C0209, E0401 +# pylint: disable=E0401 from acme_srv.helper import load_config @@ -35,7 +35,7 @@ def _config_load(self): def mac_key_get(self, kid: str = None) -> str: """ check external account binding """ - self.logger.debug('EABhandler.mac_key_get({})'.format(kid)) + self.logger.debug('EABhandler.mac_key_get(%s)', kid) mac_key = None if self.key_file and kid: @@ -47,7 +47,7 @@ def mac_key_get(self, kid: str = None) -> str: mac_key = row['eab_mac'] break except Exception as err: - self.logger.error('EABhandler.mac_key_get() error: {0}'.format(err)) + self.logger.error('EABhandler.mac_key_get() error: %s', err) - self.logger.debug('EABhandler.mac_key_get() ended with: {0}'.format(bool(mac_key))) + self.logger.debug('EABhandler.mac_key_get() ended with: %s', bool(mac_key)) return mac_key diff --git a/examples/eab_handler/skeleton_eab_handler.py b/examples/eab_handler/skeleton_eab_handler.py index 44d5bc31..94041b67 100644 --- a/examples/eab_handler/skeleton_eab_handler.py +++ b/examples/eab_handler/skeleton_eab_handler.py @@ -34,7 +34,7 @@ def _config_load(self): def mac_key_get(self, kid: str = None) -> str: """ check external account binding """ - self.logger.debug('EABhandler.mac_key_get({})'.format(kid)) + self.logger.debug('EABhandler.mac_key_get(%s)', kid) mac_key = 'mac_key' return mac_key diff --git a/examples/hooks/exception_test_hooks.py b/examples/hooks/exception_test_hooks.py index b20638f7..92b6230a 100644 --- a/examples/hooks/exception_test_hooks.py +++ b/examples/hooks/exception_test_hooks.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# pylint: disable=c0209, e0401, r0913, w0613 +# pylint: disable=e0401, r0913, w0613 """ exception hook class for testing only """ from acme_srv.helper import load_config @@ -33,18 +33,18 @@ def _config_load(self): def pre_hook(self, certificate_name, order_name, _csr) -> None: """ run before obtaining any certificates """ - self.logger.debug('Hook.pre_hook({0}/{1})'.format(certificate_name, order_name)) + self.logger.debug('Hook.pre_hook(%s/%s)', certificate_name, order_name) if self.raise_pre_hook_exception: raise SystemError('raise_pre_hook_exception') def post_hook(self, certificate_name, order_name, _csr, _error) -> None: """ run after *attempting* to obtain/renew certificates """ - self.logger.debug('Hook.post_hook({0}/{1})'.format(certificate_name, order_name)) + self.logger.debug('Hook.post_hook(%s/%s)', certificate_name, order_name) if self.raise_post_hook_exception: raise SystemError('raise_post_hook_exception') def success_hook(self, certificate_name, order_name, _csr, _certificate, _certificate_raw, _poll_identifier) -> None: """ run after each successful certificate enrollment/renewal """ - self.logger.debug('Hook.success_hook({0}/{1})'.format(certificate_name, order_name)) + self.logger.debug('Hook.success_hook(%s/%s)', certificate_name, order_name) if self.raise_success_hook_exception: raise SystemError('raise_success_hook_exception') diff --git a/examples/hooks/skeleton_hooks.py b/examples/hooks/skeleton_hooks.py index e05e81f1..1b8000a6 100644 --- a/examples/hooks/skeleton_hooks.py +++ b/examples/hooks/skeleton_hooks.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# pylint: disable=c0209, r0913, w0613 +# pylint: disable=r0913, w0613 """ example hook class """ diff --git a/examples/soap/mock_soap_srv.py b/examples/soap/mock_soap_srv.py index 58a615e9..2f1f31f5 100644 --- a/examples/soap/mock_soap_srv.py +++ b/examples/soap/mock_soap_srv.py @@ -1,13 +1,13 @@ # -*- coding: utf-8 -*- """ soap-server mock providing endpoint for soap ca handler """ -# pylint: disable=c0209, c0413, e0401 +# pylint: disable=c0413, e0401 import os import sys import argparse import tempfile import json import subprocess -from typing import List, Tuple, Dict +from typing import List, Dict from http.client import responses from wsgiref.simple_server import WSGIServer, WSGIRequestHandler import xmltodict @@ -45,9 +45,9 @@ def _csr_get(logger, soap_dic: Dict[str, str], soapenvelope: str, soapbody: str, if 'aur:CertificateRequestRaw' in soap_dic[soapenvelope][soapbody][aurrequestcertificate][aurrequest]: csr = soap_dic[soapenvelope][soapbody][aurrequestcertificate][aurrequest]['aur:CertificateRequestRaw'] if 'aur:ProfileName' in soap_dic[soapenvelope][soapbody][aurrequestcertificate][aurrequest]: - logger.info('got request profilename: {0}'.format(soap_dic[soapenvelope][soapbody][aurrequestcertificate][aurrequest]['aur:ProfileName'])) + logger.info('got request profilename: %s', soap_dic[soapenvelope][soapbody][aurrequestcertificate][aurrequest]['aur:ProfileName']) if 'aur:Email' in soap_dic[soapenvelope][soapbody][aurrequestcertificate][aurrequest]: - logger.info('got request email: {0}'.format(soap_dic[soapenvelope][soapbody][aurrequestcertificate][aurrequest]['aur:Email'])) + logger.info('got request email: %s', soap_dic[soapenvelope][soapbody][aurrequestcertificate][aurrequest]['aur:Email']) return csr @@ -71,7 +71,7 @@ def _csr_lookup(logger, soap_dic: Dict[str, str]) -> str: def _opensslcmd_pem2pkcs7_convert(logger, tmp_dir: str, filename_list: List[str]) -> List[str]: """ build openssl command """ logger.debug('_opensslcmd_pem2pkcs7_convert()') - cmd_list = ['openssl', 'crl2pkcs7', '-nocrl', '-outform', 'DER', '-out', '{0}/cert.p7b'.format(tmp_dir)] + cmd_list = ['openssl', 'crl2pkcs7', '-nocrl', '-outform', 'DER', '-out', f'{tmp_dir}/cert.p7b'] for filename in filename_list: cmd_list.append('-certfile') @@ -90,7 +90,7 @@ def _opensslcmd_csr_extract(logger, pkcs7_file: str, csr_file: str) -> List[str] def _file_load_binary(logger, filename: str) -> List[str]: """ load file at once """ - logger.debug('file_open({0})'.format(filename)) + logger.debug('file_open(%s)', filename) with open(filename, 'rb') as _file: lines = _file.read() return lines @@ -98,7 +98,7 @@ def _file_load_binary(logger, filename: str) -> List[str]: def _file_load(logger, filename: str) -> List[str]: """ load file at once """ - logger.debug('file_open({0})'.format(filename)) + logger.debug('file_open(%s)', filename) with open(filename, 'r', encoding='utf8') as _file: lines = _file.read() return lines @@ -106,14 +106,14 @@ def _file_load(logger, filename: str) -> List[str]: def _file_dump_binary(logger, filename: str, data_: str): """ dump content in binary format to file """ - logger.debug('file_dump({0})'.format(filename)) + logger.debug('file_dump(%s)', filename) with open(filename, 'wb') as file_: file_.write(data_) # lgtm [py/clear-text-storage-sensitive-data] def _file_dump(logger, filename: str, data_: str): """ dump content to file """ - logger.debug('file_dump({0})'.format(filename)) + logger.debug('file_dump(%s)', filename) with open(filename, 'w', encoding='utf8') as file_: file_.write(data_) # lgtm [py/clear-text-storage-sensitive-data] @@ -125,16 +125,16 @@ def _pem2pkcs7_convert(logger, tmp_dir: str, pem: str) -> str: filename_list = [] for cnt, certificate in enumerate(certificate_list): if certificate: - certificate = '{0}-----END CERTIFICATE-----\n'.format(certificate) - _file_dump(logger, '{0}/{1}.pem'.format(tmp_dir, cnt), certificate) - filename_list.append('{0}/{1}.pem'.format(tmp_dir, cnt)) + certificate = f'{certificate}-----END CERTIFICATE-----\n' + _file_dump(logger, f'{tmp_dir}/{cnt}.pem', certificate) + filename_list.append(f'{tmp_dir}/{cnt}.pem') openssl_cmd = _opensslcmd_pem2pkcs7_convert(logger, tmp_dir, filename_list) rcode = subprocess.call(openssl_cmd) if not rcode: - content = b64_encode(logger, _file_load_binary(logger, '{0}/cert.p7b'.format(tmp_dir))) + content = b64_encode(logger, _file_load_binary(logger, f'{tmp_dir}/cert.p7b')) else: content = None @@ -181,12 +181,12 @@ def _csr_extract(logger, tmp_dir: str, csr: str) -> str: if csr: # dump csr into a file - _file_dump_binary(logger, '{0}/file.p7b'.format(tmp_dir), b64_decode(logger, csr)) - openssl_cmd = _opensslcmd_csr_extract(logger, '{0}/file.p7b'.format(tmp_dir), '{0}/csr.der'.format(tmp_dir)) + _file_dump_binary(logger, f'{0}/file.p7b'.format(tmp_dir), b64_decode(logger, csr)) + openssl_cmd = _opensslcmd_csr_extract(logger, f'{tmp_dir}/file.p7b', f'{tmp_dir}/csr.der') rcode = subprocess.call(openssl_cmd) if not rcode: - content = convert_byte_to_string(b64_url_encode(logger, _file_load_binary(logger, '{0}/csr.der'.format(tmp_dir)))) + content = convert_byte_to_string(b64_url_encode(logger, _file_load_binary(logger, f'{tmp_dir}/csr.der'))) else: content = None else: @@ -211,7 +211,7 @@ def request_process(logger, csr: str) -> bytes: # extract csr from pkcs7 construct csr = _csr_extract(logger, tmp_dir, csr) - logger.debug('csr: {0}'.format(csr)) + logger.debug('csr: %s', csr) # enroll certificate (error, cert_bundle, _cert_raw, _unused) = ca_handler.enroll(csr) @@ -222,17 +222,17 @@ def request_process(logger, csr: str) -> bytes: pkcs7 = None if not ERROR and pkcs7: - soap_response = """ + soap_response = f""" - {0} + {pkcs7} - """.format(pkcs7) + """ else: soap_response = """ @@ -256,7 +256,7 @@ def soap_srv(environ, start_response) -> List[str]: if csr: # try: - status = "{0} {1}".format(HTTP_STATUS_CODE, responses[int(HTTP_STATUS_CODE)]) + status = f"{HTTP_STATUS_CODE} {responses[int(HTTP_STATUS_CODE)]}" # Except Exception as error: # status = "500 Internal Server Error" headers = [("Content-type", "text/xml")] diff --git a/tools/a2c_cli.py b/tools/a2c_cli.py index d180b1c0..0f6bb141 100644 --- a/tools/a2c_cli.py +++ b/tools/a2c_cli.py @@ -1,6 +1,5 @@ #!/usr/bin/python3 # -*- coding: utf-8 -*- -# pylint: disable=c0209 """ acme2certifier cli client """ import logging import datetime @@ -35,7 +34,7 @@ def csv_dump(logger, filename, content): """ dump content csv file """ - logger.debug('csv_dump({0})'.format(filename)) + logger.debug('csv_dump(%s)', filename) with open(filename, 'w', newline='', encoding='utf-8') as file_: writer = csv.writer(file_, delimiter=',', quotechar='"', quoting=csv.QUOTE_NONNUMERIC) writer.writerows(content) @@ -50,14 +49,14 @@ def generate_random_string(logger, length): def file_dump(logger, filename, data_): """ dump content to file """ - logger.debug('file_dump({0})'.format(filename)) + logger.debug('file_dump(%s)', filename) with open(filename, 'w', encoding='utf8') as file_: file_.write(data_) # lgtm [py/clear-text-storage-sensitive-data] def file_load(logger, filename): """ load file at once """ - logger.debug('file_open({0})'.format(filename)) + logger.debug('file_open(%s)', filename) with open(filename, encoding='utf8') as _file: lines = _file.read() return lines @@ -102,33 +101,33 @@ def __init__(self, logger=None, printcommand=None): def generate(self, filename): """ generate and store key """ - self.logger.debug('KeyOperations.generate({0})'.format(filename)) + self.logger.debug('KeyOperations.generate(%s)', filename) self.print('generating keys...', printreturn=False) key = jwk.JWK.generate(kty='RSA', size=2048, alg='RSA-OAEP-256', use='sig', kid=generate_random_string(self.logger, 12)) public_key = key.export_public(as_dict=True) private_key = key.export_private(as_dict=True) try: - file_dump(self.logger, '{0}.pub'.format(filename), json.dumps(public_key, indent=4, sort_keys=True)) - file_dump(self.logger, '{0}.private'.format(filename), json.dumps(private_key, indent=4, sort_keys=True)) + file_dump(self.logger, f'{filename}.pub', json.dumps(public_key, indent=4, sort_keys=True)) + file_dump(self.logger, f'{filename}.private', json.dumps(private_key, indent=4, sort_keys=True)) self.print('done...', printreturn=False) - self.print('Keep the private key {0}.pub for yourself'.format(filename), printreturn=False) - self.print('Give the public key {0}.pub to your acme2certifier administrator'.format(filename)) + self.print(f'Keep the private key {filename}.pub for yourself', printreturn=False) + self.print(f'Give the public key {filename}.pub to your acme2certifier administrator') except Exception as err_: - self.logger.error('KeyOperations.generate() failed with err: {0}'.format(err_)) - self.print('Key generation failed with error: {0}'.format(err_)) + self.logger.error('KeyOperations.generate() failed with err: %s', err_) + self.print('Key generation failed with error: %s', err_) return key def load(self, filename): """ load existing key """ - self.logger.debug('KeyOperations.load({0})'.format(filename)) + self.logger.debug('KeyOperations.load(%s)', filename) if os.path.exists(filename): - self.print('loading {0}'.format(filename), printreturn=False) + self.print(f'loading {filename}', printreturn=False) content = file_load(self.logger, filename) key = jwk.JWK.from_json(content) self.print('done...', printreturn=False) else: - self.print('Could not find {0}'.format(filename)) + self.print(f'Could not find {filename}') key = None return key @@ -140,13 +139,13 @@ def __init__(self, logger=None, printcommand=None): self.logger = logger self.print = printcommand - def sign(self, key, data, type='Unknown'): + def sign(self, key, data, cli_type='Unknown'): """ sign message """ self.logger.debug('MessageOperations.sign()') protected = {"typ": "JOSE+JSON", "kid": key['kid'], "alg": "RS256"} - plaintext = {"data": data, 'type': type, + plaintext = {"data": data, 'type': cli_type, "exp": int(time.time()) + (5 * 60)} mjws = jws.JWS(payload=json_encode(plaintext)) mjws.add_signature(key, None, json_encode(protected)) @@ -154,8 +153,8 @@ def sign(self, key, data, type='Unknown'): def send(self, server=None, message=None): """ send message """ - self.logger.debug('MessageOperations.send({0})'.format(server)) - req = requests.post('{0}/housekeeping'.format(server), data=message, timeout=20) + self.logger.debug(f'MessageOperations.send({server})') + req = requests.post(f'{server}/housekeeping', data=message, timeout=20) return req @@ -208,16 +207,16 @@ def _cli_print(self, text, date_print=True, printreturn=True): if date_print: now = datetime.datetime.now().strftime('%H:%M:%S') if printreturn: - print('{0} {1}\n'.format(now, text)) + print(f'{now} {text}\n') else: - print('{0} {1}'.format(now, text)) + print(f'{now} {text}') else: print(text) def _command_check(self, command): """ check command """ # pylint: disable=c0325 - self.logger.debug('CommandLineInterface._commend_check(): {0}'.format(command)) + self.logger.debug('CommandLineInterface._commend_check(): %s', command) if command in ('help', 'H'): self.help_print() elif command.startswith('server'): @@ -237,24 +236,24 @@ def _command_check(self, command): self._certificate_operations(command) else: if command: - self._cli_print('unknown command: "/{0}"'.format(command)) + self._cli_print(f'unknown command: "/{command}"') self.help_print() else: - self._cli_print('Unknown command: "{0}'.format(command)) + self._cli_print(f'Unknown command: "{command}"') self.help_print() def _certificate_operations(self, command): - self.logger.debug('CommandLineInterface._certificate_operations(): {0}'.format(command)) + self.logger.debug('CommandLineInterface._certificate_operations(): %s', command) def _config_operations(self, command): - self.logger.debug('CommandLineInterface._config_operations(): {0}'.format(command)) - self._cli_print('server: {0}'.format(self.server), printreturn=False) - self._cli_print('key: {0}'.format(self.key), printreturn=False) - self._cli_print('status: {0}'.format(self.status), printreturn=False) + self.logger.debug('CommandLineInterface._config_operations(): %s', command) + self._cli_print(f'server: {self.server}', printreturn=False) + self._cli_print(f'key: {self.key}', printreturn=False) + self._cli_print(f'status: {self.status}', printreturn=False) def _exec_cmd(self, cmdinput): """ execute command """ - self.logger.debug('CommandLineInterface._exec_cmd(): {0}'.format(cmdinput)) + self.logger.debug('CommandLineInterface._exec_cmd(): %s', cmdinput) cmdinput = cmdinput.rstrip() # skip empty commands if len(cmdinput) <= 1: @@ -276,12 +275,12 @@ def _intro_print(self): def _key_operations(self, command): """ key operations """ - self.logger.debug('CommandLineInterface._key_operations({0})'.format(command)) + self.logger.debug('CommandLineInterface._key_operations(%s)', command) try: (_key, command, argument) = command.split(' ', 2) except Exception: - self._cli_print('incomplete key-operations command: "{0}"'.format(command)) + self._cli_print(f'incomplete key-operations command: "{command}"') _key = None # lgtm [py/unused-local-variable] command = None argument = None # lgtm [py/unused-local-variable] @@ -293,7 +292,7 @@ def _key_operations(self, command): elif command == 'load': self.key = key.load(argument) else: - self._cli_print('unknown key command: "{0}"'.format(command)) + self._cli_print(f'unknown key command: "{command}"') if self.server: self.status = 'Configured' @@ -305,7 +304,7 @@ def _message_operations(self, command): try: (_key, command, argument) = command.split(' ', 2) except Exception: - self._cli_print('incomplete message-operations command: "{0}"'.format(command)) + self._cli_print(f'incomplete message-operations command: "{command}"') _key = None # lgtm [py/unused-local-variable] command = None argument = None # lgtm [py/unused-local-variable] @@ -326,7 +325,7 @@ def _report_operations(self, command): try: (_key, command, filename) = command.split(' ', 2) except Exception: - self._cli_print('incomplete report-operations command: "{0}"'.format(command)) + self._cli_print(f'incomplete report-operations command: "{command}"') command = None filename = None # lgtm [py/unused-local-variable] @@ -334,13 +333,13 @@ def _report_operations(self, command): try: (_filename, format_) = filename.lower().split('.', 2) except Exception: - self._cli_print('incomplete filename: "{0}"'.format(command)) + self._cli_print(f'incomplete filename: "{command}"') format_ = None if format_ in ('csv', 'json'): self._report_generate(filename, format_, command) else: - self._cli_print('Unknown report format "{0}". Must be either "csv" or "json"'.format(format)) + self._cli_print(f'Unknown report format "{format_}". Must be either "csv" or "json"') def _report_generate(self, filename, format_, command): """ generate report """ @@ -348,14 +347,14 @@ def _report_generate(self, filename, format_, command): # process report request message = MessageOperations(self.logger, self._cli_print) - signed_message = message.sign(key=self.key, type='report', data={'name': command, 'format': format_}) + signed_message = message.sign(key=self.key, cli_type='report', data={'name': command, 'format': format_}) response = message.send(server=self.server, message=signed_message) if response.status_code == 200: if format_ == 'csv': csv_dump(self.logger, filename, response.json()) else: file_dump(self.logger, filename, json.dumps(response.json(), indent=4, sort_keys=True)) - self._cli_print('saving report to {0}'.format(filename)) + self._cli_print(f'saving report to {filename}') else: if 'message' in response.json(): message = response.json()['message'] @@ -363,12 +362,12 @@ def _report_generate(self, filename, format_, command): message = response.json()['detail'] else: message = None - self._cli_print('ERROR: {0} - {1}'.format(response.status_code, message)) + self._cli_print(f'ERROR: {response.status_code} - {message}') def _prompt_get(self): """ get prompt """ self.logger.debug('CommandLineInterface._prompt_get()') - return '[{0}]:'.format(self.status) + return f'[{self.status}]:' def _quit(self): """ quit (whatever) """ @@ -377,7 +376,7 @@ def _quit(self): def _server_set(self, server): """ configure server """ - self.logger.debug('CommandLineInterface._server_set({0})'.format(server)) + self.logger.debug('CommandLineInterface._server_set(%s)', server) (_command, url) = server.split(' ') if is_url(url): @@ -387,7 +386,7 @@ def _server_set(self, server): else: self.status = 'Key missing' else: - self._cli_print('{0} is not a valid url'.format(url)) + self._cli_print(f'{url} is not a valid url') def help_print(self): """ help screen """ diff --git a/tools/cliuser_mgmt.py b/tools/cliuser_mgmt.py index 22324b93..4dede077 100644 --- a/tools/cliuser_mgmt.py +++ b/tools/cliuser_mgmt.py @@ -1,6 +1,6 @@ #!/usr/bin/python """ database updater """ -# pylint: disable=E0401, C0413, C0209 +# pylint: disable=E0401, C0413 import sys import json import argparse @@ -47,7 +47,7 @@ def arg_parse(): if os.path.exists(args.keyfile): config_dic['jwk'] = json.loads(file_load(args.keyfile)) else: - print('Error: keyfile "{0}" does not exist'.format(args.keyfile)) + print(f'Error: keyfile "{args.keyfile}" does not exist') return (debug, config_dic) diff --git a/tools/invalidator.py b/tools/invalidator.py index 4248a357..d9659054 100644 --- a/tools/invalidator.py +++ b/tools/invalidator.py @@ -1,6 +1,6 @@ #!/usr/bin/python """ database updater """ -# pylint: disable=C0209, E0401, C0413 +# pylint: disable=E0401, C0413 import sys sys.path.insert(0, '..') sys.path.insert(1, '.') @@ -20,10 +20,10 @@ with Housekeeping(DEBUG, LOGGER) as housekeeping: # manual order invalidation - order_list = housekeeping.orders_invalidate(report_format='csv', report_name='orders_invalidate_{0}'.format(SUFFIX)) + order_list = housekeeping.orders_invalidate(report_format='csv', report_name=f'orders_invalidate_{SUFFIX}') # manual authorization invalidation - authorization_list = housekeeping.authorizations_invalidate(report_format='csv', report_name='authorization_expire_{0}'.format(SUFFIX)) + authorization_list = housekeeping.authorizations_invalidate(report_format='csv', report_name=f'authorization_expire_{SUFFIX}') # update issue_uts and expire_uts in certificates table housekeeping.certificate_dates_update() diff --git a/tools/report_generator.py b/tools/report_generator.py index 63600730..36529f9d 100644 --- a/tools/report_generator.py +++ b/tools/report_generator.py @@ -1,6 +1,6 @@ #!/usr/bin/python """ database updater """ -# pylint: disable=C0209, E0401, C0413 +# pylint: disable=E0401, C0413 import sys sys.path.insert(0, '..') sys.path.insert(1, '.') @@ -26,22 +26,22 @@ with Housekeeping(DEBUG, LOGGER) as housekeeping: # certificate report in json format - cert_report = housekeeping.certreport_get(report_name='certificate_report_{0}'.format(SUFFIX), report_format='json') + cert_report = housekeeping.certreport_get(report_name=f'certificate_report_{SUFFIX}', report_format='json') # certificate report in csv format - housekeeping.certreport_get(report_name='certificate_report_{0}'.format(SUFFIX)) + housekeeping.certreport_get(report_name=f'certificate_report_{SUFFIX}') # account report in json format - account_report = housekeeping.accountreport_get(report_name='account_report_{0}'.format(SUFFIX), report_format='json', nested=True) + account_report = housekeeping.accountreport_get(report_name=f'account_report_{SUFFIX}', report_format='json', nested=True) # account report in csv report_format - housekeeping.accountreport_get(report_name='account_report_{0}'.format(SUFFIX)) + housekeeping.accountreport_get(report_name=f'account_report_{SUFFIX}') # certifiate cleanup (no delete) dump in json - cleanup_report = housekeeping.certificates_cleanup(report_format='json', report_name='certificate_cleanup_{0}'.format(SUFFIX)) + cleanup_report = housekeeping.certificates_cleanup(report_format='json', report_name=f'certificate_cleanup_{SUFFIX}') # certifiate cleanup (including delete) dump in csv # housekeeping.certificates_cleanup(report_format='csv', report_name='certificate_cleanup_{0}'.format(SUFFIX), purge=True) # manual order invalidation - order_list = housekeeping.orders_invalidate(report_format='csv', report_name='orders_invalidate_{0}'.format(SUFFIX)) + order_list = housekeeping.orders_invalidate(report_format='csv', report_name=f'orders_invalidate_{SUFFIX}') # manual authorization invalidation - authorization_list = housekeeping.authorizations_invalidate(report_format='csv', report_name='authorization_expire_{0}'.format(SUFFIX)) + authorization_list = housekeeping.authorizations_invalidate(report_format='csv', report_name=f'authorization_expire_{SUFFIX}') From 0281e71f50043bcd05bbc459306a461a915dde73 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 21 Jan 2024 09:49:34 +0100 Subject: [PATCH 026/460] [fix] mock_soap_server binary_dump() --- examples/soap/mock_soap_srv.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/soap/mock_soap_srv.py b/examples/soap/mock_soap_srv.py index 2f1f31f5..97f6eb6b 100644 --- a/examples/soap/mock_soap_srv.py +++ b/examples/soap/mock_soap_srv.py @@ -181,7 +181,7 @@ def _csr_extract(logger, tmp_dir: str, csr: str) -> str: if csr: # dump csr into a file - _file_dump_binary(logger, f'{0}/file.p7b'.format(tmp_dir), b64_decode(logger, csr)) + _file_dump_binary(logger, f'{tmp_dir}/file.p7b', b64_decode(logger, csr)) openssl_cmd = _opensslcmd_csr_extract(logger, f'{tmp_dir}/file.p7b', f'{tmp_dir}/csr.der') rcode = subprocess.call(openssl_cmd) From f625319676414a4c29f694a7b466d1a2955db8a2 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 27 Jan 2024 16:14:29 +0100 Subject: [PATCH 027/460] [fix] refactor ca_handlers to address pylint c0209 issue --- examples/ca_handler/acme_ca_handler.py | 90 ++++++------ examples/ca_handler/asa_ca_handler.py | 60 ++++---- examples/ca_handler/certifier_ca_handler.py | 66 ++++----- examples/ca_handler/cmp_ca_handler.py | 36 ++--- examples/ca_handler/ejbca_ca_handler.py | 36 ++--- examples/ca_handler/est_ca_handler.py | 28 ++-- examples/ca_handler/mscertsrv_ca_handler.py | 21 ++- examples/ca_handler/mswcce_ca_handler.py | 22 +-- examples/ca_handler/nclm_ca_handler.py | 143 ++++++++++--------- examples/ca_handler/openssl_ca_handler.py | 2 +- examples/ca_handler/openxpki_ca_handler.py | 32 ++--- examples/ca_handler/pkcs7_soap_ca_handler.py | 61 ++++---- examples/ca_handler/skeleton_ca_handler.py | 6 +- examples/ca_handler/xca_ca_handler.py | 133 ++++++++--------- 14 files changed, 364 insertions(+), 372 deletions(-) diff --git a/examples/ca_handler/acme_ca_handler.py b/examples/ca_handler/acme_ca_handler.py index 23698084..42c45846 100644 --- a/examples/ca_handler/acme_ca_handler.py +++ b/examples/ca_handler/acme_ca_handler.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """ generic ca handler for CAs supporting acme protocol """ from __future__ import print_function -# pylint: disable=C0209, E0401, W0105, R0914, W0212 +# pylint: disable= e0401, w0105, w0212 import json import textwrap import base64 @@ -94,7 +94,7 @@ def _config_parameters_load(self, config_dic: Dict[str, str]): try: self.allowed_domainlist = json.loads(config_dic['CAhandler']['allowed_domainlist']) except Exception as err: - self.logger.error('CAhandler._config_load(): failed to parse allowed_domainlist: {0}'.format(err)) + self.logger.error('CAhandler._config_load(): failed to parse allowed_domainlist: %s', err) if 'eab_kid' in config_dic['CAhandler']: self.eab_kid = config_dic['CAhandler']['eab_kid'] @@ -120,20 +120,20 @@ def _config_load(self): def _challenge_filter(self, authzr: messages.AuthorizationResource, chall_type: str = 'http-01') -> messages.ChallengeBody: """ filter authorization for challenge """ - self.logger.debug('CAhandler._challenge_filter({0})'.format(chall_type)) + self.logger.debug('CAhandler._challenge_filter(%s)', chall_type) result = None for challenge in authzr.body.challenges: if challenge.chall.to_partial_json()['type'] == chall_type: result = challenge break if not result: - self.logger.error('CAhandler._challenge_filter() ended. Could not find challenge of type {0}'.format(chall_type)) + self.logger.error('CAhandler._challenge_filter() ended. Could not find challenge of type %s', chall_type) return result def _challenge_store(self, challenge_name: str, challenge_content: str): """ store challenge into database """ - self.logger.debug('CAhandler._challenge_store({0})'.format(challenge_name)) + self.logger.debug('CAhandler._challenge_store(%s)', challenge_name) if challenge_name and challenge_content: data_dic = {'name': challenge_name, 'value1': challenge_content} @@ -158,7 +158,7 @@ def _sancheck_lists_create(self, csr: str) -> Tuple[List[str], List[str]]: except Exception: # force check to fail as something went wrong during parsing check_list.append(False) - self.logger.debug('CAhandler._csr_check(): san_list parsing failed at entry: {0}'.format(san)) + self.logger.debug('CAhandler._csr_check(): san_list parsing failed at entry: %s', san) # get common name and attach it to san_list cn_ = csr_cn_get(self.logger, csr) @@ -195,12 +195,12 @@ def _csr_check(self, csr: str) -> bool: else: result = True - self.logger.debug('CAhandler._csr_check() ended with: {0}'.format(result)) + self.logger.debug('CAhandler._csr_check() ended with: %s', result) return result def _entry_check(self, entry: str, regex: str, check_result: bool) -> bool: """ check string against regex """ - self.logger.debug('_entry_check({0}/{1}):'.format(entry, regex)) + self.logger.debug('_entry_check(%s/%s):', entry, regex) if regex.startswith('*.'): regex = regex.replace('*.', '.') @@ -210,13 +210,13 @@ def _entry_check(self, entry: str, regex: str, check_result: bool) -> bool: # parameter is in set flag accordingly and stop loop check_result = True - self.logger.debug('_entry_check() ended with: {0}'.format(check_result)) + self.logger.debug('_entry_check() ended with: %s', format(check_result)) return check_result def _list_check(self, entry: str, list_: List[str], toggle: bool = False) -> bool: """ check string against list """ - self.logger.debug('CAhandler._list_check({0}:{1})'.format(entry, toggle)) - self.logger.debug('check against list: {0}'.format(list_)) + self.logger.debug('CAhandler._list_check(%s:%s)', entry, toggle) + self.logger.debug('check against list: %s', list_) # default setting check_result = False @@ -234,7 +234,7 @@ def _list_check(self, entry: str, list_: List[str], toggle: bool = False) -> boo # toggle result if this is a blacklist check_result = not check_result - self.logger.debug('CAhandler._list_check() ended with: {0}'.format(check_result)) + self.logger.debug('CAhandler._list_check() ended with: %s', check_result) return check_result def _challenge_info(self, authzr: messages.AuthorizationResource, user_key: josepy.jwk.JWKRSA): @@ -251,7 +251,7 @@ def _challenge_info(self, authzr: messages.AuthorizationResource, user_key: jose try: (chall_name, _token) = chall_content.split('.', 2) except Exception: - self.logger.error('CAhandler._challenge_info() challenge split failed: {0}'.format(chall_content)) + self.logger.error('CAhandler._challenge_info() challenge split failed: %s', chall_content) else: challenge = self._challenge_filter(authzr, chall_type='sectigo-email-01') @@ -264,12 +264,12 @@ def _challenge_info(self, authzr: messages.AuthorizationResource, user_key: jose self.logger.error('CAhandler._challenge_info() authzr is missing') challenge = None - self.logger.debug('CAhandler._challenge_info() ended with {0}'.format(chall_name)) + self.logger.debug('CAhandler._challenge_info() ended with %s', chall_name) return (chall_name, chall_content, challenge) def _key_generate(self) -> josepy.jwk.JWKRSA: """ generate key """ - self.logger.debug('CAhandler._key_generate({0})'.format(self.key_size)) + self.logger.debug('CAhandler._key_generate(%s)', self.key_size) user_key = josepy.JWKRSA( key=rsa.generate_private_key( public_exponent=65537, @@ -282,7 +282,7 @@ def _key_generate(self) -> josepy.jwk.JWKRSA: def _user_key_load(self) -> josepy.jwk.JWKRSA: """ enroll certificate """ - self.logger.debug('CAhandler._user_key_load({0})'.format(self.keyfile)) + self.logger.debug('CAhandler._user_key_load(%s)', self.keyfile) if os.path.exists(self.keyfile): self.logger.debug('CAhandler.enroll() opening user_key') @@ -296,9 +296,9 @@ def _user_key_load(self) -> josepy.jwk.JWKRSA: with open(self.keyfile, "w", encoding='utf8') as keyf: keyf.write(json.dumps(user_key.to_json())) except Exception as err: - self.logger.error('Error during key dumping: {0}'.format(err)) + self.logger.error('Error during key dumping: %s', err) - self.logger.debug('CAhandler._user_key_load() ended with: {0}'.format(bool(user_key))) + self.logger.debug('CAhandler._user_key_load() ended with: %s', bool(user_key)) return user_key def _order_authorization(self, acmeclient: client.ClientV2, order: messages.OrderResource, user_key: josepy.jwk.JWKRSA) -> bool: @@ -322,7 +322,7 @@ def _order_authorization(self, acmeclient: client.ClientV2, order: messages.Orde self.logger.debug('CAhandler._order_authorization(): sectigo-email-01 challenge detected') authz_valid = True - self.logger.debug('CAhandler._order_authorization() ended with: {0}'.format(authz_valid)) + self.logger.debug('CAhandler._order_authorization() ended with: %s', authz_valid) return authz_valid def _order_issue(self, acmeclient: client.ClientV2, user_key: josepy.jwk.JWKRSA, csr_pem: str) -> Tuple[str, str, str]: @@ -347,8 +347,8 @@ def _order_issue(self, acmeclient: client.ClientV2, user_key: josepy.jwk.JWKRSA, cert_bundle = str(order.fullchain_pem) cert_raw = str(base64.b64encode(crypto.dump_certificate(crypto.FILETYPE_ASN1, crypto.load_certificate(crypto.FILETYPE_PEM, cert_bundle))), 'utf-8') else: - self.logger.error('CAhandler.enroll: Error getting certificate: {0}'.format(order.error)) - error = 'Error getting certificate: {0}'.format(order.error) + self.logger.error('CAhandler.enroll: Error getting certificate: %s', order.error) + error = f'Error getting certificate: {order.error}' self.logger.debug('CAhandler.enroll() ended') return (error, cert_bundle, cert_raw) @@ -361,7 +361,7 @@ def _account_lookup(self, acmeclient: client.ClientV2, reg: str, directory: mess regr = acmeclient._regr_from_response(response) regr = acmeclient.query_registration(regr) if regr: - self.logger.info('CAhandler._account_lookup: found existing account: {0}'.format(regr.uri)) + self.logger.info('CAhandler._account_lookup: found existing account: %s', regr.uri) self.account = regr.uri if self.url: # remove url from string @@ -372,11 +372,11 @@ def _account_lookup(self, acmeclient: client.ClientV2, reg: str, directory: mess def _account_create(self, acmeclient: client.ClientV2, user_key: josepy.jwk.JWKRSA, directory: messages.Directory) -> messages.RegistrationResource: """ register account """ - self.logger.debug('CAhandler._account_create(): register new account with email: {0}'.format(self.email)) + self.logger.debug('CAhandler._account_create(): register new account with email: %s', self.email) regr = None if self.email: - self.logger.debug('CAhandler.__account_register(): register new account with email: {0}'.format(self.email)) + self.logger.debug('CAhandler.__account_register(): register new account with email: %s', self.email) if self.url and 'host' in self.url_dic and self.url_dic['host'].endswith('zerossl.com'): # lgtm [py/incomplete-url-substring-sanitization] # get zerossl eab credentials self._zerossl_eab_get() @@ -388,24 +388,24 @@ def _account_create(self, acmeclient: client.ClientV2, user_key: josepy.jwk.JWKR # register with email reg = messages.NewRegistration.from_data(key=user_key, email=self.email, terms_of_service_agreed=True) regr = acmeclient.new_account(reg) - self.logger.debug('CAhandler.__account_register(): new account reqistered: {0}'.format(regr.uri)) + self.logger.debug('CAhandler.__account_register(): new account reqistered: %s', regr.uri) else: self.logger.error('CAhandler.__account_register(): registration aborted. Email address is missing') regr = None - self.logger.debug('CAhandler._account_create() ended with: {0}'.format(bool(regr))) + self.logger.debug('CAhandler._account_create() ended with: %s', bool(regr)) return regr def _account_register(self, acmeclient: client.ClientV2, user_key: josepy.jwk.JWKRSA, directory: messages.Directory) -> messages.RegistrationResource: """ register account / check registration """ - self.logger.debug('CAhandler._account_register({0})'.format(self.email)) + self.logger.debug('CAhandler._account_register(%s)', self.email) try: # we assume that the account exist and need to query the account id reg = messages.NewRegistration.from_data(key=user_key, email=self.email, terms_of_service_agreed=True, only_return_existing=True) response = acmeclient._post(directory['newAccount'], reg) regr = acmeclient._regr_from_response(response) regr = acmeclient.query_registration(regr) - self.logger.debug('CAhandler.__account_register(): found existing account: {0}'.format(regr.uri)) + self.logger.debug('CAhandler.__account_register(): found existing account: %s', regr.uri) except Exception: regr = self._account_create(acmeclient, user_key, directory) @@ -413,7 +413,7 @@ def _account_register(self, acmeclient: client.ClientV2, user_key: josepy.jwk.JW if self.url and 'acct_path' in self.path_dic: self.account = regr.uri.replace(self.url, '').replace(self.path_dic['acct_path'], '') if self.account: - self.logger.info('acme-account id is {0}. Please add an corresponding acme_account parameter to your acme_srv.cfg to avoid unnecessary lookups'.format(self.account)) + self.logger.info('acme-account id is %s. Please add an corresponding acme_account parameter to your acme_srv.cfg to avoid unnecessary lookups', self.account) return regr @@ -430,14 +430,14 @@ def _zerossl_eab_get(self): self.eab_hmac_key = response.json()['eab_hmac_key'] self.logger.debug('CAhandler._zerossl_eab_get() ended successfully') else: - self.logger.error('CAhandler._zerossl_eab_get() failed: {0}'.format(response.text)) + self.logger.error('CAhandler._zerossl_eab_get() failed: %s', response.text) def enroll(self, csr: str) -> Tuple[str, str, str, str]: """ enroll certificate """ # pylint: disable=R0915 self.logger.debug('CAhandler.enroll()') - csr_pem = '-----BEGIN CERTIFICATE REQUEST-----\n{0}\n-----END CERTIFICATE REQUEST-----\n'.format(textwrap.fill(str(b64_url_recode(self.logger, csr)), 64)) + csr_pem = f'-----BEGIN CERTIFICATE REQUEST-----\n{textwrap.fill(str(b64_url_recode(self.logger, csr)), 64)}\n-----END CERTIFICATE REQUEST-----\n' cert_bundle = None error = None @@ -453,12 +453,12 @@ def enroll(self, csr: str) -> Tuple[str, str, str, str]: user_key = self._user_key_load() net = client.ClientNetwork(user_key) - directory = messages.Directory.from_json(net.get('{0}{1}'.format(self.url, self.path_dic['directory_path'])).json()) + directory = messages.Directory.from_json(net.get(f'{self.url}{self.path_dic["directory_path"]}').json()) acmeclient = client.ClientV2(directory, net=net) reg = messages.Registration.from_data(key=user_key, terms_of_service_agreed=True) if self.account: - regr = messages.RegistrationResource(uri="{0}{1}{2}".format(self.url, self.path_dic['acct_path'], self.account), body=reg) + regr = messages.RegistrationResource(uri=f"{self.url}{self.path_dic['acct_path']}{self.account}", body=reg) self.logger.debug('CAhandler.enroll(): checking remote registration status') regr = acmeclient.query_registration(regr) else: @@ -469,13 +469,13 @@ def enroll(self, csr: str) -> Tuple[str, str, str, str]: (error, cert_bundle, cert_raw) = self._order_issue(acmeclient, user_key, csr_pem) elif not regr.body.status and regr.uri: # this is an exisitng but not configured account. Throw error but continue enrolling - self.logger.info('Existing but not configured ACME account: {0}'.format(regr.uri)) + self.logger.info('Existing but not configured ACME account: %s', regr.uri) (error, cert_bundle, cert_raw) = self._order_issue(acmeclient, user_key, csr_pem) else: - self.logger.error('CAhandler.enroll: Bad ACME account: {0}'.format(regr.body.error)) - error = 'Bad ACME account: {0}'.format(regr.body.error) + self.logger.error('CAhandler.enroll: Bad ACME account: %s', regr.body.error) + error = f'Bad ACME account: {regr.body.error}' except Exception as err: - self.logger.error('CAhandler.enroll: error: {0}'.format(err)) + self.logger.error('CAhandler.enroll: error: %s', err) error = str(err) finally: del user_key @@ -509,7 +509,7 @@ def revoke(self, _cert: str, _rev_reason: str, _rev_date: str) -> Tuple[int, str detail = None try: - certpem = '-----BEGIN CERTIFICATE-----\n{0}\n-----END CERTIFICATE-----\n'.format(textwrap.fill(str(b64_url_recode(self.logger, _cert)), 64)) + certpem = f'-----BEGIN CERTIFICATE-----\n{textwrap.fill(str(b64_url_recode(self.logger, _cert)), 64)}\n-----END CERTIFICATE-----\n' cert = josepy.ComparableX509(crypto.load_certificate(crypto.FILETYPE_PEM, certpem)) if os.path.exists(self.keyfile): @@ -517,7 +517,7 @@ def revoke(self, _cert: str, _rev_reason: str, _rev_date: str) -> Tuple[int, str net = client.ClientNetwork(user_key) if user_key: - directory = messages.Directory.from_json(net.get('{0}{1}'.format(self.url, self.path_dic['directory_path'])).json()) + directory = messages.Directory.from_json(net.get(f"{self.url}{self.path_dic['directory_path']}").json()) acmeclient = client.ClientV2(directory, net=net) reg = messages.NewRegistration.from_data(key=user_key, email=self.email, terms_of_service_agreed=True, only_return_existing=True) @@ -525,7 +525,7 @@ def revoke(self, _cert: str, _rev_reason: str, _rev_date: str) -> Tuple[int, str self._account_lookup(acmeclient, reg, directory) if self.account: - regr = messages.RegistrationResource(uri="{0}{1}{2}".format(self.url, self.path_dic['acct_path'], self.account), body=reg) + regr = messages.RegistrationResource(uri=f"{self.url}{self.path_dic['acct_path']}{self.account}", body=reg) self.logger.debug('CAhandler.revoke() checking remote registration status') regr = acmeclient.query_registration(regr) @@ -536,18 +536,18 @@ def revoke(self, _cert: str, _rev_reason: str, _rev_date: str) -> Tuple[int, str code = 200 message = None else: - self.logger.error('CAhandler.enroll: Bad ACME account: {0}'.format(regr.body.error)) - detail = 'Bad ACME account: {0}'.format(regr.body.error) + self.logger.error('CAhandler.enroll: Bad ACME account: %s', regr.body.error) + detail = f'Bad ACME account: {regr.body.error}' else: self.logger.error('CAhandler.revoke(): could not find account key and lookup at acme-endpoint failed.') detail = 'account lookup failed' else: - self.logger.error('CAhandler.revoke(): could not load user_key {0}'.format(self.keyfile)) + self.logger.error('CAhandler.revoke(): could not load user_key %s', self.keyfile) detail = 'Internal Error' except Exception as err: - self.logger.error('CAhandler.enroll: error: {0}'.format(err)) + self.logger.error('CAhandler.enroll: error: %s', err) detail = str(err) finally: @@ -564,5 +564,5 @@ def trigger(self, _payload: str) -> Tuple[int, str, str]: cert_bundle = None cert_raw = None - self.logger.debug('CAhandler.trigger() ended with error: {0}'.format(error)) + self.logger.debug('CAhandler.trigger() ended with error: %s', error) return (error, cert_bundle, cert_raw) diff --git a/examples/ca_handler/asa_ca_handler.py b/examples/ca_handler/asa_ca_handler.py index 6f2d2570..9d551cc8 100644 --- a/examples/ca_handler/asa_ca_handler.py +++ b/examples/ca_handler/asa_ca_handler.py @@ -6,7 +6,7 @@ import json import requests from requests.auth import HTTPBasicAuth -# pylint: disable=C0209, E0401 +# pylint: disable=e0401 from acme_srv.helper import load_config, encode_url, csr_pubkey_get, csr_cn_get, csr_san_get, uts_now, uts_to_date_utc, b64_decode, cert_der2pem, convert_byte_to_string, cert_ski_get, header_info_get, csr_san_byte_get @@ -48,10 +48,10 @@ def _api_get(self, url: str) -> Tuple[int, Dict[str, str]]: try: content = api_response.json() except Exception as err_: - self.logger.error('CAhandler._api_get() returned error during json parsing: {0}'.format(err_)) + self.logger.error('CAhandler._api_get() returned error during json parsing: %s', err_) content = str(err_) except Exception as err_: - self.logger.error('CAhandler._api_get() returned error: {0}'.format(err_)) + self.logger.error('CAhandler._api_get() returned error: %s', err_) code = 500 content = str(err_) @@ -69,12 +69,12 @@ def _api_post(self, url: str, data: Dict[str, str]) -> Tuple[int, Dict[str, str] try: content = api_response.json() except Exception as err_: - self.logger.error('CAhandler._api_post() returned error during json parsing: {0}'.format(err_)) + self.logger.error('CAhandler._api_post() returned error during json parsing: %s', err_) content = str(err_) else: content = None except Exception as err_: - self.logger.error('CAhandler._api_post() returned error: {0}'.format(err_)) + self.logger.error('CAhandler._api_post() returned error: %s', err_) code = 500 content = str(err_) @@ -111,7 +111,7 @@ def _certificates_list(self) -> Dict[str, str]: """ list profiles """ self.logger.debug('CAhandler._certificates_list()') - url = '{0}/list_certificates?issuerName={1}'.format(self.api_host, encode_url(self.logger, self.ca_name)) + url = f'{self.api_host}/list_certificates?issuerName={encode_url(self.logger, self.ca_name)}' _code, api_response = self._api_get(url) self.logger.debug('CAhandler._certificates_list() ended') @@ -125,7 +125,7 @@ def _config_headerinfo_get(self, config_dic: Dict[str, str]): try: self.header_info_field = json.loads(config_dic['Order']['header_info_list'])[0] except Exception as err_: - self.logger.warning('Order._config_orderconfig_load() header_info_list failed with error: {0}'.format(err_)) + self.logger.warning('Order._config_orderconfig_load() header_info_list failed with error: %s', err_) self.logger.debug('_config_header_info() ended') @@ -217,7 +217,7 @@ def _config_load(self): for ele in ['api_host', 'api_user', 'api_password', 'api_key', 'ca_name', 'profile_name']: if not getattr(self, ele): - self.logger.error('CAhandler._config_load(): {0} not set'.format(ele)) + self.logger.error('CAhandler._config_load(): %s not set', ele) self._auth_set() @@ -235,11 +235,11 @@ def _csr_cn_get(self, csr: str) -> str: if san_list: (_type, san_value) = san_list[0].split(':') cn = san_value - self.logger.info('CAhandler._csr_cn_get(): CN not found in CSR. Using first SAN entry as CN: {0}'.format(san_value)) + self.logger.info('CAhandler._csr_cn_get(): CN not found in CSR. Using first SAN entry as CN: %s', san_value) else: self.logger.error('CAhandler._csr_cn_get(): CN not found in CSR. No SAN entries found') - self.logger.debug('CAhandler._csr_cn_get() ended with: {0}'.format(cn)) + self.logger.debug('CAhandler._csr_cn_get() ended with: %s', cn) return cn def _issuer_verify(self) -> str: @@ -252,20 +252,20 @@ def _issuer_verify(self) -> str: if self.ca_name in api_response['issuers']: error = None else: - error = 'CA {0} not found'.format(self.ca_name) - self.logger.error('CAhandler.enroll(): CA {0} not found'.format(self.ca_name)) + error = f'CA {self.ca_name} not found' + self.logger.error('CAhandler.enroll(): CA %s not found', self.ca_name) else: error = 'Malformed response' self.logger.error('CAhandler.enroll(): "Malformed response. "issuers" key not found') - self.logger.debug('CAhandler._issuer_verify() ended with: {0}'.format(error)) + self.logger.debug('CAhandler._issuer_verify() ended with: %s', error) return error def _issuers_list(self) -> Dict[str, str]: """ list issuers """ self.logger.debug('CAhandler._list_issuers()') - url = '{0}/list_issuers'.format(self.api_host) + url = f'{self.api_host}/list_issuers' _code, api_response = self._api_get(url) self.logger.debug('CAhandler._list_issuers() ended') @@ -275,7 +275,7 @@ def _profiles_list(self) -> Dict[str, str]: """ list profiles """ self.logger.debug('CAhandler._profiles_list()') - url = '{0}/list_profiles?issuerName={1}'.format(self.api_host, encode_url(self.logger, self.ca_name)) + url = f'{self.api_host}/list_profiles?issuerName={encode_url(self.logger, self.ca_name)}' _code, api_response = self._api_get(url) self.logger.debug('CAhandler._profiles_list() ended') @@ -283,20 +283,20 @@ def _profiles_list(self) -> Dict[str, str]: def _profile_verify(self) -> str: """ verify profile """ - self.logger.debug('CAhandler._profile_verify({0})'.format(self.profile_name)) + self.logger.debug('CAhandler._profile_verify(%s)', self.profile_name) api_response = self._profiles_list() if 'profiles' in api_response: if self.profile_name in api_response['profiles']: error = None else: - error = 'Profile {0} not found'.format(self.profile_name) - self.logger.error('CAhandler.enroll(): Profile {0} not found'.format(self.profile_name)) + error = f'Profile {self.profile_name} not found' + self.logger.error('CAhandler.enroll(): Profile %s not found', self.profile_name) else: error = 'Malformed response' self.logger.error('CAhandler.enroll(): "Malformed response. "profiles" key not found') - self.logger.debug('CAhandler._profile_verify() ended with: {0}'.format(error)) + self.logger.debug('CAhandler._profile_verify() ended with: %s', error) return error def _validity_dates_get(self) -> Tuple[str, str]: @@ -325,7 +325,7 @@ def _issuer_chain_get(self) -> str: """ get issuer chain """ self.logger.debug('CAhandler._issuer_chain_get()') - url = '{0}/get_issuer_chain?issuerName={1}'.format(self.api_host, encode_url(self.logger, self.ca_name)) + url = f'{self.api_host}/get_issuer_chain?issuerName={encode_url(self.logger, self.ca_name)}' _code, api_response = self._api_get(url) if 'certs' in api_response: pem_chain = self._pem_cert_chain_generate(api_response['certs']) @@ -340,13 +340,13 @@ def _cert_get(self, data_dic: Dict[str, str]) -> str: """ get certificate """ self.logger.debug('CAhandler._cert_get()') - url = '{0}/issue_certificate'.format(self.api_host) + url = f'{self.api_host}/issue_certificate' code, api_response = self._api_post(url, data_dic) if code == 200 and api_response: cert = api_response else: - self.logger.error('CAhandler._cert_get(): enrollment failed: {0}/{1}'.format(code, api_response)) + self.logger.error('CAhandler._cert_get(): enrollment failed: %s/%s', code, api_response) cert = None self.logger.debug('CAhandler._cert_get() ended') @@ -357,7 +357,7 @@ def _cert_status_get(self, certificate: str) -> str: self.logger.debug('CAhandler._cert_status_get()') data_dic = {'certificateFile': certificate} - url = '{0}/verify_certificate?issuerName={1}'.format(self.api_host, encode_url(self.logger, self.ca_name)) + url = f'{self.api_host}/verify_certificate?issuerName={encode_url(self.logger, self.ca_name)}' code, api_response = self._api_post(url, data_dic) api_response['code'] = code @@ -392,7 +392,7 @@ def _enrollment_dic_create(self, csr: str) -> Dict[str, str]: def _profile_name_get(self, csr: str) -> str: """ get profile id from csr """ - self.logger.debug('CAhandler._profile_name_get({0})'.format(csr)) + self.logger.debug('CAhandler._profile_name_get(%s)', csr) profile_name = None # parse profileid from http_header @@ -406,9 +406,9 @@ def _profile_name_get(self, csr: str) -> str: profile_name = ele.split('=')[1] break except Exception as err: - self.logger.error('CAhandler._profile_name_get() could not parse profile_name: {0}'.format(err)) + self.logger.error('CAhandler._profile_name_get() could not parse profile_name: %s', err) - self.logger.debug('CAhandler._profile_name_get() ended with: {0}'.format(profile_name)) + self.logger.debug('CAhandler._profile_name_get() ended with: %s', profile_name) return profile_name def enroll(self, csr: str) -> Tuple[str, str, str, str]: @@ -429,7 +429,7 @@ def enroll(self, csr: str) -> Tuple[str, str, str, str]: # parse profileid from http_header profile_name = self._profile_name_get(csr=csr) if profile_name: - self.logger.info('CAhandler._enrollment_dic_create(): profile_name found in header_info: {0}'.format(profile_name)) + self.logger.info('CAhandler._enrollment_dic_create(): profile_name found in header_info: %s', profile_name) self.profile_name = profile_name # verify profile @@ -449,7 +449,7 @@ def enroll(self, csr: str) -> Tuple[str, str, str, str]: else: error = 'Enrollment failed' - self.logger.debug('Certificate.enroll() ended with: {0}'.format(error)) + self.logger.debug('Certificate.enroll() ended with: %s', error) return (error, cert_bundle, cert_raw, poll_indentifier) def poll(self, _cert_name: str, poll_identifier: str, _csr: str) -> Tuple[str, str, str, str, bool]: @@ -474,7 +474,7 @@ def revoke(self, cert: str, _rev_reason: str = 'unspecified', _rev_date: str = u cert_ski = cert_ski_get(self.logger, cert) # get subjectKeyIdentifier from certificate - url = '{0}/revoke_certificate?issuerName={1}&certificateId={2}'.format(self.api_host, encode_url(self.logger, self.ca_name), cert_ski) + url = f'{self.api_host}/revoke_certificate?issuerName={encode_url(self.logger, self.ca_name)}&certificateId={cert_ski}' data_dic = {} code, content_dic = self._api_post(url, data_dic) if content_dic: @@ -497,5 +497,5 @@ def trigger(self, _payload: str) -> Tuple[str, str, str]: cert_bundle = None cert_raw = None - self.logger.debug('CAhandler.trigger() ended with error: {0}'.format(error)) + self.logger.debug('CAhandler.trigger() ended with error: %s', error) return (error, cert_bundle, cert_raw) diff --git a/examples/ca_handler/certifier_ca_handler.py b/examples/ca_handler/certifier_ca_handler.py index fd776a5b..c02cedc7 100644 --- a/examples/ca_handler/certifier_ca_handler.py +++ b/examples/ca_handler/certifier_ca_handler.py @@ -9,7 +9,7 @@ from typing import List, Tuple, Dict import requests from requests.auth import HTTPBasicAuth -# pylint: disable=C0209, E0401 +# pylint: disable=e0401 from acme_srv.helper import load_config, cert_serial_get, uts_now, uts_to_date_utc, b64_decode, b64_encode, cert_pem2der, parse_url, proxy_check, error_dic_get, header_info_get @@ -85,34 +85,34 @@ def _api_post(self, url: str, data: Dict[str, str]) -> Dict[str, str]: try: api_response = requests.post(url=url, json=data, auth=self.auth, verify=self.ca_bundle, proxies=self.proxy, timeout=self.request_timeout).json() except Exception as err_: - self.logger.error('CAhandler._api_post() returned error: {0}'.format(err_)) + self.logger.error('CAhandler._api_post() returned error: %s', err_) api_response = str(err_) return api_response def _ca_get(self, filter_key: str = None, filter_value: str = None) -> Dict[str, str]: """ get list of CAs""" - self.logger.debug('_ca_get({0}:{1})'.format(filter_key, filter_value)) + self.logger.debug('_ca_get(%s:%s)', filter_key, filter_value) params = {} if filter_key: - params['q'] = '{0}:{1}'.format(filter_key, filter_value) + params['q'] = f'{filter_key}:{filter_value}' if self.api_host: try: api_response = requests.get(self.api_host + '/v1/cas', auth=self.auth, params=params, proxies=self.proxy, verify=self.ca_bundle, timeout=self.request_timeout).json() except Exception as err_: - self.logger.error('CAhandler._ca_get() returned error: {0}'.format(str(err_))) + self.logger.error('CAhandler._ca_get() returned error: %s', str(err_)) api_response = {'status': 500, 'message': str(err_), 'statusMessage': 'Internal Server Error'} else: self.logger.error('CAhandler._ca_get(): api_host is misisng in configuration') api_response = {} - self.logger.debug('CAhandler._ca_get() ended with: {0}'.format(api_response)) + self.logger.debug('CAhandler._ca_get() ended with: %s', api_response) return api_response def _ca_get_properties(self, filter_key: str, filter_value: str) -> Dict[str, str]: """ get properties for a single CAs""" - self.logger.debug('_ca_get_properties({0}:{1})'.format(filter_key, filter_value)) + self.logger.debug('_ca_get_properties(%s:%s)', filter_key, filter_value) ca_list = self._ca_get(filter_key, filter_value) ca_dic = {} if 'status' in ca_list and 'message' in ca_list: @@ -125,12 +125,12 @@ def _ca_get_properties(self, filter_key: str, filter_value: str) -> Dict[str, st break if not ca_dic: ca_dic = {'status': 404, 'message': 'CA not found', 'statusMessage': 'Not Found'} - self.logger.debug('CAhandler._ca_get_properties() ended with: {0}'.format(ca_dic)) + self.logger.debug('CAhandler._ca_get_properties() ended with: %s', ca_dic) return ca_dic def _cert_get(self, csr: str) -> Dict[str, str]: """ get certificate from CA """ - self.logger.debug('CAhandler._cert_get({0})'.format(csr)) + self.logger.debug('CAhandler._cert_get(%s)', csr) ca_dic = self._ca_get_properties('name', self.ca_name) cert_dic = {} @@ -150,18 +150,18 @@ def _cert_get(self, csr: str) -> Dict[str, str]: if not cert_dic: cert_dic = ca_dic - self.logger.debug('CAhandler._cert_get() ended with: {0}'.format(cert_dic)) + self.logger.debug('CAhandler._cert_get() ended with: %s', cert_dic) return cert_dic def _cert_get_properties(self, serial: str, ca_link: str) -> Dict[str, str]: """ get properties for a single cert """ - self.logger.debug('_cert_get_properties({0}: {1})'.format(serial, ca_link)) + self.logger.debug('_cert_get_properties(%s:%s)', serial, ca_link) - params = {'q': 'issuer-id:{0},serial-number:{1}'.format(ca_link, serial)} + params = {'q': f'issuer-id:{ca_link},serial-number:{serial}'} try: api_response = requests.get(self.api_host + '/v1/certificates', auth=self.auth, params=params, verify=self.ca_bundle, proxies=self.proxy, timeout=self.request_timeout).json() except Exception as err_: - self.logger.error('CAhandler._cert_get_properties() returned error: {0}'.format(str(err_))) + self.logger.error('CAhandler._cert_get_properties() returned error: %s', str(err_)) api_response = {'status': 500, 'message': str(err_), 'statusMessage': 'Internal Server Error'} self.logger.debug('CAhandler._cert_get_properties() ended') return api_response @@ -213,7 +213,7 @@ def _config_user_load(self, config_dic: Dict[str, str]): try: self.api_user = os.environ[config_dic['CAhandler']['api_user_variable']] except Exception as err: - self.logger.error('CAhandler._config_load() could not load user_variable:{0}'.format(err)) + self.logger.error('CAhandler._config_load() could not load user_variable:%s', err) if 'api_user' in config_dic['CAhandler']: if self.api_user: self.logger.info('CAhandler._config_load() overwrite api_user') @@ -232,7 +232,7 @@ def _config_password_load(self, config_dic: Dict[str, str]): try: self.api_password = os.environ[config_dic['CAhandler']['api_password_variable']] except Exception as err: - self.logger.error('CAhandler._config_load() could not load passphrase_variable:{0}'.format(err)) + self.logger.error('CAhandler._config_load() could not load passphrase_variable:%s', err) if 'api_password' in config_dic['CAhandler']: if self.api_password: self.logger.info('CAhandler._config_load() overwrite api_password_variable') @@ -285,7 +285,7 @@ def _config_proxy_load(self, config_dic: Dict[str, str]): proxy_server = proxy_check(self.logger, fqdn, proxy_list) self.proxy = {'http': proxy_server, 'https': proxy_server} except Exception as err_: - self.logger.warning('Challenge._config_load() proxy_server_list failed with error: {0}'.format(err_)) + self.logger.warning('Challenge._config_load() proxy_server_list failed with error: %s', err_) self.logger.debug('_config_proxy_load() ended') @@ -297,7 +297,7 @@ def _config_headerinfo_get(self, config_dic: Dict[str, str]): try: self.header_info_field = json.loads(config_dic['Order']['header_info_list'])[0] except Exception as err_: - self.logger.warning('Order._config_orderconfig_load() header_info_list failed with error: {0}'.format(err_)) + self.logger.warning('Order._config_orderconfig_load() header_info_list failed with error: %s', err_) self.logger.debug('_config_header_info() ended') @@ -362,7 +362,7 @@ def _poll_cert_get(self, request_dic: Dict[str, str], poll_identifier: str, erro def _loop_poll(self, request_url: str) -> Tuple[str, str, str, str]: """ poll request """ - self.logger.debug('CAhandler._loop_poll({0})'.format(request_url)) + self.logger.debug('CAhandler._loop_poll(%s)', request_url) error = None cert_bundle = None @@ -387,16 +387,16 @@ def _loop_poll(self, request_url: str) -> Tuple[str, str, str, str]: self.logger.error('CAhandler._loop_poll(): no request url specified') poll_identifier = request_url - self.logger.debug('CAhandler._loop_poll() ended with error: {0}'.format(error)) + self.logger.debug('CAhandler._loop_poll() ended with error: %s', error) return (error, cert_bundle, cert_raw, poll_identifier) def _pem_list_cert_get(self, cert_dic: Dict[str, str]) -> Dict[str, str]: self.logger.debug('CAhandler._pem_list_cert_get()') if 'issuer' in cert_dic: - self.logger.debug('issuer found: {0}'.format(cert_dic['issuer'])) + self.logger.debug('issuer found: %s', cert_dic['issuer']) ca_cert_dic = requests.get(cert_dic['issuer'], auth=self.auth, verify=self.ca_bundle, proxies=self.proxy, timeout=self.request_timeout).json() else: - self.logger.debug('issuer found: {0}'.format(cert_dic['issuerCa'])) + self.logger.debug('issuer found: %s', cert_dic['issuerCa']) ca_cert_dic = requests.get(cert_dic['issuerCa'], auth=self.auth, verify=self.ca_bundle, proxies=self.proxy, timeout=self.request_timeout).json() cert_dic = {} @@ -440,7 +440,7 @@ def _pem_cert_chain_generate(self, cert_dic: str) -> str: if pem_list: pem_file = '' for cert in pem_list: - pem_file = '{0}-----BEGIN CERTIFICATE-----\n{1}\n-----END CERTIFICATE-----\n'.format(pem_file, textwrap.fill(cert, 64)) + pem_file = f'{pem_file}-----BEGIN CERTIFICATE-----\n{textwrap.fill(cert, 64)}\n-----END CERTIFICATE-----\n' else: pem_file = None @@ -449,7 +449,7 @@ def _pem_cert_chain_generate(self, cert_dic: str) -> str: def _profile_id_get(self, csr: str) -> str: """ get profile id from csr """ - self.logger.debug('CAhandler._profile_id_get({0})'.format(csr)) + self.logger.debug('CAhandler._profile_id_get(%s)', csr) profile_id = None # parse profileid from http_header @@ -463,14 +463,14 @@ def _profile_id_get(self, csr: str) -> str: profile_id = ele.split('=')[1] break except Exception as err: - self.logger.error('CAhandler._profile_id_get() could not parse profile_id: {0}'.format(err)) + self.logger.error('CAhandler._profile_id_get() could not parse profile_id: %s', err) - self.logger.debug('CAhandler._profile_id_get() ended with: {0}'.format(profile_id)) + self.logger.debug('CAhandler._profile_id_get() ended with: %s', profile_id) return profile_id def _request_poll(self, request_url: str) -> Tuple[str, str, str, str, bool]: """ poll request """ - self.logger.debug('CAhandler._request_poll({0})'.format(request_url)) + self.logger.debug('CAhandler._request_poll(%s)', request_url) error = None cert_bundle = None @@ -481,7 +481,7 @@ def _request_poll(self, request_url: str) -> Tuple[str, str, str, str, bool]: try: request_dic = requests.get(request_url, auth=self.auth, verify=self.ca_bundle, proxies=self.proxy, timeout=self.request_timeout).json() except Exception as err: - self.logger.error('CAhandler._request.poll() returned: {0}'.format(err)) + self.logger.error('CAhandler._request.poll() returned: %s', err) request_dic = {} # check response @@ -492,11 +492,11 @@ def _request_poll(self, request_url: str) -> Tuple[str, str, str, str, bool]: error = 'Request rejected by operator' rejected = True else: - error = 'Unknown request status: {0}'.format(request_dic['status']) + error = f'Unknown request status: {request_dic['status']}' else: error = '"status" field not found in response.' - self.logger.debug('CAhandler._request_poll() ended with error: {0}'.format(error)) + self.logger.debug('CAhandler._request_poll() ended with error: %s', error) return (error, cert_bundle, cert_raw, poll_identifier, rejected) def _trigger_bundle_build(self, cert_raw: str, ca_dic: Dict[str, str]) -> Tuple[str, str]: @@ -518,7 +518,7 @@ def _trigger_bundle_build(self, cert_raw: str, ca_dic: Dict[str, str]) -> Tuple[ else: error = 'serial number lookup via rest failed' - self.logger.debug('CAhandler._trigger_bundle_build() ended with: {0}'.format(error)) + self.logger.debug('CAhandler._trigger_bundle_build() ended with: %s', error) return (error, cert_bundle) def enroll(self, csr: str) -> Tuple[str, str, str, str]: @@ -564,13 +564,13 @@ def poll(self, cert_name: str, poll_identifier: str, _csr: str) -> Tuple[str, st if poll_identifier: (error, cert_bundle, cert_raw, poll_identifier, rejected) = self._request_poll(poll_identifier) else: - self.logger.debug('skipping cert: {0} as there is no poll_identifier'.format(cert_name)) + self.logger.debug('skipping cert: %s as there is no poll_identifier', cert_name) return (error, cert_bundle, cert_raw, poll_identifier, rejected) def revoke(self, cert: str, rev_reason: str = 'unspecified', rev_date: str = uts_to_date_utc(uts_now())) -> Tuple[int, str, str]: """ revoke certificate """ - self.logger.debug('CAhandler.revoke({0}: {1})'.format(rev_reason, rev_date)) + self.logger.debug('CAhandler.revoke(%s: %s)', rev_reason, rev_date) # get error message err_dic = error_dic_get(self.logger) @@ -620,5 +620,5 @@ def trigger(self, payload: str) -> Tuple[str, str, str]: else: error = 'No payload given' - self.logger.debug('CAhandler.trigger() ended with error: {0}'.format(error)) + self.logger.debug('CAhandler.trigger() ended with error: %s', error) return (error, cert_bundle, cert_raw) diff --git a/examples/ca_handler/cmp_ca_handler.py b/examples/ca_handler/cmp_ca_handler.py index bbf7b4af..72ca86b3 100644 --- a/examples/ca_handler/cmp_ca_handler.py +++ b/examples/ca_handler/cmp_ca_handler.py @@ -6,7 +6,7 @@ import subprocess import tempfile from typing import List, Tuple, Dict -# pylint: disable=E0401, C0209 +# pylint: disable=e0401 from acme_srv.helper import load_config, build_pem_file, b64_url_recode @@ -59,7 +59,7 @@ def _certs_bundle(self) -> Tuple[str, str]: cert_raw = cert_raw.replace('-----BEGIN CERTIFICATE-----\n', '') cert_raw = cert_raw.replace('-----END CERTIFICATE-----\n', '') cert_raw = cert_raw.replace('\n', '') - self.logger.debug('CAhandler._certs_bundle() ended with {0}/{1}'.format(bool(cert_bundle), bool(cert_raw))) + self.logger.debug('CAhandler._certs_bundle() ended with %s/%s', bool(cert_bundle), bool(cert_raw)) return (cert_bundle, cert_raw) def _config_refsecret_load(self, config_dic: Dict[str, str]): @@ -88,8 +88,8 @@ def _config_paramters_load(self): # create temporary directory self.tmp_dir = tempfile.mkdtemp() - self.ca_pubs_file = '{0}/capubs.pem'.format(self.tmp_dir) - self.cert_file = '{0}/cert.pem'.format(self.tmp_dir) + self.ca_pubs_file = f'{self.tmp_dir}/capubs.pem' + self.cert_file = f'{self.tmp_dir}/cert.pem' # defaulting openssl_bin if not self.openssl_bin: @@ -127,14 +127,14 @@ def _config_cmpparameter_load(self, ele: str, config_dic: Dict[str, str]): try: self.ref = os.environ[config_dic['CAhandler']['cmp_ref_variable']] except Exception as err: - self.logger.error('CAhandler._config_load() could not load cmp_ref:{0}'.format(err)) + self.logger.error('CAhandler._config_load() could not load cmp_ref:%s', err) elif ele == 'cmp_secret_variable': try: self.secret = os.environ[config_dic['CAhandler']['cmp_secret_variable']] except Exception as err: - self.logger.error('CAhandler._config_load() could not load cmp_secret_variable:{0}'.format(err)) + self.logger.error('CAhandler._config_load() could not load cmp_secret_variable:%s', err) elif ele in ('cmp_secret', 'cmp_ref'): - self.logger.debug('CAhandler._config_cmpparameter_load() ignore {0}'.format(ele)) + self.logger.debug('CAhandler._config_cmpparameter_load() ignore %s', ele) else: if config_dic['CAhandler'][ele] == 'True' or config_dic['CAhandler'][ele] == 'False': self.config_dic[ele[4:]] = config_dic.getboolean('CAhandler', ele, fallback=False) @@ -167,11 +167,11 @@ def _opensslcmd_build(self) -> List[str]: cmd_list = [self.openssl_bin, 'cmp'] for ele, value in self.config_dic.items(): - cmd_list.append('-{0}'.format(str(ele))) + cmd_list.append(f'-{str(ele)}') if value is not True: cmd_list.append(str(value)) - cmd_list.extend(['-csr', '{0}/csr.pem'.format(self.tmp_dir), '-extracertsout', self.ca_pubs_file, '-certout', self.cert_file]) + cmd_list.extend(['-csr', f'{self.tmp_dir}/csr.pem', '-extracertsout', self.ca_pubs_file, '-certout', self.cert_file]) # set timeouts if not configured if '-msg_timeout' not in cmd_list: @@ -184,24 +184,24 @@ def _opensslcmd_build(self) -> List[str]: if self.secret and self.ref: cmd_list.extend(['-secret', self.secret]) - self.logger.debug('CAhandler._opensslcmd_build() ended with: {0}'.format(' '.join(cmd_list))) + self.logger.debug('CAhandler._opensslcmd_build() ended with: %s', ' '.join(cmd_list)) return cmd_list def _file_save(self, filename: str, content: str): """ save content to file """ - self.logger.debug('CAhandler._file_save({0})'.format(filename)) + self.logger.debug('CAhandler._file_save(%s)', filename) with open(filename, 'w', encoding='utf-8') as fso: fso.write(content) self.logger.debug('CAhandler._file_save() ended') def _tmp_dir_delete(self): """ delete temp files """ - self.logger.debug('CAhandler._tmp_dir_delete({0})'.format(self.tmp_dir)) + self.logger.debug('CAhandler._tmp_dir_delete(%s)', self.tmp_dir) if os.path.exists(self.tmp_dir): shutil.rmtree(self.tmp_dir) else: - self.logger.error('CAhandler._tmp_dir_delete(): failed: {0}'.format(self.tmp_dir)) + self.logger.error('CAhandler._tmp_dir_delete(): failed: %s', self.tmp_dir) def enroll(self, csr: str) -> Tuple[str, str, str, bool]: """ enroll certificate from via MS certsrv """ @@ -215,17 +215,17 @@ def enroll(self, csr: str) -> Tuple[str, str, str, bool]: # prepare the CSR to be signed csr = build_pem_file(self.logger, None, b64_url_recode(self.logger, csr), None, True) # dump csr key - self._file_save('{0}/csr.pem'.format(self.tmp_dir), csr) + self._file_save(f'{self.tmp_dir}/csr.pem', csr) # build openssl command and run it openssl_cmd = self._opensslcmd_build() rcode = subprocess.call(openssl_cmd) if rcode: - self.logger.error('CAhandler.enroll(): failed: {0}'.format(rcode)) + self.logger.error(f'CAhandler.enroll(): failed: {rcode}') error = 'rc from enrollment not 0' # generate certificates we need to return - if os.path.isfile('{0}/cert.pem'.format(self.tmp_dir)): + if os.path.isfile(f'{self.tmp_dir}/cert.pem'): (cert_bundle, cert_raw) = self._certs_bundle() else: error = 'Enrollment failed' @@ -236,7 +236,7 @@ def enroll(self, csr: str) -> Tuple[str, str, str, bool]: else: error = 'Config incomplete' - self.logger.debug('Certificate.enroll() ended with error: {0}'.format(error)) + self.logger.debug('Certificate.enroll() ended with error: %s', error) return (error, cert_bundle, cert_raw, None) def poll(self, _cert_name: str, poll_identifier: str, _csr: str) -> Tuple[str, str, str, str, str, bool]: @@ -271,5 +271,5 @@ def trigger(self, _payload: str) -> Tuple[int, str, str]: cert_bundle = None cert_raw = None - self.logger.debug('CAhandler.trigger() ended with error: {0}'.format(error)) + self.logger.debug('CAhandler.trigger() ended with error: %s', error) return (error, cert_bundle, cert_raw) diff --git a/examples/ca_handler/ejbca_ca_handler.py b/examples/ca_handler/ejbca_ca_handler.py index a3ef7777..5b677c6a 100644 --- a/examples/ca_handler/ejbca_ca_handler.py +++ b/examples/ca_handler/ejbca_ca_handler.py @@ -4,7 +4,7 @@ from typing import Tuple, Dict import requests from requests_pkcs12 import Pkcs12Adapter -# pylint: disable=C0209, E0401 +# pylint: disable=e0401 from acme_srv.helper import load_config, build_pem_file, b64_url_recode, cert_der2pem, b64_decode, convert_byte_to_string, cert_serial_get, cert_issuer_get, encode_url @@ -36,16 +36,16 @@ def __exit__(self, *args): def _cert_status_check(self, issuer_dn: str, cert_serial: str) -> Dict[str, str]: """ check certificate status """ - self.logger.debug('CAhandler._cert_status_check({0}: {1})'.format(issuer_dn, cert_serial)) + self.logger.debug('CAhandler._cert_status_check(%s: %s)', issuer_dn, cert_serial) # define path - path = "/ejbca/ejbca-rest-api/v1/certificate/{0}/{1}/revocationstatus".format(encode_url(self.logger, issuer_dn), cert_serial) + path = f"/ejbca/ejbca-rest-api/v1/certificate/{encode_url(self.logger, issuer_dn)}/{cert_serial}/revocationstatus" if self.api_host: try: certstatus_response = self.session.get(self.api_host + path, proxies=self.proxy, verify=self.ca_bundle, timeout=self.request_timeout).json() except Exception as err_: - self.logger.error('CAhandler._ca_get() returned error: {0}'.format(str(err_))) + self.logger.error('CAhandler._ca_get() returned error: %s', str(err_)) certstatus_response = {'status': 'nok', 'error': str(err_)} else: self.logger.error('CAhandler._status_get(): api_host option is misisng in configuration') @@ -75,7 +75,7 @@ def _config_authuser_load(self, config_dic: Dict[str, str]): try: self.username = os.environ[config_dic['CAhandler']['username_variable']] except Exception as err: - self.logger.error('CAhandler._config_authuser_load() could not load username_variable:{0}'.format(err)) + self.logger.error('CAhandler._config_authuser_load() could not load username_variable:%s', err) if 'username' in config_dic['CAhandler']: if self.username: @@ -93,7 +93,7 @@ def _config_enrollmentcode_load(self, config_dic: Dict[str, str]): try: self.enrollment_code = os.environ[config_dic['CAhandler']['enrollment_code_variable']] except Exception as err: - self.logger.error('CAhandler._config_authuser_load() could not load enrollment_code_variable:{0}'.format(err)) + self.logger.error('CAhandler._config_authuser_load() could not load enrollment_code_variable:%s', err) if 'enrollment_code' in config_dic['CAhandler']: if self.enrollment_code: @@ -112,7 +112,7 @@ def _config_session_load(self, config_dic: Dict[str, str]): try: self.cert_passphrase = os.environ[config_dic['CAhandler']['cert_passphrase_variable']] except Exception as err: - self.logger.error('CAhandler._config_authuser_load() could not load cert_passphrase_variable:{0}'.format(err)) + self.logger.error('CAhandler._config_authuser_load() could not load cert_passphrase_variable:%s', err) if 'cert_passphrase' in config_dic['CAhandler']: if self.cert_passphrase: @@ -169,29 +169,29 @@ def _config_load(self): variable_dic = self.__dict__ for ele in ['api_host', 'cert_profile_name', 'ee_profile_name', 'ca_name', 'username', 'enrollment_code']: if not variable_dic[ele]: - self.logger.error('CAhandler._config_load(): configuration incomplete: parameter "{0}" is missing in configuration file.'.format(ele)) + self.logger.error('CAhandler._config_load(): configuration incomplete: parameter "%s" is missing in configuration file.', ele) self.logger.debug('CAhandler._config_load() ended') def _api_post(self, url: str, data: Dict[str, str]) -> Dict[str, str]: """ generic wrapper for an API post call """ - self.logger.debug('_api_post({0})'.format(url)) + self.logger.debug('_api_post(%s)', url) try: api_response = self.session.post(url, json=data, proxies=self.proxy, verify=self.ca_bundle, timeout=self.request_timeout).json() except Exception as err_: - self.logger.error('CAhandler._api_post() returned error: {0}'.format(err_)) + self.logger.error('CAhandler._api_post() returned error: %s', err_) api_response = str(err_) return api_response def _api_put(self, url: str) -> Dict[str, str]: """ generic wrapper for an API put call """ - self.logger.debug('_api_put({0})'.format(url)) + self.logger.debug('_api_put(%s)', url) try: api_response = self.session.put(url, proxies=self.proxy, verify=self.ca_bundle, timeout=self.request_timeout).json() except Exception as err_: - self.logger.error('CAhandler._api_put() returned error: {0}'.format(err_)) + self.logger.error('CAhandler._api_put() returned error: %s', err_) api_response = str(err_) return api_response @@ -204,7 +204,7 @@ def _status_get(self) -> Dict[str, str]: try: api_response = self.session.get(self.api_host + '/ejbca/ejbca-rest-api/v1/certificate/status', proxies=self.proxy, verify=self.ca_bundle, timeout=self.request_timeout).json() except Exception as err_: - self.logger.error('CAhandler._ca_get() returned error: {0}'.format(str(err_))) + self.logger.error('CAhandler._ca_get() returned error: %s', str(err_)) api_response = {'status': 'nok', 'error': str(err_)} else: self.logger.error('CAhandler._status_get(): api_host parameter is misisng in configuration') @@ -255,10 +255,10 @@ def enroll(self, csr: str) -> Tuple[str, str, str, str]: cert_raw = sign_response['certificate'] cert_bundle = convert_byte_to_string(cert_der2pem(b64_decode(self.logger, cert_raw))) for ca_cert in sign_response['certificate_chain']: - cert_bundle = '{0}{1}'.format(cert_bundle, convert_byte_to_string(cert_der2pem(b64_decode(self.logger, ca_cert)))) + cert_bundle = f'{cert_bundle}{convert_byte_to_string(cert_der2pem(b64_decode(self.logger, ca_cert)))}' else: error = 'Malformed response' - self.logger.error('CAhandler.enroll(): Malformed Rest response: {0}'.format(sign_response)) + self.logger.error('CAhandler.enroll(): Malformed Rest response: %s', sign_response) else: if 'error' in status_dic: @@ -284,7 +284,7 @@ def poll(self, _cert_name: str, poll_identifier: str, _csr: str) -> Tuple[str, s def revoke(self, cert: str, rev_reason: str = 'UNSPECIFIED', rev_date: str = None) -> Tuple[int, str, str]: """ revoke certificate """ - self.logger.debug('CAhandler.revoke({0}: {1})'.format(rev_reason, rev_date)) + self.logger.debug('CAhandler.revoke(%s: %s)', rev_reason, rev_date) code = None message = None detail = None @@ -299,7 +299,7 @@ def revoke(self, cert: str, rev_reason: str = 'UNSPECIFIED', rev_date: str = Non if 'revoked' in certstatus_dic: if not certstatus_dic['revoked']: # this is the revocation path - path = "/ejbca/ejbca-rest-api/v1/certificate/{0}/{1}/revoke?reason={2}".format(encode_url(self.logger, issuer_dn), cert_serial, rev_reason.upper()) + path = f"/ejbca/ejbca-rest-api/v1/certificate/{encode_url(self.logger, issuer_dn)}/{cert_serial}/revoke?reason={rev_reason.upper()}" revoke_response = self._api_put(self.api_host + path) if 'revoked' in revoke_response and revoke_response['revoked']: @@ -329,5 +329,5 @@ def trigger(self, _payload: str) -> Tuple[str, str, str]: cert_bundle = None cert_raw = None - self.logger.debug('CAhandler.trigger() ended with error: {0}'.format(error)) + self.logger.debug('CAhandler.trigger() ended with error: %s', error) return (error, cert_bundle, cert_raw) diff --git a/examples/ca_handler/est_ca_handler.py b/examples/ca_handler/est_ca_handler.py index fcef8517..e2e151bf 100644 --- a/examples/ca_handler/est_ca_handler.py +++ b/examples/ca_handler/est_ca_handler.py @@ -11,7 +11,7 @@ from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.serialization.pkcs7 import load_pem_pkcs7_certificates, load_der_pkcs7_certificates -# pylint: disable=C0209, E0401 +# pylint: disable=e0401 from acme_srv.helper import load_config, b64_decode, b64_url_recode, convert_byte_to_string, convert_string_to_byte, parse_url, proxy_check @@ -54,7 +54,7 @@ def _cacerts_get(self) -> Tuple[str, str]: response = self.session.get(self.est_host + '/cacerts', auth=HTTPBasicAuth(self.est_user, self.est_password), verify=self.ca_bundle, proxies=self.proxy, timeout=self.request_timeout) pem = self._pkcs7_to_pem(b64_decode(self.logger, response.text)) except Exception as err_: - self.logger.error('CAhandler._cacerts_get() returned an error: {0}'.format(err_)) + self.logger.error('CAhandler._cacerts_get() returned an error: %s', err_) error = err_ pem = None else: @@ -62,7 +62,7 @@ def _cacerts_get(self) -> Tuple[str, str]: error = None pem = None - self.logger.debug('CAhandler._cacerts_get() ended with err: {0}'.format(error)) + self.logger.debug('CAhandler._cacerts_get() ended with err: %s', error) return (error, pem) def _cert_bundle_create(self, error: str, ca_pem: str, cert_raw: str) -> Tuple[str, str, str]: @@ -76,7 +76,7 @@ def _cert_bundle_create(self, error: str, ca_pem: str, cert_raw: str) -> Tuple[s cert_raw = cert_raw.replace('-----END CERTIFICATE-----\n', '') cert_raw = cert_raw.replace('\n', '') else: - self.logger.error('CAhandler.enroll() _simpleenroll error: {0}'.format(error)) + self.logger.error('CAhandler.enroll() _simpleenroll error: %s', error) self.logger.debug('CAhandler._cert_bundle_create()') return (error, cert_bundle, cert_raw) @@ -89,7 +89,7 @@ def _config_host_load(self, config_dic: Dict[str, str]): try: self.est_host = os.environ[config_dic['CAhandler']['est_host_variable']] + '/.well-known/est' except Exception as err: - self.logger.error('CAhandler._config_load() could not load est_host_variable:{0}'.format(err)) + self.logger.error('CAhandler._config_load() could not load est_host_variable:%s', err) if 'est_host' in config_dic['CAhandler']: if self.est_host: self.logger.info('CAhandler._config_load() overwrite est_host') @@ -106,7 +106,7 @@ def _cert_passphrase_load(self, config_dic: Dict[str, str]): try: self.cert_passphrase = os.environ[config_dic['CAhandler']['cert_passphrase_variable']] except Exception as err: - self.logger.error('CAhandler._config_authuser_load() could not load cert_passphrase_variable:{0}'.format(err)) + self.logger.error('CAhandler._config_authuser_load() could not load cert_passphrase_variable:%s', err) if 'cert_passphrase' in config_dic['CAhandler']: if self.cert_passphrase: self.logger.info('CAhandler._config_load() overwrite cert_passphrase') @@ -141,7 +141,7 @@ def _config_userauth_load(self, config_dic: Dict[str, str]): try: self.est_user = os.environ[config_dic['CAhandler']['est_user_variable']] except Exception as err: - self.logger.error('CAhandler._config_load() could not load est_user_variable:{0}'.format(err)) + self.logger.error('CAhandler._config_load() could not load est_user_variable:%s', err) if 'est_user' in config_dic['CAhandler']: if self.est_user: self.logger.info('CAhandler._config_load() overwrite est_user') @@ -157,7 +157,7 @@ def _config_password_load(self, config_dic: Dict[str, str]): try: self.est_password = os.environ[config_dic['CAhandler']['est_password_variable']] except Exception as err: - self.logger.error('CAhandler._config_load() could not load est_password:{0}'.format(err)) + self.logger.error('CAhandler._config_load() could not load est_password:%s', err) if 'est_password' in config_dic['CAhandler']: if self.est_password: self.logger.info('CAhandler._config_load() overwrite est_password') @@ -183,7 +183,7 @@ def _config_parameters_load(self, config_dic: Dict[str, str]): try: self.request_timeout = int(config_dic['CAhandler']['request_timeout']) except Exception: - self.logger.error('CAhandler._config_load() could not load request_timeout:{0}'.format(config_dic['CAhandler']['request_timeout'])) + self.logger.error('CAhandler._config_load() could not load request_timeout:%s', config_dic['CAhandler']['request_timeout']) self.request_timeout = 20 self.logger.debug('CAhandler._config_load() ended') @@ -201,7 +201,7 @@ def _config_proxy_load(self, config_dic: Dict[str, str]): proxy_server = proxy_check(self.logger, fqdn, proxy_list) self.proxy = {'http': proxy_server, 'https': proxy_server} except Exception as err_: - self.logger.warning('Challenge._config_load() proxy_server_list failed with error: {0}'.format(err_)) + self.logger.warning('Challenge._config_load() proxy_server_list failed with error: %s', err_) self.logger.debug('CAhandler._config_proxy_load() ended') @@ -276,11 +276,11 @@ def _simpleenroll(self, csr: str) -> Tuple[str, str]: # response.raise_for_status() pem = self._pkcs7_to_pem(b64_decode(self.logger, response.text)) except Exception as err_: - self.logger.error('CAhandler._simpleenroll() returned an error: {0}'.format(err_)) + self.logger.error('CAhandler._simpleenroll() returned an error: %s', err_) error = str(err_) pem = None - self.logger.debug('CAhandler._simpleenroll() ended with err: {0}'.format(error)) + self.logger.debug('CAhandler._simpleenroll() ended with err: %s', error) return (error, pem) def enroll(self, csr: str) -> Tuple[str, str, str, bool]: @@ -304,7 +304,7 @@ def enroll(self, csr: str) -> Tuple[str, str, str, bool]: error = 'no CA certificates found' self.logger.error('CAhandler.enroll(): no CA certificates found') else: - self.logger.error('CAhandler.enroll() _cacerts_get error: {0}'.format(error)) + self.logger.error('CAhandler.enroll() _cacerts_get error: %s', error) self.logger.debug('Certificate.enroll() ended') return (error, cert_bundle, cert_raw, None) @@ -340,5 +340,5 @@ def trigger(self, _payload: str) -> Tuple[str, str, str]: cert_bundle = None cert_raw = None - self.logger.debug('CAhandler.trigger() ended with error: {0}'.format(error)) + self.logger.debug('CAhandler.trigger() ended with error: %s', error) return (error, cert_bundle, cert_raw) diff --git a/examples/ca_handler/mscertsrv_ca_handler.py b/examples/ca_handler/mscertsrv_ca_handler.py index 743e6455..9378098c 100644 --- a/examples/ca_handler/mscertsrv_ca_handler.py +++ b/examples/ca_handler/mscertsrv_ca_handler.py @@ -7,9 +7,8 @@ from typing import List, Tuple, Dict from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.serialization.pkcs7 import load_pem_pkcs7_certificates, load_der_pkcs7_certificates -# pylint: disable=C0209, E0401, E0611 +# pylint: disable=e0401, e0611 from examples.ca_handler.certsrv import Certsrv -# pylint: disable=E0401 from acme_srv.helper import load_config, b64_url_recode, convert_byte_to_string, proxy_check, convert_string_to_byte @@ -39,7 +38,7 @@ def _check_credentials(self, ca_server: str) -> bool: """ check creadentials """ self.logger.debug('CAhandler.__check_credentials()') auth_check = ca_server.check_credentials() - self.logger.debug('CAhandler.__check_credentials() ended with {0}'.format(auth_check)) + self.logger.debug('CAhandler.__check_credentials() ended with %s', auth_check) return auth_check def _cert_bundle_create(self, ca_pem: str = None, cert_raw: str = None) -> Tuple[str, str, str]: @@ -68,7 +67,7 @@ def _config_user_load(self, config_dic: Dict[str, str]): try: self.user = os.environ[config_dic['CAhandler']['user_variable']] except Exception as err: - self.logger.error('CAhandler._config_load() could not load user_variable:{0}'.format(err)) + self.logger.error('CAhandler._config_load() could not load user_variable:%s', err) if 'user' in config_dic['CAhandler']: if self.user: self.logger.info('CAhandler._config_load() overwrite user') @@ -84,7 +83,7 @@ def _config_password_load(self, config_dic: Dict[str, str]): try: self.password = os.environ[config_dic['CAhandler']['password_variable']] except Exception as err: - self.logger.error('CAhandler._config_load() could not load password_variable:{0}'.format(err)) + self.logger.error('CAhandler._config_load() could not load password_variable:%s', err) if 'password' in config_dic['CAhandler']: if self.password: self.logger.info('CAhandler._config_load() overwrite password') @@ -100,7 +99,7 @@ def _config_hostname_load(self, config_dic: Dict[str, str]): try: self.host = os.environ[config_dic['CAhandler']['host_variable']] except Exception as err: - self.logger.error('CAhandler._config_load() could not load host_variable:{0}'.format(err)) + self.logger.error('CAhandler._config_load() could not load host_variable:%s', err) if 'host' in config_dic['CAhandler']: if self.host: self.logger.info('CAhandler._config_load() overwrite host') @@ -132,7 +131,7 @@ def _config_proxy_load(self, config_dic: Dict[str, str]): proxy_server = proxy_check(self.logger, self.host, proxy_list) self.proxy = {'http': proxy_server, 'https': proxy_server} except Exception as err_: - self.logger.warning('CAhandler._config_load() proxy_server_list failed with error: {0}'.format(err_)) + self.logger.warning('CAhandler._config_load() proxy_server_list failed with error: %s', err_) self.logger.debug('CAhandler._config_proxy_load() ended') @@ -180,7 +179,7 @@ def _pkcs7_to_pem(self, pkcs7_content: str, outform: str = 'string') -> List[str def enroll(self, csr: str) -> Tuple[str, str, str, bool]: """ enroll certificate from via MS certsrv """ - self.logger.debug('CAhandler.enroll({0})'.format(self.template)) + self.logger.debug('CAhandler.enroll(%s)', self.template) cert_bundle = None error = None cert_raw = None @@ -203,7 +202,7 @@ def enroll(self, csr: str) -> Tuple[str, str, str, bool]: # ca_pem = ca_pem.replace('\r\n', '\n') except Exception as err_: ca_pem = None - self.logger.error('ca_server.get_chain() failed with error: {0}'.format(err_)) + self.logger.error('ca_server.get_chain() failed with error: %s', err_) try: cert_raw = convert_byte_to_string(ca_server.get_cert(csr, self.template)) @@ -211,7 +210,7 @@ def enroll(self, csr: str) -> Tuple[str, str, str, bool]: cert_raw = cert_raw.replace('\r\n', '\n') except Exception as err_: cert_raw = None - self.logger.error('ca_server.get_cert() failed with error: {0}'.format(err_)) + self.logger.error('ca_server.get_cert() failed with error: %s', err_) # create bundle (error, cert_bundle, cert_raw) = self._cert_bundle_create(ca_pem, cert_raw) @@ -257,5 +256,5 @@ def trigger(self, _payload: str) -> Tuple[int, str, str]: cert_bundle = None cert_raw = None - self.logger.debug('CAhandler.trigger() ended with error: {0}'.format(error)) + self.logger.debug('CAhandler.trigger() ended with error: %s', error) return (error, cert_bundle, cert_raw) diff --git a/examples/ca_handler/mswcce_ca_handler.py b/examples/ca_handler/mswcce_ca_handler.py index 3b8bbc22..4a5da473 100644 --- a/examples/ca_handler/mswcce_ca_handler.py +++ b/examples/ca_handler/mswcce_ca_handler.py @@ -3,9 +3,9 @@ from __future__ import print_function import os import json -from typing import List, Tuple, Dict +from typing import Tuple, Dict -# pylint: disable=E0401, E0611, C0209 +# pylint: disable=e0401, e0611 from examples.ca_handler.ms_wcce.target import Target from examples.ca_handler.ms_wcce.request import Request @@ -52,7 +52,7 @@ def _config_host_load(self, config_dic: Dict[str, str]): try: self.host = os.environ[config_dic['CAhandler']['host_variable']] except Exception as err: - self.logger.error('CAhandler._config_load() could not load host_variable:{0}'.format(err)) + self.logger.error('CAhandler._config_load() could not load host_variable:%s', err) if 'host' in config_dic['CAhandler']: if self.host: self.logger.info('CAhandler._config_load() overwrite host') @@ -68,7 +68,7 @@ def _config_credentials_load(self, config_dic: Dict[str, str]): try: self.user = os.environ[config_dic['CAhandler']['user_variable']] except Exception as err: - self.logger.error('CAhandler._config_load() could not load user_variable:{0}'.format(err)) + self.logger.error('CAhandler._config_load() could not load user_variable:%s', err) if 'user' in config_dic['CAhandler']: if self.user: self.logger.info('CAhandler._config_load() overwrite user') @@ -78,7 +78,7 @@ def _config_credentials_load(self, config_dic: Dict[str, str]): try: self.password = os.environ[config_dic['CAhandler']['password_variable']] except Exception as err: - self.logger.error('CAhandler._config_load() could not load password_variable:{0}'.format(err)) + self.logger.error('CAhandler._config_load() could not load password_variable:%s', err) if 'password' in config_dic['CAhandler']: if self.password: self.logger.info('CAhandler._config_load() overwrite password') @@ -104,7 +104,7 @@ def _config_parameters_load(self, config_dic: Dict[str, str]): try: self.use_kerberos = config_dic.getboolean('CAhandler', 'use_kerberos', fallback=False) except Exception as err_: - self.logger.warning('CAhandler._config_load() use_kerberos failed with error: {0}'.format(err_)) + self.logger.warning('CAhandler._config_load() use_kerberos failed with error: %s', err_) self.logger.debug("CAhandler._config_parameters_load()") @@ -118,7 +118,7 @@ def _config_proxy_load(self, config_dic: Dict[str, str]): proxy_server = proxy_check(self.logger, self.host, proxy_list) self.proxy = {'http': proxy_server, 'https': proxy_server} except Exception as err_: - self.logger.warning('CAhandler._config_load() proxy_server_list failed with error: {0}'.format(err_)) + self.logger.warning('CAhandler._config_load() proxy_server_list failed with error: %s', err_) self.logger.debug("CAhandler._config_proxy_load() ended") @@ -144,7 +144,7 @@ def _file_load(self, bundle: str) -> str: with open(bundle, 'r', encoding='utf-8') as fso: file_ = fso.read() except Exception as err_: - self.logger.error('CAhandler._file_load(): could not load {0}. Error: {1}'.format(bundle, err_)) + self.logger.error('CAhandler._file_load(): could not load %s. Error: %s', bundle, err_) return file_ def request_create(self) -> Request: @@ -170,7 +170,7 @@ def request_create(self) -> Request: def enroll(self, csr: str) -> Tuple[str, str, str, str]: """enroll certificate via MS-WCCE""" - self.logger.debug("CAhandler.enroll({0})".format(self.template)) + self.logger.debug("CAhandler.enroll(%s)", self.template) cert_bundle = None error = None cert_raw = None @@ -198,7 +198,7 @@ def enroll(self, csr: str) -> Tuple[str, str, str, str]: cert_raw = cert_raw.replace("\r\n", "\n") except Exception as err_: cert_raw = None - self.logger.error("ca_server.get_cert() failed with error: {0}".format(err_)) + self.logger.error("ca_server.get_cert() failed with error: %s", err_) if cert_raw: if ca_pem: @@ -247,5 +247,5 @@ def trigger(self, _payload: str) -> Tuple[str, str, str]: cert_bundle = None cert_raw = None - self.logger.debug("CAhandler.trigger() ended with error: {0}".format(error)) + self.logger.debug("CAhandler.trigger() ended with error: %s", error) return (error, cert_bundle, cert_raw) diff --git a/examples/ca_handler/nclm_ca_handler.py b/examples/ca_handler/nclm_ca_handler.py index fc2de2e9..666b3b26 100644 --- a/examples/ca_handler/nclm_ca_handler.py +++ b/examples/ca_handler/nclm_ca_handler.py @@ -6,7 +6,7 @@ import json from typing import List, Tuple, Dict import requests -# pylint: disable=C0209, E0401, R0913 +# pylint: disable=e0401, r0913 from acme_srv.helper import load_config, build_pem_file, csr_cn_get, b64_encode, b64_url_recode, convert_string_to_byte, csr_san_get, cert_serial_get, date_to_uts_utc, uts_now, parse_url, proxy_check, error_dic_get @@ -49,10 +49,10 @@ def _api_post(self, url: str, data: Dict[str, str]) -> Dict[str, str]: try: api_response = requests.post(url=url, json=data, headers=self.headers, verify=self.ca_bundle, proxies=self.proxy, timeout=self.request_timeout).json() except Exception as err_: - self.logger.error('CAhandler._api_post() returned error: {0}'.format(err_)) + self.logger.error('CAhandler._api_post() returned error: %s', err_) api_response = str(err_) - self.logger.debug('CAhandler._api_post() ended with: {0}'.format(api_response)) + self.logger.debug('CAhandler._api_post() ended with: %s', api_response) return api_response def _ca_id_lookup(self) -> int: @@ -73,8 +73,8 @@ def _ca_id_lookup(self) -> int: if not ca_id: # log error - self.logger.error('_ca_id_lookup(): no ca id found for {0}'.format(self.ca_name)) - self.logger.debug('CAhandler._ca_id_lookup() ended with: {0}'.format(ca_id)) + self.logger.error('_ca_id_lookup(): no ca id found for %s', self.ca_name) + self.logger.debug('CAhandler._ca_id_lookup() ended with: %s', ca_id) return ca_id def _ca_id_get(self, ca_list: Dict[str, str]) -> int: @@ -92,7 +92,7 @@ def _ca_id_get(self, ca_list: Dict[str, str]) -> int: else: self.logger.error('ca_id.lookup() policyLinkId field is missing ...') - self.logger.debug('CAhandler._ca_id_get() with {0}'.format(ca_id)) + self.logger.debug('CAhandler._ca_id_get() with %s', ca_id) return ca_id def _ca_policylink_id_lookup(self) -> int: @@ -100,7 +100,7 @@ def _ca_policylink_id_lookup(self) -> int: self.logger.debug('CAhandler._ca_policylink_id_lookup()') # query CAs - ca_list = requests.get(self.api_host + '/policy/ca?entityRef=CONTAINER&entityId={0}&allowedOnly=true&withTemplateById=0&enrollWithImportedCSR=true&csrHasPrivateKey=false&csrTemplateVersion=0'.format(self.tsg_info_dic['id']), headers=self.headers, verify=self.ca_bundle, proxies=self.proxy, timeout=self.request_timeout).json() + ca_list = requests.get(self.api_host + f'/policy/ca?entityRef=CONTAINER&entityId={self.tsg_info_dic['id']}&allowedOnly=true&withTemplateById=0&enrollWithImportedCSR=true&csrHasPrivateKey=false&csrTemplateVersion=0', headers=self.headers, verify=self.ca_bundle, proxies=self.proxy, timeout=self.request_timeout).json() ca_id = None if 'ca' in ca_list: ca_id = self._ca_id_get(ca_list) @@ -110,8 +110,8 @@ def _ca_policylink_id_lookup(self) -> int: if not ca_id: # log error - self.logger.error('CAhandler_ca_policylink_id_lookup(): no policylink id found for {0}'.format(self.ca_name)) - self.logger.debug('CAhandler._ca_policylink_id_lookup() ended with: {0}'.format(ca_id)) + self.logger.error('CAhandler_ca_policylink_id_lookup(): no policylink id found for %s', self.ca_name) + self.logger.debug('CAhandler._ca_policylink_id_lookup() ended with: %s', ca_id) return ca_id def _cert_bundle_get(self, cert_dic: Dict[str, str], count: int, cert_id: int, cert_raw: str, cert_bundle: str, issuer_loop: bool, error: str) -> Tuple[str, str, str, bool, int]: @@ -121,27 +121,27 @@ def _cert_bundle_get(self, cert_dic: Dict[str, str], count: int, cert_id: int, c if 'der' in cert_dic['certificate']: cert_raw = cert_dic['certificate']['der'] else: - error = 'no der certificate returned for id {0}'.format(cert_id) - self.logger.error('CAhandler._cert_bundle_build(): no der certificate returned for id: {0}'.format(cert_id)) + error = f'no der certificate returned for id {cert_id}' + self.logger.error('CAhandler._cert_bundle_build(): no der certificate returned for id: %s', cert_id) if 'pem' in cert_dic['certificate']: - cert_bundle = '{0}{1}'.format(cert_bundle, cert_dic['certificate']['pem']) + cert_bundle = f'{cert_bundle}{cert_dic['certificate']['pem']}' else: - error = 'no pem certificate returned for id {0}'.format(cert_id) - self.logger.error('CAhandler._cert_bundle_build(): no pem certificate returned for id: {0}'.format(cert_id)) + error = f'no pem certificate returned for id {cert_id}' + self.logger.error('CAhandler._cert_bundle_build(): no pem certificate returned for id: %s', cert_id) if 'issuerInfo' in cert_dic['certificate']: if 'id' in cert_dic['certificate']['issuerInfo'] and cert_dic['certificate']['issuerInfo']['id'] != cert_id: - self.logger.debug('CAhandler._cert_bundle_build() fetch certificate for certid: {0}'.format(cert_dic['certificate']['issuerInfo']['id'])) + self.logger.debug('CAhandler._cert_bundle_build() fetch certificate for certid: %s', cert_dic['certificate']['issuerInfo']['id']) cert_id = cert_dic['certificate']['issuerInfo']['id'] issuer_loop = True - self.logger.debug('CAhandler._cert_bundle_get() ended with: {0}'.format(cert_id)) + self.logger.debug('CAhandler._cert_bundle_get() ended with: %s', cert_id) return (error, cert_raw, cert_bundle, issuer_loop, cert_id) def _cert_bundle_build(self, cert_id: int) -> Tuple[str, str, str]: """ download cert and create bundle """ - self.logger.debug('CAhandler._cert_bundle_build({0})'.format(cert_id)) + self.logger.debug('CAhandler._cert_bundle_build(%s)', cert_id) cert_bundle = '' error = None cert_raw = None @@ -152,14 +152,14 @@ def _cert_bundle_build(self, cert_id: int) -> Tuple[str, str, str]: # set issuer loop to False to avoid ending in an endless loop issuer_loop = False count += 1 - self.logger.debug('CAhandler._cert_bundle_build() fetch certificate for certid: {0}'.format(cert_id)) + self.logger.debug('CAhandler._cert_bundle_build() fetch certificate for certid: %s', cert_id) cert_dic = requests.get(self.api_host + '/certificates/' + str(cert_id), headers=self.headers, verify=self.ca_bundle, proxies=self.proxy, timeout=self.request_timeout).json() if 'certificate' in cert_dic: (error, cert_raw, cert_bundle, issuer_loop, cert_id) = self._cert_bundle_get(cert_dic, count, cert_id, cert_raw, cert_bundle, issuer_loop, error) else: - self.logger.error('CAhandler._cert_bundle_build(): invalid reponse returned for id: {0}'.format(cert_id)) - error = 'invalid reponse returned for id: {0}'.format(cert_id) + self.logger.error('CAhandler._cert_bundle_build(): invalid reponse returned for id: %s', cert_id) + error = f'invalid reponse returned for id: {cert_id}' # we need this for backwards compability if cert_bundle == '': @@ -170,14 +170,14 @@ def _cert_bundle_build(self, cert_id: int) -> Tuple[str, str, str]: def _cert_list_fetch(self, url: str) -> List[str]: """ fetch certificate list and consider pagination """ - self.logger.debug('CAhandler._cert_list_fetch({0})'.format(url)) + self.logger.debug('CAhandler._cert_list_fetch(%s)', url) cert_list = [] while url: try: _tmp_cert_list = requests.get(url, headers=self.headers, verify=self.ca_bundle, proxies=self.proxy, timeout=self.request_timeout).json() except Exception as err_: - self.logger.error('CAhandler._cert_list_fetch() returned error: {0}'.format(str(err_))) + self.logger.error('CAhandler._cert_list_fetch() returned error: %s', str(err_)) _tmp_cert_list = [] if 'certificates' in _tmp_cert_list: @@ -189,12 +189,12 @@ def _cert_list_fetch(self, url: str) -> List[str]: else: url = None - self.logger.debug('CAhandler._cert_list_fetch() ended with {0} entries'.format(len(cert_list))) + self.logger.debug('CAhandler._cert_list_fetch() ended with %s entries', len(cert_list)) return cert_list def _cert_list_lookup(self, csr_cn: str) -> Dict[str, str]: """ get certificates """ - self.logger.debug('CAhandler._cert_list_lookup({0})'.format(csr_cn)) + self.logger.debug('CAhandler._cert_list_lookup(%s)', csr_cn) try: if csr_cn: @@ -203,7 +203,7 @@ def _cert_list_lookup(self, csr_cn: str) -> Dict[str, str]: url = self.api_host + '/certificates?stateCurrent=false&stateHistory=false&stateWaiting=false&stateManual=false&stateUnattached=false&expiresAfter=%22%22&expiresBefore=%22%22&sortAttribute=createdAt&sortOrder=desc&containerId=' + str(self.tsg_info_dic['id']) cert_list = self._cert_list_fetch(url) except Exception as err_: - self.logger.error('CAhandler._cert_id_lookup() returned error: {0}'.format(str(err_))) + self.logger.error('CAhandler._cert_id_lookup() returned error: %s', str(err_)) cert_list = [] self.logger.debug('CAhandler._cert_list_lookup() ended') @@ -226,7 +226,7 @@ def _cert_id_get(self, cert_list: Dict[str, str], san_list: List[str]) -> int: def _cert_id_lookup(self, csr_cn: str, san_list: List[str] = None) -> int: """ lookup cert id based on CN """ - self.logger.debug('CAhandler._cert_id_lookup({0}:{1})'.format(csr_cn, san_list)) + self.logger.debug('CAhandler._cert_id_lookup(%s:%s)', csr_cn, san_list) # get certificate list having the csr cn cert_list = self._cert_list_lookup(csr_cn) @@ -236,11 +236,11 @@ def _cert_id_lookup(self, csr_cn: str, san_list: List[str] = None) -> int: try: cert_id = self._cert_id_get(cert_list, san_list) except Exception as err_: - self.logger.error('_cert_id_lookup(): response incomplete: {0}'.format(err_)) + self.logger.error('_cert_id_lookup(): response incomplete: %s', err_) else: - self.logger.error('_cert_id_lookup(): no certificates found for {0}'.format(csr_cn)) + self.logger.error('_cert_id_lookup(): no certificates found for %s', csr_cn) - self.logger.debug('CAhandler._cert_id_lookup() ended with: {0}'.format(cert_id)) + self.logger.debug('CAhandler._cert_id_lookup() ended with: %s', cert_id) return cert_id def _config_api_access_check(self): @@ -298,7 +298,7 @@ def _config_api_user_load(self, config_dic: Dict[str, str]): try: self.credential_dic['api_user'] = os.environ[config_dic['CAhandler']['api_user_variable']] except Exception as err: - self.logger.error('CAhandler._config_load() could not load user_variable:{0}'.format(err)) + self.logger.error('CAhandler._config_load() could not load user_variable:%s', err) if 'api_user' in config_dic['CAhandler']: if self.credential_dic['api_user']: self.logger.info('CAhandler._config_load() overwrite api_user') @@ -314,7 +314,7 @@ def _config_api_password_load(self, config_dic: Dict[str, str]): try: self.credential_dic['api_password'] = os.environ[config_dic['CAhandler']['api_password_variable']] except Exception as err: - self.logger.error('CAhandler._config_load() could not load password_variable:{0}'.format(err)) + self.logger.error('CAhandler._config_load() could not load password_variable:%s', err) if 'api_password' in config_dic['CAhandler']: if self.credential_dic['api_password']: self.logger.info('CAhandler._config_load() overwrite api_password') @@ -353,7 +353,7 @@ def _config_proxy_load(self, config_dic: Dict[str, str]): proxy_server = proxy_check(self.logger, fqdn, proxy_list) self.proxy = {'http': proxy_server, 'https': proxy_server} except Exception as err_: - self.logger.warning('Challenge._config_load() proxy_server_list failed with error: {0}'.format(err_)) + self.logger.warning('Challenge._config_load() proxy_server_list failed with error: %s', err_) self.logger.debug('CAhandler._config_proxy_load() ended') @@ -365,7 +365,7 @@ def _config_timer_load(self, config_dic: Dict[str, str]): try: self.request_delta_treshold = int(config_dic['CAhandler']['request_delta_treshold']) except Exception: - self.logger.error('CAhandler._config_load() could not load request_delta_treshold:{0}'.format(config_dic['CAhandler']['request_delta_treshold'])) + self.logger.error('CAhandler._config_load() could not load request_delta_treshold:%s', config_dic['CAhandler']['request_delta_treshold']) # check if we get a ca bundle for verification if 'ca_bundle' in config_dic['CAhandler']: @@ -411,9 +411,9 @@ def _lastrequests_get(self) -> Dict[str, str]: else: self.logger.error('_lastrequests_get(): response incomplete:') except Exception as err_: - self.logger.error('CAhandler._lastrequests_get() returned error: {0}'.format(str(err_))) + self.logger.error('CAhandler._lastrequests_get() returned error: %s', str(err_)) - self.logger.debug('CAhandler._lastrequests_get() endet with {0}'.format(len(req_all))) + self.logger.debug('CAhandler._lastrequests_get() endet with %s', len(req_all)) return req_all def _reqcn_lookup(self, req: Dict[str, str]) -> str: @@ -429,7 +429,7 @@ def _reqcn_lookup(self, req: Dict[str, str]) -> str: req_cn = field.lower().replace('cn=', '') break - self.logger.debug('CAhandler._reqcn_lookup() ended with: {0}'.format(req_cn)) + self.logger.debug('CAhandler._reqcn_lookup() ended with: %s', req_cn) return req_cn def _reqid_from_last_requests(self, last_request_list: Dict[str, str], csr: str) -> int: @@ -442,7 +442,7 @@ def _reqid_from_last_requests(self, last_request_list: Dict[str, str], csr: str) req_id = _req['requestId'] break - self.logger.debug('CAhandler._reqid_from_last_requests() ended with: {0}'.format(req_id)) + self.logger.debug('CAhandler._reqid_from_last_requests() ended with: %s', req_id) return req_id def _reqid_lookup(self, csr: str, csr_cn: str, uts_n: int, unused_request_list: Dict[str, str], last_request_list: Dict[str, str]) -> int: @@ -468,7 +468,7 @@ def _reqid_lookup(self, csr: str, csr_cn: str, uts_n: int, unused_request_list: else: req_id = self._reqid_from_last_requests(last_request_list, csr) - self.logger.debug('CAhandler._reqid_lookup() ended with: {0}'.format(req_id)) + self.logger.debug('CAhandler._reqid_lookup() ended with: %s', req_id) return req_id def _csr_id_lookup(self, csr_cn: str, _csr_san_list: Dict[str, str], csr: str = None) -> int: @@ -490,10 +490,10 @@ def _csr_id_lookup(self, csr_cn: str, _csr_san_list: Dict[str, str], csr: str = try: req_id = self._reqid_lookup(csr, csr_cn, uts_n, unused_request_list, last_request_list) except Exception as err_: - self.logger.error('_csr_id_lookup(): response incomplete: {0}'.format(err_)) + self.logger.error('_csr_id_lookup(): response incomplete: %s', err_) req_id = None - self.logger.debug('CAhandler._csr_id_lookup() ended with: {0}'.format(req_id)) + self.logger.debug('CAhandler._csr_id_lookup() ended with: %s', req_id) return req_id def _login(self): @@ -501,26 +501,26 @@ def _login(self): self.logger.debug('CAhandler._login()') # check first if API is reachable api_response = requests.get(self.api_host, proxies=self.proxy, timeout=self.request_timeout) - self.logger.debug('api response code:{0}'.format(api_response.status_code)) + self.logger.debug('api response code:%s', api_response.status_code) if api_response.ok: # all fine try to login - self.logger.debug('log in to {0} as user "{1}"'.format(self.api_host, self.credential_dic['api_user'])) + self.logger.debug('log in to %s as user "%s"', self.api_host, self.credential_dic['api_user']) data = {'username': self.credential_dic['api_user'], 'password': self.credential_dic['api_password']} api_response = requests.post(url=self.api_host + '/token?grant_type=client_credentials', json=data, proxies=self.proxy, timeout=self.request_timeout) if api_response.ok: json_dic = api_response.json() if 'access_token' in json_dic: - self.headers = {"Authorization": "Bearer {0}".format(json_dic['access_token'])} + self.headers = {"Authorization": f"Bearer {json_dic['access_token']}"} _username = json_dic.get('username', None) _realms = json_dic.get('realms', None) - self.logger.debug('login response:\n user: {0}\n token: {1}\n realms: {2}\n'.format(_username, json_dic['access_token'], _realms)) + self.logger.debug('login response:\n user: %s\n token: %s\n realms: %s\n', _username, json_dic['access_token'], _realms) else: self.logger.error('CAhandler._login(): No token returned. Aborting...') else: - self.logger.error('CAhandler._login() error during post: {0}'.format(api_response.status_code)) + self.logger.error('CAhandler._login() error during post: %s', api_response.status_code) else: # If response code is not ok (200), print the resulting http error code with description - self.logger.error('CAhandler._login() error during get: {0}'.format(api_response.status_code)) + self.logger.error('CAhandler._login() error during get: %s', api_response.status_code) def _request_import(self, csr: str) -> Dict[str, str]: """ import certificate request to NCLM """ @@ -529,7 +529,7 @@ def _request_import(self, csr: str) -> Dict[str, str]: try: result = self._api_post(self.api_host + self.endpoint_dic['tsg'] + str(self.tsg_info_dic['id']) + '/importrequest', data_dic) except Exception as err_: - self.logger.error('CAhandler._request_import() returned error: {0}'.format(str(err_))) + self.logger.error('CAhandler._request_import() returned error: %s', str(err_)) result = None return result @@ -539,13 +539,13 @@ def _unusedrequests_get(self) -> Dict[str, str]: try: result = requests.get(self.api_host + self.endpoint_dic['tsg'] + str(self.tsg_info_dic['id']) + '/unusedrequests', headers=self.headers, verify=self.ca_bundle, proxies=self.proxy, timeout=self.request_timeout).json() except Exception as err_: - self.logger.error('CAhandler._unusedrequests_get() returned error: {0}'.format(str(err_))) + self.logger.error('CAhandler._unusedrequests_get() returned error: %s', str(err_)) result = None return result def _san_compare(self, csr_san: str, cert_san: str) -> bool: """ compare sans from csr with san in cert """ - self.logger.debug('CAhandler._san_compare({0}, {1})'.format(csr_san, cert_san)) + self.logger.debug('CAhandler._san_compare(%s, %s)', csr_san, cert_san) # convert csr_sans to lower case csr_san_lower = [] for ele in csr_san: @@ -556,7 +556,7 @@ def _san_compare(self, csr_san: str, cert_san: str) -> bool: cert_san_lower = [] for stype in cert_san: for san in cert_san[stype]: - cert_san_lower.append('{0}:{1}'.format(stype.lower(), san.lower())) + cert_san_lower.append(f'{stype.lower()}:{san.lower()}') result = False @@ -564,23 +564,23 @@ def _san_compare(self, csr_san: str, cert_san: str) -> bool: if sorted(csr_san_lower) == sorted(cert_san_lower): result = True - self.logger.debug('CAhandler._san_compare() ended with: {0}'.format(result)) + self.logger.debug('CAhandler._san_compare() ended with: %s', result) return result def _template_list_get(self) -> Dict[str, str]: """ get list of templates """ - self.logger.debug('CAhandler._template_id_lookup({0})'.format(self.tsg_info_dic['id'])) + self.logger.debug('CAhandler._template_id_lookup(%s)', self.tsg_info_dic['id']) try: template_list = requests.get(self.api_host + '/policy/ca/7/templates?entityRef=CONTAINER&entityId=' + str(self.tsg_info_dic['id']) + '&allowedOnly=true&enroll=true', headers=self.headers, verify=self.ca_bundle, proxies=self.proxy, timeout=self.request_timeout).json() except Exception as err_: - self.logger.error('CAhandler._template_id_lookup() returned error: {0}'.format(err_)) + self.logger.error('CAhandler._template_id_lookup() returned error: %s', err_) template_list = [] return template_list def _templates_enumerate(self, template_list: Dict[str, str]): """ get template id based on name """ - self.logger.debug('CAhandler._template_id_lookup() for template: {0}'.format(self.template_info_dic['name'])) + self.logger.debug('CAhandler._template_id_lookup() for template: %s', self.template_info_dic['name']) for template in template_list['template']['items']: if 'allowed' in template and template['allowed'] and 'linkType' in template and template['linkType'].lower() == 'template': @@ -591,7 +591,7 @@ def _templates_enumerate(self, template_list: Dict[str, str]): def _template_id_lookup(self): """ get template id based on name """ - self.logger.debug('CAhandler._template_id_lookup() for template: {0}'.format(self.template_info_dic['name'])) + self.logger.debug('CAhandler._template_id_lookup() for template: %s', self.template_info_dic['name']) # get list of templates template_list = self._template_list_get() @@ -600,17 +600,17 @@ def _template_id_lookup(self): if 'template' in template_list and 'items' in template_list['template']: self._templates_enumerate(template_list) else: - self.logger.error('CAhandler._template_id_lookup() no templates found for filter: {0}...'.format(self.template_info_dic['name'])) + self.logger.error('CAhandler._template_id_lookup() no templates found for filter: %s...', self.template_info_dic['name']) - self.logger.debug('CAhandler._template_id_lookup() ended with: {0}'.format(str(self.template_info_dic['id']))) + self.logger.debug('CAhandler._template_id_lookup() ended with: %s', str(self.template_info_dic['id'])) def _tsg_id_lookup(self): """ get target system id based on name """ - self.logger.debug('CAhandler._tsg_id_lookup() for tsg: {0}'.format(self.tsg_info_dic['name'])) + self.logger.debug('CAhandler._tsg_id_lookup() for tsg: %s', self.tsg_info_dic['name']) try: tsg_list = requests.get(self.api_host + '/targetsystemgroups?freeText=' + str(self.tsg_info_dic['name']) + '&offset=0&limit=50&fetchPath=true', headers=self.headers, verify=self.ca_bundle, proxies=self.proxy, timeout=self.request_timeout).json() except Exception as err_: - self.logger.error('CAhandler._tsg_id_lookup() returned error: {0}'.format(err_)) + self.logger.error('CAhandler._tsg_id_lookup() returned error: %s', err_) tsg_list = [] if 'targetSystemGroups' in tsg_list: for tsg in tsg_list['targetSystemGroups']: @@ -619,10 +619,10 @@ def _tsg_id_lookup(self): self.tsg_info_dic['id'] = tsg['id'] break else: - self.logger.error('CAhandler._tsg_id_lookup() incomplete response: {0}'.format(tsg)) + self.logger.error('CAhandler._tsg_id_lookup() incomplete response: %s', tsg) else: - self.logger.error('CAhandler._tsg_id_lookup() no target-system-groups found for filter: {0}...'.format(self.tsg_info_dic['name'])) - self.logger.debug('CAhandler._tsg_id_lookup() ended with: {0}'.format(str(self.tsg_info_dic['id']))) + self.logger.error('CAhandler._tsg_id_lookup() no target-system-groups found for filter: %s...', self.tsg_info_dic['name']) + self.logger.debug('CAhandler._tsg_id_lookup() ended with: %s', str(self.tsg_info_dic['id'])) def _cert_enroll(self, csr: str, csr_cn: str, csr_san_list: List[str], policylink_id: int) -> Tuple[str, str, str]: """ enroll operation """ @@ -648,8 +648,8 @@ def _cert_enroll(self, csr: str, csr_cn: str, csr_san_list: List[str], policylin if cert_id: (error, cert_bundle, cert_raw) = self._cert_bundle_build(cert_id) else: - error = 'certifcate id lookup failed for: {0}, {1}'.format(csr_cn, csr_san_list) - self.logger.error('CAhandler.eroll(): certifcate id lookup failed for: {0}, {1}'.format(csr_cn, csr_san_list)) + error = f'certifcate id lookup failed for: {csr_cn}, {csr_san_list}' + self.logger.error('CAhandler.eroll(): certifcate id lookup failed for: %s, %s', csr_cn, csr_san_list) return (error, cert_bundle, cert_raw) @@ -680,10 +680,10 @@ def enroll(self, csr: str) -> Tuple[str, str, str, str]: # enroll operation (error, cert_bundle, cert_raw) = self._cert_enroll(csr, csr_cn, csr_san_list, policylink_id) else: - error = 'enrollment aborted. policylink_id: {0}, tsg_id: {1}'.format(policylink_id, self.tsg_info_dic['id']) - self.logger.error('CAhandler.eroll(): enrollment aborted. policylink_id: {0}, tsg_id: {1}'.format(policylink_id, self.tsg_info_dic['id'])) + error = f'enrollment aborted. policylink_id: {policylink_id}, tsg_id: {self.tsg_info_dic['id']}' + self.logger.error('CAhandler.eroll(): enrollment aborted. policylink_id: %s, tsg_id: %s', policylink_id, self.tsg_info_dic['id']) else: - error = 'CAhandler.eroll(): ID lookup for targetSystemGroup "{0}" failed.'.format(self.tsg_info_dic['name']) + error = f'CAhandler.eroll(): ID lookup for targetSystemGroup "{self.tsg_info_dic['name']}" failed.' else: self.logger.error(self.error) @@ -705,15 +705,16 @@ def poll(self, _cert_name: str, poll_identifier: str, _csr: str) -> Tuple[str, s def revoke(self, cert: str, rev_reason: str, rev_date: str) -> Tuple[int, str, str]: """ revoke certificate """ self.logger.debug('CAhandler.revoke()') + # get serial from pem file and convert to formated hex - serial = '0{:x}'.format(cert_serial_get(self.logger, cert)) + serial = f'0{cert_serial_get(self.logger, cert, hexformat=True)}' hex_serial = ':'.join(serial[i:i + 2] for i in range(0, len(serial), 2)) # search for certificate try: cert_list = requests.get(self.api_host + '/certificates?freeText==' + str(hex_serial) + '&stateCurrent=false&stateHistory=false&stateWaiting=false&stateManual=false&stateUnattached=false&expiresAfter=%22%22&expiresBefore=%22%22&sortAttribute=createdAt&sortOrder=desc&containerId=' + str(self.tsg_info_dic['id']), headers=self.headers, verify=self.ca_bundle, proxies=self.proxy, timeout=self.request_timeout).json() except Exception as err_: - self.logger.error('CAhandler.revoke(): request get aborted with err: {0}'.format(err_)) + self.logger.error('CAhandler.revoke(): request get aborted with err: %s', err_) cert_list = [] err_dic = error_dic_get(self.logger) @@ -726,7 +727,7 @@ def revoke(self, cert: str, rev_reason: str, rev_date: str) -> Tuple[int, str, s code = 200 message = None except Exception as err: - self.logger.error('CAhandler.revoke(): _api_post got aborted with err: {0}'.format(err)) + self.logger.error('CAhandler.revoke(): _api_post got aborted with err: %s', err) code = 500 message = err_dic['serverinternal'] detail = 'Revocation operation failed' @@ -749,5 +750,5 @@ def trigger(self, _payload: str) -> Tuple[str, str, str]: cert_bundle = None cert_raw = None - self.logger.debug('CAhandler.trigger() ended with error: {0}'.format(error)) + self.logger.debug('CAhandler.trigger() ended with error: %s', error) return (error, cert_bundle, cert_raw) diff --git a/examples/ca_handler/openssl_ca_handler.py b/examples/ca_handler/openssl_ca_handler.py index 16730c88..6600fc3c 100644 --- a/examples/ca_handler/openssl_ca_handler.py +++ b/examples/ca_handler/openssl_ca_handler.py @@ -13,7 +13,7 @@ from cryptography.hazmat.primitives import serialization, hashes from cryptography.x509 import BasicConstraints, ExtendedKeyUsage, SubjectKeyIdentifier, AuthorityKeyIdentifier, KeyUsage, SubjectAlternativeName from cryptography.x509.oid import ExtendedKeyUsageOID, NameOID -# pylint: disable=C0209, E0401, R0913 +# pylint: disable=e0401 from acme_srv.helper import load_config, build_pem_file, uts_now, uts_to_date_utc, b64_url_recode, cert_serial_get, convert_string_to_byte, convert_byte_to_string, csr_cn_get, csr_san_get diff --git a/examples/ca_handler/openxpki_ca_handler.py b/examples/ca_handler/openxpki_ca_handler.py index 1d0b3042..0b682c67 100644 --- a/examples/ca_handler/openxpki_ca_handler.py +++ b/examples/ca_handler/openxpki_ca_handler.py @@ -6,7 +6,7 @@ from typing import Tuple, Dict import requests from requests_pkcs12 import Pkcs12Adapter -# pylint: disable=C0209, E0401 +# pylint: disable=e0401 from acme_srv.helper import load_config, build_pem_file, cert_pem2der, b64_url_recode, b64_encode, error_dic_get from acme_srv.db_handler import DBstore @@ -48,10 +48,10 @@ def _cert_bundle_create(self, response: Dict[str, str]) -> Tuple[str, str, str]: if 'data' in response and 'certificate' in response['data'] and 'chain' in response['data']: # create base65 encoded der file cert_raw = b64_encode(self.logger, cert_pem2der(response['data']['certificate'])) - cert_bundle = '{0}\n{1}'.format(response['data']['certificate'], response['data']['chain']) + cert_bundle = f'{response['data']['certificate']}\n{response['data']['chain']}' else: error = 'Malformed response' - self.logger.error('CAhandler._cert_bundle_create() returned malformed response: {0}'.format(response)) + self.logger.error('CAhandler._cert_bundle_create() returned malformed response: %s', response) return (error, cert_bundle, cert_raw) @@ -64,7 +64,7 @@ def _cert_identifier_get(self, cert_raw: str) -> str: if 'poll_identifier' in result and result['poll_identifier']: cert_identifier = result['poll_identifier'] - self.logger.debug('CAhandler._cert_identifier_get() ended with: {0}'.format(cert_identifier)) + self.logger.debug('CAhandler._cert_identifier_get() ended with: %s', cert_identifier) return cert_identifier def _config_server_load(self, config_dic): @@ -95,7 +95,7 @@ def _config_ca_load(self, config_dic): try: self.ca_bundle = config_dic.getboolean('CAhandler', 'ca_bundle') except Exception as err: - self.logger.debug('CAhandler._config_server_load(): failed to load ca_bundle option: {0}'.format(err)) + self.logger.debug('CAhandler._config_server_load(): failed to load ca_bundle option: %s', err) self.ca_bundle = config_dic['CAhandler']['ca_bundle'] if 'cert_profile_name' in config_dic['CAhandler']: @@ -105,7 +105,7 @@ def _config_ca_load(self, config_dic): try: self.polling_timeout = int(config_dic['CAhandler']['polling_timeout']) except Exception as err: - self.logger.error('CAhandler._config_server_load(): failed to load polling_timeout option: {0}'.format(err)) + self.logger.error('CAhandler._config_server_load(): failed to load polling_timeout option: %s', err) self.polling_timeout = 0 def _config_passphrase_load(self, config_dic: Dict[str, str]): @@ -117,7 +117,7 @@ def _config_passphrase_load(self, config_dic: Dict[str, str]): try: self.cert_passphrase = os.environ[config_dic['CAhandler']['cert_passphrase_variable']] except Exception as err: - self.logger.error('CAhandler._config_passphrase_load() could not load cert_passphrase_variable:{0}'.format(err)) + self.logger.error('CAhandler._config_passphrase_load() could not load cert_passphrase_variable:%s', err) if 'cert_passphrase' in config_dic['CAhandler']: self.logger.debug('CAhandler._config_passphrase_load(): load passphrase from config file') @@ -162,7 +162,7 @@ def _config_load(self): variable_dic = self.__dict__ for ele in ['host', 'cert_profile_name', 'endpoint_name']: if not variable_dic[ele]: - self.logger.error('CAhandler._config_load(): configuration incomplete: parameter "{0}" is missing in configuration file.'.format(ele)) + self.logger.error('CAhandler._config_load(): configuration incomplete: parameter "%s" is missing in configuration file.', ele) self.logger.debug('CAhandler._config_load() ended') def _enroll(self, data_dic: Dict[str, str]) -> Tuple[str, str, str, str]: @@ -188,11 +188,11 @@ def _enroll(self, data_dic: Dict[str, str]) -> Tuple[str, str, str, str]: elif 'result' in sign_response and 'state' in sign_response['result'] and sign_response['result']['state'].upper() == 'PENDING': # request to be approved by operator poll_indentifier = sign_response['result']['data']['transaction_id'] - self.logger.info('CAhandler.enroll(): Request pending. Transaction_id: {0} Workflow_id: {1}'.format(poll_indentifier, sign_response['result']['id'])) + self.logger.info('CAhandler.enroll(): Request pending. Transaction_id: %s Workflow_id: %s', poll_indentifier, sign_response['result']['id']) else: # ernoll failed error = 'Malformed response' - self.logger.error('CAhandler.enroll(): Malformed Rest response: {0}'.format(sign_response)) + self.logger.error('CAhandler.enroll(): Malformed Rest response: %s', sign_response) break_loop = True if break_loop: @@ -202,7 +202,7 @@ def _enroll(self, data_dic: Dict[str, str]) -> Tuple[str, str, str, str]: # sleep time.sleep(10) - self.logger.debug('CAhandler._enroll() ended: Poll_identifier: {0}'.format(poll_indentifier)) + self.logger.debug('CAhandler._enroll() ended: Poll_identifier: %s', poll_indentifier) return (error, cert_bundle, cert_raw, poll_indentifier) def _rpc_post(self, path: str, data_dic: Dict[str, str]) -> Dict[str, str]: @@ -213,7 +213,7 @@ def _rpc_post(self, path: str, data_dic: Dict[str, str]) -> Dict[str, str]: response = self.session.post(self.host + path, data=data_dic, verify=self.ca_bundle, proxies=self.proxy, timeout=self.request_timeout).json() except Exception as err_: - self.logger.error('CAhandler._rpc_post() returned an error: {0}'.format(err_)) + self.logger.error('CAhandler._rpc_post() returned an error: %s', err_) response = {} self.logger.debug('CAhandler._rpc_post() ended.') @@ -237,14 +237,14 @@ def _revoke(self, cert_identifier: str, rev_reason: str) -> Tuple[int, str, str] code = 400 message = self.err_msg_dic['serverinternal'] detail = 'Revocation failed' - self.logger.error('CAhandler._revoke() failed with: {0}'.format(revocation_response)) + self.logger.error('CAhandler._revoke() failed with: %s', revocation_response) else: code = 400 message = self.err_msg_dic['serverinternal'] detail = 'Incomplete configuration' - self.logger.debug('CAhandler._revoke() ended with: {0} {1}'.format(code, detail)) + self.logger.debug('CAhandler._revoke() ended with: %s %s', code, detail) return (code, message, detail) def enroll(self, csr: str) -> Tuple[str, str, str, str]: @@ -294,7 +294,7 @@ def poll(self, _cert_name: str, poll_identifier: str, _csr: str) -> Tuple[str, s def revoke(self, cert: str, rev_reason: str = 'unspecified', rev_date: str = None) -> Tuple[int, str, str]: """ revoke certificate """ - self.logger.debug('CAhandler.revoke({0}: {1})'.format(rev_reason, rev_date)) + self.logger.debug('CAhandler.revoke(%s: %s)', rev_reason, rev_date) code = None message = None detail = None @@ -323,5 +323,5 @@ def trigger(self, _payload: str) -> Tuple[str, str, str]: cert_bundle = None cert_raw = None - self.logger.debug('CAhandler.trigger() ended with error: {0}'.format(error)) + self.logger.debug('CAhandler.trigger() ended with error: %s', error) return (error, cert_bundle, cert_raw) diff --git a/examples/ca_handler/pkcs7_soap_ca_handler.py b/examples/ca_handler/pkcs7_soap_ca_handler.py index 774f414d..9860982b 100644 --- a/examples/ca_handler/pkcs7_soap_ca_handler.py +++ b/examples/ca_handler/pkcs7_soap_ca_handler.py @@ -2,7 +2,7 @@ """ propritary soap_ca_handler """ from __future__ import print_function import subprocess -# pylint: disable=C0209, E0401 +# pylint: disable=e0401 import os import binascii import requests @@ -22,7 +22,7 @@ def binary_read(logger, file_name): """ dump filename in binary format """ - logger.debug('read_binary({0})'.format(file_name)) + logger.debug('read_binary(%s)', file_name) # dump csr into file with open(file_name, 'rb') as reader: content = reader.read() @@ -32,7 +32,8 @@ def binary_read(logger, file_name): def binary_write(logger, file_name, content): """ dump filename in binary format """ - logger.debug('write_binary({0})'.format(file_name)) + logger.debug('write_binary(%s)', file_name) + # dump csr into file with open(file_name, 'wb') as writer: writer.write(content) @@ -71,7 +72,7 @@ def _script_config_load(self, config_dic): self.signing_script_dic[ele] = config_dic['CAhandler'][ele] else: if value: - self.logger.error('CAhandler._config_load(): {0} option is missing in config file'.format(ele)) + self.logger.error('CAhandler._config_load(): %s option is missing in config file', ele) def _self_signing_config_load(self, config_dic): """ load configuriation options for self signing """ @@ -82,7 +83,7 @@ def _self_signing_config_load(self, config_dic): with open(config_dic['CAhandler']['signing_cert'], 'rb') as open_file: self.signing_cert = x509.load_pem_x509_certificate(open_file.read(), default_backend()) else: - self.logger.error('CAhandler._config_load(): signing_cert {0} not found.'.format(config_dic['CAhandler']['signing_cert'])) + self.logger.error('CAhandler._config_load(): signing_cert %s not found.', config_dic['CAhandler']['signing_cert']) else: self.logger.error('CAhandler._config_load(): signing_cert option is missing in config file') @@ -95,7 +96,7 @@ def _self_signing_config_load(self, config_dic): self.signing_key = serialization.load_pem_private_key( open_file.read(), password=self.password, backend=default_backend()) else: - self.logger.error('CAhandler._config_load(): signing_key {0} not found.'.format(config_dic['CAhandler']['signing_key'])) + self.logger.error('CAhandler._config_load(): signing_key %s not found.', config_dic['CAhandler']['signing_key']) else: self.logger.error('CAhandler._config_load(): signing_key option is missing in config file') @@ -240,21 +241,21 @@ def _pkcs7_create(self, cert, csr, private_key): def _soaprequest_build(self, pkcs7): """ build soap request payload """ self.logger.debug('CAhandler._soaprequest_build()') - data = """ + data = f""" - {0} - {1} - {2} + {self.profilename} + {pkcs7} + {self.email} true -""".format(self.profilename, pkcs7, self.email) # pylint: disable=c0209 +""" return data def _soaprequest_send(self, payload): @@ -278,21 +279,21 @@ def _soaprequest_send(self, payload): b64_cert_bundle = soap_dic[senvelope_field_name][sbody_field_name]['RequestCertificateResponse']['RequestCertificateResult']['IssuedCertificate'] except Exception: self.logger.error('CAhandler._soaprequest_send() - XML Parsing error') - self.logger.debug('CAhandler._soaprequest_send() xml2dict: {0}'.format(resp.text)) + self.logger.debug('CAhandler._soaprequest_send() xml2dict: %s', resp.text) error = 'Parsing error' else: - self.logger.error('CAhandler._soaprequest_send(): http status_code {0}'.format(resp.status_code)) + self.logger.error('CAhandler._soaprequest_send(): http status_code %s', resp.status_code) error = 'Server error' try: soap_dic = xmltodict.parse(resp.text) - self.logger.error('CAhandler._soaprequest_send() - faultcode: {0}'.format(soap_dic[senvelope_field_name][sbody_field_name]['s:Fault']['faultcode'])) - self.logger.error('CAhandler._soaprequest_send() - faultstring: {0}'.format(soap_dic[senvelope_field_name][sbody_field_name]['s:Fault']['faultstring'])) + self.logger.error('CAhandler._soaprequest_send() - faultcode: %s', soap_dic[senvelope_field_name][sbody_field_name]['s:Fault']['faultcode']) + self.logger.error('CAhandler._soaprequest_send() - faultstring: %s', soap_dic[senvelope_field_name][sbody_field_name]['s:Fault']['faultstring']) except Exception: self.logger.error('CAhandler._soaprequest_send() - unkown error') - self.logger.debug('CAhandler._soaprequest_send() unk: {0}'.format(resp.text)) + self.logger.debug('CAhandler._soaprequest_send() unk: %s', resp.text) except Exception as err: - self.logger.error('CAhandler._soaprequest_send(): {0}'.format(err)) + self.logger.error('CAhandler._soaprequest_send(): %s', err) error = 'Connection error' payload = None # lgtm [py/unused-local-variable] resp = None # lgtm [py/unused-local-variable] @@ -341,19 +342,19 @@ def _pkcs7_signing_config_verify(self): for ele in signing_parameters: if ele not in self.signing_script_dic: - error = 'signing config incomplete: option {0} is missing'.format(ele) + error = f'signing config incomplete: option {ele} is missing' break if ele == 'signing_csr_path': if not os.path.isdir(self.signing_script_dic[ele]): - error = 'signing_csr_path {0} does not exist or is not a directory'.format(ele) + error = f'signing_csr_path {ele} does not exist or is not a directory' break - self.logger.debug('CAhandler._pkcs7_signing_config_verify() returned with {0}'.format(error)) + self.logger.debug('CAhandler._pkcs7_signing_config_verify() returned with %s', error) return error def _signing_command_build(self, csr_unsigned, csr_signed): """ build signing command """ - self.logger.debug('CAhandler._signing_command_build({0})'.format(csr_unsigned)) + self.logger.debug('CAhandler._signing_command_build(%s)', csr_unsigned) if 'signing_script' in self.signing_script_dic: if 'signing_user' in self.signing_script_dic: @@ -372,7 +373,7 @@ def _signing_command_build(self, csr_unsigned, csr_signed): else: cmd_list = [] - self.logger.debug('CAhandler._signing_command_build() ended with: {0}'.format(' '.join(cmd_list))) + self.logger.debug('CAhandler._signing_command_build() ended with: %s', ' '.join(cmd_list)) return cmd_list def _pkcs7_sign_external(self, csr): @@ -382,14 +383,14 @@ def _pkcs7_sign_external(self, csr): # check external signing configuration signing_check = self._pkcs7_signing_config_verify() if signing_check: - self.logger.error('CAhandler._pkcs7_sign_external(): config incomplete: {0}'.format(signing_check)) + self.logger.error('CAhandler._pkcs7_sign_external(): config incomplete: %s', signing_check) rcode = 'Config incomplete' pkcs7_bundle = None else: # define temporary filenames _fname = generate_random_string(self.logger, 12) - unsigned_filename = '{0}/{1}.der'.format(self.signing_script_dic['signing_csr_path'], _fname) - signed_filename = '{0}/{1}_signed.der'.format(self.signing_script_dic['signing_csr_path'], _fname) + unsigned_filename = f'{self.signing_script_dic['signing_csr_path']}/{_fname}.der' + signed_filename = f'{self.signing_script_dic['signing_csr_path']}/{_fname}_signed.der' # build signing command signing_cmd = self._signing_command_build(unsigned_filename, signed_filename) @@ -402,14 +403,14 @@ def _pkcs7_sign_external(self, csr): if not rcode: pkcs7_bundle = binary_read(self.logger, signed_filename) else: - self.logger.error('CAhandler._pkcs7_sign_external() aborted with error: {0}'.format(rcode)) + self.logger.error('CAhandler._pkcs7_sign_external() aborted with error: %s', rcode) pkcs7_bundle = None # delete temporary files for ele in (unsigned_filename, signed_filename): if os.path.isfile(ele): os.remove(ele) - self.logger.debug('CAhandler._pkcs7_sign_external() ended with error: {0}'.format(rcode)) + self.logger.debug('CAhandler._pkcs7_sign_external() ended with error: %s', rcode) return (rcode, pkcs7_bundle) def enroll(self, csr): @@ -438,7 +439,7 @@ def enroll(self, csr): payload = self._soaprequest_build(b64_encode(self.logger, pkcs7_bundle)) (error, b64_cert_bundle) = self._soaprequest_send(payload) else: - self.logger.error('CAhandler.enroll() aborted with error: {0}'.format(error)) + self.logger.error('CAhandler.enroll() aborted with error: %s', error) b64_cert_bundle = None # lgtm [py/unused-local-variable] if not error and b64_cert_bundle: @@ -450,7 +451,7 @@ def enroll(self, csr): cert_raw = self._certraw_get(certificate_list[0]) else: if error: - self.logger.error('CAhandler.enroll() _soaprequest_send() aborted with error: {0}'.format(error)) + self.logger.error('CAhandler.enroll() _soaprequest_send() aborted with error: %s', error) else: self.logger.error('CAhandler.enroll() _soaprequest_send() did not return a bundle') @@ -489,5 +490,5 @@ def trigger(self, _payload): cert_bundle = None cert_raw = None - self.logger.debug('CAhandler.trigger() ended with error: {0}'.format(error)) + self.logger.debug('CAhandler.trigger() ended with error: %s', error) return (error, cert_bundle, cert_raw) diff --git a/examples/ca_handler/skeleton_ca_handler.py b/examples/ca_handler/skeleton_ca_handler.py index f0ab6e1a..b6ad48e6 100644 --- a/examples/ca_handler/skeleton_ca_handler.py +++ b/examples/ca_handler/skeleton_ca_handler.py @@ -2,7 +2,7 @@ """ skeleton for customized CA handler """ from __future__ import print_function from typing import Tuple -# pylint: disable=C0209, E0401 +# pylint: disable=e0401 from acme_srv.helper import load_config, header_info_get @@ -34,7 +34,7 @@ def _config_load(self): def _stub_func(self, parameter: str): """" load config from file """ - self.logger.debug('CAhandler._stub_func({0})'.format(parameter)) + self.logger.debug('CAhandler._stub_func(%s)', parameter) self.logger.debug('CAhandler._stub_func() ended') @@ -90,5 +90,5 @@ def trigger(self, payload: str) -> Tuple[str, str, str]: cert_raw = None self._stub_func(payload) - self.logger.debug('CAhandler.trigger() ended with error: {0}'.format(error)) + self.logger.debug('CAhandler.trigger() ended with error: %s', error) return (error, cert_bundle, cert_raw) diff --git a/examples/ca_handler/xca_ca_handler.py b/examples/ca_handler/xca_ca_handler.py index 46c6863a..0ef984cd 100644 --- a/examples/ca_handler/xca_ca_handler.py +++ b/examples/ca_handler/xca_ca_handler.py @@ -13,7 +13,7 @@ from cryptography.x509 import BasicConstraints, ExtendedKeyUsage, SubjectKeyIdentifier, AuthorityKeyIdentifier, KeyUsage, SubjectAlternativeName from cryptography.x509.oid import ExtendedKeyUsageOID from OpenSSL import crypto as pyossslcrypto -# pylint: disable=C0209, E0401 +# pylint: disable=e0401 from acme_srv.helper import load_config, build_pem_file, uts_now, uts_to_date_utc, b64_encode, b64_decode, b64_url_recode, cert_serial_get, convert_string_to_byte, convert_byte_to_string, csr_cn_get, csr_san_get, error_dic_get, header_info_get @@ -79,18 +79,18 @@ def _asn1_stream_parse(self, asn1_stream: str = None) -> Dict[str, str]: stream_list.pop(0) for ele in stream_list: - oid = '2.5.{0}.{1}'.format(ele[0], ele[1]) + oid = f'2.5.{ele[0]}.{ele[1]}' if oid in oid_dic: value_len = ele[3] value = ele[4:4 + value_len] dn_dic[oid_dic[oid]] = value.decode('utf-8') - self.logger.debug('CAhandler._asn1_stream_parse() ended: {0}'.format(bool(dn_dic))) + self.logger.debug('CAhandler._asn1_stream_parse() ended: %s', bool(dn_dic)) return dn_dic def _ca_cert_load(self) -> Tuple[object, int]: """ load ca key from database """ - self.logger.debug('CAhandler._ca_cert_load({0})'.format(self.issuing_ca_name)) + self.logger.debug('CAhandler._ca_cert_load({%s)', self.issuing_ca_name) # query database for key self._db_open() @@ -99,7 +99,7 @@ def _ca_cert_load(self) -> Tuple[object, int]: try: db_result = dict_from_row(self.cursor.fetchone()) except Exception: - self.logger.error('cert lookup failed: {0}'.format(self.cursor.fetchone())) + self.logger.error('cert lookup failed: %s', self.cursor.fetchone()) db_result = {} self._db_close() @@ -111,12 +111,12 @@ def _ca_cert_load(self) -> Tuple[object, int]: ca_cert = x509.load_der_x509_certificate(b64_decode(self.logger, db_result['cert']), backend=default_backend()) ca_id = db_result['id'] except Exception as err_: - self.logger.error('CAhandler._ca_cert_load() failed with error: {0}'.format(err_)) + self.logger.error('CAhandler._ca_cert_load() failed with error: %s', err_) return (ca_cert, ca_id) def _ca_key_load(self) -> object: """ load ca key from database """ - self.logger.debug('CAhandler._ca_key_load({0})'.format(self.issuing_ca_key)) + self.logger.debug('CAhandler._ca_key_load(%s)', self.issuing_ca_key) # query database for key self._db_open() @@ -125,19 +125,19 @@ def _ca_key_load(self) -> object: try: db_result = dict_from_row(self.cursor.fetchone()) except Exception as _err: - self.logger.error('key lookup failed: {0}'.format(self.cursor.fetchone())) + self.logger.error('key lookup failed: %s', self.cursor.fetchone()) db_result = {} self._db_close() ca_key = None if db_result and 'private' in db_result: try: - private_key = '-----BEGIN ENCRYPTED PRIVATE KEY-----\n{0}\n-----END ENCRYPTED PRIVATE KEY-----'.format(db_result['private']) + private_key = f'-----BEGIN ENCRYPTED PRIVATE KEY-----\n{db_result['private']}\n-----END ENCRYPTED PRIVATE KEY-----' ca_key = serialization.load_pem_private_key(convert_string_to_byte(private_key), password=convert_string_to_byte(self.passphrase), backend=default_backend()) except Exception as err_: - self.logger.error('CAhandler._ca_key_load() failed with error: {0}'.format(err_)) + self.logger.error('CAhandler._ca_key_load() failed with error: %s', err_) else: - self.logger.error('CAhandler._ca_key_load() failed to load key: {0}'.format(db_result)) + self.logger.error('CAhandler._ca_key_load() failed to load key: %s', db_result) self.logger.debug('CAhandler._ca_key_load() ended') return ca_key @@ -177,29 +177,29 @@ def _cert_insert(self, cert_dic: Dict[str, str] = None) -> int: row_id = self.cursor.lastrowid self._db_close() else: - self.logger.error('CAhandler._cert_insert() aborted. wrong datatypes: {}'.format(cert_dic)) + self.logger.error('CAhandler._cert_insert() aborted. wrong datatypes: %s', cert_dic) else: - self.logger.error('CAhandler._cert_insert() aborted. dataset incomplete: {}'.format(cert_dic)) + self.logger.error('CAhandler._cert_insert() aborted. dataset incomplete: %s', cert_dic) else: self.logger.error('CAhandler._cert_insert() aborted. dataset empty') - self.logger.debug('CAhandler._cert_insert() ended with row_id: {0}'.format(row_id)) + self.logger.debug('CAhandler._cert_insert() ended with row_id: %s', row_id) return row_id def _cert_search(self, column: str, value: str) -> Dict[str, str]: """ load ca key from database """ - self.logger.debug('CAhandler._cert_search({0}:{1})'.format(column, value)) + self.logger.debug('CAhandler._cert_search({%s:%s)', column, value) # query database for key self._db_open() - pre_statement = '''SELECT * from items WHERE type == 3 and {0} LIKE ?'''.format(column) + pre_statement = f'''SELECT * from items WHERE type == 3 and {column} LIKE ?''' self.cursor.execute(pre_statement, [value]) cert_result = {} try: item_result = dict_from_row(self.cursor.fetchone()) except Exception: - self.logger.error('CAhandler._cert_search(): item search failed: {0}'.format(self.cursor.fetchone())) + self.logger.error('CAhandler._cert_search(): item search failed: %s', self.cursor.fetchone()) item_result = {} if item_result: @@ -209,7 +209,7 @@ def _cert_search(self, column: str, value: str) -> Dict[str, str]: try: cert_result = dict_from_row(self.cursor.fetchone()) except Exception: - self.logger.error('CAhandler._cert_search(): cert search failed: item: {0}'.format(item_id)) + self.logger.error('CAhandler._cert_search(): cert search failed: item: %s', item_id) self._db_close() self.logger.debug('CAhandler._cert_search() ended') @@ -220,7 +220,7 @@ def _cert_subject_generate(self, req: object, request_name: str, dn_dic: Dict[st self.logger.debug('CAhandler._cert_subject_generate()') if not bool(req.subject): - self.logger.info('rewrite CN to {0}'.format(request_name)) + self.logger.info('rewrite CN to %s', request_name) subject = x509.Name([x509.NameAttribute(x509.NameOID.COMMON_NAME, request_name)]) else: subject = req.subject @@ -247,7 +247,7 @@ def _cert_sign(self, csr: str, request_name: str, ca_key: object, ca_cert: objec # set cert_validity if 'validity' in template_dic: - self.logger.info('take validity from template: {0}'.format(template_dic['validity'])) + self.logger.info('take validity from template: %s', template_dic['validity']) # take validity from template cert_validity = template_dic['validity'] else: @@ -284,7 +284,7 @@ def _cert_sign(self, csr: str, request_name: str, ca_key: object, ca_cert: objec cert_subject_hash = self._subject_name_hash_get(cert) # store certificate - self._store_cert(ca_id, request_name, '{:X}'.format(serial), convert_byte_to_string(b64_encode(self.logger, cert.public_bytes(serialization.Encoding.DER))), cert_subject_hash, issuer_subject_hash) + self._store_cert(ca_id, request_name, f'{serial:X}', convert_byte_to_string(b64_encode(self.logger, cert.public_bytes(serialization.Encoding.DER))), cert_subject_hash, issuer_subject_hash) cert_bundle = self._pemcertchain_generate(convert_byte_to_string(cert.public_bytes(serialization.Encoding.PEM)), convert_byte_to_string(ca_cert.public_bytes(serialization.Encoding.PEM))) cert_raw = convert_byte_to_string(b64_encode(self.logger, cert.public_bytes(serialization.Encoding.DER))) @@ -299,7 +299,7 @@ def _config_check(self) -> str: if self.xdb_file: if not os.path.exists(self.xdb_file): - error = 'xdb_file {0} does not exist'.format(self.xdb_file) + error = f'xdb_file {self.xdb_file} does not exist' self.xdb_file = None else: error = 'xdb_file must be specified in config file' @@ -308,10 +308,10 @@ def _config_check(self) -> str: error = 'issuing_ca_name must be set in config file' if error: - self.logger.debug('CAhandler config error: {0}'.format(error)) + self.logger.debug('CAhandler config error: %s', error) if not self.issuing_ca_key: - self.logger.debug('use self.issuing_ca_name as self.issuing_ca_key: {0}'.format(self.issuing_ca_name)) + self.logger.debug('use self.issuing_ca_name as self.issuing_ca_key: %s', self.issuing_ca_name) self.issuing_ca_key = self.issuing_ca_name self.logger.debug('CAhandler._config_check() ended') @@ -329,7 +329,7 @@ def _config_load(self): try: self.passphrase = os.environ[config_dic['CAhandler']['passphrase_variable']] except Exception as err: - self.logger.error('CAhandler._config_load() could not load passphrase_variable:{0}'.format(err)) + self.logger.error('CAhandler._config_load() could not load passphrase_variable:%s', err) if 'passphrase' in config_dic['CAhandler']: # overwrite passphrase specified in variable @@ -385,13 +385,13 @@ def _csr_insert(self, csr_dic: Dict[str, str] = None) -> int: row_id = self.cursor.lastrowid self._db_close() else: - self.logger.error('CAhandler._csr_insert() aborted. wrong datatypes: {}'.format(csr_dic)) + self.logger.error('CAhandler._csr_insert() aborted. wrong datatypes: %s', csr_dic) else: - self.logger.error('CAhandler._csr_insert() aborted. dataset incomplete: {}'.format(csr_dic)) + self.logger.error('CAhandler._csr_insert() aborted. dataset incomplete: %s', csr_dic) else: self.logger.error('CAhandler._csr_insert() aborted. dataset empty') - self.logger.debug('CAhandler._csr_insert() ended with row_id: {0}'.format(row_id)) + self.logger.debug('CAhandler._csr_insert() ended with row_id: %s', row_id) return row_id def _csr_search(self, column: str, value: str) -> Dict[str, str]: @@ -400,7 +400,7 @@ def _csr_search(self, column: str, value: str) -> Dict[str, str]: # query database for key self._db_open() - pre_statement = '''SELECT * from view_requests WHERE {0} LIKE ?'''.format(column) + pre_statement = f'''SELECT * from view_requests WHERE {column} LIKE ?''' self.cursor.execute(pre_statement, [value]) try: @@ -408,7 +408,7 @@ def _csr_search(self, column: str, value: str) -> Dict[str, str]: except Exception: db_result = {} self._db_close() - self.logger.debug('CAhandler._csr_search() ended with: {0}'.format(bool(db_result))) + self.logger.debug('CAhandler._csr_search() ended with: %s', bool(db_result)) return db_result def _db_open(self): @@ -456,15 +456,6 @@ def _extended_keyusage_generate(self, template_dic: Dict[str, str], _csr_extensi if ele in eku_mapping_dic: eku_list.append(eku_mapping_dic[ele]) - # elif 'extendedKeyUsage' in csr_extensions_dic: - # # eku usage in extention - # try: - # ekuc = csr_extensions_dic['extendedKeyUsage'].get_critical() - # except Exception: - # ekuc = False - # # pylint: disable=C2801 - # eku_string = csr_extensions_dic['extendedKeyUsage'].__str__() - else: # neither extension nor template eku_list = None @@ -507,7 +498,7 @@ def _extension_list_generate(self, template_dic: Dict[str, str], cert: str, ca_c # add subjectAltName(s) if 'subjectAltName' in csr_extensions_dic: # pylint: disable=C2801 - self.logger.info('CAhandler._extension_list_generate(): adding subAltNames: {0}'.format(csr_extensions_dic['subjectAltName'].__str__())) + self.logger.info('CAhandler._extension_list_generate(): adding subAltNames: %s', csr_extensions_dic['subjectAltName'].__str__()) extension_list.append({'name': SubjectAlternativeName(csr_extensions_dic['subjectAltName'].value), 'critical': False}) self.logger.debug('CAhandler._extension_list_generate() ended') @@ -529,13 +520,13 @@ def _item_insert(self, item_dic: Dict[str, str] = None) -> int: self.cursor.execute('''UPDATE ITEMS SET stamp = :stamp WHERE id = :stamp''', data_dic) self._db_close() else: - self.logger.error('CAhandler._insert_insert() aborted. wrong datatypes: {}'.format(item_dic)) + self.logger.error('CAhandler._insert_insert() aborted. wrong datatypes: %s', item_dic) else: - self.logger.error('CAhandler._item_insert() aborted. dataset incomplete: {}'.format(item_dic)) + self.logger.error('CAhandler._item_insert() aborted. dataset incomplete: %s', item_dic) else: self.logger.error('CAhandler._insert_insert() aborted. dataset empty') - self.logger.debug('CAhandler._item_insert() ended with row_id: {0}'.format(row_id)) + self.logger.debug('CAhandler._item_insert() ended with row_id: %s', row_id) return row_id def _keyusage_generate(self, template_dic: Dict[str, str], _csr_extensions_dic: Dict[str, str] = None) -> Tuple[bool, Dict[str, str]]: @@ -585,22 +576,22 @@ def _kue_generate(self, kuval: int = 0, ku_csr: str = None) -> Dict[str, str]: self.logger.info('CAhandler._kue_generate() with 23') ku_dic = self._ku_dict_generate(23) - self.logger.debug('CAhandler._kue_generate() ended with: {0}'.format(ku_dic)) + self.logger.debug('CAhandler._kue_generate() ended with: %s', ku_dic) return ku_dic def _ku_dict_generate(self, kuval: int = 0) -> Dict[str, str]: - self.logger.debug('CAhandler._ku_dict_generate({0})'.format(kuval)) + self.logger.debug('CAhandler._ku_dict_generate(%s)', kuval) # generate and reverse key_usage_list key_usage_list = ['digital_signature', 'content_commitment', 'key_encipherment', 'data_encipherment', 'key_agreement', 'key_cert_sign', 'crl_sign', 'encipher_only', 'decipher_only'] key_usage_dic = {'digital_signature': False, 'content_commitment': False, 'key_encipherment': False, 'data_encipherment': False, 'key_agreement': False, 'key_cert_sign': False, 'crl_sign': False, 'encipher_only': False, 'decipher_only': False} - kubin = '{0:b}'.format(kuval)[::-1] + kubin = f'{kuval:b}'[::-1] for idx, ele in enumerate(kubin): if ele == '1': key_usage_dic[key_usage_list[idx]] = True - self.logger.debug('CAhandler._ku_dict_generate() ended with: {0}'.format(key_usage_dic)) + self.logger.debug('CAhandler._ku_dict_generate() ended with: %s', key_usage_dic) return key_usage_dic def _pemcertchain_generate(self, ee_cert: str, issuer_cert: str = None) -> str: @@ -608,7 +599,7 @@ def _pemcertchain_generate(self, ee_cert: str, issuer_cert: str = None) -> str: self.logger.debug('CAhandler._pemcertchain_generate()') if issuer_cert: - pem_chain = '{0}{1}'.format(ee_cert, issuer_cert) + pem_chain = f'{ee_cert}{issuer_cert}' else: pem_chain = ee_cert @@ -616,7 +607,7 @@ def _pemcertchain_generate(self, ee_cert: str, issuer_cert: str = None) -> str: cert_dic = self._cert_search('items.name', cert) if cert_dic and 'cert' in cert_dic: ca_cert = x509.load_der_x509_certificate(b64_decode(self.logger, cert_dic['cert']), backend=default_backend()) - pem_chain = '{0}{1}'.format(pem_chain, convert_byte_to_string(ca_cert.public_bytes(serialization.Encoding.PEM))) + pem_chain = f'{pem_chain}{convert_byte_to_string(ca_cert.public_bytes(serialization.Encoding.PEM))}' self.logger.debug('CAhandler._pemcertchain_generate() ended') return pem_chain @@ -632,9 +623,9 @@ def _requestname_get(self, csr: str = None) -> str: try: (_identifiier, request_name,) = san_list[0].split(':') except Exception: - self.logger.error('ERROR: CAhandler._request_name_get(): SAN split failed: {0}'.format(san_list)) + self.logger.error('ERROR: CAhandler._request_name_get(): SAN split failed: %s', san_list) - self.logger.debug('CAhandler._requestname_get() ended with: {0}'.format(request_name)) + self.logger.debug('CAhandler._requestname_get() ended with: %s', request_name) return request_name def _revocation_insert(self, rev_dic: Dict[str, str] = None) -> int: @@ -650,17 +641,17 @@ def _revocation_insert(self, rev_dic: Dict[str, str] = None) -> int: row_id = self.cursor.lastrowid self._db_close() else: - self.logger.error('CAhandler._revocation_insert() aborted. wrong datatypes: {}'.format(rev_dic)) + self.logger.error('CAhandler._revocation_insert() aborted. wrong datatypes: %s', rev_dic) else: - self.logger.error('CAhandler._revocation_insert() aborted. dataset incomplete: {}'.format(rev_dic)) + self.logger.error('CAhandler._revocation_insert() aborted. dataset incomplete: %s', rev_dic) else: self.logger.error('CAhandler._revocation_insert() aborted. dataset empty') - self.logger.debug('CAhandler._revocation_insert() ended with row_id: {0}'.format(row_id)) + self.logger.debug('CAhandler._revocation_insert() ended with row_id: %s', row_id) return row_id def _revocation_check(self, serial: str, ca_id: int, err_msg_dic: Dict[str, str] = None) -> Tuple[int, str, str]: - self.logger.debug('CAhandler.revoke({0}/{1})'.format(serial, ca_id)) + self.logger.debug('CAhandler.revoke(%s/%s)', serial, ca_id) # check if certificate has alreay been revoked: if not self._revocation_search('serial', serial): @@ -679,7 +670,7 @@ def _revocation_check(self, serial: str, ca_id: int, err_msg_dic: Dict[str, str] message = err_msg_dic['alreadyrevoked'] detail = 'Certificate has already been revoked' - self.logger.debug('CAhandler.revoke() ended with: {0}'.format(code)) + self.logger.debug('CAhandler.revoke() ended with: %s', code) return (code, message, detail) def _revocation_search(self, column: str, value: str) -> Dict[str, str]: @@ -687,7 +678,7 @@ def _revocation_search(self, column: str, value: str) -> Dict[str, str]: self.logger.debug('CAhandler._revocation_search()') # query database for key self._db_open() - pre_statement = '''SELECT * from revocations WHERE {0} LIKE ?'''.format(column) + pre_statement = f'''SELECT * from revocations WHERE {column} LIKE ?''' self.cursor.execute(pre_statement, [value]) try: @@ -730,12 +721,12 @@ def _stream_split(self, byte_stream: str = None) -> Tuple[str, str]: asn1_stream = byte_stream[:pos] utf_stream = byte_stream[pos:] - self.logger.debug('CAhandler._stream_split() ended: {0}:{1}'.format(bool(asn1_stream), bool(utf_stream))) + self.logger.debug('CAhandler._stream_split() ended: %s:%s', bool(asn1_stream), bool(utf_stream)) return (asn1_stream, utf_stream) def _stub_func(self, parameter: str) -> str: """" load config from file """ - self.logger.debug('CAhandler._stub_func({0})'.format(parameter)) + self.logger.debug('CAhandler._stub_func(%s)', parameter) self.logger.debug('CAhandler._stub_func() ended') return parameter @@ -755,19 +746,19 @@ def _subject_modify(self, subject: str, dn_dic: Dict[str, str] = None) -> str: subject_name_list = [] if 'organizationalUnitName' in dn_dic and dn_dic['organizationalUnitName']: - self.logger.info('rewrite OU to {0}'.format(dn_dic['organizationalUnitName'])) + self.logger.info('rewrite OU to %s', dn_dic['organizationalUnitName']) subject_name_list.append(x509.NameAttribute(x509.NameOID.ORGANIZATIONAL_UNIT_NAME, dn_dic['organizationalUnitName'])) if 'organizationName' in dn_dic and dn_dic['organizationName']: - self.logger.info('rewrite O to {0}'.format(dn_dic['organizationName'])) + self.logger.info('rewrite O to %s', dn_dic['organizationName']) subject_name_list.append(x509.NameAttribute(x509.NameOID.ORGANIZATION_NAME, dn_dic['organizationName'])) if 'localityName' in dn_dic and dn_dic['localityName']: - self.logger.info('rewrite L to {0}'.format(dn_dic['localityName'])) + self.logger.info('rewrite L to %s', dn_dic['localityName']) subject_name_list.append(x509.NameAttribute(x509.NameOID.LOCALITY_NAME, dn_dic['localityName'])) if 'stateOrProvinceName' in dn_dic and dn_dic['stateOrProvinceName']: - self.logger.info('rewrite ST to {0}'.format(dn_dic['stateOrProvinceName'])) + self.logger.info('rewrite ST to %s', dn_dic['stateOrProvinceName']) subject_name_list.append(x509.NameAttribute(x509.NameOID.STATE_OR_PROVINCE_NAME, dn_dic['stateOrProvinceName'])) if 'countryName' in dn_dic and dn_dic['countryName']: - self.logger.info('rewrite C to {0}'.format(dn_dic['countryName'])) + self.logger.info('rewrite C to %s', dn_dic['countryName']) subject_name_list.append(x509.NameAttribute(x509.NameOID.COUNTRY_NAME, dn_dic['countryName'])) if subject_name_list: @@ -778,7 +769,7 @@ def _subject_modify(self, subject: str, dn_dic: Dict[str, str] = None) -> str: def _template_load(self) -> Tuple[Dict[str, str], Dict[str, str]]: """ load template from database """ - self.logger.debug('CAhandler._template_load({0})'.format(self.template_name)) + self.logger.debug('CAhandler._template_load(%s)', self.template_name) # query database for template self._db_open() pre_statement = '''SELECT * from view_templates WHERE name LIKE ?''' @@ -786,7 +777,7 @@ def _template_load(self) -> Tuple[Dict[str, str], Dict[str, str]]: try: db_result = dict_from_row(self.cursor.fetchone()) except Exception: - self.logger.error('template lookup failed: {0}'.format(self.cursor.fetchone())) + self.logger.error('template lookup failed: %s', self.cursor.fetchone()) db_result = {} # parse template @@ -848,7 +839,7 @@ def _utf_stream_parse(self, utf_stream: str = None) -> Dict[str, str]: # convert list into a directory template_dic = {item: parameter_list[index + 1] for index, item in enumerate(parameter_list) if index % 2 == 0} - self.logger.debug('CAhandler._utf_stream_parse() ended: {0}'.format(bool(template_dic))) + self.logger.debug('CAhandler._utf_stream_parse() ended: %s', bool(template_dic)) return template_dic def _validity_calculate(self, template_dic: Dict[str, str] = None) -> int: @@ -869,7 +860,7 @@ def _validity_calculate(self, template_dic: Dict[str, str] = None) -> int: else: cert_validity = 365 - self.logger.debug('CAhandler._validity_calculate() ended with: {0}'.format(cert_validity)) + self.logger.debug('CAhandler._validity_calculate() ended with: %s', cert_validity) return cert_validity def _xca_template_process(self, template_dic: Dict[str, str], csr_extensions_dic: Dict[str, str], cert: str, ca_cert: str) -> List[str]: @@ -924,7 +915,7 @@ def enroll(self, csr: str = None) -> Tuple[str, str, str, str]: # lookup http header information from request qset = header_info_get(self.logger, csr=csr) if qset: - self.logger.info('header_info: {0}'.format(qset[-1]['header_info'])) + self.logger.info('header_info: %s', qset[-1]['header_info']) if not error: request_name = self._requestname_get(csr) @@ -973,7 +964,7 @@ def revoke(self, cert: str, _rev_reason: str = 'unspecified', _rev_date: str = N serial = cert_serial_get(self.logger, cert) if serial: - serial = '{:X}'.format(serial) + serial = f'{serial:X}' if ca_id and serial: (code, message, detail) = self._revocation_check(serial, ca_id, err_msg_dic) @@ -998,5 +989,5 @@ def trigger(self, payload: str) -> Tuple[str, str, str]: cert_raw = None self._stub_func(payload) - self.logger.debug('CAhandler.trigger() ended with error: {0}'.format(error)) + self.logger.debug('CAhandler.trigger() ended with error: %s', error) return (error, cert_bundle, cert_raw) From 33a00e4a816148dcb9255ba8b910b5a076d8b809 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 27 Jan 2024 17:04:57 +0100 Subject: [PATCH 028/460] [fix] f-string handling --- examples/ca_handler/certifier_ca_handler.py | 2 +- examples/ca_handler/nclm_ca_handler.py | 8 ++++---- examples/ca_handler/openxpki_ca_handler.py | 2 +- examples/ca_handler/pkcs7_soap_ca_handler.py | 4 ++-- examples/ca_handler/xca_ca_handler.py | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/examples/ca_handler/certifier_ca_handler.py b/examples/ca_handler/certifier_ca_handler.py index c02cedc7..95a24d28 100644 --- a/examples/ca_handler/certifier_ca_handler.py +++ b/examples/ca_handler/certifier_ca_handler.py @@ -492,7 +492,7 @@ def _request_poll(self, request_url: str) -> Tuple[str, str, str, str, bool]: error = 'Request rejected by operator' rejected = True else: - error = f'Unknown request status: {request_dic['status']}' + error = f'Unknown request status: {request_dic["status"]}' else: error = '"status" field not found in response.' diff --git a/examples/ca_handler/nclm_ca_handler.py b/examples/ca_handler/nclm_ca_handler.py index 666b3b26..dfe7ebb5 100644 --- a/examples/ca_handler/nclm_ca_handler.py +++ b/examples/ca_handler/nclm_ca_handler.py @@ -100,7 +100,7 @@ def _ca_policylink_id_lookup(self) -> int: self.logger.debug('CAhandler._ca_policylink_id_lookup()') # query CAs - ca_list = requests.get(self.api_host + f'/policy/ca?entityRef=CONTAINER&entityId={self.tsg_info_dic['id']}&allowedOnly=true&withTemplateById=0&enrollWithImportedCSR=true&csrHasPrivateKey=false&csrTemplateVersion=0', headers=self.headers, verify=self.ca_bundle, proxies=self.proxy, timeout=self.request_timeout).json() + ca_list = requests.get(self.api_host + f'/policy/ca?entityRef=CONTAINER&entityId={self.tsg_info_dic["id"]}&allowedOnly=true&withTemplateById=0&enrollWithImportedCSR=true&csrHasPrivateKey=false&csrTemplateVersion=0', headers=self.headers, verify=self.ca_bundle, proxies=self.proxy, timeout=self.request_timeout).json() ca_id = None if 'ca' in ca_list: ca_id = self._ca_id_get(ca_list) @@ -125,7 +125,7 @@ def _cert_bundle_get(self, cert_dic: Dict[str, str], count: int, cert_id: int, c self.logger.error('CAhandler._cert_bundle_build(): no der certificate returned for id: %s', cert_id) if 'pem' in cert_dic['certificate']: - cert_bundle = f'{cert_bundle}{cert_dic['certificate']['pem']}' + cert_bundle = f'{cert_bundle}{cert_dic["certificate"]["pem"]}' else: error = f'no pem certificate returned for id {cert_id}' self.logger.error('CAhandler._cert_bundle_build(): no pem certificate returned for id: %s', cert_id) @@ -680,10 +680,10 @@ def enroll(self, csr: str) -> Tuple[str, str, str, str]: # enroll operation (error, cert_bundle, cert_raw) = self._cert_enroll(csr, csr_cn, csr_san_list, policylink_id) else: - error = f'enrollment aborted. policylink_id: {policylink_id}, tsg_id: {self.tsg_info_dic['id']}' + error = f'enrollment aborted. policylink_id: {policylink_id}, tsg_id: {self.tsg_info_dic["id"]}' self.logger.error('CAhandler.eroll(): enrollment aborted. policylink_id: %s, tsg_id: %s', policylink_id, self.tsg_info_dic['id']) else: - error = f'CAhandler.eroll(): ID lookup for targetSystemGroup "{self.tsg_info_dic['name']}" failed.' + error = f'CAhandler.eroll(): ID lookup for targetSystemGroup "{self.tsg_info_dic["name"]}" failed.' else: self.logger.error(self.error) diff --git a/examples/ca_handler/openxpki_ca_handler.py b/examples/ca_handler/openxpki_ca_handler.py index 0b682c67..ecbe5f72 100644 --- a/examples/ca_handler/openxpki_ca_handler.py +++ b/examples/ca_handler/openxpki_ca_handler.py @@ -48,7 +48,7 @@ def _cert_bundle_create(self, response: Dict[str, str]) -> Tuple[str, str, str]: if 'data' in response and 'certificate' in response['data'] and 'chain' in response['data']: # create base65 encoded der file cert_raw = b64_encode(self.logger, cert_pem2der(response['data']['certificate'])) - cert_bundle = f'{response['data']['certificate']}\n{response['data']['chain']}' + cert_bundle = f'{response["data"]["certificate"]}\n{response["data"]["chain"]}' else: error = 'Malformed response' self.logger.error('CAhandler._cert_bundle_create() returned malformed response: %s', response) diff --git a/examples/ca_handler/pkcs7_soap_ca_handler.py b/examples/ca_handler/pkcs7_soap_ca_handler.py index 9860982b..fabaa282 100644 --- a/examples/ca_handler/pkcs7_soap_ca_handler.py +++ b/examples/ca_handler/pkcs7_soap_ca_handler.py @@ -389,8 +389,8 @@ def _pkcs7_sign_external(self, csr): else: # define temporary filenames _fname = generate_random_string(self.logger, 12) - unsigned_filename = f'{self.signing_script_dic['signing_csr_path']}/{_fname}.der' - signed_filename = f'{self.signing_script_dic['signing_csr_path']}/{_fname}_signed.der' + unsigned_filename = f'{self.signing_script_dic["signing_csr_path"]}/{_fname}.der' + signed_filename = f'{self.signing_script_dic["signing_csr_path"]}/{_fname}_signed.der' # build signing command signing_cmd = self._signing_command_build(unsigned_filename, signed_filename) diff --git a/examples/ca_handler/xca_ca_handler.py b/examples/ca_handler/xca_ca_handler.py index 0ef984cd..2b402114 100644 --- a/examples/ca_handler/xca_ca_handler.py +++ b/examples/ca_handler/xca_ca_handler.py @@ -132,7 +132,7 @@ def _ca_key_load(self) -> object: ca_key = None if db_result and 'private' in db_result: try: - private_key = f'-----BEGIN ENCRYPTED PRIVATE KEY-----\n{db_result['private']}\n-----END ENCRYPTED PRIVATE KEY-----' + private_key = f'-----BEGIN ENCRYPTED PRIVATE KEY-----\n{db_result["private"]}\n-----END ENCRYPTED PRIVATE KEY-----' ca_key = serialization.load_pem_private_key(convert_string_to_byte(private_key), password=convert_string_to_byte(self.passphrase), backend=default_backend()) except Exception as err_: self.logger.error('CAhandler._ca_key_load() failed with error: %s', err_) From 570c275e8c9838c0471589ba17ff352851547a4b Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 27 Jan 2024 17:52:16 +0100 Subject: [PATCH 029/460] [wf] action migration to node20 --- .../workflows/acme_sh-application-test.yml | 14 ++-- .github/workflows/alpn-test.yml | 4 +- .github/workflows/ari-test.yml | 14 ++-- .github/workflows/ca_handler_tests_acme.yml | 16 ++--- .github/workflows/ca_handler_tests_asa.yml | 6 +- .../workflows/ca_handler_tests_certifier.yml | 10 +-- .github/workflows/ca_handler_tests_cmp.yml | 16 ++--- .github/workflows/ca_handler_tests_ejbca.yml | 12 ++-- .github/workflows/ca_handler_tests_est.yml | 4 +- .github/workflows/ca_handler_tests_msca.yml | 20 +++--- .github/workflows/ca_handler_tests_nclm.yml | 4 +- .../workflows/ca_handler_tests_openssl.yml | 10 +-- .../workflows/ca_handler_tests_openxpki.yml | 16 ++--- .../workflows/ca_handler_tests_pkcs7_soap.yml | 4 +- .github/workflows/ca_handler_tests_xca.yml | 8 +-- .github/workflows/caddy-application-test.yml | 24 +++---- .../workflows/certbot-application-test.yml | 16 ++--- .../certmanager-application-test.yml | 68 +++++++++---------- .github/workflows/codescanner.yml | 8 +-- .github/workflows/container-tests.yml | 22 +++--- .github/workflows/create_release.yml | 2 +- .github/workflows/django_tests..yml | 36 +++++----- .github/workflows/dns-test.yml | 4 +- .github/workflows/eab-test.yml | 4 +- .github/workflows/enrollment-timeout.yml | 2 +- .github/workflows/hooks-test.yml | 8 +-- .github/workflows/ip-address-tests.yml | 16 ++--- .github/workflows/ipv6-test.yml | 8 +-- .github/workflows/lego-application-test.yml | 14 ++-- .github/workflows/manual-install-test.yml | 12 ++-- .github/workflows/proxy-test.yml | 8 +-- .../workflows/push_images_to_dockerhub.yml | 14 ++-- .github/workflows/python-test.yml | 4 +- .github/workflows/test_headerinfo.yml | 18 ++--- .github/workflows/tnauth-test.yml | 4 +- .../workflows/traffic-application-test.yml | 4 +- .github/workflows/upgrade_tests..yml | 50 +++++++------- .../workflows/winacme-application-test.yml | 6 +- .github/workflows/wsgi_handler-test.yml | 4 +- 39 files changed, 257 insertions(+), 257 deletions(-) diff --git a/.github/workflows/acme_sh-application-test.yml b/.github/workflows/acme_sh-application-test.yml index d83305ea..b55972a5 100644 --- a/.github/workflows/acme_sh-application-test.yml +++ b/.github/workflows/acme_sh-application-test.yml @@ -19,7 +19,7 @@ jobs: keylength: [2048, 4096, ec-521] steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" working-directory: examples/Docker/ @@ -129,7 +129,7 @@ jobs: keylength: [2048, 4096, ec-521] steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (apache2_django)" working-directory: examples/Docker/ @@ -141,7 +141,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -246,7 +246,7 @@ jobs: keylength: [2048, 4096, ec-521] steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (nginx_django)" working-directory: examples/Docker/ @@ -258,7 +258,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -362,7 +362,7 @@ jobs: keylength: [2048, 4096, ec-521] steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (nginx_django)" working-directory: examples/Docker/ @@ -375,7 +375,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s diff --git a/.github/workflows/alpn-test.yml b/.github/workflows/alpn-test.yml index 579b8e50..482146b3 100644 --- a/.github/workflows/alpn-test.yml +++ b/.github/workflows/alpn-test.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" working-directory: examples/Docker/ @@ -77,7 +77,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Retrieve Version from version.py run: | diff --git a/.github/workflows/ari-test.yml b/.github/workflows/ari-test.yml index 6f0ce0cc..f30fa309 100644 --- a/.github/workflows/ari-test.yml +++ b/.github/workflows/ari-test.yml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" working-directory: examples/Docker/ @@ -79,7 +79,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (apache2_django)" working-directory: examples/Docker/ @@ -91,7 +91,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -150,7 +150,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (nginx_django)" working-directory: examples/Docker/ @@ -162,7 +162,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -220,7 +220,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (nginx_django)" working-directory: examples/Docker/ @@ -233,7 +233,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s diff --git a/.github/workflows/ca_handler_tests_acme.yml b/.github/workflows/ca_handler_tests_acme.yml index b0a2b0de..70e31792 100644 --- a/.github/workflows/ca_handler_tests_acme.yml +++ b/.github/workflows/ca_handler_tests_acme.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" working-directory: examples/Docker/ @@ -34,7 +34,7 @@ jobs: docker run -d -p 80:80 --rm -id --network acme --name=acme-le-sim -v "$(pwd)/examples/Docker/data-le":/var/www/acme2certifier/volume/ grindsa/acme2certifier:apache2-wsgi - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -93,7 +93,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" working-directory: examples/Docker/ @@ -115,7 +115,7 @@ jobs: docker run -d -p 80:80 --rm -id --network acme --name=acme-le-sim -v "$(pwd)/examples/Docker/data-le":/var/www/acme2certifier/volume/ grindsa/acme2certifier:devel - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -174,7 +174,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Retrieve Version from version.py run: | @@ -208,7 +208,7 @@ jobs: docker run -d -p 80:80 --rm -id --network acme --name=acme-le-sim -v "$(pwd)/examples/Docker/data-le":/var/www/acme2certifier/volume/ grindsa/acme2certifier:apache2-wsgi - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -279,7 +279,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Retrieve Version from version.py run: | @@ -314,7 +314,7 @@ jobs: docker run -d -p 80:80 --rm -id --network acme --name=acme-le-sim -v "$(pwd)/examples/Docker/data-le":/var/www/acme2certifier/volume/ grindsa/acme2certifier:devel - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s diff --git a/.github/workflows/ca_handler_tests_asa.yml b/.github/workflows/ca_handler_tests_asa.yml index c029b816..ea97fe1a 100644 --- a/.github/workflows/ca_handler_tests_asa.yml +++ b/.github/workflows/ca_handler_tests_asa.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" working-directory: examples/Docker/ @@ -201,7 +201,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Retrieve Version from version.py run: | @@ -410,7 +410,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" working-directory: examples/Docker/ diff --git a/.github/workflows/ca_handler_tests_certifier.yml b/.github/workflows/ca_handler_tests_certifier.yml index 528bd812..728379b8 100644 --- a/.github/workflows/ca_handler_tests_certifier.yml +++ b/.github/workflows/ca_handler_tests_certifier.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" working-directory: examples/Docker/ @@ -118,7 +118,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" working-directory: examples/Docker/ @@ -225,7 +225,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" working-directory: examples/Docker/ @@ -332,7 +332,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Retrieve Version from version.py run: | @@ -462,7 +462,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" working-directory: examples/Docker/ diff --git a/.github/workflows/ca_handler_tests_cmp.yml b/.github/workflows/ca_handler_tests_cmp.yml index 790c22da..3b1a9354 100644 --- a/.github/workflows/ca_handler_tests_cmp.yml +++ b/.github/workflows/ca_handler_tests_cmp.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 #- name: "[ PREPARE ] patch docker file to ubuntu 22.04" # run: | @@ -103,7 +103,7 @@ jobs: CMP_HOST: ${{ secrets.CMP_HOST }} - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 5s @@ -137,7 +137,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] patch docker file to ubuntu 22.04" run: | @@ -226,7 +226,7 @@ jobs: CMP_HOST: ${{ secrets.CMP_HOST }} - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 5s @@ -260,7 +260,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Retrieve Version from version.py run: | @@ -373,7 +373,7 @@ jobs: CMP_HOST: ${{ secrets.CMP_HOST }} - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 5s @@ -409,7 +409,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Retrieve Version from version.py run: | @@ -522,7 +522,7 @@ jobs: CMP_HOST: ${{ secrets.CMP_HOST }} - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 5s diff --git a/.github/workflows/ca_handler_tests_ejbca.yml b/.github/workflows/ca_handler_tests_ejbca.yml index be593e28..d7900f42 100644 --- a/.github/workflows/ca_handler_tests_ejbca.yml +++ b/.github/workflows/ca_handler_tests_ejbca.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] get runner ip" run: | @@ -43,7 +43,7 @@ jobs: docker run -id --rm -p 80:8080 -p 443:8443 -e TLS_SETUP_ENABLED=true -v $(pwd)/examples/ejbca:/tmp/data -v $(pwd)/examples/Docker/data:/tmp/store --name "ejbca" -h ejbca keyfactor/ejbca-ce - name: "Sleep for 180s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 180s @@ -75,7 +75,7 @@ jobs: CAID: ${{ env.CAID }} - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -192,7 +192,7 @@ jobs: steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] get runner ip" run: | @@ -220,7 +220,7 @@ jobs: docker run -id --rm -p 80:8080 -p 443:8443 -e TLS_SETUP_ENABLED=true -v $(pwd)/examples/ejbca:/tmp/data -v $(pwd)/data:/tmp/store --name "ejbca" -h ejbca keyfactor/ejbca-ce - name: "Sleep for 180s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 180s @@ -253,7 +253,7 @@ jobs: CAID: ${{ env.CAID }} - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s diff --git a/.github/workflows/ca_handler_tests_est.yml b/.github/workflows/ca_handler_tests_est.yml index 549a2843..94fa0f81 100644 --- a/.github/workflows/ca_handler_tests_est.yml +++ b/.github/workflows/ca_handler_tests_est.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] create network" run: | @@ -145,7 +145,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Retrieve Version from version.py run: | diff --git a/.github/workflows/ca_handler_tests_msca.yml b/.github/workflows/ca_handler_tests_msca.yml index ea8f32e4..f0fae3e1 100644 --- a/.github/workflows/ca_handler_tests_msca.yml +++ b/.github/workflows/ca_handler_tests_msca.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] get runner ip" run: | @@ -97,7 +97,7 @@ jobs: WCCE_HOST: ${{ secrets.WCCE_HOST }} - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 5s @@ -144,7 +144,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] get runner ip" run: | @@ -256,7 +256,7 @@ jobs: WCCE_HOST: ${{ secrets.WCCE_HOST }} - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 5s @@ -314,7 +314,7 @@ jobs: steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" working-directory: examples/Docker/ @@ -406,7 +406,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] get runner ip" run: | @@ -511,7 +511,7 @@ jobs: WCCE_HOST: ${{ secrets.WCCE_HOST }} - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 5s @@ -556,7 +556,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] get runner ip" run: | @@ -703,7 +703,7 @@ jobs: WCCE_HOST: ${{ secrets.WCCE_HOST }} - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 5s @@ -754,7 +754,7 @@ jobs: authscheme: ['ntlm'] steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] get runner ip" run: | diff --git a/.github/workflows/ca_handler_tests_nclm.yml b/.github/workflows/ca_handler_tests_nclm.yml index 80a79e40..b6dc6ded 100644 --- a/.github/workflows/ca_handler_tests_nclm.yml +++ b/.github/workflows/ca_handler_tests_nclm.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" working-directory: examples/Docker/ @@ -130,7 +130,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Retrieve Version from version.py run: | diff --git a/.github/workflows/ca_handler_tests_openssl.yml b/.github/workflows/ca_handler_tests_openssl.yml index 409c4ae7..aea37d78 100644 --- a/.github/workflows/ca_handler_tests_openssl.yml +++ b/.github/workflows/ca_handler_tests_openssl.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" working-directory: examples/Docker/ @@ -117,7 +117,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" working-directory: examples/Docker/ @@ -226,7 +226,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" working-directory: examples/Docker/ @@ -299,7 +299,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" working-directory: examples/Docker/ @@ -370,7 +370,7 @@ jobs: steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Retrieve Version from version.py run: | diff --git a/.github/workflows/ca_handler_tests_openxpki.yml b/.github/workflows/ca_handler_tests_openxpki.yml index 83bf8d91..d8d426f4 100644 --- a/.github/workflows/ca_handler_tests_openxpki.yml +++ b/.github/workflows/ca_handler_tests_openxpki.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] get runner ip" run: | @@ -58,7 +58,7 @@ jobs: docker-compose up & - name: "Sleep for 60s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 60s @@ -70,7 +70,7 @@ jobs: docker start openxpki-docker_openxpki-server_1 - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -82,7 +82,7 @@ jobs: docker exec -id openxpki-docker_openxpki-client_1 apt-get install -y libjson-pp-perl - name: "Sleep for 45s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 45s @@ -343,7 +343,7 @@ jobs: steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] get runner ip" run: | @@ -385,7 +385,7 @@ jobs: docker-compose up & - name: "Sleep for 60s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 60s @@ -397,7 +397,7 @@ jobs: docker start openxpki-docker_openxpki-server_1 - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -409,7 +409,7 @@ jobs: docker exec -id openxpki-docker_openxpki-client_1 apt-get install -y libjson-pp-perl - name: "Sleep for 45s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 45s diff --git a/.github/workflows/ca_handler_tests_pkcs7_soap.yml b/.github/workflows/ca_handler_tests_pkcs7_soap.yml index ba3f2d40..c46ea5b0 100644 --- a/.github/workflows/ca_handler_tests_pkcs7_soap.yml +++ b/.github/workflows/ca_handler_tests_pkcs7_soap.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] SOAP server" run: | @@ -132,7 +132,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] SOAP server" run: | diff --git a/.github/workflows/ca_handler_tests_xca.yml b/.github/workflows/ca_handler_tests_xca.yml index 03b09691..04cddbe4 100644 --- a/.github/workflows/ca_handler_tests_xca.yml +++ b/.github/workflows/ca_handler_tests_xca.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" working-directory: examples/Docker/ @@ -132,7 +132,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" working-directory: examples/Docker/ @@ -247,7 +247,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Retrieve Version from version.py run: | @@ -384,7 +384,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Retrieve Version from version.py run: | diff --git a/.github/workflows/caddy-application-test.yml b/.github/workflows/caddy-application-test.yml index 857e6c57..ab8e0fdf 100644 --- a/.github/workflows/caddy-application-test.yml +++ b/.github/workflows/caddy-application-test.yml @@ -18,7 +18,7 @@ jobs: ports: ['-p 80:80 -p 443:443', '-p 443:443'] steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "Build docker-compose (apache2_wsgi)" working-directory: examples/Docker/ @@ -40,7 +40,7 @@ jobs: docker-compose logs - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -62,7 +62,7 @@ jobs: docker run -d --rm ${{ matrix.ports }} --network acme -v $PWD/caddy/Caddyfile:/etc/caddy/Caddyfile -v$PWD/caddy/acme2certifier_cabundle.pem:/tmp/acme2certifier_cabundle.pem -v $(pwd)/caddy/config:/config -v $(pwd)/caddy/data:/data --name=caddy caddy:2 - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -99,7 +99,7 @@ jobs: ports: ['-p 80:80 -p 443:443', '-p 443:443'] steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "Build docker-compose (apache2_django)" working-directory: examples/Docker/ @@ -123,7 +123,7 @@ jobs: docker-compose logs - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -145,7 +145,7 @@ jobs: docker run -d --rm ${{ matrix.ports }} --network acme -v $PWD/caddy/Caddyfile:/etc/caddy/Caddyfile -v$PWD/caddy/acme2certifier_cabundle.pem:/tmp/acme2certifier_cabundle.pem -v $(pwd)/caddy/config:/config -v $(pwd)/caddy/data:/data --name=caddy caddy:2 - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -182,7 +182,7 @@ jobs: ports: ['-p 80:80 -p 443:443', '-p 443:443'] steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "Build docker-compose (nginx_wsgi)" working-directory: examples/Docker/ @@ -206,7 +206,7 @@ jobs: docker-compose logs - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -228,7 +228,7 @@ jobs: docker run -d --rm ${{ matrix.ports }} --network acme -v $PWD/caddy/Caddyfile:/etc/caddy/Caddyfile -v$PWD/caddy/acme2certifier_cabundle.pem:/tmp/acme2certifier_cabundle.pem -v $(pwd)/caddy/config:/config -v $(pwd)/caddy/data:/data --name=caddy caddy:2 - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -264,7 +264,7 @@ jobs: ports: ['-p 80:80 -p 443:443', '-p 443:443'] steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "Build docker-compose (nginx_django)" working-directory: examples/Docker/ @@ -290,7 +290,7 @@ jobs: docker-compose logs - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -311,7 +311,7 @@ jobs: docker run -d --rm ${{ matrix.ports }} --network acme -v $PWD/caddy/Caddyfile:/etc/caddy/Caddyfile -v$PWD/caddy/acme2certifier_cabundle.pem:/tmp/acme2certifier_cabundle.pem -v $(pwd)/caddy/config:/config -v $(pwd)/caddy/data:/data --name=caddy caddy:2 - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s diff --git a/.github/workflows/certbot-application-test.yml b/.github/workflows/certbot-application-test.yml index da29c134..bc17c1fb 100644 --- a/.github/workflows/certbot-application-test.yml +++ b/.github/workflows/certbot-application-test.yml @@ -19,7 +19,7 @@ jobs: keylength: [2048, 4096] steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" working-directory: examples/Docker/ @@ -30,7 +30,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -109,7 +109,7 @@ jobs: keylength: [2048, 4096] steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (apache2_django)" working-directory: examples/Docker/ @@ -121,7 +121,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -201,7 +201,7 @@ jobs: keylength: [2048, 4096] steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (nginx_django)" working-directory: examples/Docker/ @@ -213,7 +213,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -292,7 +292,7 @@ jobs: keylength: [2048, 4096] steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (nginx_django)" working-directory: examples/Docker/ @@ -305,7 +305,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s diff --git a/.github/workflows/certmanager-application-test.yml b/.github/workflows/certmanager-application-test.yml index 0c5bc297..6638a695 100644 --- a/.github/workflows/certmanager-application-test.yml +++ b/.github/workflows/certmanager-application-test.yml @@ -15,7 +15,7 @@ jobs: steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] get runner ip" run: | @@ -48,7 +48,7 @@ jobs: run: | sudo microk8s.kubectl apply -f data/dnsmasq.yml - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -98,7 +98,7 @@ jobs: sudo microk8s.kubectl apply -f data/k8s-acme-srv.yml sudo microk8s.kubectl get pods -n cert-manager-acme - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -119,7 +119,7 @@ jobs: sudo microk8s.kubectl apply -f data/k8s-cert-mgr-http-01.yml - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 20s @@ -128,7 +128,7 @@ jobs: sudo microk8s.kubectl describe ClusterIssuer acme2certifier sudo microk8s.kubectl describe challenge - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 20s @@ -137,7 +137,7 @@ jobs: sudo microk8s.kubectl describe ClusterIssuer acme2certifier sudo microk8s.kubectl describe challenge - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 20s @@ -170,7 +170,7 @@ jobs: steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] get runner ip" run: | @@ -203,7 +203,7 @@ jobs: run: | sudo microk8s.kubectl apply -f data/dnsmasq.yml - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -255,7 +255,7 @@ jobs: sudo microk8s.kubectl get pods -n cert-manager-acme - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -276,7 +276,7 @@ jobs: sudo microk8s.kubectl apply -f data/k8s-cert-mgr-http-01.yml - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 20s @@ -285,7 +285,7 @@ jobs: sudo microk8s.kubectl describe ClusterIssuer acme2certifier sudo microk8s.kubectl describe challenge - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 20s @@ -294,7 +294,7 @@ jobs: sudo microk8s.kubectl describe ClusterIssuer acme2certifier sudo microk8s.kubectl describe challenge - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 20s @@ -326,7 +326,7 @@ jobs: steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] get runner ip" run: | @@ -360,7 +360,7 @@ jobs: sudo microk8s.kubectl apply -f data/dnsmasq.yml - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -410,7 +410,7 @@ jobs: sudo microk8s.kubectl apply -f data/k8s-acme-srv.yml sudo microk8s.kubectl get pods -n cert-manager-acme - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -430,7 +430,7 @@ jobs: sudo sed -i "s/ACME_SRV/${{ env.ACME_IP }}/g" data/k8s-cert-mgr-http-01.yml sudo microk8s.kubectl apply -f data/k8s-cert-mgr-http-01.yml - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 20s @@ -439,7 +439,7 @@ jobs: sudo microk8s.kubectl describe ClusterIssuer acme2certifier sudo microk8s.kubectl describe challenge - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 20s @@ -448,7 +448,7 @@ jobs: sudo microk8s.kubectl describe ClusterIssuer acme2certifier sudo microk8s.kubectl describe challenge - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 20s @@ -478,7 +478,7 @@ jobs: steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] get runner ip" run: | @@ -514,7 +514,7 @@ jobs: sudo microk8s.kubectl apply -f data/dnsmasq.yml - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -568,7 +568,7 @@ jobs: sudo microk8s.kubectl get pods -n cert-manager-acme - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -589,7 +589,7 @@ jobs: sudo microk8s.kubectl apply -f data/k8s-cert-mgr-http-01.yml - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 20s @@ -599,7 +599,7 @@ jobs: sudo microk8s.kubectl describe challenge - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 20s @@ -608,7 +608,7 @@ jobs: sudo microk8s.kubectl describe ClusterIssuer acme2certifier sudo microk8s.kubectl describe challenge - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 20s @@ -640,7 +640,7 @@ jobs: steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] change dns" run: | @@ -695,7 +695,7 @@ jobs: sudo microk8s.kubectl get pods -n cert-manager-acme - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -721,7 +721,7 @@ jobs: sudo microk8s.kubectl apply -f data/k8s-cert-mgr-dns-01.yml - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 20s @@ -731,7 +731,7 @@ jobs: sudo microk8s.kubectl describe challenge -n cert-manager-acme - name: "[ WAIT ] Sleep for 30s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 60s @@ -741,7 +741,7 @@ jobs: sudo microk8s.kubectl describe challenge -n cert-manager-acme - name: "[ WAIT ] Sleep for 60s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 60s @@ -751,7 +751,7 @@ jobs: sudo microk8s.kubectl describe challenge -n cert-manager-acme - name: "[ WAIT ] Sleep for 60s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 60s @@ -772,7 +772,7 @@ jobs: sudo microk8s.kubectl apply -f data/k8s-cert-mgr-dns-01.yml - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 20s @@ -781,7 +781,7 @@ jobs: sudo microk8s.kubectl describe issuer acme2certifier -n cert-manager-acme sudo microk8s.kubectl describe challenge -n cert-manager-acme - name: "[ WAIT ] Sleep for 30s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 60s @@ -791,7 +791,7 @@ jobs: sudo microk8s.kubectl describe challenge -n cert-manager-acme - name: "[ WAIT ] Sleep for 60s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 60s @@ -801,7 +801,7 @@ jobs: sudo microk8s.kubectl describe challenge -n cert-manager-acme - name: "[ WAIT ] Sleep for 60s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 60s diff --git a/.github/workflows/codescanner.yml b/.github/workflows/codescanner.yml index f3b35b00..dfe56d71 100644 --- a/.github/workflows/codescanner.yml +++ b/.github/workflows/codescanner.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@master with: @@ -35,7 +35,7 @@ jobs: name: SonarCloud Analysis runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis @@ -67,7 +67,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: # We must fetch at least the immediate parents so that if this is # a pull request then we can checkout the head. @@ -112,7 +112,7 @@ jobs: # steps: # # Checkout your code repository to scan # - name: Checkout repository - # uses: actions/checkout@v3 + # uses: actions/checkout@v4 # with: # We must fetch at least the immediate parents so that if this is # a pull request then we can checkout the head. diff --git a/.github/workflows/container-tests.yml b/.github/workflows/container-tests.yml index a5ab5d2f..2e2fcfd9 100644 --- a/.github/workflows/container-tests.yml +++ b/.github/workflows/container-tests.yml @@ -13,7 +13,7 @@ jobs: name: "Docker compose - apache2 wsgi" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: "Build the stack" working-directory: examples/Docker/ run: | @@ -52,7 +52,7 @@ jobs: head -n 13 data/ca_handler.py docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s - name: "Test if http://acme-srv/directory is accessable" @@ -79,7 +79,7 @@ jobs: name: "Docker compose - nginx wsgi" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: "Build the stack" working-directory: examples/Docker/ run: | @@ -100,7 +100,7 @@ jobs: docker-compose restart docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s - name: "Test if http://acme-srv/directory is accessable" @@ -124,7 +124,7 @@ jobs: head -n 13 data/ca_handler.py docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s - name: "Test if http://acme-srv/directory is accessable" @@ -151,7 +151,7 @@ jobs: name: "Docker compose - apache2 django" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: "Build the stack" working-directory: examples/Docker/ run: | @@ -172,7 +172,7 @@ jobs: docker-compose restart docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s - name: "Test if http://acme-srv/directory is accessable" @@ -196,7 +196,7 @@ jobs: head -n 13 data/ca_handler.py docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s - name: "Test if http://acme-srv/directory is accessable" @@ -222,7 +222,7 @@ jobs: name: "Docker compose - nginx django" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: "Build the stack" working-directory: examples/Docker/ run: | @@ -245,7 +245,7 @@ jobs: docker-compose restart docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s - name: "Test if http://acme-srv/directory is accessable" @@ -269,7 +269,7 @@ jobs: head -n 13 data/ca_handler.py docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s - name: "Test if http://acme-srv/directory is accessable" diff --git a/.github/workflows/create_release.yml b/.github/workflows/create_release.yml index f7a8ec85..0074fe51 100644 --- a/.github/workflows/create_release.yml +++ b/.github/workflows/create_release.yml @@ -20,7 +20,7 @@ jobs: id: acme2certifier_ver # The step ID to refer to later. - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Retrieve Version from version.py run: | diff --git a/.github/workflows/django_tests..yml b/.github/workflows/django_tests..yml index 0baf3162..12e9c3c9 100644 --- a/.github/workflows/django_tests..yml +++ b/.github/workflows/django_tests..yml @@ -16,7 +16,7 @@ jobs: fail-fast: false steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build environment" working-directory: examples/Docker/ @@ -34,7 +34,7 @@ jobs: docker run --name mariadbsrv --network acme -e MARIADB_ROOT_PASSWORD=foobar -d mariadb - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -116,7 +116,7 @@ jobs: fail-fast: false steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build environment" working-directory: examples/Docker/ @@ -140,7 +140,7 @@ jobs: docker run --name postgresdbsrv --network acme -e POSTGRES_PASSWORD=foobar -d postgres - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -149,7 +149,7 @@ jobs: run: | docker run -v "$(pwd)/data/pgsql/a2c.psql":/tmp/a2c.psql -v "$(pwd)/data/pgsql/pgpass:/root/.pgpass" --rm --network acme postgres psql -U postgres -h postgresdbsrv -f /tmp/a2c.psql - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -226,7 +226,7 @@ jobs: fail-fast: false steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build environment" working-directory: examples/Docker/ @@ -245,7 +245,7 @@ jobs: docker run --name mariadbsrv --network acme -e MARIADB_ROOT_PASSWORD=foobar -d mariadb - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -274,7 +274,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -333,7 +333,7 @@ jobs: fail-fast: false steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build environment" working-directory: examples/Docker/ @@ -358,7 +358,7 @@ jobs: docker run --name postgresdbsrv --network acme -e POSTGRES_PASSWORD=foobar -d postgres - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -367,7 +367,7 @@ jobs: run: | docker run -v "$(pwd)/data/pgsql/a2c.psql":/tmp/a2c.psql -v "$(pwd)/data/pgsql/pgpass:/root/.pgpass" --rm --network acme postgres psql -U postgres -h postgresdbsrv -f /tmp/a2c.psql - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -390,7 +390,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -450,7 +450,7 @@ jobs: fail-fast: false steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Retrieve Version from version.py run: | @@ -575,7 +575,7 @@ jobs: fail-fast: false steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Retrieve Version from version.py run: | @@ -621,7 +621,7 @@ jobs: # docker run --name mariadbsrv --network acme -e MARIADB_ROOT_PASSWORD=foobar -d mariadb - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -717,7 +717,7 @@ jobs: fail-fast: false steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Retrieve Version from version.py run: | @@ -768,7 +768,7 @@ jobs: docker run --name postgresdbsrv -v /tmp/pgsql/data:/var/lib/postgresql/data --network acme -e POSTGRES_PASSWORD=foobar -d postgres - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -777,7 +777,7 @@ jobs: docker run -v /tmp/pgsql/a2c.psql:/tmp/a2c.psql -v /tmp/pgsql/pgpass:/root/.pgpass --rm --network acme postgres psql -U postgres -h postgresdbsrv -f /tmp/a2c.psql - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s diff --git a/.github/workflows/dns-test.yml b/.github/workflows/dns-test.yml index 722df31e..d166df32 100644 --- a/.github/workflows/dns-test.yml +++ b/.github/workflows/dns-test.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" working-directory: examples/Docker/ @@ -120,7 +120,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Retrieve Version from version.py run: | diff --git a/.github/workflows/eab-test.yml b/.github/workflows/eab-test.yml index 900f41a4..02b49a55 100644 --- a/.github/workflows/eab-test.yml +++ b/.github/workflows/eab-test.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" working-directory: examples/Docker/ @@ -134,7 +134,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Retrieve Version from version.py run: | diff --git a/.github/workflows/enrollment-timeout.yml b/.github/workflows/enrollment-timeout.yml index 637db422..226ef2ba 100644 --- a/.github/workflows/enrollment-timeout.yml +++ b/.github/workflows/enrollment-timeout.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" working-directory: examples/Docker/ diff --git a/.github/workflows/hooks-test.yml b/.github/workflows/hooks-test.yml index 6ed8a7b9..8cde6836 100644 --- a/.github/workflows/hooks-test.yml +++ b/.github/workflows/hooks-test.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" working-directory: examples/Docker/ @@ -106,7 +106,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Retrieve Version from version.py run: | @@ -221,7 +221,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" working-directory: examples/Docker/ @@ -386,7 +386,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Retrieve Version from version.py diff --git a/.github/workflows/ip-address-tests.yml b/.github/workflows/ip-address-tests.yml index 1b4ec67c..5a73be33 100644 --- a/.github/workflows/ip-address-tests.yml +++ b/.github/workflows/ip-address-tests.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] get runner ip" run: | @@ -42,7 +42,7 @@ jobs: docker-compose logs - name: "Sleep for 5s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 5s @@ -86,7 +86,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] get runner ip" run: | @@ -116,7 +116,7 @@ jobs: docker-compose logs - name: "Sleep for 5s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 5s @@ -160,7 +160,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] get runner ip" run: | @@ -190,7 +190,7 @@ jobs: docker-compose logs - name: "Sleep for 5s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 5s @@ -234,7 +234,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] get runner ip" run: | @@ -266,7 +266,7 @@ jobs: docker-compose logs - name: "Sleep for 5s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 5s diff --git a/.github/workflows/ipv6-test.yml b/.github/workflows/ipv6-test.yml index 23019679..7e79d023 100644 --- a/.github/workflows/ipv6-test.yml +++ b/.github/workflows/ipv6-test.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" working-directory: examples/Docker/ run: | @@ -61,7 +61,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (nginx_wsgi)" working-directory: examples/Docker/ run: | @@ -110,7 +110,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (apache2_django)" working-directory: examples/Docker/ run: | @@ -160,7 +160,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (nginx_django)" working-directory: examples/Docker/ run: | diff --git a/.github/workflows/lego-application-test.yml b/.github/workflows/lego-application-test.yml index 5c387b3f..797cc4a6 100644 --- a/.github/workflows/lego-application-test.yml +++ b/.github/workflows/lego-application-test.yml @@ -19,7 +19,7 @@ jobs: keylength: [rsa2048, rsa4096, ec256] steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" working-directory: examples/Docker/ @@ -100,7 +100,7 @@ jobs: keylength: [rsa2048, rsa4096, ec256] steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (apache2_django)" working-directory: examples/Docker/ @@ -112,7 +112,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -188,7 +188,7 @@ jobs: keylength: [rsa2048, rsa4096, ec256] steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (nginx_django)" working-directory: examples/Docker/ @@ -200,7 +200,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -275,7 +275,7 @@ jobs: keylength: [rsa2048, rsa4096, ec256] steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (nginx_django)" working-directory: examples/Docker/ @@ -288,7 +288,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s diff --git a/.github/workflows/manual-install-test.yml b/.github/workflows/manual-install-test.yml index d38343dd..87cdc8c7 100644 --- a/.github/workflows/manual-install-test.yml +++ b/.github/workflows/manual-install-test.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] get runner ip" run: | @@ -76,7 +76,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] get runner ip" run: | @@ -137,7 +137,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] get runner ip" run: | @@ -199,7 +199,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Branch name run: echo running on branch ${GITHUB_REF##*/} @@ -279,7 +279,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] get runner ip" run: | @@ -373,7 +373,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] get runner ip" run: | diff --git a/.github/workflows/proxy-test.yml b/.github/workflows/proxy-test.yml index 3adb0242..40706549 100644 --- a/.github/workflows/proxy-test.yml +++ b/.github/workflows/proxy-test.yml @@ -17,7 +17,7 @@ jobs: steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] create network" run: | @@ -29,7 +29,7 @@ jobs: docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -267,7 +267,7 @@ jobs: steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Retrieve Version from version.py run: | @@ -311,7 +311,7 @@ jobs: docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s diff --git a/.github/workflows/push_images_to_dockerhub.yml b/.github/workflows/push_images_to_dockerhub.yml index 7b3b9caa..e2d00889 100644 --- a/.github/workflows/push_images_to_dockerhub.yml +++ b/.github/workflows/push_images_to_dockerhub.yml @@ -11,7 +11,7 @@ jobs: #update_docker_hub_description: # runs-on: ubuntu-latest # steps: - # - uses: actions/checkout@v3 + # - uses: actions/checkout@v4 # - name: Docker Hub Description # uses: peter-evans/dockerhub-description@v2 # env: @@ -32,7 +32,7 @@ jobs: id: acme2certifier_ver # The step ID to refer to later. - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "Retrieve Version from version.py" run: | @@ -103,7 +103,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] setup openssl ca_handler" run: | @@ -155,7 +155,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] setup openssl ca_handler and django config" run: | @@ -172,7 +172,7 @@ jobs: docker run -d -p 80:80 --rm -id --network acme --name=acme-srv -v "$(pwd)/examples/Docker/data":/var/www/acme2certifier/volume/ grindsa/acme2certifier:apache2-django - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 5s @@ -218,7 +218,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] setup openssl ca_handler" run: | @@ -270,7 +270,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] setup openssl ca_handler and django config" run: | diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index 8cd772bc..06357bb7 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -17,7 +17,7 @@ jobs: python_version: ['3.x', '3.12', '3.11', '3.10', '3.9', '3.8'] name: Python Unittest (${{ matrix.python_version }}) steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python_version }} uses: actions/setup-python@v4 with: @@ -41,7 +41,7 @@ jobs: python_version: [3.x, 3.8] name: Pylint test (${{ matrix.python_version }}) steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python_version }} uses: actions/setup-python@v4 with: diff --git a/.github/workflows/test_headerinfo.yml b/.github/workflows/test_headerinfo.yml index dc16baba..d0ae6a23 100644 --- a/.github/workflows/test_headerinfo.yml +++ b/.github/workflows/test_headerinfo.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "Build docker-compose (apache2_wsgi)" working-directory: examples/Docker/ @@ -92,7 +92,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "Build docker-compose (apache2_wsgi)" working-directory: examples/Docker/ @@ -138,7 +138,7 @@ jobs: XCA_DB_NAME: ${{ secrets.XCA_DB_NAME }} - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -177,7 +177,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "Build docker-compose (apache2_wsgi)" working-directory: examples/Docker/ @@ -222,7 +222,7 @@ jobs: XCA_DB_NAME: ${{ secrets.XCA_DB_NAME }} - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -261,7 +261,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "Build docker-compose (apache2_wsgi)" working-directory: examples/Docker/ @@ -274,7 +274,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -313,7 +313,7 @@ jobs: XCA_DB_NAME: ${{ secrets.XCA_DB_NAME }} - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -352,7 +352,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Retrieve Version from version.py run: | diff --git a/.github/workflows/tnauth-test.yml b/.github/workflows/tnauth-test.yml index 7873ef9a..b56aba37 100644 --- a/.github/workflows/tnauth-test.yml +++ b/.github/workflows/tnauth-test.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" working-directory: examples/Docker/ @@ -75,7 +75,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Retrieve Version from version.py run: | diff --git a/.github/workflows/traffic-application-test.yml b/.github/workflows/traffic-application-test.yml index 6219aea1..d199c95f 100644 --- a/.github/workflows/traffic-application-test.yml +++ b/.github/workflows/traffic-application-test.yml @@ -19,7 +19,7 @@ jobs: challenge_type: [tlschallenge=true, httpchallenge.entrypoint=web] steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "get runner information" run: | @@ -60,7 +60,7 @@ jobs: docker-compose up -d - name: "Sleep for 30s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 30s diff --git a/.github/workflows/upgrade_tests..yml b/.github/workflows/upgrade_tests..yml index f6ba895a..9d1209ab 100644 --- a/.github/workflows/upgrade_tests..yml +++ b/.github/workflows/upgrade_tests..yml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] prepare environment" working-directory: examples/Docker/ @@ -39,7 +39,7 @@ jobs: docker logs acme-srv - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 5s @@ -86,7 +86,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 5s @@ -141,7 +141,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] prepare environment" working-directory: examples/Docker/ @@ -166,7 +166,7 @@ jobs: docker logs acme-srv - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 5s @@ -213,7 +213,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 5s @@ -269,7 +269,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] prepare environment" working-directory: examples/Docker/ @@ -284,7 +284,7 @@ jobs: docker run --name mariadbsrv --network acme -e MARIADB_ROOT_PASSWORD=foobar -d mariadb - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -315,7 +315,7 @@ jobs: docker logs acme-srv - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 5s @@ -362,7 +362,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 5s @@ -417,7 +417,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] prepare environment" working-directory: examples/Docker/ @@ -432,7 +432,7 @@ jobs: docker run --name mariadbsrv --network acme -e MARIADB_ROOT_PASSWORD=foobar -d mariadb - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -463,7 +463,7 @@ jobs: docker logs acme-srv - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 5s @@ -511,7 +511,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 5s @@ -566,7 +566,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Retrieve Version from version.py run: | @@ -677,7 +677,7 @@ jobs: sudo rm -rf $PWD/acme-sh/* - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -729,7 +729,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Retrieve Version from version.py run: | @@ -779,7 +779,7 @@ jobs: docker run --name mariadbsrv --network acme -e MARIADB_ROOT_PASSWORD=foobar -d mariadb - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -860,7 +860,7 @@ jobs: sudo rm -rf $PWD/acme-sh/* - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -912,7 +912,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Retrieve Version from version.py run: | @@ -1025,7 +1025,7 @@ jobs: sudo rm -rf $PWD/acme-sh/* - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -1077,7 +1077,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Retrieve Version from version.py run: | @@ -1134,7 +1134,7 @@ jobs: docker run --name postgresdbsrv --network acme -e POSTGRES_PASSWORD=foobar -d postgres - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -1144,7 +1144,7 @@ jobs: docker run -v "$(pwd)/data/pgsql/a2c.psql":/tmp/a2c.psql -v "$(pwd)/data/pgsql/pgpass:/root/.pgpass" --rm --network acme postgres psql -U postgres -h postgresdbsrv -f /tmp/a2c.psql - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s @@ -1218,7 +1218,7 @@ jobs: sudo rm -rf $PWD/acme-sh/* - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 10s diff --git a/.github/workflows/winacme-application-test.yml b/.github/workflows/winacme-application-test.yml index 3d369ddb..ce27e59d 100644 --- a/.github/workflows/winacme-application-test.yml +++ b/.github/workflows/winacme-application-test.yml @@ -16,7 +16,7 @@ jobs: steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] get RunnerIP" run: | @@ -63,7 +63,7 @@ jobs: run: | Start-Process powershell {python .\manage.py runserver 0.0.0.0:8080 3>&1 2>&1 > volume\redirection.log} - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 5s @@ -90,7 +90,7 @@ jobs: Start-Process powershell {python .\manage.py runsslserver 0.0.0.0:443 --certificate acme2certifier/acme2certifier_cert.pem --key acme2certifier/acme2certifier_key.pem 3>&1 2>&1 > volume\redirection_ssl.log} - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v1 + uses: juliangruber/sleep-action@v2 with: time: 5s diff --git a/.github/workflows/wsgi_handler-test.yml b/.github/workflows/wsgi_handler-test.yml index f0af73b5..32a1665d 100644 --- a/.github/workflows/wsgi_handler-test.yml +++ b/.github/workflows/wsgi_handler-test.yml @@ -16,7 +16,7 @@ jobs: fail-fast: false steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" working-directory: examples/Docker/ @@ -86,7 +86,7 @@ jobs: fail-fast: false steps: - name: "checkout GIT" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "[ PREPARE ] Build docker-compose (nginx_wsgi)" working-directory: examples/Docker/ From 93cbf70c6627aa20f6b0856311f045fa71018b03 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 27 Jan 2024 17:59:22 +0100 Subject: [PATCH 030/460] [fix] slee-action version --- .../workflows/acme_sh-application-test.yml | 6 +- .github/workflows/ari-test.yml | 6 +- .github/workflows/ca_handler_tests_acme.yml | 8 +-- .github/workflows/ca_handler_tests_cmp.yml | 8 +-- .github/workflows/ca_handler_tests_ejbca.yml | 8 +-- .github/workflows/ca_handler_tests_msca.yml | 8 +-- .../workflows/ca_handler_tests_openxpki.yml | 12 ++-- .github/workflows/caddy-application-test.yml | 16 ++--- .../workflows/certbot-application-test.yml | 8 +-- .../certmanager-application-test.yml | 58 +++++++++---------- .github/workflows/container-tests.yml | 14 ++--- .github/workflows/django_tests..yml | 22 +++---- .github/workflows/ip-address-tests.yml | 8 +-- .github/workflows/lego-application-test.yml | 6 +- .github/workflows/proxy-test.yml | 4 +- .../workflows/push_images_to_dockerhub.yml | 2 +- .github/workflows/test_headerinfo.yml | 8 +-- .../workflows/traffic-application-test.yml | 2 +- .github/workflows/upgrade_tests..yml | 34 +++++------ .../workflows/winacme-application-test.yml | 4 +- 20 files changed, 121 insertions(+), 121 deletions(-) diff --git a/.github/workflows/acme_sh-application-test.yml b/.github/workflows/acme_sh-application-test.yml index b55972a5..921cddc9 100644 --- a/.github/workflows/acme_sh-application-test.yml +++ b/.github/workflows/acme_sh-application-test.yml @@ -141,7 +141,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -258,7 +258,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -375,7 +375,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s diff --git a/.github/workflows/ari-test.yml b/.github/workflows/ari-test.yml index f30fa309..3178fe85 100644 --- a/.github/workflows/ari-test.yml +++ b/.github/workflows/ari-test.yml @@ -91,7 +91,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -162,7 +162,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -233,7 +233,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s diff --git a/.github/workflows/ca_handler_tests_acme.yml b/.github/workflows/ca_handler_tests_acme.yml index 70e31792..da3b6211 100644 --- a/.github/workflows/ca_handler_tests_acme.yml +++ b/.github/workflows/ca_handler_tests_acme.yml @@ -34,7 +34,7 @@ jobs: docker run -d -p 80:80 --rm -id --network acme --name=acme-le-sim -v "$(pwd)/examples/Docker/data-le":/var/www/acme2certifier/volume/ grindsa/acme2certifier:apache2-wsgi - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -115,7 +115,7 @@ jobs: docker run -d -p 80:80 --rm -id --network acme --name=acme-le-sim -v "$(pwd)/examples/Docker/data-le":/var/www/acme2certifier/volume/ grindsa/acme2certifier:devel - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -208,7 +208,7 @@ jobs: docker run -d -p 80:80 --rm -id --network acme --name=acme-le-sim -v "$(pwd)/examples/Docker/data-le":/var/www/acme2certifier/volume/ grindsa/acme2certifier:apache2-wsgi - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -314,7 +314,7 @@ jobs: docker run -d -p 80:80 --rm -id --network acme --name=acme-le-sim -v "$(pwd)/examples/Docker/data-le":/var/www/acme2certifier/volume/ grindsa/acme2certifier:devel - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s diff --git a/.github/workflows/ca_handler_tests_cmp.yml b/.github/workflows/ca_handler_tests_cmp.yml index 3b1a9354..ca5885be 100644 --- a/.github/workflows/ca_handler_tests_cmp.yml +++ b/.github/workflows/ca_handler_tests_cmp.yml @@ -103,7 +103,7 @@ jobs: CMP_HOST: ${{ secrets.CMP_HOST }} - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 5s @@ -226,7 +226,7 @@ jobs: CMP_HOST: ${{ secrets.CMP_HOST }} - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 5s @@ -373,7 +373,7 @@ jobs: CMP_HOST: ${{ secrets.CMP_HOST }} - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 5s @@ -522,7 +522,7 @@ jobs: CMP_HOST: ${{ secrets.CMP_HOST }} - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 5s diff --git a/.github/workflows/ca_handler_tests_ejbca.yml b/.github/workflows/ca_handler_tests_ejbca.yml index d7900f42..46def7f4 100644 --- a/.github/workflows/ca_handler_tests_ejbca.yml +++ b/.github/workflows/ca_handler_tests_ejbca.yml @@ -43,7 +43,7 @@ jobs: docker run -id --rm -p 80:8080 -p 443:8443 -e TLS_SETUP_ENABLED=true -v $(pwd)/examples/ejbca:/tmp/data -v $(pwd)/examples/Docker/data:/tmp/store --name "ejbca" -h ejbca keyfactor/ejbca-ce - name: "Sleep for 180s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 180s @@ -75,7 +75,7 @@ jobs: CAID: ${{ env.CAID }} - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -220,7 +220,7 @@ jobs: docker run -id --rm -p 80:8080 -p 443:8443 -e TLS_SETUP_ENABLED=true -v $(pwd)/examples/ejbca:/tmp/data -v $(pwd)/data:/tmp/store --name "ejbca" -h ejbca keyfactor/ejbca-ce - name: "Sleep for 180s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 180s @@ -253,7 +253,7 @@ jobs: CAID: ${{ env.CAID }} - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s diff --git a/.github/workflows/ca_handler_tests_msca.yml b/.github/workflows/ca_handler_tests_msca.yml index f0fae3e1..3ce7fe35 100644 --- a/.github/workflows/ca_handler_tests_msca.yml +++ b/.github/workflows/ca_handler_tests_msca.yml @@ -97,7 +97,7 @@ jobs: WCCE_HOST: ${{ secrets.WCCE_HOST }} - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 5s @@ -256,7 +256,7 @@ jobs: WCCE_HOST: ${{ secrets.WCCE_HOST }} - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 5s @@ -511,7 +511,7 @@ jobs: WCCE_HOST: ${{ secrets.WCCE_HOST }} - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 5s @@ -703,7 +703,7 @@ jobs: WCCE_HOST: ${{ secrets.WCCE_HOST }} - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 5s diff --git a/.github/workflows/ca_handler_tests_openxpki.yml b/.github/workflows/ca_handler_tests_openxpki.yml index d8d426f4..3cb2ed46 100644 --- a/.github/workflows/ca_handler_tests_openxpki.yml +++ b/.github/workflows/ca_handler_tests_openxpki.yml @@ -58,7 +58,7 @@ jobs: docker-compose up & - name: "Sleep for 60s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 60s @@ -70,7 +70,7 @@ jobs: docker start openxpki-docker_openxpki-server_1 - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -82,7 +82,7 @@ jobs: docker exec -id openxpki-docker_openxpki-client_1 apt-get install -y libjson-pp-perl - name: "Sleep for 45s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 45s @@ -385,7 +385,7 @@ jobs: docker-compose up & - name: "Sleep for 60s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 60s @@ -397,7 +397,7 @@ jobs: docker start openxpki-docker_openxpki-server_1 - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -409,7 +409,7 @@ jobs: docker exec -id openxpki-docker_openxpki-client_1 apt-get install -y libjson-pp-perl - name: "Sleep for 45s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 45s diff --git a/.github/workflows/caddy-application-test.yml b/.github/workflows/caddy-application-test.yml index ab8e0fdf..55a89dc2 100644 --- a/.github/workflows/caddy-application-test.yml +++ b/.github/workflows/caddy-application-test.yml @@ -40,7 +40,7 @@ jobs: docker-compose logs - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -62,7 +62,7 @@ jobs: docker run -d --rm ${{ matrix.ports }} --network acme -v $PWD/caddy/Caddyfile:/etc/caddy/Caddyfile -v$PWD/caddy/acme2certifier_cabundle.pem:/tmp/acme2certifier_cabundle.pem -v $(pwd)/caddy/config:/config -v $(pwd)/caddy/data:/data --name=caddy caddy:2 - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -123,7 +123,7 @@ jobs: docker-compose logs - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -145,7 +145,7 @@ jobs: docker run -d --rm ${{ matrix.ports }} --network acme -v $PWD/caddy/Caddyfile:/etc/caddy/Caddyfile -v$PWD/caddy/acme2certifier_cabundle.pem:/tmp/acme2certifier_cabundle.pem -v $(pwd)/caddy/config:/config -v $(pwd)/caddy/data:/data --name=caddy caddy:2 - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -206,7 +206,7 @@ jobs: docker-compose logs - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -228,7 +228,7 @@ jobs: docker run -d --rm ${{ matrix.ports }} --network acme -v $PWD/caddy/Caddyfile:/etc/caddy/Caddyfile -v$PWD/caddy/acme2certifier_cabundle.pem:/tmp/acme2certifier_cabundle.pem -v $(pwd)/caddy/config:/config -v $(pwd)/caddy/data:/data --name=caddy caddy:2 - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -290,7 +290,7 @@ jobs: docker-compose logs - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -311,7 +311,7 @@ jobs: docker run -d --rm ${{ matrix.ports }} --network acme -v $PWD/caddy/Caddyfile:/etc/caddy/Caddyfile -v$PWD/caddy/acme2certifier_cabundle.pem:/tmp/acme2certifier_cabundle.pem -v $(pwd)/caddy/config:/config -v $(pwd)/caddy/data:/data --name=caddy caddy:2 - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s diff --git a/.github/workflows/certbot-application-test.yml b/.github/workflows/certbot-application-test.yml index bc17c1fb..35cd79ba 100644 --- a/.github/workflows/certbot-application-test.yml +++ b/.github/workflows/certbot-application-test.yml @@ -30,7 +30,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -121,7 +121,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -213,7 +213,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -305,7 +305,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s diff --git a/.github/workflows/certmanager-application-test.yml b/.github/workflows/certmanager-application-test.yml index 6638a695..d446af54 100644 --- a/.github/workflows/certmanager-application-test.yml +++ b/.github/workflows/certmanager-application-test.yml @@ -48,7 +48,7 @@ jobs: run: | sudo microk8s.kubectl apply -f data/dnsmasq.yml - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -98,7 +98,7 @@ jobs: sudo microk8s.kubectl apply -f data/k8s-acme-srv.yml sudo microk8s.kubectl get pods -n cert-manager-acme - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -119,7 +119,7 @@ jobs: sudo microk8s.kubectl apply -f data/k8s-cert-mgr-http-01.yml - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 20s @@ -128,7 +128,7 @@ jobs: sudo microk8s.kubectl describe ClusterIssuer acme2certifier sudo microk8s.kubectl describe challenge - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 20s @@ -137,7 +137,7 @@ jobs: sudo microk8s.kubectl describe ClusterIssuer acme2certifier sudo microk8s.kubectl describe challenge - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 20s @@ -203,7 +203,7 @@ jobs: run: | sudo microk8s.kubectl apply -f data/dnsmasq.yml - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -255,7 +255,7 @@ jobs: sudo microk8s.kubectl get pods -n cert-manager-acme - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -276,7 +276,7 @@ jobs: sudo microk8s.kubectl apply -f data/k8s-cert-mgr-http-01.yml - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 20s @@ -285,7 +285,7 @@ jobs: sudo microk8s.kubectl describe ClusterIssuer acme2certifier sudo microk8s.kubectl describe challenge - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 20s @@ -294,7 +294,7 @@ jobs: sudo microk8s.kubectl describe ClusterIssuer acme2certifier sudo microk8s.kubectl describe challenge - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 20s @@ -360,7 +360,7 @@ jobs: sudo microk8s.kubectl apply -f data/dnsmasq.yml - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -410,7 +410,7 @@ jobs: sudo microk8s.kubectl apply -f data/k8s-acme-srv.yml sudo microk8s.kubectl get pods -n cert-manager-acme - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -430,7 +430,7 @@ jobs: sudo sed -i "s/ACME_SRV/${{ env.ACME_IP }}/g" data/k8s-cert-mgr-http-01.yml sudo microk8s.kubectl apply -f data/k8s-cert-mgr-http-01.yml - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 20s @@ -439,7 +439,7 @@ jobs: sudo microk8s.kubectl describe ClusterIssuer acme2certifier sudo microk8s.kubectl describe challenge - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 20s @@ -448,7 +448,7 @@ jobs: sudo microk8s.kubectl describe ClusterIssuer acme2certifier sudo microk8s.kubectl describe challenge - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 20s @@ -514,7 +514,7 @@ jobs: sudo microk8s.kubectl apply -f data/dnsmasq.yml - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -568,7 +568,7 @@ jobs: sudo microk8s.kubectl get pods -n cert-manager-acme - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -589,7 +589,7 @@ jobs: sudo microk8s.kubectl apply -f data/k8s-cert-mgr-http-01.yml - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 20s @@ -599,7 +599,7 @@ jobs: sudo microk8s.kubectl describe challenge - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 20s @@ -608,7 +608,7 @@ jobs: sudo microk8s.kubectl describe ClusterIssuer acme2certifier sudo microk8s.kubectl describe challenge - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 20s @@ -695,7 +695,7 @@ jobs: sudo microk8s.kubectl get pods -n cert-manager-acme - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -721,7 +721,7 @@ jobs: sudo microk8s.kubectl apply -f data/k8s-cert-mgr-dns-01.yml - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 20s @@ -731,7 +731,7 @@ jobs: sudo microk8s.kubectl describe challenge -n cert-manager-acme - name: "[ WAIT ] Sleep for 30s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 60s @@ -741,7 +741,7 @@ jobs: sudo microk8s.kubectl describe challenge -n cert-manager-acme - name: "[ WAIT ] Sleep for 60s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 60s @@ -751,7 +751,7 @@ jobs: sudo microk8s.kubectl describe challenge -n cert-manager-acme - name: "[ WAIT ] Sleep for 60s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 60s @@ -772,7 +772,7 @@ jobs: sudo microk8s.kubectl apply -f data/k8s-cert-mgr-dns-01.yml - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 20s @@ -781,7 +781,7 @@ jobs: sudo microk8s.kubectl describe issuer acme2certifier -n cert-manager-acme sudo microk8s.kubectl describe challenge -n cert-manager-acme - name: "[ WAIT ] Sleep for 30s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 60s @@ -791,7 +791,7 @@ jobs: sudo microk8s.kubectl describe challenge -n cert-manager-acme - name: "[ WAIT ] Sleep for 60s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 60s @@ -801,7 +801,7 @@ jobs: sudo microk8s.kubectl describe challenge -n cert-manager-acme - name: "[ WAIT ] Sleep for 60s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 60s diff --git a/.github/workflows/container-tests.yml b/.github/workflows/container-tests.yml index 2e2fcfd9..0c898118 100644 --- a/.github/workflows/container-tests.yml +++ b/.github/workflows/container-tests.yml @@ -52,7 +52,7 @@ jobs: head -n 13 data/ca_handler.py docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s - name: "Test if http://acme-srv/directory is accessable" @@ -100,7 +100,7 @@ jobs: docker-compose restart docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s - name: "Test if http://acme-srv/directory is accessable" @@ -124,7 +124,7 @@ jobs: head -n 13 data/ca_handler.py docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s - name: "Test if http://acme-srv/directory is accessable" @@ -172,7 +172,7 @@ jobs: docker-compose restart docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s - name: "Test if http://acme-srv/directory is accessable" @@ -196,7 +196,7 @@ jobs: head -n 13 data/ca_handler.py docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s - name: "Test if http://acme-srv/directory is accessable" @@ -245,7 +245,7 @@ jobs: docker-compose restart docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s - name: "Test if http://acme-srv/directory is accessable" @@ -269,7 +269,7 @@ jobs: head -n 13 data/ca_handler.py docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s - name: "Test if http://acme-srv/directory is accessable" diff --git a/.github/workflows/django_tests..yml b/.github/workflows/django_tests..yml index 12e9c3c9..0fb675b6 100644 --- a/.github/workflows/django_tests..yml +++ b/.github/workflows/django_tests..yml @@ -34,7 +34,7 @@ jobs: docker run --name mariadbsrv --network acme -e MARIADB_ROOT_PASSWORD=foobar -d mariadb - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -140,7 +140,7 @@ jobs: docker run --name postgresdbsrv --network acme -e POSTGRES_PASSWORD=foobar -d postgres - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -149,7 +149,7 @@ jobs: run: | docker run -v "$(pwd)/data/pgsql/a2c.psql":/tmp/a2c.psql -v "$(pwd)/data/pgsql/pgpass:/root/.pgpass" --rm --network acme postgres psql -U postgres -h postgresdbsrv -f /tmp/a2c.psql - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -245,7 +245,7 @@ jobs: docker run --name mariadbsrv --network acme -e MARIADB_ROOT_PASSWORD=foobar -d mariadb - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -274,7 +274,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -358,7 +358,7 @@ jobs: docker run --name postgresdbsrv --network acme -e POSTGRES_PASSWORD=foobar -d postgres - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -367,7 +367,7 @@ jobs: run: | docker run -v "$(pwd)/data/pgsql/a2c.psql":/tmp/a2c.psql -v "$(pwd)/data/pgsql/pgpass:/root/.pgpass" --rm --network acme postgres psql -U postgres -h postgresdbsrv -f /tmp/a2c.psql - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -390,7 +390,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -621,7 +621,7 @@ jobs: # docker run --name mariadbsrv --network acme -e MARIADB_ROOT_PASSWORD=foobar -d mariadb - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -768,7 +768,7 @@ jobs: docker run --name postgresdbsrv -v /tmp/pgsql/data:/var/lib/postgresql/data --network acme -e POSTGRES_PASSWORD=foobar -d postgres - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -777,7 +777,7 @@ jobs: docker run -v /tmp/pgsql/a2c.psql:/tmp/a2c.psql -v /tmp/pgsql/pgpass:/root/.pgpass --rm --network acme postgres psql -U postgres -h postgresdbsrv -f /tmp/a2c.psql - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s diff --git a/.github/workflows/ip-address-tests.yml b/.github/workflows/ip-address-tests.yml index 5a73be33..8607be6f 100644 --- a/.github/workflows/ip-address-tests.yml +++ b/.github/workflows/ip-address-tests.yml @@ -42,7 +42,7 @@ jobs: docker-compose logs - name: "Sleep for 5s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 5s @@ -116,7 +116,7 @@ jobs: docker-compose logs - name: "Sleep for 5s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 5s @@ -190,7 +190,7 @@ jobs: docker-compose logs - name: "Sleep for 5s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 5s @@ -266,7 +266,7 @@ jobs: docker-compose logs - name: "Sleep for 5s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 5s diff --git a/.github/workflows/lego-application-test.yml b/.github/workflows/lego-application-test.yml index 797cc4a6..c47cdd73 100644 --- a/.github/workflows/lego-application-test.yml +++ b/.github/workflows/lego-application-test.yml @@ -112,7 +112,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -200,7 +200,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -288,7 +288,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s diff --git a/.github/workflows/proxy-test.yml b/.github/workflows/proxy-test.yml index 40706549..e285301b 100644 --- a/.github/workflows/proxy-test.yml +++ b/.github/workflows/proxy-test.yml @@ -29,7 +29,7 @@ jobs: docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -311,7 +311,7 @@ jobs: docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s diff --git a/.github/workflows/push_images_to_dockerhub.yml b/.github/workflows/push_images_to_dockerhub.yml index e2d00889..988eaf86 100644 --- a/.github/workflows/push_images_to_dockerhub.yml +++ b/.github/workflows/push_images_to_dockerhub.yml @@ -172,7 +172,7 @@ jobs: docker run -d -p 80:80 --rm -id --network acme --name=acme-srv -v "$(pwd)/examples/Docker/data":/var/www/acme2certifier/volume/ grindsa/acme2certifier:apache2-django - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 5s diff --git a/.github/workflows/test_headerinfo.yml b/.github/workflows/test_headerinfo.yml index d0ae6a23..5ba9edbf 100644 --- a/.github/workflows/test_headerinfo.yml +++ b/.github/workflows/test_headerinfo.yml @@ -138,7 +138,7 @@ jobs: XCA_DB_NAME: ${{ secrets.XCA_DB_NAME }} - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -222,7 +222,7 @@ jobs: XCA_DB_NAME: ${{ secrets.XCA_DB_NAME }} - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -274,7 +274,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -313,7 +313,7 @@ jobs: XCA_DB_NAME: ${{ secrets.XCA_DB_NAME }} - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s diff --git a/.github/workflows/traffic-application-test.yml b/.github/workflows/traffic-application-test.yml index d199c95f..35be2580 100644 --- a/.github/workflows/traffic-application-test.yml +++ b/.github/workflows/traffic-application-test.yml @@ -60,7 +60,7 @@ jobs: docker-compose up -d - name: "Sleep for 30s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 30s diff --git a/.github/workflows/upgrade_tests..yml b/.github/workflows/upgrade_tests..yml index 9d1209ab..5188e76d 100644 --- a/.github/workflows/upgrade_tests..yml +++ b/.github/workflows/upgrade_tests..yml @@ -39,7 +39,7 @@ jobs: docker logs acme-srv - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 5s @@ -86,7 +86,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 5s @@ -166,7 +166,7 @@ jobs: docker logs acme-srv - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 5s @@ -213,7 +213,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 5s @@ -284,7 +284,7 @@ jobs: docker run --name mariadbsrv --network acme -e MARIADB_ROOT_PASSWORD=foobar -d mariadb - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -315,7 +315,7 @@ jobs: docker logs acme-srv - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 5s @@ -362,7 +362,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 5s @@ -432,7 +432,7 @@ jobs: docker run --name mariadbsrv --network acme -e MARIADB_ROOT_PASSWORD=foobar -d mariadb - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -463,7 +463,7 @@ jobs: docker logs acme-srv - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 5s @@ -511,7 +511,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 5s @@ -677,7 +677,7 @@ jobs: sudo rm -rf $PWD/acme-sh/* - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -779,7 +779,7 @@ jobs: docker run --name mariadbsrv --network acme -e MARIADB_ROOT_PASSWORD=foobar -d mariadb - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -860,7 +860,7 @@ jobs: sudo rm -rf $PWD/acme-sh/* - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -1025,7 +1025,7 @@ jobs: sudo rm -rf $PWD/acme-sh/* - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -1134,7 +1134,7 @@ jobs: docker run --name postgresdbsrv --network acme -e POSTGRES_PASSWORD=foobar -d postgres - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -1144,7 +1144,7 @@ jobs: docker run -v "$(pwd)/data/pgsql/a2c.psql":/tmp/a2c.psql -v "$(pwd)/data/pgsql/pgpass:/root/.pgpass" --rm --network acme postgres psql -U postgres -h postgresdbsrv -f /tmp/a2c.psql - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s @@ -1218,7 +1218,7 @@ jobs: sudo rm -rf $PWD/acme-sh/* - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 10s diff --git a/.github/workflows/winacme-application-test.yml b/.github/workflows/winacme-application-test.yml index ce27e59d..808c1683 100644 --- a/.github/workflows/winacme-application-test.yml +++ b/.github/workflows/winacme-application-test.yml @@ -63,7 +63,7 @@ jobs: run: | Start-Process powershell {python .\manage.py runserver 0.0.0.0:8080 3>&1 2>&1 > volume\redirection.log} - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 5s @@ -90,7 +90,7 @@ jobs: Start-Process powershell {python .\manage.py runsslserver 0.0.0.0:443 --certificate acme2certifier/acme2certifier_cert.pem --key acme2certifier/acme2certifier_key.pem 3>&1 2>&1 > volume\redirection_ssl.log} - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v2 + uses: juliangruber/sleep-action@v2.0.0 with: time: 5s From bf97b856d407b6f221468021d3f108d15269f86d Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 28 Jan 2024 07:40:41 +0100 Subject: [PATCH 031/460] [wf] use grindsa/sleep-action --- .../workflows/acme_sh-application-test.yml | 6 +- .github/workflows/ari-test.yml | 6 +- .github/workflows/ca_handler_tests_acme.yml | 8 +-- .github/workflows/ca_handler_tests_cmp.yml | 8 +-- .github/workflows/ca_handler_tests_ejbca.yml | 8 +-- .github/workflows/ca_handler_tests_msca.yml | 8 +-- .../workflows/ca_handler_tests_openxpki.yml | 12 ++-- .github/workflows/caddy-application-test.yml | 16 ++--- .../workflows/certbot-application-test.yml | 8 +-- .../certmanager-application-test.yml | 58 +++++++++---------- .github/workflows/container-tests.yml | 14 ++--- .github/workflows/django_tests..yml | 22 +++---- .github/workflows/ip-address-tests.yml | 8 +-- .github/workflows/lego-application-test.yml | 6 +- .github/workflows/proxy-test.yml | 4 +- .../workflows/push_images_to_dockerhub.yml | 2 +- .github/workflows/test_headerinfo.yml | 8 +-- .../workflows/traffic-application-test.yml | 2 +- .github/workflows/upgrade_tests..yml | 34 +++++------ .../workflows/winacme-application-test.yml | 4 +- 20 files changed, 121 insertions(+), 121 deletions(-) diff --git a/.github/workflows/acme_sh-application-test.yml b/.github/workflows/acme_sh-application-test.yml index 921cddc9..66a53c51 100644 --- a/.github/workflows/acme_sh-application-test.yml +++ b/.github/workflows/acme_sh-application-test.yml @@ -141,7 +141,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -258,7 +258,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -375,7 +375,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s diff --git a/.github/workflows/ari-test.yml b/.github/workflows/ari-test.yml index 3178fe85..7096cf52 100644 --- a/.github/workflows/ari-test.yml +++ b/.github/workflows/ari-test.yml @@ -91,7 +91,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -162,7 +162,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -233,7 +233,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s diff --git a/.github/workflows/ca_handler_tests_acme.yml b/.github/workflows/ca_handler_tests_acme.yml index da3b6211..02c2900d 100644 --- a/.github/workflows/ca_handler_tests_acme.yml +++ b/.github/workflows/ca_handler_tests_acme.yml @@ -34,7 +34,7 @@ jobs: docker run -d -p 80:80 --rm -id --network acme --name=acme-le-sim -v "$(pwd)/examples/Docker/data-le":/var/www/acme2certifier/volume/ grindsa/acme2certifier:apache2-wsgi - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -115,7 +115,7 @@ jobs: docker run -d -p 80:80 --rm -id --network acme --name=acme-le-sim -v "$(pwd)/examples/Docker/data-le":/var/www/acme2certifier/volume/ grindsa/acme2certifier:devel - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -208,7 +208,7 @@ jobs: docker run -d -p 80:80 --rm -id --network acme --name=acme-le-sim -v "$(pwd)/examples/Docker/data-le":/var/www/acme2certifier/volume/ grindsa/acme2certifier:apache2-wsgi - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -314,7 +314,7 @@ jobs: docker run -d -p 80:80 --rm -id --network acme --name=acme-le-sim -v "$(pwd)/examples/Docker/data-le":/var/www/acme2certifier/volume/ grindsa/acme2certifier:devel - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s diff --git a/.github/workflows/ca_handler_tests_cmp.yml b/.github/workflows/ca_handler_tests_cmp.yml index ca5885be..c83ee29a 100644 --- a/.github/workflows/ca_handler_tests_cmp.yml +++ b/.github/workflows/ca_handler_tests_cmp.yml @@ -103,7 +103,7 @@ jobs: CMP_HOST: ${{ secrets.CMP_HOST }} - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 5s @@ -226,7 +226,7 @@ jobs: CMP_HOST: ${{ secrets.CMP_HOST }} - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 5s @@ -373,7 +373,7 @@ jobs: CMP_HOST: ${{ secrets.CMP_HOST }} - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 5s @@ -522,7 +522,7 @@ jobs: CMP_HOST: ${{ secrets.CMP_HOST }} - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 5s diff --git a/.github/workflows/ca_handler_tests_ejbca.yml b/.github/workflows/ca_handler_tests_ejbca.yml index 46def7f4..ba6300f3 100644 --- a/.github/workflows/ca_handler_tests_ejbca.yml +++ b/.github/workflows/ca_handler_tests_ejbca.yml @@ -43,7 +43,7 @@ jobs: docker run -id --rm -p 80:8080 -p 443:8443 -e TLS_SETUP_ENABLED=true -v $(pwd)/examples/ejbca:/tmp/data -v $(pwd)/examples/Docker/data:/tmp/store --name "ejbca" -h ejbca keyfactor/ejbca-ce - name: "Sleep for 180s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 180s @@ -75,7 +75,7 @@ jobs: CAID: ${{ env.CAID }} - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -220,7 +220,7 @@ jobs: docker run -id --rm -p 80:8080 -p 443:8443 -e TLS_SETUP_ENABLED=true -v $(pwd)/examples/ejbca:/tmp/data -v $(pwd)/data:/tmp/store --name "ejbca" -h ejbca keyfactor/ejbca-ce - name: "Sleep for 180s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 180s @@ -253,7 +253,7 @@ jobs: CAID: ${{ env.CAID }} - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s diff --git a/.github/workflows/ca_handler_tests_msca.yml b/.github/workflows/ca_handler_tests_msca.yml index 3ce7fe35..1bd7b6e0 100644 --- a/.github/workflows/ca_handler_tests_msca.yml +++ b/.github/workflows/ca_handler_tests_msca.yml @@ -97,7 +97,7 @@ jobs: WCCE_HOST: ${{ secrets.WCCE_HOST }} - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 5s @@ -256,7 +256,7 @@ jobs: WCCE_HOST: ${{ secrets.WCCE_HOST }} - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 5s @@ -511,7 +511,7 @@ jobs: WCCE_HOST: ${{ secrets.WCCE_HOST }} - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 5s @@ -703,7 +703,7 @@ jobs: WCCE_HOST: ${{ secrets.WCCE_HOST }} - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 5s diff --git a/.github/workflows/ca_handler_tests_openxpki.yml b/.github/workflows/ca_handler_tests_openxpki.yml index 3cb2ed46..2cbac21a 100644 --- a/.github/workflows/ca_handler_tests_openxpki.yml +++ b/.github/workflows/ca_handler_tests_openxpki.yml @@ -58,7 +58,7 @@ jobs: docker-compose up & - name: "Sleep for 60s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 60s @@ -70,7 +70,7 @@ jobs: docker start openxpki-docker_openxpki-server_1 - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -82,7 +82,7 @@ jobs: docker exec -id openxpki-docker_openxpki-client_1 apt-get install -y libjson-pp-perl - name: "Sleep for 45s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 45s @@ -385,7 +385,7 @@ jobs: docker-compose up & - name: "Sleep for 60s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 60s @@ -397,7 +397,7 @@ jobs: docker start openxpki-docker_openxpki-server_1 - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -409,7 +409,7 @@ jobs: docker exec -id openxpki-docker_openxpki-client_1 apt-get install -y libjson-pp-perl - name: "Sleep for 45s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 45s diff --git a/.github/workflows/caddy-application-test.yml b/.github/workflows/caddy-application-test.yml index 55a89dc2..cc3d066f 100644 --- a/.github/workflows/caddy-application-test.yml +++ b/.github/workflows/caddy-application-test.yml @@ -40,7 +40,7 @@ jobs: docker-compose logs - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -62,7 +62,7 @@ jobs: docker run -d --rm ${{ matrix.ports }} --network acme -v $PWD/caddy/Caddyfile:/etc/caddy/Caddyfile -v$PWD/caddy/acme2certifier_cabundle.pem:/tmp/acme2certifier_cabundle.pem -v $(pwd)/caddy/config:/config -v $(pwd)/caddy/data:/data --name=caddy caddy:2 - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -123,7 +123,7 @@ jobs: docker-compose logs - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -145,7 +145,7 @@ jobs: docker run -d --rm ${{ matrix.ports }} --network acme -v $PWD/caddy/Caddyfile:/etc/caddy/Caddyfile -v$PWD/caddy/acme2certifier_cabundle.pem:/tmp/acme2certifier_cabundle.pem -v $(pwd)/caddy/config:/config -v $(pwd)/caddy/data:/data --name=caddy caddy:2 - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -206,7 +206,7 @@ jobs: docker-compose logs - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -228,7 +228,7 @@ jobs: docker run -d --rm ${{ matrix.ports }} --network acme -v $PWD/caddy/Caddyfile:/etc/caddy/Caddyfile -v$PWD/caddy/acme2certifier_cabundle.pem:/tmp/acme2certifier_cabundle.pem -v $(pwd)/caddy/config:/config -v $(pwd)/caddy/data:/data --name=caddy caddy:2 - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -290,7 +290,7 @@ jobs: docker-compose logs - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -311,7 +311,7 @@ jobs: docker run -d --rm ${{ matrix.ports }} --network acme -v $PWD/caddy/Caddyfile:/etc/caddy/Caddyfile -v$PWD/caddy/acme2certifier_cabundle.pem:/tmp/acme2certifier_cabundle.pem -v $(pwd)/caddy/config:/config -v $(pwd)/caddy/data:/data --name=caddy caddy:2 - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s diff --git a/.github/workflows/certbot-application-test.yml b/.github/workflows/certbot-application-test.yml index 35cd79ba..9d1f62bf 100644 --- a/.github/workflows/certbot-application-test.yml +++ b/.github/workflows/certbot-application-test.yml @@ -30,7 +30,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -121,7 +121,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -213,7 +213,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -305,7 +305,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s diff --git a/.github/workflows/certmanager-application-test.yml b/.github/workflows/certmanager-application-test.yml index d446af54..a4ca38b3 100644 --- a/.github/workflows/certmanager-application-test.yml +++ b/.github/workflows/certmanager-application-test.yml @@ -48,7 +48,7 @@ jobs: run: | sudo microk8s.kubectl apply -f data/dnsmasq.yml - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -98,7 +98,7 @@ jobs: sudo microk8s.kubectl apply -f data/k8s-acme-srv.yml sudo microk8s.kubectl get pods -n cert-manager-acme - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -119,7 +119,7 @@ jobs: sudo microk8s.kubectl apply -f data/k8s-cert-mgr-http-01.yml - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 20s @@ -128,7 +128,7 @@ jobs: sudo microk8s.kubectl describe ClusterIssuer acme2certifier sudo microk8s.kubectl describe challenge - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 20s @@ -137,7 +137,7 @@ jobs: sudo microk8s.kubectl describe ClusterIssuer acme2certifier sudo microk8s.kubectl describe challenge - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 20s @@ -203,7 +203,7 @@ jobs: run: | sudo microk8s.kubectl apply -f data/dnsmasq.yml - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -255,7 +255,7 @@ jobs: sudo microk8s.kubectl get pods -n cert-manager-acme - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -276,7 +276,7 @@ jobs: sudo microk8s.kubectl apply -f data/k8s-cert-mgr-http-01.yml - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 20s @@ -285,7 +285,7 @@ jobs: sudo microk8s.kubectl describe ClusterIssuer acme2certifier sudo microk8s.kubectl describe challenge - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 20s @@ -294,7 +294,7 @@ jobs: sudo microk8s.kubectl describe ClusterIssuer acme2certifier sudo microk8s.kubectl describe challenge - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 20s @@ -360,7 +360,7 @@ jobs: sudo microk8s.kubectl apply -f data/dnsmasq.yml - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -410,7 +410,7 @@ jobs: sudo microk8s.kubectl apply -f data/k8s-acme-srv.yml sudo microk8s.kubectl get pods -n cert-manager-acme - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -430,7 +430,7 @@ jobs: sudo sed -i "s/ACME_SRV/${{ env.ACME_IP }}/g" data/k8s-cert-mgr-http-01.yml sudo microk8s.kubectl apply -f data/k8s-cert-mgr-http-01.yml - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 20s @@ -439,7 +439,7 @@ jobs: sudo microk8s.kubectl describe ClusterIssuer acme2certifier sudo microk8s.kubectl describe challenge - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 20s @@ -448,7 +448,7 @@ jobs: sudo microk8s.kubectl describe ClusterIssuer acme2certifier sudo microk8s.kubectl describe challenge - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 20s @@ -514,7 +514,7 @@ jobs: sudo microk8s.kubectl apply -f data/dnsmasq.yml - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -568,7 +568,7 @@ jobs: sudo microk8s.kubectl get pods -n cert-manager-acme - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -589,7 +589,7 @@ jobs: sudo microk8s.kubectl apply -f data/k8s-cert-mgr-http-01.yml - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 20s @@ -599,7 +599,7 @@ jobs: sudo microk8s.kubectl describe challenge - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 20s @@ -608,7 +608,7 @@ jobs: sudo microk8s.kubectl describe ClusterIssuer acme2certifier sudo microk8s.kubectl describe challenge - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 20s @@ -695,7 +695,7 @@ jobs: sudo microk8s.kubectl get pods -n cert-manager-acme - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -721,7 +721,7 @@ jobs: sudo microk8s.kubectl apply -f data/k8s-cert-mgr-dns-01.yml - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 20s @@ -731,7 +731,7 @@ jobs: sudo microk8s.kubectl describe challenge -n cert-manager-acme - name: "[ WAIT ] Sleep for 30s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 60s @@ -741,7 +741,7 @@ jobs: sudo microk8s.kubectl describe challenge -n cert-manager-acme - name: "[ WAIT ] Sleep for 60s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 60s @@ -751,7 +751,7 @@ jobs: sudo microk8s.kubectl describe challenge -n cert-manager-acme - name: "[ WAIT ] Sleep for 60s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 60s @@ -772,7 +772,7 @@ jobs: sudo microk8s.kubectl apply -f data/k8s-cert-mgr-dns-01.yml - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 20s @@ -781,7 +781,7 @@ jobs: sudo microk8s.kubectl describe issuer acme2certifier -n cert-manager-acme sudo microk8s.kubectl describe challenge -n cert-manager-acme - name: "[ WAIT ] Sleep for 30s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 60s @@ -791,7 +791,7 @@ jobs: sudo microk8s.kubectl describe challenge -n cert-manager-acme - name: "[ WAIT ] Sleep for 60s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 60s @@ -801,7 +801,7 @@ jobs: sudo microk8s.kubectl describe challenge -n cert-manager-acme - name: "[ WAIT ] Sleep for 60s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 60s diff --git a/.github/workflows/container-tests.yml b/.github/workflows/container-tests.yml index 0c898118..32ac5dcc 100644 --- a/.github/workflows/container-tests.yml +++ b/.github/workflows/container-tests.yml @@ -52,7 +52,7 @@ jobs: head -n 13 data/ca_handler.py docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s - name: "Test if http://acme-srv/directory is accessable" @@ -100,7 +100,7 @@ jobs: docker-compose restart docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s - name: "Test if http://acme-srv/directory is accessable" @@ -124,7 +124,7 @@ jobs: head -n 13 data/ca_handler.py docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s - name: "Test if http://acme-srv/directory is accessable" @@ -172,7 +172,7 @@ jobs: docker-compose restart docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s - name: "Test if http://acme-srv/directory is accessable" @@ -196,7 +196,7 @@ jobs: head -n 13 data/ca_handler.py docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s - name: "Test if http://acme-srv/directory is accessable" @@ -245,7 +245,7 @@ jobs: docker-compose restart docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s - name: "Test if http://acme-srv/directory is accessable" @@ -269,7 +269,7 @@ jobs: head -n 13 data/ca_handler.py docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s - name: "Test if http://acme-srv/directory is accessable" diff --git a/.github/workflows/django_tests..yml b/.github/workflows/django_tests..yml index 0fb675b6..95dc88d7 100644 --- a/.github/workflows/django_tests..yml +++ b/.github/workflows/django_tests..yml @@ -34,7 +34,7 @@ jobs: docker run --name mariadbsrv --network acme -e MARIADB_ROOT_PASSWORD=foobar -d mariadb - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -140,7 +140,7 @@ jobs: docker run --name postgresdbsrv --network acme -e POSTGRES_PASSWORD=foobar -d postgres - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -149,7 +149,7 @@ jobs: run: | docker run -v "$(pwd)/data/pgsql/a2c.psql":/tmp/a2c.psql -v "$(pwd)/data/pgsql/pgpass:/root/.pgpass" --rm --network acme postgres psql -U postgres -h postgresdbsrv -f /tmp/a2c.psql - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -245,7 +245,7 @@ jobs: docker run --name mariadbsrv --network acme -e MARIADB_ROOT_PASSWORD=foobar -d mariadb - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -274,7 +274,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -358,7 +358,7 @@ jobs: docker run --name postgresdbsrv --network acme -e POSTGRES_PASSWORD=foobar -d postgres - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -367,7 +367,7 @@ jobs: run: | docker run -v "$(pwd)/data/pgsql/a2c.psql":/tmp/a2c.psql -v "$(pwd)/data/pgsql/pgpass:/root/.pgpass" --rm --network acme postgres psql -U postgres -h postgresdbsrv -f /tmp/a2c.psql - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -390,7 +390,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -621,7 +621,7 @@ jobs: # docker run --name mariadbsrv --network acme -e MARIADB_ROOT_PASSWORD=foobar -d mariadb - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -768,7 +768,7 @@ jobs: docker run --name postgresdbsrv -v /tmp/pgsql/data:/var/lib/postgresql/data --network acme -e POSTGRES_PASSWORD=foobar -d postgres - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -777,7 +777,7 @@ jobs: docker run -v /tmp/pgsql/a2c.psql:/tmp/a2c.psql -v /tmp/pgsql/pgpass:/root/.pgpass --rm --network acme postgres psql -U postgres -h postgresdbsrv -f /tmp/a2c.psql - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s diff --git a/.github/workflows/ip-address-tests.yml b/.github/workflows/ip-address-tests.yml index 8607be6f..b8aed5d4 100644 --- a/.github/workflows/ip-address-tests.yml +++ b/.github/workflows/ip-address-tests.yml @@ -42,7 +42,7 @@ jobs: docker-compose logs - name: "Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 5s @@ -116,7 +116,7 @@ jobs: docker-compose logs - name: "Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 5s @@ -190,7 +190,7 @@ jobs: docker-compose logs - name: "Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 5s @@ -266,7 +266,7 @@ jobs: docker-compose logs - name: "Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 5s diff --git a/.github/workflows/lego-application-test.yml b/.github/workflows/lego-application-test.yml index c47cdd73..76802464 100644 --- a/.github/workflows/lego-application-test.yml +++ b/.github/workflows/lego-application-test.yml @@ -112,7 +112,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -200,7 +200,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -288,7 +288,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s diff --git a/.github/workflows/proxy-test.yml b/.github/workflows/proxy-test.yml index e285301b..b171932f 100644 --- a/.github/workflows/proxy-test.yml +++ b/.github/workflows/proxy-test.yml @@ -29,7 +29,7 @@ jobs: docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -311,7 +311,7 @@ jobs: docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s diff --git a/.github/workflows/push_images_to_dockerhub.yml b/.github/workflows/push_images_to_dockerhub.yml index 988eaf86..aadbb006 100644 --- a/.github/workflows/push_images_to_dockerhub.yml +++ b/.github/workflows/push_images_to_dockerhub.yml @@ -172,7 +172,7 @@ jobs: docker run -d -p 80:80 --rm -id --network acme --name=acme-srv -v "$(pwd)/examples/Docker/data":/var/www/acme2certifier/volume/ grindsa/acme2certifier:apache2-django - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 5s diff --git a/.github/workflows/test_headerinfo.yml b/.github/workflows/test_headerinfo.yml index 5ba9edbf..72724674 100644 --- a/.github/workflows/test_headerinfo.yml +++ b/.github/workflows/test_headerinfo.yml @@ -138,7 +138,7 @@ jobs: XCA_DB_NAME: ${{ secrets.XCA_DB_NAME }} - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -222,7 +222,7 @@ jobs: XCA_DB_NAME: ${{ secrets.XCA_DB_NAME }} - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -274,7 +274,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -313,7 +313,7 @@ jobs: XCA_DB_NAME: ${{ secrets.XCA_DB_NAME }} - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s diff --git a/.github/workflows/traffic-application-test.yml b/.github/workflows/traffic-application-test.yml index 35be2580..36b26636 100644 --- a/.github/workflows/traffic-application-test.yml +++ b/.github/workflows/traffic-application-test.yml @@ -60,7 +60,7 @@ jobs: docker-compose up -d - name: "Sleep for 30s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 30s diff --git a/.github/workflows/upgrade_tests..yml b/.github/workflows/upgrade_tests..yml index 5188e76d..2280c589 100644 --- a/.github/workflows/upgrade_tests..yml +++ b/.github/workflows/upgrade_tests..yml @@ -39,7 +39,7 @@ jobs: docker logs acme-srv - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 5s @@ -86,7 +86,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 5s @@ -166,7 +166,7 @@ jobs: docker logs acme-srv - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 5s @@ -213,7 +213,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 5s @@ -284,7 +284,7 @@ jobs: docker run --name mariadbsrv --network acme -e MARIADB_ROOT_PASSWORD=foobar -d mariadb - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -315,7 +315,7 @@ jobs: docker logs acme-srv - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 5s @@ -362,7 +362,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 5s @@ -432,7 +432,7 @@ jobs: docker run --name mariadbsrv --network acme -e MARIADB_ROOT_PASSWORD=foobar -d mariadb - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -463,7 +463,7 @@ jobs: docker logs acme-srv - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 5s @@ -511,7 +511,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 5s @@ -677,7 +677,7 @@ jobs: sudo rm -rf $PWD/acme-sh/* - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -779,7 +779,7 @@ jobs: docker run --name mariadbsrv --network acme -e MARIADB_ROOT_PASSWORD=foobar -d mariadb - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -860,7 +860,7 @@ jobs: sudo rm -rf $PWD/acme-sh/* - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -1025,7 +1025,7 @@ jobs: sudo rm -rf $PWD/acme-sh/* - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -1134,7 +1134,7 @@ jobs: docker run --name postgresdbsrv --network acme -e POSTGRES_PASSWORD=foobar -d postgres - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -1144,7 +1144,7 @@ jobs: docker run -v "$(pwd)/data/pgsql/a2c.psql":/tmp/a2c.psql -v "$(pwd)/data/pgsql/pgpass:/root/.pgpass" --rm --network acme postgres psql -U postgres -h postgresdbsrv -f /tmp/a2c.psql - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s @@ -1218,7 +1218,7 @@ jobs: sudo rm -rf $PWD/acme-sh/* - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 10s diff --git a/.github/workflows/winacme-application-test.yml b/.github/workflows/winacme-application-test.yml index 808c1683..ceb46bc2 100644 --- a/.github/workflows/winacme-application-test.yml +++ b/.github/workflows/winacme-application-test.yml @@ -63,7 +63,7 @@ jobs: run: | Start-Process powershell {python .\manage.py runserver 0.0.0.0:8080 3>&1 2>&1 > volume\redirection.log} - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 5s @@ -90,7 +90,7 @@ jobs: Start-Process powershell {python .\manage.py runsslserver 0.0.0.0:443 --certificate acme2certifier/acme2certifier_cert.pem --key acme2certifier/acme2certifier_key.pem 3>&1 2>&1 > volume\redirection_ssl.log} - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.0 + uses: grindsa/sleep-action@node20 with: time: 5s From e116e67a6d43f61c7cef9a44f7887dcd2cec2b13 Mon Sep 17 00:00:00 2001 From: grindsa Date: Mon, 29 Jan 2024 07:46:14 +0100 Subject: [PATCH 032/460] [fix] extend logging to ease eab troubleshooting --- acme_srv/account.py | 3 ++- acme_srv/helper.py | 7 +++++++ acme_srv/signature.py | 1 + 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/acme_srv/account.py b/acme_srv/account.py index e8542b8b..781466d9 100644 --- a/acme_srv/account.py +++ b/acme_srv/account.py @@ -299,7 +299,7 @@ def _eab_verify(self, payload: Dict[str, str]) -> Tuple[int, str, str]: message = self.err_msg_dic['unauthorized'] detail = 'eab kid lookup failed' - self.logger.debug('_eab_check() ended with: {0}'.format(code)) + self.logger.debug('Account._eab_verify() ended with: {0}'.format(code)) return (code, message, detail) def _eab_check(self, protected: Dict[str, str], payload: Dict[str, str]) -> Tuple[int, str, str]: @@ -337,6 +337,7 @@ def _eab_signature_verify(self, content: Dict[str, str], mac_key: str) -> Tuple[ else: sig_check = False error = None + self.logger.debug('Account._eab_signature_verify() ended with: {0}'.format(sig_check)) return (sig_check, error) diff --git a/acme_srv/helper.py b/acme_srv/helper.py index 19c56fed..0464db75 100644 --- a/acme_srv/helper.py +++ b/acme_srv/helper.py @@ -701,8 +701,10 @@ def signature_check(logger: logging.Logger, message: str, pub_key: str, json_: b # load key try: if json_: + logger.debug('signature_check(): load key from json') jwkey = jwk.JWK.from_json(pub_key) else: + logger.debug('signature_check(): load plain json') jwkey = jwk.JWK(**pub_key) except Exception as err: logger.error('load key failed {0}'.format(err)) @@ -720,9 +722,14 @@ def signature_check(logger: logging.Logger, message: str, pub_key: str, json_: b except Exception as err: logger.error('verify failed {0}'.format(err)) error = str(err) + else: + logger.error('No jwkey extracted') + # error = 'No jwkey extracted' else: + logger.error('No pubkey specified.') error = 'No key specified.' + logger.debug('signature_check() ended with: %s, %s', result, error) return (result, error) diff --git a/acme_srv/signature.py b/acme_srv/signature.py index fa6ae983..f32df67b 100644 --- a/acme_srv/signature.py +++ b/acme_srv/signature.py @@ -101,4 +101,5 @@ def eab_check(self, content: str, mac_key: str) -> Tuple[str, str]: if content and mac_key: (result, error) = signature_check(self.logger, content, mac_key, json_=True) + self.logger.debug('Signature.signature_check() ended with: %s:%s', result, error) return (result, error) From 38adc7132cb2ad7477b1000f7380f67b94222276 Mon Sep 17 00:00:00 2001 From: grindsa Date: Mon, 29 Jan 2024 17:34:23 +0100 Subject: [PATCH 033/460] [fix] codesmell in helper.py --- acme_srv/helper.py | 1 - test/test_helper.py | 5 ++++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/acme_srv/helper.py b/acme_srv/helper.py index f42a2753..3af0fb0c 100644 --- a/acme_srv/helper.py +++ b/acme_srv/helper.py @@ -828,7 +828,6 @@ def signature_check(logger: logging.Logger, message: str, pub_key: str, json_: b error = str(err) else: logger.error('No jwkey extracted') - # error = 'No jwkey extracted' else: logger.error('No pubkey specified.') error = 'No key specified.' diff --git a/test/test_helper.py b/test/test_helper.py index a79bf8e0..821d1653 100644 --- a/test/test_helper.py +++ b/test/test_helper.py @@ -1152,7 +1152,10 @@ def test_150_helper_signature_check(self): error = 'type object argument after ** must be a mapping, not str' else: error = 'jwcrypto.jwk.JWK() argument after ** must be a mapping, not str' - self.assertEqual((False, error), self.signature_check(self.logger, message, mkey)) + + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertEqual((False, error), self.signature_check(self.logger, message, mkey)) + self.assertIn('ERROR:test_a2c:No jwkey extracted', lcm.output) def test_151_helper_signature_check(self): """ sucessful validation invalid key """ From 9f8b00665b3e7c3990693f4d31954b48c4f6074e Mon Sep 17 00:00:00 2001 From: grindsa Date: Mon, 29 Jan 2024 19:44:28 +0100 Subject: [PATCH 034/460] [fix] copy only el9 rpms in workflows --- .github/workflows/django_tests..yml | 6 +++--- .github/workflows/upgrade_tests..yml | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/django_tests..yml b/.github/workflows/django_tests..yml index 95dc88d7..8daaddda 100644 --- a/.github/workflows/django_tests..yml +++ b/.github/workflows/django_tests..yml @@ -492,7 +492,7 @@ jobs: - name: "Retrieve rpms from SBOM repo" run: | git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom - cp /tmp/sbom/rpm-repo/RPMs/*.rpm data + cp /tmp/sbom/rpm-repo/RPMs/*el9*.rpm data env: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} @@ -634,7 +634,7 @@ jobs: - name: "Retrieve rpms from SBOM repo" run: | git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom - cp /tmp/sbom/rpm-repo/RPMs/*.rpm data + cp /tmp/sbom/rpm-repo/RPMs/*el9*.rpm data env: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} @@ -784,7 +784,7 @@ jobs: - name: "Retrieve rpms from SBOM repo" run: | git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom - cp /tmp/sbom/rpm-repo/RPMs/*.rpm data + cp /tmp/sbom/rpm-repo/RPMs/*el9*.rpm data env: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} diff --git a/.github/workflows/upgrade_tests..yml b/.github/workflows/upgrade_tests..yml index 2280c589..85198a53 100644 --- a/.github/workflows/upgrade_tests..yml +++ b/.github/workflows/upgrade_tests..yml @@ -608,7 +608,7 @@ jobs: - name: "Retrieve rpms from SBOM repo" run: | git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom - cp /tmp/sbom/rpm-repo/RPMs/*.rpm data + cp /tmp/sbom/rpm-repo/RPMs/*el9*.rpm data env: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} @@ -793,7 +793,7 @@ jobs: - name: "Retrieve rpms from SBOM repo" run: | git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom - cp /tmp/sbom/rpm-repo/RPMs/*.rpm data + cp /tmp/sbom/rpm-repo/RPMs/*el9*.rpm data env: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} @@ -958,7 +958,7 @@ jobs: - name: "Retrieve rpms from SBOM repo" run: | git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom - cp /tmp/sbom/rpm-repo/RPMs/*.rpm data + cp /tmp/sbom/rpm-repo/RPMs/*el9*.rpm data env: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} @@ -1151,7 +1151,7 @@ jobs: - name: "Retrieve rpms from SBOM repo" run: | git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom - cp /tmp/sbom/rpm-repo/RPMs/*.rpm data + cp /tmp/sbom/rpm-repo/RPMs/*el9*.rpm data env: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} From 162c712be25b5b77e7593981b2b716d1b0f7562e Mon Sep 17 00:00:00 2001 From: grindsa Date: Mon, 29 Jan 2024 20:44:42 +0100 Subject: [PATCH 035/460] [doc] jwcrypto update as part of the rpm installation on RH 8.x --- docs/install_rpm.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/install_rpm.md b/docs/install_rpm.md index 3af460b6..328a4e73 100644 --- a/docs/install_rpm.md +++ b/docs/install_rpm.md @@ -17,6 +17,8 @@ $ sudo yum update -y $ sudo yum -y localinstall /tmp/acme2certifier/acme2certifier-0.23.1-1.0.noarch.rpm ``` +In case you install on Redhat 8.x you need to upgrade the [python3-jwcrypto package](https://jwcrypto.readthedocs.io/en/latest/) to version 0.8 or higher. A backport of the package being part of [RHEL9](https://rockylinux.pkgs.org/9/rockylinux-appstream-aarch64/python3-jwcrypto-0.8-4.el9.noarch.rpm.html) can be found in the [the a2c rpm repository](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/python3-jwcrypto-0.8-4.el8.noarch.rpm) + 4. Copy NGINX configuration file ```bash From 1e0bf58d3bf900734b444fbaf44361f29e811372 Mon Sep 17 00:00:00 2001 From: grindsa Date: Mon, 29 Jan 2024 20:46:01 +0100 Subject: [PATCH 036/460] [doc] jwcrypto update as part of the rpm installation on RH 8.x --- docs/install_rpm.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/install_rpm.md b/docs/install_rpm.md index 3af460b6..328a4e73 100644 --- a/docs/install_rpm.md +++ b/docs/install_rpm.md @@ -17,6 +17,8 @@ $ sudo yum update -y $ sudo yum -y localinstall /tmp/acme2certifier/acme2certifier-0.23.1-1.0.noarch.rpm ``` +In case you install on Redhat 8.x you need to upgrade the [python3-jwcrypto package](https://jwcrypto.readthedocs.io/en/latest/) to version 0.8 or higher. A backport of the package being part of [RHEL9](https://rockylinux.pkgs.org/9/rockylinux-appstream-aarch64/python3-jwcrypto-0.8-4.el9.noarch.rpm.html) can be found in the [the a2c rpm repository](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/python3-jwcrypto-0.8-4.el8.noarch.rpm) + 4. Copy NGINX configuration file ```bash From 87b4aa27a05a6d379f4ab34050f4272c8bf682c8 Mon Sep 17 00:00:00 2001 From: grindsa Date: Tue, 30 Jan 2024 16:31:24 +0100 Subject: [PATCH 037/460] [wf] copy el9 packages in actions only --- .github/workflows/django_tests..yml | 20 +++----------------- .github/workflows/upgrade_tests..yml | 8 ++++---- 2 files changed, 7 insertions(+), 21 deletions(-) diff --git a/.github/workflows/django_tests..yml b/.github/workflows/django_tests..yml index 95dc88d7..8ba84a26 100644 --- a/.github/workflows/django_tests..yml +++ b/.github/workflows/django_tests..yml @@ -12,8 +12,6 @@ jobs: apache_django_mariadb: name: "apache_django_mariadb" runs-on: ubuntu-latest - strategy: - fail-fast: false steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -112,8 +110,6 @@ jobs: apache_django_psql: name: "apache_django_psql" runs-on: ubuntu-latest - strategy: - fail-fast: false steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -222,8 +218,6 @@ jobs: nginx_django_mariadb: name: "nginx_django_mariadb" runs-on: ubuntu-latest - strategy: - fail-fast: false steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -329,8 +323,6 @@ jobs: nginx_django_psql: name: "nginx_django_psql" runs-on: ubuntu-latest - strategy: - fail-fast: false steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -446,8 +438,6 @@ jobs: nginx_django_rpm_sqlite: name: "nginx_django_rpm_sqlite" runs-on: ubuntu-latest - strategy: - fail-fast: false steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -492,7 +482,7 @@ jobs: - name: "Retrieve rpms from SBOM repo" run: | git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom - cp /tmp/sbom/rpm-repo/RPMs/*.rpm data + cp /tmp/sbom/rpm-repo/RPMs/*el9*.rpm data env: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} @@ -571,8 +561,6 @@ jobs: nginx_django_rpm_mariadb: name: "nginx_django_rpm_mariadb" runs-on: ubuntu-latest - strategy: - fail-fast: false steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -634,7 +622,7 @@ jobs: - name: "Retrieve rpms from SBOM repo" run: | git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom - cp /tmp/sbom/rpm-repo/RPMs/*.rpm data + cp /tmp/sbom/rpm-repo/RPMs/*el9*.rpm data env: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} @@ -713,8 +701,6 @@ jobs: nginx_django_rpm_psql: name: "nginx_django_rpm_psql" runs-on: ubuntu-latest - strategy: - fail-fast: false steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -784,7 +770,7 @@ jobs: - name: "Retrieve rpms from SBOM repo" run: | git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom - cp /tmp/sbom/rpm-repo/RPMs/*.rpm data + cp /tmp/sbom/rpm-repo/RPMs/*el9*.rpm data env: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} diff --git a/.github/workflows/upgrade_tests..yml b/.github/workflows/upgrade_tests..yml index 2280c589..85198a53 100644 --- a/.github/workflows/upgrade_tests..yml +++ b/.github/workflows/upgrade_tests..yml @@ -608,7 +608,7 @@ jobs: - name: "Retrieve rpms from SBOM repo" run: | git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom - cp /tmp/sbom/rpm-repo/RPMs/*.rpm data + cp /tmp/sbom/rpm-repo/RPMs/*el9*.rpm data env: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} @@ -793,7 +793,7 @@ jobs: - name: "Retrieve rpms from SBOM repo" run: | git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom - cp /tmp/sbom/rpm-repo/RPMs/*.rpm data + cp /tmp/sbom/rpm-repo/RPMs/*el9*.rpm data env: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} @@ -958,7 +958,7 @@ jobs: - name: "Retrieve rpms from SBOM repo" run: | git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom - cp /tmp/sbom/rpm-repo/RPMs/*.rpm data + cp /tmp/sbom/rpm-repo/RPMs/*el9*.rpm data env: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} @@ -1151,7 +1151,7 @@ jobs: - name: "Retrieve rpms from SBOM repo" run: | git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom - cp /tmp/sbom/rpm-repo/RPMs/*.rpm data + cp /tmp/sbom/rpm-repo/RPMs/*el9*.rpm data env: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} From 056a4d3553b462e3c0c8ada291a53153380ae5b3 Mon Sep 17 00:00:00 2001 From: grindsa Date: Tue, 30 Jan 2024 16:58:14 +0100 Subject: [PATCH 038/460] [fix] migrate upload-artifact to v4 --- .github/workflows/acme_sh-application-test.yml | 8 ++++---- .github/workflows/alpn-test.yml | 4 ++-- .github/workflows/ari-test.yml | 8 ++++---- .github/workflows/ca_handler_tests_acme.yml | 8 ++++---- .github/workflows/ca_handler_tests_asa.yml | 6 +++--- .github/workflows/ca_handler_tests_certifier.yml | 10 +++++----- .github/workflows/ca_handler_tests_cmp.yml | 8 ++++---- .github/workflows/ca_handler_tests_ejbca.yml | 4 ++-- .github/workflows/ca_handler_tests_est.yml | 4 ++-- .github/workflows/ca_handler_tests_msca.yml | 12 ++++++------ .github/workflows/ca_handler_tests_nclm.yml | 4 ++-- .github/workflows/ca_handler_tests_openssl.yml | 10 +++++----- .github/workflows/ca_handler_tests_openxpki.yml | 4 ++-- .../workflows/ca_handler_tests_pkcs7_soap.yml | 4 ++-- .github/workflows/ca_handler_tests_xca.yml | 8 ++++---- .github/workflows/caddy-application-test.yml | 8 ++++---- .github/workflows/certbot-application-test.yml | 8 ++++---- .../workflows/certmanager-application-test.yml | 10 +++++----- .github/workflows/container-tests.yml | 8 ++++---- .github/workflows/django_tests..yml | 14 +++++++------- .github/workflows/dns-test.yml | 4 ++-- .github/workflows/eab-test.yml | 4 ++-- .github/workflows/enrollment-timeout.yml | 2 +- .github/workflows/hooks-test.yml | 8 ++++---- .github/workflows/ip-address-tests.yml | 8 ++++---- .github/workflows/ipv6-test.yml | 8 ++++---- .github/workflows/lego-application-test.yml | 8 ++++---- .github/workflows/manual-install-test.yml | 12 ++++++------ .github/workflows/proxy-test.yml | 4 ++-- .github/workflows/push_images_to_dockerhub.yml | 8 ++++---- .github/workflows/test_headerinfo.yml | 10 +++++----- .github/workflows/tnauth-test.yml | 4 ++-- .github/workflows/traffic-application-test.yml | 2 +- .github/workflows/upgrade_tests..yml | 16 ++++++++-------- .github/workflows/winacme-application-test.yml | 2 +- .github/workflows/wsgi_handler-test.yml | 4 ++-- 36 files changed, 127 insertions(+), 127 deletions(-) diff --git a/.github/workflows/acme_sh-application-test.yml b/.github/workflows/acme_sh-application-test.yml index 66a53c51..af8d349d 100644 --- a/.github/workflows/acme_sh-application-test.yml +++ b/.github/workflows/acme_sh-application-test.yml @@ -113,7 +113,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh - name: "[ * ] uploading artifacts" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: acme_sh_apache2_wsgi-${{ matrix.accountkeylength }}_key-${{ matrix.keylength }}.tar.gz @@ -230,7 +230,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh - name: "[ * ] uploading artifacts" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: acme_sh_apache2_django-${{ matrix.accountkeylength }}_key-${{ matrix.keylength }}.tar.gz @@ -346,7 +346,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh - name: "[ * ] uploading artifacts" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: acme_sh_nginx_wsgi-${{ matrix.accountkeylength }}_key-${{ matrix.keylength }}.tar.gz @@ -464,7 +464,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh - name: "[ * ] uploading artifacts" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: acme_sh_nginx_django-${{ matrix.accountkeylength }}_key-${{ matrix.keylength }}.tar.gz diff --git a/.github/workflows/alpn-test.yml b/.github/workflows/alpn-test.yml index 482146b3..3ce013ac 100644 --- a/.github/workflows/alpn-test.yml +++ b/.github/workflows/alpn-test.yml @@ -66,7 +66,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: alpn.tar.gz @@ -156,7 +156,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: alpn-rpm.tar.gz diff --git a/.github/workflows/ari-test.yml b/.github/workflows/ari-test.yml index 7096cf52..2f7266e8 100644 --- a/.github/workflows/ari-test.yml +++ b/.github/workflows/ari-test.yml @@ -68,7 +68,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: ari_apache2_wsgi.tar.gz @@ -139,7 +139,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: ari_apache2_django.tar.gz @@ -209,7 +209,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: ari_nginx_wsgi.tar.gz @@ -281,7 +281,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: ari_nginx_django.tar.gz diff --git a/.github/workflows/ca_handler_tests_acme.yml b/.github/workflows/ca_handler_tests_acme.yml index 02c2900d..e5f832e2 100644 --- a/.github/workflows/ca_handler_tests_acme.yml +++ b/.github/workflows/ca_handler_tests_acme.yml @@ -82,7 +82,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data docker-compose.log acme-le-sim.log - name: "[ * ] uploading artifacts" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: acme_ca_handler.tar.gz @@ -163,7 +163,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data docker-compose.log acme-le-sim.log - name: "[ * ] uploading artifacts" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: acme_ca_handler_sectigo.tar.gz @@ -268,7 +268,7 @@ jobs: docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: acme_ca_handler_rpm.tar.gz @@ -382,7 +382,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: acme_ca_handler_sectigo_rpm.tar.gz diff --git a/.github/workflows/ca_handler_tests_asa.yml b/.github/workflows/ca_handler_tests_asa.yml index ea97fe1a..12bdd312 100644 --- a/.github/workflows/ca_handler_tests_asa.yml +++ b/.github/workflows/ca_handler_tests_asa.yml @@ -190,7 +190,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh certbot lego - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: asa_wsgi.tar.gz @@ -398,7 +398,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: asa_handler_tests_rpm.tar.gz @@ -503,7 +503,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: asa_handler_headerinfo_tests.tar.gz diff --git a/.github/workflows/ca_handler_tests_certifier.yml b/.github/workflows/ca_handler_tests_certifier.yml index 728379b8..f7ba39ad 100644 --- a/.github/workflows/ca_handler_tests_certifier.yml +++ b/.github/workflows/ca_handler_tests_certifier.yml @@ -107,7 +107,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh certbot lego - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: ncm.tar.gz @@ -214,7 +214,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh certbot lego - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: certifier_p101_handler_tests.tar.gz @@ -321,7 +321,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh certbot lego - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: certifier_p102_handler_tests.tar.gz @@ -450,7 +450,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: certifier_ca_handler_rpm.tar.gz @@ -550,7 +550,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: certifier_handler_headerinfo_tests.tar.gz diff --git a/.github/workflows/ca_handler_tests_cmp.yml b/.github/workflows/ca_handler_tests_cmp.yml index c83ee29a..b90c79f6 100644 --- a/.github/workflows/ca_handler_tests_cmp.yml +++ b/.github/workflows/ca_handler_tests_cmp.yml @@ -126,7 +126,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh certbot lego - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: cmpkeycert.tar.gz @@ -249,7 +249,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh certbot lego - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: cmprefpsk.tar.gz @@ -398,7 +398,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: cmpkeycert.tar_rpm.gz @@ -547,7 +547,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: cmprefpsk.tar_rpm.gz diff --git a/.github/workflows/ca_handler_tests_ejbca.yml b/.github/workflows/ca_handler_tests_ejbca.yml index ba6300f3..eb367890 100644 --- a/.github/workflows/ca_handler_tests_ejbca.yml +++ b/.github/workflows/ca_handler_tests_ejbca.yml @@ -180,7 +180,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz ejbca.log a2c.log data acme-sh certbot lego - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: ejbca.tar.gz @@ -375,7 +375,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data ejbca.log acme-srv.log acme-sh - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: ejb_rpm.tar.gz diff --git a/.github/workflows/ca_handler_tests_est.yml b/.github/workflows/ca_handler_tests_est.yml index 94fa0f81..885e7e1d 100644 --- a/.github/workflows/ca_handler_tests_est.yml +++ b/.github/workflows/ca_handler_tests_est.yml @@ -134,7 +134,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: est.tar.gz @@ -293,7 +293,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: est-rpm.tar.gz diff --git a/.github/workflows/ca_handler_tests_msca.yml b/.github/workflows/ca_handler_tests_msca.yml index 1bd7b6e0..e1f059ec 100644 --- a/.github/workflows/ca_handler_tests_msca.yml +++ b/.github/workflows/ca_handler_tests_msca.yml @@ -133,7 +133,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh certbot lego - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: wcce_ntlm.tar.gz @@ -298,7 +298,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh certbot lego dnsmasq - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: wcce_krb.tar.gz @@ -395,7 +395,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh certbot lego - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: wse.${{ matrix.authscheme }}.tar.gz @@ -545,7 +545,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: wcce_ntlm_rpm.tar.gz @@ -739,7 +739,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: wcce_handler_krb_tests_rpm.tar.gz @@ -873,7 +873,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: wes_rpm.tar.gz diff --git a/.github/workflows/ca_handler_tests_nclm.yml b/.github/workflows/ca_handler_tests_nclm.yml index b6dc6ded..d1df4ecb 100644 --- a/.github/workflows/ca_handler_tests_nclm.yml +++ b/.github/workflows/ca_handler_tests_nclm.yml @@ -118,7 +118,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh certbot lego - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: nclm.tar.gz @@ -240,7 +240,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: nclm_ca_handler_rpm.tar.gz diff --git a/.github/workflows/ca_handler_tests_openssl.yml b/.github/workflows/ca_handler_tests_openssl.yml index aea37d78..a174bce2 100644 --- a/.github/workflows/ca_handler_tests_openssl.yml +++ b/.github/workflows/ca_handler_tests_openssl.yml @@ -106,7 +106,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh certbot lego - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: openssl_ca_handler_no_tmpl_tests.tar.gz @@ -215,7 +215,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh certbot lego - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: openssl_ca_handler_tmpl_tests.tar.gz @@ -288,7 +288,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data certbot - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: openssl_ca_handler_enforce_tests.tar.gz @@ -358,7 +358,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data certbot - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: openssl_ca_handler_validity_adjust_tests.tar.gz @@ -484,7 +484,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh certbot lego - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: openssl-rpmopenssl_ca_handler_no_tmpl_tests_rpm.tar.gz diff --git a/.github/workflows/ca_handler_tests_openxpki.yml b/.github/workflows/ca_handler_tests_openxpki.yml index 2cbac21a..cb066b3e 100644 --- a/.github/workflows/ca_handler_tests_openxpki.yml +++ b/.github/workflows/ca_handler_tests_openxpki.yml @@ -331,7 +331,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz openxpki.log a2c.log data acme-sh certbot lego - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: openxpki.tar.gz @@ -686,7 +686,7 @@ jobs: docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data openxpki_server.log openxpki_client.log acme-srv.log acme-sh - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: openxpki_rpm.tar.gz diff --git a/.github/workflows/ca_handler_tests_pkcs7_soap.yml b/.github/workflows/ca_handler_tests_pkcs7_soap.yml index c46ea5b0..af638e4d 100644 --- a/.github/workflows/ca_handler_tests_pkcs7_soap.yml +++ b/.github/workflows/ca_handler_tests_pkcs7_soap.yml @@ -121,7 +121,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz a2c.log data soap-srv.log acme-sh certbot lego - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: pkcs7soap-int.tar.gz @@ -242,7 +242,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz a2c.log data soap-srv.log acme-sh certbot lego - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: pkcs7soap-ext.tar.gz diff --git a/.github/workflows/ca_handler_tests_xca.yml b/.github/workflows/ca_handler_tests_xca.yml index 04cddbe4..83299824 100644 --- a/.github/workflows/ca_handler_tests_xca.yml +++ b/.github/workflows/ca_handler_tests_xca.yml @@ -121,7 +121,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh certbot lego - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: xca_handler_no_tmpl_tests.tar.gz @@ -236,7 +236,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh certbot lego - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: xca_handler_tmpl_tests.tar.gz @@ -373,7 +373,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: xca_handler_no_tmpl_tests_rpm.tar.gz @@ -507,7 +507,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: xca_handler_tmpl_tests_rpm.tar.gz diff --git a/.github/workflows/caddy-application-test.yml b/.github/workflows/caddy-application-test.yml index cc3d066f..2a9f1a15 100644 --- a/.github/workflows/caddy-application-test.yml +++ b/.github/workflows/caddy-application-test.yml @@ -83,7 +83,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log caddy.log data caddy - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: caddy_apache2_wsgi-${{ github.run_id }}.tar.gz @@ -166,7 +166,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log caddy.log data caddy - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: caddy_apache2_django-${{ github.run_id }}.tar.gz @@ -249,7 +249,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log caddy.log data caddy - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: caddy_nginx_wsgi-${{ github.run_id }}.tar.gz @@ -332,7 +332,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log caddy.log data caddy - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: caddy_nginx_django-${{ github.run_id }}.tar.gz diff --git a/.github/workflows/certbot-application-test.yml b/.github/workflows/certbot-application-test.yml index 9d1f62bf..da2668dd 100644 --- a/.github/workflows/certbot-application-test.yml +++ b/.github/workflows/certbot-application-test.yml @@ -94,7 +94,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data certbot - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: certbot_key-${{ matrix.keylength }}.tar.gz @@ -186,7 +186,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data certbot - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: certbot_key-${{ matrix.keylength }}.tar.gz @@ -277,7 +277,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data certbot - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: certbot_key-${{ matrix.keylength }}.tar.gz @@ -370,7 +370,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data certbot - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: certbot_key-${{ matrix.keylength }}.tar.gz diff --git a/.github/workflows/certmanager-application-test.yml b/.github/workflows/certmanager-application-test.yml index a4ca38b3..ebdb0eff 100644 --- a/.github/workflows/certmanager-application-test.yml +++ b/.github/workflows/certmanager-application-test.yml @@ -157,7 +157,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz acme2certifier.log data - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: cert-manager-http-apwsgi.tar.gz @@ -314,7 +314,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz acme2certifier.log data - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: cert-manager-http-apdjango.tar.gz @@ -466,7 +466,7 @@ jobs: sudo microk8s.kubectl logs acme2certifier -n cert-manager-acme > ${{ github.workspace }}/artifact/acme2certifier.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz acme2certifier.log data - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: cert-manager-http-nginxwsgi.tar.gz @@ -628,7 +628,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz acme2certifier.log data - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: cert-manager-http-nginxdjango.tar.gz @@ -820,7 +820,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz acme2certifier.log data - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: cert-manager-dns-apwsgi.tar.gz diff --git a/.github/workflows/container-tests.yml b/.github/workflows/container-tests.yml index 32ac5dcc..a40d8ce5 100644 --- a/.github/workflows/container-tests.yml +++ b/.github/workflows/container-tests.yml @@ -69,7 +69,7 @@ jobs: docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme_sh - name: "[ * ] uploading artifacts" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: docker-compose_apache2_wsgi.tar.gz @@ -141,7 +141,7 @@ jobs: docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme_sh - name: "[ * ] uploading artifacts" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: docker-compose_nginx_wsgi.tar.gz @@ -213,7 +213,7 @@ jobs: docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme_sh - name: "[ * ] uploading artifacts" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: docker-compose_apache2_django.tar.gz @@ -286,7 +286,7 @@ jobs: docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme_sh - name: "[ * ] uploading artifacts" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: docker-compose_nginx_django.tar.gz diff --git a/.github/workflows/django_tests..yml b/.github/workflows/django_tests..yml index 8ba84a26..9041e418 100644 --- a/.github/workflows/django_tests..yml +++ b/.github/workflows/django_tests..yml @@ -101,7 +101,7 @@ jobs: docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: apache-django-mariadb.tar.gz @@ -209,7 +209,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: apache-django-psql.tar.gz @@ -314,7 +314,7 @@ jobs: docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: nginx-django-mariadb.tar.gz @@ -429,7 +429,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: nginx-django-psql.tar.gz @@ -552,7 +552,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: nginx_django_rpm_sqlite.tar.gz @@ -692,7 +692,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh /tmp/mysql - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: nginx_django_rpm_mariadb.tar.gz @@ -840,7 +840,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh /tmp/pgsql - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: nginx_django_rpm_psql.tar.gz diff --git a/.github/workflows/dns-test.yml b/.github/workflows/dns-test.yml index d166df32..bc0a1f27 100644 --- a/.github/workflows/dns-test.yml +++ b/.github/workflows/dns-test.yml @@ -108,7 +108,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: eab.tar.gz @@ -233,7 +233,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: eab.tar.gz diff --git a/.github/workflows/eab-test.yml b/.github/workflows/eab-test.yml index 02b49a55..c7b6ed37 100644 --- a/.github/workflows/eab-test.yml +++ b/.github/workflows/eab-test.yml @@ -123,7 +123,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: eab-${{ matrix.keylength }}.tar.gz @@ -265,7 +265,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: eab-rpm.tar.gz diff --git a/.github/workflows/enrollment-timeout.yml b/.github/workflows/enrollment-timeout.yml index 226ef2ba..a659905d 100644 --- a/.github/workflows/enrollment-timeout.yml +++ b/.github/workflows/enrollment-timeout.yml @@ -103,7 +103,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh - name: "[ * ] uploading artifacts" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: async_enrollment_cert_reusage.tar.gz diff --git a/.github/workflows/hooks-test.yml b/.github/workflows/hooks-test.yml index 8cde6836..838e3e55 100644 --- a/.github/workflows/hooks-test.yml +++ b/.github/workflows/hooks-test.yml @@ -95,7 +95,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: hooks.tar.gz @@ -210,7 +210,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: hooks-rpm.tar.gz @@ -375,7 +375,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: hooks_exception_handling.tar.gz @@ -556,7 +556,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: hooks-rpm.tar.gz diff --git a/.github/workflows/ip-address-tests.yml b/.github/workflows/ip-address-tests.yml index b8aed5d4..44b92170 100644 --- a/.github/workflows/ip-address-tests.yml +++ b/.github/workflows/ip-address-tests.yml @@ -75,7 +75,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: ip_apache2_wsgi.tar.gz @@ -149,7 +149,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: ip_apache2_django.tar.gz @@ -223,7 +223,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: ip_nginx_wsgi.tar.gz @@ -299,7 +299,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: ip_nginx_django.tar.gz diff --git a/.github/workflows/ipv6-test.yml b/.github/workflows/ipv6-test.yml index 7e79d023..5567e07b 100644 --- a/.github/workflows/ipv6-test.yml +++ b/.github/workflows/ipv6-test.yml @@ -50,7 +50,7 @@ jobs: docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: lego_key-${{ matrix.keylength }}.tar.gz @@ -99,7 +99,7 @@ jobs: docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: lego_key-${{ matrix.keylength }}.tar.gz @@ -149,7 +149,7 @@ jobs: docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: lego_key-${{ matrix.keylength }}.tar.gz @@ -200,7 +200,7 @@ jobs: docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: lego_key-${{ matrix.keylength }}.tar.gz diff --git a/.github/workflows/lego-application-test.yml b/.github/workflows/lego-application-test.yml index 76802464..4e53bfb1 100644 --- a/.github/workflows/lego-application-test.yml +++ b/.github/workflows/lego-application-test.yml @@ -85,7 +85,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: lego_key-${{ matrix.keylength }}.tar.gz @@ -173,7 +173,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: lego_key-${{ matrix.keylength }}.tar.gz @@ -260,7 +260,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: lego_key-${{ matrix.keylength }}.tar.gz @@ -349,7 +349,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: lego_key-${{ matrix.keylength }}.tar.gz diff --git a/.github/workflows/manual-install-test.yml b/.github/workflows/manual-install-test.yml index 87cdc8c7..c753b5b3 100644 --- a/.github/workflows/manual-install-test.yml +++ b/.github/workflows/manual-install-test.yml @@ -65,7 +65,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: apache.tar.gz @@ -126,7 +126,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: nginx.tar.gz @@ -188,7 +188,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz acme-srv.log acme-sh - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: alma_nginx_wsgi.tar.gz @@ -268,7 +268,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: alma_nginx_wsgi_rpm.tar.gz @@ -362,7 +362,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: deb_apache.tar.gz @@ -488,7 +488,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: deb_nginx.tar.gz diff --git a/.github/workflows/proxy-test.yml b/.github/workflows/proxy-test.yml index b171932f..f3ef7182 100644 --- a/.github/workflows/proxy-test.yml +++ b/.github/workflows/proxy-test.yml @@ -252,7 +252,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: proxy.tar.gz @@ -559,7 +559,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data proxy.log acme-srv.log acme-sh - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: proxy-rpm.tar.gz diff --git a/.github/workflows/push_images_to_dockerhub.yml b/.github/workflows/push_images_to_dockerhub.yml index aadbb006..70f5eead 100644 --- a/.github/workflows/push_images_to_dockerhub.yml +++ b/.github/workflows/push_images_to_dockerhub.yml @@ -142,7 +142,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker.log data acme-sh - name: "[ * ] uploading artifacts" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: apache_wsgi.tar.gz @@ -205,7 +205,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker.log data acme-sh - name: "[ * ] uploading artifacts" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: apache_django.tar.gz @@ -257,7 +257,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker.log data acme-sh - name: "[ * ] uploading artifacts" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: nginx_wsgi.tar.gz @@ -312,7 +312,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker.log data acme-sh - name: "[ * ] uploading artifacts" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: nginx_django.tar.gz diff --git a/.github/workflows/test_headerinfo.yml b/.github/workflows/test_headerinfo.yml index 72724674..f9f0d6ba 100644 --- a/.github/workflows/test_headerinfo.yml +++ b/.github/workflows/test_headerinfo.yml @@ -81,7 +81,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: ap_wsgi_header_info.tar.gz @@ -166,7 +166,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: ap_django_header_info_tests.tar.gz @@ -250,7 +250,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: nginx_wsgi_header_info_tests.tar.gz @@ -341,7 +341,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: nginx_django_header_info_tests.tar.gz @@ -435,7 +435,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: rpm_header_info.ap_wsgi.tar.gz diff --git a/.github/workflows/tnauth-test.yml b/.github/workflows/tnauth-test.yml index b56aba37..c3253734 100644 --- a/.github/workflows/tnauth-test.yml +++ b/.github/workflows/tnauth-test.yml @@ -63,7 +63,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: tnauth.tar.gz @@ -150,7 +150,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme_sh - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: tnauth-rpm.tar.gz diff --git a/.github/workflows/traffic-application-test.yml b/.github/workflows/traffic-application-test.yml index 36b26636..cd7bb71c 100644 --- a/.github/workflows/traffic-application-test.yml +++ b/.github/workflows/traffic-application-test.yml @@ -82,7 +82,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data traefik - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: traffic-${{ matrix.challenge_type }}.tar.gz diff --git a/.github/workflows/upgrade_tests..yml b/.github/workflows/upgrade_tests..yml index 85198a53..76aa85e6 100644 --- a/.github/workflows/upgrade_tests..yml +++ b/.github/workflows/upgrade_tests..yml @@ -130,7 +130,7 @@ jobs: docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: apache2-wsgi-upgrade.tar.gz @@ -257,7 +257,7 @@ jobs: docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: nginx-wsgi-upgrade.tar.gz @@ -406,7 +406,7 @@ jobs: docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: apache2-django-upgrade.tar.gz @@ -555,7 +555,7 @@ jobs: docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: nginx-django-upgrade.tar.gz @@ -718,7 +718,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: rpm_wsgi_upgrade_nginx.tar.gz @@ -901,7 +901,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: rpm_django_upgrade_nginx_mariadb.tar.gz @@ -1066,7 +1066,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: rpm_django_upgrade_nginx_sqlite.tar.gz @@ -1259,7 +1259,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: rpm_django_upgrade_nginx_psql.tar.gz diff --git a/.github/workflows/winacme-application-test.yml b/.github/workflows/winacme-application-test.yml index ceb46bc2..a52090dd 100644 --- a/.github/workflows/winacme-application-test.yml +++ b/.github/workflows/winacme-application-test.yml @@ -145,7 +145,7 @@ jobs: cp acme_srv\acme_srv.cfg ${{ github.workspace }}\artifact\upload - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: win-acme.tar.gz diff --git a/.github/workflows/wsgi_handler-test.yml b/.github/workflows/wsgi_handler-test.yml index 32a1665d..b9fedf1b 100644 --- a/.github/workflows/wsgi_handler-test.yml +++ b/.github/workflows/wsgi_handler-test.yml @@ -73,7 +73,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: a2_custdb.tar.gz @@ -146,7 +146,7 @@ jobs: sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: nginx_cust_db.tar.gz From f8f4122cb95f1f5d0f10f00603fc721e5d27d0ab Mon Sep 17 00:00:00 2001 From: grindsa Date: Tue, 30 Jan 2024 17:16:52 +0100 Subject: [PATCH 039/460] [doc] linkfix --- docs/install_rpm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/install_rpm.md b/docs/install_rpm.md index 328a4e73..8c3ec5f5 100644 --- a/docs/install_rpm.md +++ b/docs/install_rpm.md @@ -17,7 +17,7 @@ $ sudo yum update -y $ sudo yum -y localinstall /tmp/acme2certifier/acme2certifier-0.23.1-1.0.noarch.rpm ``` -In case you install on Redhat 8.x you need to upgrade the [python3-jwcrypto package](https://jwcrypto.readthedocs.io/en/latest/) to version 0.8 or higher. A backport of the package being part of [RHEL9](https://rockylinux.pkgs.org/9/rockylinux-appstream-aarch64/python3-jwcrypto-0.8-4.el9.noarch.rpm.html) can be found in the [the a2c rpm repository](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/python3-jwcrypto-0.8-4.el8.noarch.rpm) +In case you install on Redhat 8.x you need to upgrade the [python3-jwcrypto package](https://jwcrypto.readthedocs.io/en/latest/) to version 0.8 or higher. A backport of the package being part of [RHEL9](https://rpmfind.net/linux/RPM/centos-stream/9/appstream/x86_64/python3-jwcrypto-0.8-4.el9.noarch.html) can be found in the [the a2c rpm repository](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/python3-jwcrypto-0.8-4.el8.noarch.rpm) 4. Copy NGINX configuration file From 949ebf2e363e7f2c2f6d5724d06fb0fd2bf17b85 Mon Sep 17 00:00:00 2001 From: grindsa Date: Tue, 30 Jan 2024 20:51:16 +0100 Subject: [PATCH 040/460] [feat] db update --- examples/db_handler/django_handler.py | 4 ++-- examples/db_handler/wsgi_handler.py | 16 ++++++++++++---- examples/django/acme_srv/models.py | 2 ++ 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/examples/db_handler/django_handler.py b/examples/db_handler/django_handler.py index b8a487b3..7311619d 100644 --- a/examples/db_handler/django_handler.py +++ b/examples/db_handler/django_handler.py @@ -273,10 +273,10 @@ def certificate_lookup(self, mkey: str, value: str, vlist: List[str] = ('name', self.logger.debug('DBStore.certificate_lookup() ended with: %s', result) return result - def certificates_search(self, mkey: str, value: str, vlist: List[str] = ('name', 'csr', 'cert', 'order__name'), operator=None) -> QuerySet[Certificate]: + def certificates_search(self, mkey: str, value: str, vlist: List[str] = ('name', 'csr', 'cert', 'order__name'), operant=None) -> QuerySet[Certificate]: """ search certificate based on "something" """ self.logger.debug('DBStore.certificates_search(%s:%s)', mkey, value) - mkey = self._modify_key(mkey, operator) + mkey = self._modify_key(mkey, operant) return Certificate.objects.filter(**{mkey: value}).values(*vlist) def challenge_lookup(self, mkey: str, value: str, vlist: List[str] = ('type', 'token', 'status__name')) -> Dict[str, str]: diff --git a/examples/db_handler/wsgi_handler.py b/examples/db_handler/wsgi_handler.py index 53a53d24..f2240a3c 100644 --- a/examples/db_handler/wsgi_handler.py +++ b/examples/db_handler/wsgi_handler.py @@ -156,7 +156,7 @@ def _certificate_update(self, data_dic: Dict[str, str], exists: Dict[str, str]) if 'replaced' not in data_dic: data_dic['replaced'] = exists['replaced'] - self.cursor.execute('''UPDATE Certificate SET cert = :cert, cert_raw = :cert_raw, issue_uts = :issue_uts, expire_uts = :expire_uts, renewal_info = :renewal_info, poll_identifier = :poll_identifier, replaced = :replaced, header_info = :header_info WHERE name = :name''', data_dic) + self.cursor.execute('''UPDATE Certificate SET cert = :cert, cert_raw = :cert_raw, issue_uts = :issue_uts, expire_uts = :expire_uts, renewal_info = :renewal_info, poll_identifier = :poll_identifier, replaced = :replaced, header_info = :header_info, serial = :serial, aki = :aki WHERE name = :name''', data_dic) self._db_close() rid = dict_from_row(exists)['id'] self.logger.debug('_certificate_update() ended with: %s', rid) @@ -282,7 +282,7 @@ def _db_create(self): ''') self.logger.debug('create certificate') self.cursor.execute(''' - CREATE TABLE "certificate" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(15) NOT NULL UNIQUE, "cert" text, "cert_raw" text, "error" text, "order_id" integer NOT NULL REFERENCES "order" ("id"), "csr" text NOT NULL, "poll_identifier" text, "header_info" text, "created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, "renewal_info" text, "issue_uts" integer DEFAULT 0, "expire_uts" integer DEFAULT 0, "replaced" bolean DEFAULT 0) + CREATE TABLE "certificate" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(15) NOT NULL UNIQUE, "cert" text, "cert_raw" text, "error" text, "order_id" integer NOT NULL REFERENCES "order" ("id"), "csr" text NOT NULL, "poll_identifier" text, "header_info" text, "created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, "renewal_info" text, "aki" text, "serial" text, "issue_uts" integer DEFAULT 0, "expire_uts" integer DEFAULT 0, "replaced" bolean DEFAULT 0) ''') self.cursor.execute(''' CREATE TABLE "housekeeping" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(15) NOT NULL UNIQUE, "value" text, "modified_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL) @@ -381,6 +381,12 @@ def _db_update_certificate(self): if 'header_info' not in certificate_column_list: self.logger.info('alter certificate table - add header_info') self.cursor.execute('''ALTER TABLE certificate ADD COLUMN header_info text''') + if 'aki' not in certificate_column_list: + self.logger.info('alter certificate table - add aki') + self.cursor.execute('''ALTER TABLE certificate ADD COLUMN aki text''') + if 'serial' not in certificate_column_list: + self.logger.info('alter certificate table - add serial') + self.cursor.execute('''ALTER TABLE certificate ADD COLUMN serial text''') def _db_update_challenge(self): """ alter challenge table """ @@ -863,7 +869,10 @@ def certificate_add(self, data_dic: Dict[str, str]) -> int: data_dic['renewal_info'] = exists['renewal_info'] if 'header_info' not in data_dic: data_dic['header_info'] = exists['header_info'] - + if 'aki' not in data_dic: + data_dic['aki'] = exists['aki'] + if 'serial' not in data_dic: + data_dic['serial'] = exists['serial'] rid = self._certificate_update(data_dic, exists) else: rid = self._certificate_insert(data_dic) @@ -964,7 +973,6 @@ def certificates_search(self, column: str, string: str, vlist: List[str] = ('nam WHERE {column} {operant} ?''' self.cursor.execute(pre_statement, [string]) rows = self.cursor.fetchall() - cert_list = [] for row in rows: lookup = dict_from_row(row) diff --git a/examples/django/acme_srv/models.py b/examples/django/acme_srv/models.py index 22be6d78..1f574df7 100644 --- a/examples/django/acme_srv/models.py +++ b/examples/django/acme_srv/models.py @@ -104,6 +104,8 @@ class Certificate(models.Model): expire_uts = models.IntegerField(default=0) issue_uts = models.IntegerField(default=0) renewal_info = models.TextField(null=True, blank=True) # NOSONAR + aki = models.TextField(null=True, blank=True) # NOSONAR + serial = models.TextField(null=True, blank=True) # NOSONAR replaced = models.BooleanField(default=False) header_info = models.TextField(null=True, blank=True) # NOSONAR created_at = models.DateTimeField(auto_now_add=True, null=True) # NOSONAR From f7112d8532e0d64edca4d3269e5a2a31c9bf3952 Mon Sep 17 00:00:00 2001 From: grindsa Date: Tue, 30 Jan 2024 20:52:00 +0100 Subject: [PATCH 041/460] [feat] serial-aki in enrollment --- acme_srv/certificate.py | 6 ++++-- acme_srv/helper.py | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/acme_srv/certificate.py b/acme_srv/certificate.py index e1f6ffbd..2c8162fb 100644 --- a/acme_srv/certificate.py +++ b/acme_srv/certificate.py @@ -4,7 +4,7 @@ from __future__ import print_function import json from typing import List, Tuple, Dict -from acme_srv.helper import b64_url_recode, generate_random_string, cert_cn_get, cert_san_get, cert_extensions_get, hooks_load, uts_now, uts_to_date_utc, date_to_uts_utc, load_config, csr_san_get, csr_extensions_get, cert_dates_get, ca_handler_load, error_dic_get, string_sanitize, pembundle_to_list, certid_asn1_get +from acme_srv.helper import b64_url_recode, generate_random_string, cert_cn_get, cert_san_get, cert_extensions_get, hooks_load, uts_now, uts_to_date_utc, date_to_uts_utc, load_config, csr_san_get, csr_extensions_get, cert_dates_get, ca_handler_load, error_dic_get, string_sanitize, pembundle_to_list, certid_asn1_get, cert_serial_get, cert_aki_get from acme_srv.db_handler import DBstore from acme_srv.message import Message from acme_srv.threadwithreturnvalue import ThreadWithReturnValue @@ -653,8 +653,10 @@ def _store_cert(self, certificate_name: str, certificate: str, raw: str, issue_u self.logger.debug('Certificate._store_cert(%s)', certificate_name) renewal_info_hex = self._renewal_info_get(certificate) + serial = cert_serial_get(self.logger, raw, hexformat=True) + aki = cert_aki_get(self.logger, raw) - data_dic = {'cert': certificate, 'name': certificate_name, 'cert_raw': raw, 'issue_uts': issue_uts, 'expire_uts': expire_uts, 'poll_identifier': poll_identifier, 'renewal_info': renewal_info_hex} + data_dic = {'cert': certificate, 'name': certificate_name, 'cert_raw': raw, 'issue_uts': issue_uts, 'expire_uts': expire_uts, 'poll_identifier': poll_identifier, 'renewal_info': renewal_info_hex, 'serial': serial, 'aki': aki} try: cert_id = self.dbstore.certificate_add(data_dic) except Exception as err_: diff --git a/acme_srv/helper.py b/acme_srv/helper.py index 3af0fb0c..a9e74d09 100644 --- a/acme_srv/helper.py +++ b/acme_srv/helper.py @@ -187,6 +187,42 @@ def hooks_load(logger: logging.Logger, config_dic: Dict) -> importlib.import_mod return hooks_module +def cert_aki_get(logger: logging.Logger, certificate: str) -> str: + """ get subject key identifier from certificate """ + logger.debug('cert_ski_get()') + + cert = cert_load(logger, certificate, recode=True) + try: + aki = cert.extensions.get_extension_for_oid(x509.OID_AUTHORITY_KEY_IDENTIFIER) + aki_value = aki.value.key_identifier.hex() + except Exception as err: + aki_value = cert_aki_pyopenssl_get(logger, certificate) + logger.debug('cert_aki_get() ended with: %s', aki_value) + return aki_value + + +def cert_aki_pyopenssl_get(logger, certificate: str) -> str: + """Get Authority Key Identifier from a certificate as a hex string.""" + logger.debug('cert_aki_pyopenssl_cert()') + + pem_data = convert_string_to_byte(build_pem_file(logger, None, b64_url_recode(logger, certificate), True)) + cert = crypto.load_certificate(crypto.FILETYPE_PEM, pem_data) + # Get the AKI extension + ski = None + for i in range(cert.get_extension_count()): + ext = cert.get_extension(i) + if 'subjectKeyIdentifier' in str(ext.get_short_name()): + aki = ext + if aki: + # Get the SKI value and convert it to hex + aki_hex = aki.get_data()[2:].hex() + else: + logger.error("cert_ski_pyopenssl_get(): No SKI found in certificate") + aki_hex = None + logger.debug('cert_ski_pyopenssl_cert() ended with: %s', aki_hex) + return aki_hex + + def cert_load(logger: logging.Logger, certificate: str, recode: bool) -> x509.Certificate: """ load certificate object from pem _Format """ logger.debug('cert_load(%s)', recode) From 3d51707187c081b6784754f23850e6460b12dcaa Mon Sep 17 00:00:00 2001 From: grindsa Date: Tue, 30 Jan 2024 20:52:16 +0100 Subject: [PATCH 042/460] [fix] populate serial-aki --- acme_srv/renewalinfo.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/acme_srv/renewalinfo.py b/acme_srv/renewalinfo.py index 4c0d9344..0f9c5d29 100644 --- a/acme_srv/renewalinfo.py +++ b/acme_srv/renewalinfo.py @@ -4,7 +4,7 @@ from typing import Dict from acme_srv.db_handler import DBstore from acme_srv.message import Message -from acme_srv.helper import string_sanitize, certid_hex_get, uts_to_date_utc, error_dic_get, load_config, uts_now +from acme_srv.helper import string_sanitize, certid_hex_get, uts_to_date_utc, error_dic_get, load_config, uts_now, cert_serial_get, cert_aki_get class Renewalinfo(object): @@ -51,6 +51,23 @@ def _config_load(self): except Exception as err_: self.logger.error('acme2certifier Renewalinfo._config_load() retry_after_timeout parsing error: %s', err_) + def _cert_table_update(self): + """ add serial and aki to certificate table """ + self.logger.debug('Renewalinfo._cert_table_update()') + + certificate_list = self.dbstore.certificates_search('serial', None, operant='is', vlist=['id', 'name', 'cert', 'cert_raw', 'serial', 'aki']) + + update_cnt = 0 + for cert in certificate_list: + if cert['cert_raw']: + serial = cert_serial_get(self.logger, cert['cert_raw'], hexformat=True) + aki = cert_aki_get(self.logger, cert['cert_raw']) + data_dic = {'serial': serial, 'aki': aki, 'name': cert['name'], 'cert_raw': cert['cert_raw'], 'cert': cert['cert']} + self.dbstore.certificate_add(data_dic) + update_cnt += 1 + + self.logger.debug('Renewalinfo._cert_table_update(%s) - done', update_cnt) + def _lookup(self, certid_hex: str) -> Dict[str, str]: """ lookup expiry dates based on renewal info """ self.logger.debug('Renewalinfo._lookup()') @@ -114,6 +131,9 @@ def get(self, url: str) -> Dict[str, str]: """ get renewal information """ self.logger.debug('Renewalinfo.get()') + # shousekeeping - add serial and aki to certificate table + self._cert_table_update() + # parse renewalinfo renewalinfo_string = self.renewalinfo_string_get(url) From a2d1d0d7f1a2c95b06ed3baae8732ef96c102dfb Mon Sep 17 00:00:00 2001 From: grindsa Date: Tue, 30 Jan 2024 21:02:55 +0100 Subject: [PATCH 043/460] [tst] unittests --- test/test_certificate.py | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/test/test_certificate.py b/test/test_certificate.py index 6e11cf98..63e052f9 100644 --- a/test/test_certificate.py +++ b/test/test_certificate.py @@ -45,25 +45,37 @@ def test_001_certificate_store_csr(self, mock_name): mock_name.return_value = 'bar' self.assertEqual('bar', self.certificate.store_csr('order_name', 'csr', 'header_info')) + @patch('acme_srv.certificate.cert_aki_get') + @patch('acme_srv.certificate.cert_serial_get') @patch('acme_srv.certificate.Certificate._renewal_info_get') - def test_002_certificate__store_cert(self, mock_renew): + def test_002_certificate__store_cert(self, mock_renew, mock_serial, mock_aki): """ test Certificate.store_cert() and check if we get something back """ self.certificate.dbstore.certificate_add.return_value = 'bar' mock_renew.return_value = 'renewal_info' + mock_serial.return_value = 'serial' + mock_aki.return_value = 'aki' self.assertEqual('bar', self.certificate._store_cert('cert_name', 'cert', 'raw')) self.assertTrue(mock_renew.called) + self.assertTrue(mock_serial.called) + self.assertTrue(mock_aki.called) + @patch('acme_srv.certificate.cert_aki_get') + @patch('acme_srv.certificate.cert_serial_get') @patch('acme_srv.certificate.generate_random_string') - def test_003_certificate_store_csr(self, mock_name): + def test_003_certificate_store_csr(self, mock_name, mock_serial, mock_aki): """ test Certificate.store_csr() with an exception store_csr """ self.certificate.dbstore.certificate_add.side_effect = Exception('exc_cert_add') mock_name.return_value = 'bar' with self.assertLogs('test_a2c', level='INFO') as lcm: self.assertEqual('bar', self.certificate.store_csr('order_name', 'csr', 'header_info')) self.assertIn('CRITICAL:test_a2c:Database error in Certificate.store_csr(): exc_cert_add', lcm.output) + self.assertFalse(mock_serial.called) + self.assertFalse(mock_aki.called) + @patch('acme_srv.certificate.cert_aki_get') + @patch('acme_srv.certificate.cert_serial_get') @patch('acme_srv.certificate.Certificate._renewal_info_get') - def test_004_certificate__store_cert(self, mock_renew): + def test_004_certificate__store_cert(self, mock_renew, mock_serial, mock_aki): """ test Certificate.store_cert() and check if we get something back """ self.certificate.dbstore.certificate_add.side_effect = Exception('exc_cert_add') mock_renew.return_value = 'renewal_info' @@ -71,6 +83,8 @@ def test_004_certificate__store_cert(self, mock_renew): self.assertFalse(self.certificate._store_cert('cert_name', 'cert', 'raw')) self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Certificate._store_cert(): exc_cert_add', lcm.output) self.assertTrue(mock_renew.called) + self.assertTrue(mock_serial.called) + self.assertTrue(mock_aki.called) def test_005_certificate__info(self): """ test Certificate.new_get() """ @@ -1582,8 +1596,10 @@ def test_142_certificate__invalidation_check(self): timestamp = 159624000 self.assertEqual((False, {'name': 'certname', 'cert': None, 'foo': 'bar'}), self.certificate._invalidation_check(cert_entry, timestamp)) + @patch('acme_srv.certificate.cert_aki_get') + @patch('acme_srv.certificate.cert_serial_get') @patch('acme_srv.certificate.Certificate._renewal_info_get') - def test_143_certificate_poll(self, mock_renew): + def test_143_certificate_poll(self, mock_renew, mock_serial, mock_aki): """ test Certificate.poll - dbstore.order_update() raises an exception """ self.certificate.dbstore.order_update.side_effect = Exception('exc_cert_poll') ca_handler_module = importlib.import_module('examples.ca_handler.skeleton_ca_handler') @@ -1594,6 +1610,8 @@ def test_143_certificate_poll(self, mock_renew): self.certificate.poll('certificate_name', 'poll_identifier', 'csr', 'order_name') self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Certificate.poll(): exc_cert_poll', lcm.output) self.assertTrue(mock_renew.called) + self.assertTrue(mock_serial.called) + self.assertTrue(mock_aki.called) def test_144_certificate_poll(self): """ test Certificate.poll - dbstore.order_update() raises an exception and certreq rejected """ @@ -1605,8 +1623,10 @@ def test_144_certificate_poll(self): self.certificate.poll('certificate_name', 'poll_identifier', 'csr', 'order_name') self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Certificate.poll(): exc_cert_poll', lcm.output) + @patch('acme_srv.certificate.cert_aki_get') + @patch('acme_srv.certificate.cert_serial_get') @patch('acme_srv.certificate.Certificate._renewal_info_get') - def test_145_certificate__store_cert(self, mock_renew): + def test_145_certificate__store_cert(self, mock_renew, mock_serial, mock_aki): """ test Certificate.store_cert() - dbstore.certificate_add raises an exception """ self.certificate.dbstore.certificate_add.side_effect = Exception('exc_cert_add') mock_renew.return_value = 'renewal_info' @@ -1614,6 +1634,8 @@ def test_145_certificate__store_cert(self, mock_renew): self.certificate._store_cert('cert_name', 'cert', 'raw') self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Certificate._store_cert(): exc_cert_add', lcm.output) self.assertTrue(mock_renew.called) + self.assertTrue(mock_serial.called) + self.assertTrue(mock_aki.called) def test_146_certificate__store_cert_error(self): """ test Certificate.store_cert_error() - dbstore.certificate_add raises an exception """ From 5abc2ddaff3cb04822deacdfb694d52224dfeb8b Mon Sep 17 00:00:00 2001 From: grindsa Date: Fri, 2 Feb 2024 07:36:59 +0100 Subject: [PATCH 044/460] [feat] support of draft-ietf-acme-ari-02 --- acme_srv/renewalinfo.py | 114 +++++++++++++++++++++++++++++----------- 1 file changed, 83 insertions(+), 31 deletions(-) diff --git a/acme_srv/renewalinfo.py b/acme_srv/renewalinfo.py index 0f9c5d29..f41e84e4 100644 --- a/acme_srv/renewalinfo.py +++ b/acme_srv/renewalinfo.py @@ -4,7 +4,7 @@ from typing import Dict from acme_srv.db_handler import DBstore from acme_srv.message import Message -from acme_srv.helper import string_sanitize, certid_hex_get, uts_to_date_utc, error_dic_get, load_config, uts_now, cert_serial_get, cert_aki_get +from acme_srv.helper import string_sanitize, certid_hex_get, uts_to_date_utc, error_dic_get, load_config, uts_now, cert_serial_get, cert_aki_get, b64_url_recode, b64_decode class Renewalinfo(object): @@ -51,6 +51,25 @@ def _config_load(self): except Exception as err_: self.logger.error('acme2certifier Renewalinfo._config_load() retry_after_timeout parsing error: %s', err_) + def _cert_dic_lookup(self, renewalinfo_string: str) -> Dict[str, str]: + """ lookup certificate based on renewalinfo string """ + self.logger.debug('Renewalinfo._cert_dic_lookup(%s)', renewalinfo_string) + + if '.' in renewalinfo_string: + # draft-ietf-acme-ari-02 + (serial, aki) = self._serial_aki_get(self.logger, renewalinfo_string) + # lookup database for certificate data + cert_dic = self._draft02_lookup(serial, aki) + + else: + # draft-ietf-acme-ari-01 + (_mda, certid_hex) = certid_hex_get(self.logger, renewalinfo_string) + # lookup database for certificate data + cert_dic = self._draft01_lookup(certid_hex) + + self.logger.debug('Renewalinfo._cert_dic_lookup(%s) - ended with: %s', renewalinfo_string, bool(cert_dic)) + return cert_dic + def _cert_table_update(self): """ add serial and aki to certificate table """ self.logger.debug('Renewalinfo._cert_table_update()') @@ -68,24 +87,38 @@ def _cert_table_update(self): self.logger.debug('Renewalinfo._cert_table_update(%s) - done', update_cnt) - def _lookup(self, certid_hex: str) -> Dict[str, str]: - """ lookup expiry dates based on renewal info """ - self.logger.debug('Renewalinfo._lookup()') + def _draft01_lookup(self, certid_hex: str) -> Dict[str, str]: + """ lookup expiry dates based on certid accoridng to acme-ari-01 """ + self.logger.debug('Renewalinfo._draft01_lookup()') try: result_dic = self.dbstore.certificate_lookup('renewal_info', certid_hex, ('id', 'name', 'cert', 'cert_raw', 'expire_uts', 'issue_uts', 'created_at')) except Exception as err_: - self.logger.critical('acme2certifier database error in Renewalinfo._lookup(): %s', err_) + self.logger.critical('acme2certifier database error in Renewalinfo._draft01_lookup(): %s', err_) result_dic = None return result_dic - def _renewalinfo_get(self, certid_hex: str) -> Dict[str, str]: - """ create dictionary containing renwal infor data """ - self.logger.debug('Renewalinfo.get()') + def _draft02_lookup(self, serial: str, aki: str) -> Dict[str, str]: + """ lookup expiry dates based on certid accoridng to acme-ari-02 """ + self.logger.debug('Renewalinfo._draft02_lookup()') + + cert_dic = {} + try: + cert_list = self.dbstore.certificates_search('serial', serial, operant='is', vlist=['id', 'name', 'cert', 'cert_raw', 'expire_uts', 'issue_uts', 'aki', 'created_at']) + for cert in cert_list: + if cert['aki'] == aki: + cert_dic = cert + break + except Exception as err_: + self.logger.critical('acme2certifier database error in Renewalinfo._lookup(): %s', err_) + + self.logger.debug('Renewalinfo._draft02_lookup() ended with: %s', bool(cert_dic)) + return cert_dic - # lookup database for certificate data - cert_dic = self._lookup(certid_hex) + def _renewalinfo_generate(self, cert_dic: Dict[str, str]) -> Dict[str, str]: + """ create dictionary containing renwal info data """ + self.logger.debug('Renewalinfo._renewalinfo_generate()') if 'expire_uts' in cert_dic and cert_dic['expire_uts']: @@ -111,9 +144,20 @@ def _renewalinfo_get(self, certid_hex: str) -> Dict[str, str]: else: renewalinfo_dic = {} + self.logger.debug('Renewalinfo._renewalinfo_generate() ended') return renewalinfo_dic - def renewalinfo_string_get(self, url: str) -> str: + def _renewalinfo_get(self, renewalinfo_string: str) -> Dict[str, str]: + """ get renewal info dictionary """ + self.logger.debug('Renewalinfo._renewalinfo_get()') + + cert_dic = self._cert_dic_lookup(renewalinfo_string) + rewalinfo_dic = self._renewalinfo_generate(cert_dic) + + self.logger.debug('Renewalinfo._renewalinfo_get() ended with: %s', rewalinfo_dic) + return rewalinfo_dic + + def _renewalinfo_string_get(self, url: str) -> str: """ get renewal string from url""" self.logger.debug('Renewalinfo.renewal_string_get()') @@ -127,6 +171,22 @@ def renewalinfo_string_get(self, url: str) -> str: self.logger.debug('Renewalinfo.renewal_string_get() - renewalinfo_string: %s', renewalinfo_string) return renewalinfo_string + def _serial_aki_get(self, logger: object, renewalinfo_string: str) -> (str, str): + """ get serial and aki from renewalinfo string """ + logger.debug('Renewalinfo._serial_aki_get()') + + # split renewalinfo_string + renewalinfo_list = renewalinfo_string.split('.') + + if len(renewalinfo_list) == 2: + serial = b64_decode(self.logger, b64_url_recode(self.logger, renewalinfo_list[1])).hex() + aki = b64_decode(self.logger, b64_url_recode(self.logger, renewalinfo_list[0])).hex() + else: + serial = None + aki = None + + return (serial, aki) + def get(self, url: str) -> Dict[str, str]: """ get renewal information """ self.logger.debug('Renewalinfo.get()') @@ -134,27 +194,21 @@ def get(self, url: str) -> Dict[str, str]: # shousekeeping - add serial and aki to certificate table self._cert_table_update() - # parse renewalinfo - renewalinfo_string = self.renewalinfo_string_get(url) + # parse renewalinfo string + renewalinfo_string = self._renewalinfo_string_get(url) - (mda, certid_hex) = certid_hex_get(self.logger, renewalinfo_string) + # get renewal information + rewalinfo_dic = self._renewalinfo_get(renewalinfo_string) response_dic = {} - # we cannot verify the AKI thus we accept any value - if mda: - # get renewal window datas - rewalinfo_dic = self._renewalinfo_get(certid_hex) - if rewalinfo_dic: - response_dic['code'] = 200 - # filter certificate and decode it - response_dic['data'] = rewalinfo_dic - # order status is processing - ratelimiting - response_dic['header'] = {'Retry-After': f'{self.retry_after_timeout}'.format()} - else: - response_dic['code'] = 404 - response_dic['data'] = self.err_msg_dic['malformed'] + if rewalinfo_dic: + response_dic['code'] = 200 + # filter certificate and decode it + response_dic['data'] = rewalinfo_dic + # order status is processing - ratelimiting + response_dic['header'] = {'Retry-After': f'{self.retry_after_timeout}'.format()} else: - response_dic['code'] = 400 + response_dic['code'] = 404 response_dic['data'] = self.err_msg_dic['malformed'] return response_dic @@ -169,9 +223,7 @@ def update(self, content: str) -> Dict[str, str]: response_dic = {} if code == 200 and 'certid' in payload and 'replaced' in payload: - (_mda, certid_hex) = certid_hex_get(self.logger, payload['certid']) - - cert_dic = self._lookup(certid_hex) + cert_dic = self._cert_dic_lookup(payload['certid']) if cert_dic and payload['replaced']: cert_dic['replaced'] = True From 1b2e4be93f23315b2cc3ea687531ee2ce36dec91 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 3 Feb 2024 09:09:59 +0100 Subject: [PATCH 045/460] [tst] Unittests --- acme_srv/helper.py | 10 +- acme_srv/renewalinfo.py | 17 ++- test/test_helper.py | 56 +++++++- test/test_renewalinfo.py | 298 ++++++++++++++++++++++++++------------- 4 files changed, 274 insertions(+), 107 deletions(-) diff --git a/acme_srv/helper.py b/acme_srv/helper.py index a9e74d09..da43f11f 100644 --- a/acme_srv/helper.py +++ b/acme_srv/helper.py @@ -195,7 +195,7 @@ def cert_aki_get(logger: logging.Logger, certificate: str) -> str: try: aki = cert.extensions.get_extension_for_oid(x509.OID_AUTHORITY_KEY_IDENTIFIER) aki_value = aki.value.key_identifier.hex() - except Exception as err: + except Exception as _err: aki_value = cert_aki_pyopenssl_get(logger, certificate) logger.debug('cert_aki_get() ended with: %s', aki_value) return aki_value @@ -208,16 +208,16 @@ def cert_aki_pyopenssl_get(logger, certificate: str) -> str: pem_data = convert_string_to_byte(build_pem_file(logger, None, b64_url_recode(logger, certificate), True)) cert = crypto.load_certificate(crypto.FILETYPE_PEM, pem_data) # Get the AKI extension - ski = None + aki = None for i in range(cert.get_extension_count()): ext = cert.get_extension(i) - if 'subjectKeyIdentifier' in str(ext.get_short_name()): + if 'authorityKeyIdentifier' in str(ext.get_short_name()): aki = ext if aki: # Get the SKI value and convert it to hex - aki_hex = aki.get_data()[2:].hex() + aki_hex = aki.get_data()[4:].hex() else: - logger.error("cert_ski_pyopenssl_get(): No SKI found in certificate") + logger.error("cert_ski_pyopenssl_get(): No AKI found in certificate") aki_hex = None logger.debug('cert_ski_pyopenssl_cert() ended with: %s', aki_hex) return aki_hex diff --git a/acme_srv/renewalinfo.py b/acme_srv/renewalinfo.py index f41e84e4..825898f7 100644 --- a/acme_srv/renewalinfo.py +++ b/acme_srv/renewalinfo.py @@ -57,7 +57,7 @@ def _cert_dic_lookup(self, renewalinfo_string: str) -> Dict[str, str]: if '.' in renewalinfo_string: # draft-ietf-acme-ari-02 - (serial, aki) = self._serial_aki_get(self.logger, renewalinfo_string) + (serial, aki) = self._serial_aki_get(renewalinfo_string) # lookup database for certificate data cert_dic = self._draft02_lookup(serial, aki) @@ -74,11 +74,15 @@ def _cert_table_update(self): """ add serial and aki to certificate table """ self.logger.debug('Renewalinfo._cert_table_update()') - certificate_list = self.dbstore.certificates_search('serial', None, operant='is', vlist=['id', 'name', 'cert', 'cert_raw', 'serial', 'aki']) + try: + certificate_list = self.dbstore.certificates_search('serial', None, operant='is', vlist=['id', 'name', 'cert', 'cert_raw', 'serial', 'aki']) + except Exception as err_: + self.logger.critical('acme2certifier database error in Renewalinfo._cert_table_update(): %s', err_) + certificate_list = [] update_cnt = 0 for cert in certificate_list: - if cert['cert_raw']: + if 'cert_raw' in cert and cert['cert_raw'] and 'name' in cert and 'cert' in cert: serial = cert_serial_get(self.logger, cert['cert_raw'], hexformat=True) aki = cert_aki_get(self.logger, cert['cert_raw']) data_dic = {'serial': serial, 'aki': aki, 'name': cert['name'], 'cert_raw': cert['cert_raw'], 'cert': cert['cert']} @@ -111,7 +115,7 @@ def _draft02_lookup(self, serial: str, aki: str) -> Dict[str, str]: cert_dic = cert break except Exception as err_: - self.logger.critical('acme2certifier database error in Renewalinfo._lookup(): %s', err_) + self.logger.critical('acme2certifier database error in Renewalinfo._draft02_lookup(): %s', err_) self.logger.debug('Renewalinfo._draft02_lookup() ended with: %s', bool(cert_dic)) return cert_dic @@ -171,9 +175,9 @@ def _renewalinfo_string_get(self, url: str) -> str: self.logger.debug('Renewalinfo.renewal_string_get() - renewalinfo_string: %s', renewalinfo_string) return renewalinfo_string - def _serial_aki_get(self, logger: object, renewalinfo_string: str) -> (str, str): + def _serial_aki_get(self, renewalinfo_string: str) -> (str, str): """ get serial and aki from renewalinfo string """ - logger.debug('Renewalinfo._serial_aki_get()') + self.logger.debug('Renewalinfo._serial_aki_get()') # split renewalinfo_string renewalinfo_list = renewalinfo_string.split('.') @@ -185,6 +189,7 @@ def _serial_aki_get(self, logger: object, renewalinfo_string: str) -> (str, str) serial = None aki = None + self.logger.debug('Renewalinfo._serial_aki_get() - serial: %s, aki: %s', serial, aki=aki) return (serial, aki) def get(self, url: str) -> Dict[str, str]: diff --git a/test/test_helper.py b/test/test_helper.py index 821d1653..e16909f7 100644 --- a/test/test_helper.py +++ b/test/test_helper.py @@ -26,7 +26,7 @@ def setUp(self): """ setup unittest """ import logging logging.basicConfig(level=logging.CRITICAL) - from acme_srv.helper import b64decode_pad, b64_decode, b64_encode, b64_url_encode, b64_url_recode, convert_string_to_byte, convert_byte_to_string, decode_message, decode_deserialize, get_url, generate_random_string, signature_check, validate_email, uts_to_date_utc, date_to_uts_utc, load_config, cert_serial_get, cert_san_get, cert_san_pyopenssl_get, cert_dates_get, build_pem_file, date_to_datestr, datestr_to_date, dkeys_lower, csr_cn_get, cert_pubkey_get, csr_pubkey_get, url_get, url_get_with_own_dns, dns_server_list_load, csr_san_get, csr_san_byte_get, csr_extensions_get, fqdn_resolve, fqdn_in_san_check, sha256_hash, sha256_hash_hex, cert_der2pem, cert_pem2der, cert_extensions_get, csr_dn_get, logger_setup, logger_info, print_debug, jwk_thumbprint_get, allowed_gai_family, patched_create_connection, validate_csr, servercert_get, txt_get, proxystring_convert, proxy_check, handle_exception, ca_handler_load, eab_handler_load, hooks_load, error_dic_get, _logger_nonce_modify, _logger_certificate_modify, _logger_token_modify, _logger_challenges_modify, config_check, cert_issuer_get, cert_cn_get, string_sanitize, pembundle_to_list, certid_asn1_get, certid_check, certid_hex_get, v6_adjust, ipv6_chk, ip_validate, header_info_get, encode_url, uts_now, cert_ski_get, cert_ski_pyopenssl_get + from acme_srv.helper import b64decode_pad, b64_decode, b64_encode, b64_url_encode, b64_url_recode, convert_string_to_byte, convert_byte_to_string, decode_message, decode_deserialize, get_url, generate_random_string, signature_check, validate_email, uts_to_date_utc, date_to_uts_utc, load_config, cert_serial_get, cert_san_get, cert_san_pyopenssl_get, cert_dates_get, build_pem_file, date_to_datestr, datestr_to_date, dkeys_lower, csr_cn_get, cert_pubkey_get, csr_pubkey_get, url_get, url_get_with_own_dns, dns_server_list_load, csr_san_get, csr_san_byte_get, csr_extensions_get, fqdn_resolve, fqdn_in_san_check, sha256_hash, sha256_hash_hex, cert_der2pem, cert_pem2der, cert_extensions_get, csr_dn_get, logger_setup, logger_info, print_debug, jwk_thumbprint_get, allowed_gai_family, patched_create_connection, validate_csr, servercert_get, txt_get, proxystring_convert, proxy_check, handle_exception, ca_handler_load, eab_handler_load, hooks_load, error_dic_get, _logger_nonce_modify, _logger_certificate_modify, _logger_token_modify, _logger_challenges_modify, config_check, cert_issuer_get, cert_cn_get, string_sanitize, pembundle_to_list, certid_asn1_get, certid_check, certid_hex_get, v6_adjust, ipv6_chk, ip_validate, header_info_get, encode_url, uts_now, cert_ski_get, cert_ski_pyopenssl_get, cert_aki_get, cert_aki_pyopenssl_get self.logger = logging.getLogger('test_a2c') self.allowed_gai_family = allowed_gai_family self.b64_decode = b64_decode @@ -44,6 +44,8 @@ def setUp(self): self.cert_san_get = cert_san_get self.cert_san_pyopenssl_get = cert_san_pyopenssl_get self.cert_serial_get = cert_serial_get + self.cert_aki_get = cert_aki_get + self.cert_aki_pyopenssl_get = cert_aki_pyopenssl_get self.cert_ski_get = cert_ski_get self.cert_ski_pyopenssl_get = cert_ski_pyopenssl_get self.cert_issuer_get = cert_issuer_get @@ -2159,5 +2161,57 @@ def test_281_ski_get(self, mock_load): self.assertFalse(self.cert_ski_pyopenssl_get(self.logger, cert)) self.assertIn('ERROR:test_a2c:cert_ski_pyopenssl_get(): No SKI found in certificate', lcm.output) + def test_282_cert_aki_get(self): + """ test cert_san_get aki""" + cert = """MIIEOzCCAiOgAwIBAgIIKndYX0qdb04wDQYJKoZIhvcNAQELBQAwKjEXMBUGA1UE + CxMOYWNtZTJjZXJ0aWZpZXIxDzANBgNVBAMTBnN1Yi1jYTAeFw0yNDAxMjkyMDA0 + NTZaFw0yNTAxMjgyMDA0NTZaMD8xFzAVBgNVBAMTDmxlZ28uYmFyLmxvY2FsMRcw + FQYDVQQKDA5hY21lMmNlcnRpZmllcjELMAkGA1UEBhMCREUwWTATBgcqhkjOPQIB + BggqhkjOPQMBBwNCAAQKIqEIxeS0JIN+iqsJ+08IJFFmuvfpjFnH4wFD2OLlmeTv + fpDsnD00uw/orLvecDvjt48JvgYR8Wv+9C4ajIDfo4IBGTCCARUwHQYDVR0OBBYE + FCka80MPgj45/quHJ9oF8Cc1YlsXMB8GA1UdIwQYMBaAFL/ejo4GIiKrrUPI3dRP + qKtIQT7VMAsGA1UdDwQEAwID6DBRBgNVHSUBAf8ERzBFBggrBgEFBQcDAQYIKwYB + BQUHAwIGCCsGAQUFBwMDBggrBgEFBQcDBAYIKwYBBQUHAwgGCCsGAQUFBwMJBgcr + BgEFAgMFMEoGA1UdHwRDMEEwHqAcoBqGGFVSSTpodHRwOi8vZm9vLmJhci5sb2Nh + bDAfoB2gG4YZVVJJOmh0dHA6Ly9mb28xLmJhci5sb2NhbDAMBgNVHRMBAf8EAjAA + MBkGA1UdEQQSMBCCDmxlZ28uYmFyLmxvY2FsMA0GCSqGSIb3DQEBCwUAA4ICAQB4 + FxJwQ/aILMzh7jBSr358RA92mX8srPmzQrjPYoU7T2LxwMf+eb0z5x0PMFH8j5Fg + RvRGWo6rcco8rL+B+gvrVhQ0TfAFEF77WJfKG2XMlnEN/9Ri73J7+dA45kaw8CZR + SfUBpIW6fb4N+6frXyIKwBaZnrT6qiy+Izu+ZH6RkaTFrBn5yOWvVyk7aBHE1eZ+ + 3+eA3qBI4UPaeYFSwr3gY5dxfbPktlFgvpCI22ff4NAb/fzjAQsKRTkXkOVqAvBJ + cWI5d/g32IVMLq0ub13XLe+yHk0iCxyMaIRdN4+W6RYi3gvtTQh6LaOjncWDYLds + m+vN+YqXEqieY5TC1oC8kG9We9eHzKHdNquJnrju536DPqh4xYEDcb+PGvTr3sqY + dSikA9v5FuWUGeiZD/ZEvw/p7F7DevD5NO1JaOtfWDwDwxFHEyn+iwTVq3QDEc4j + +oyGnQJs5Spoyz3tJi31VMJk+EAKKUV66aVNynLM7Ce4Oj0M67o4pcnDd0uWBMSA + g4lH8KIX0IsmMfLnirIqOOwrZ4UkPKlEjD+oZQf5IBukfdHob/bo4fW8q4eU/I8z + 9w3BTdV1yNVH/ANHg5AItoPabkr65oBTwY51j3FVq0gK+4xVrevcyIeY3A9XFzA1 + 8k/gX7O/kf/IrM0dcZWJnsW39byiWhUd4JetJaGeKg""" + self.assertEqual('bfde8e8e062222abad43c8ddd44fa8ab48413ed5', self.cert_aki_get(self.logger, cert)) + + def test_283_cert_aki_pyopenssl_get(self): + """ test cert_san_get aki""" + cert = 'MIIEOzCCAiOgAwIBAgIIKndYX0qdb04wDQYJKoZIhvcNAQELBQAwKjEXMBUGA1UECxMOYWNtZTJjZXJ0aWZpZXIxDzANBgNVBAMTBnN1Yi1jYTAeFw0yNDAxMjkyMDA0NTZaFw0yNTAxMjgyMDA0NTZaMD8xFzAVBgNVBAMTDmxlZ28uYmFyLmxvY2FsMRcwFQYDVQQKDA5hY21lMmNlcnRpZmllcjELMAkGA1UEBhMCREUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQKIqEIxeS0JIN+iqsJ+08IJFFmuvfpjFnH4wFD2OLlmeTvfpDsnD00uw/orLvecDvjt48JvgYR8Wv+9C4ajIDfo4IBGTCCARUwHQYDVR0OBBYEFCka80MPgj45/quHJ9oF8Cc1YlsXMB8GA1UdIwQYMBaAFL/ejo4GIiKrrUPI3dRPqKtIQT7VMAsGA1UdDwQEAwID6DBRBgNVHSUBAf8ERzBFBggrBgEFBQcDAQYIKwYBBQUHAwIGCCsGAQUFBwMDBggrBgEFBQcDBAYIKwYBBQUHAwgGCCsGAQUFBwMJBgcrBgEFAgMFMEoGA1UdHwRDMEEwHqAcoBqGGFVSSTpodHRwOi8vZm9vLmJhci5sb2NhbDAfoB2gG4YZVVJJOmh0dHA6Ly9mb28xLmJhci5sb2NhbDAMBgNVHRMBAf8EAjAAMBkGA1UdEQQSMBCCDmxlZ28uYmFyLmxvY2FsMA0GCSqGSIb3DQEBCwUAA4ICAQB4FxJwQ/aILMzh7jBSr358RA92mX8srPmzQrjPYoU7T2LxwMf+eb0z5x0PMFH8j5FgRvRGWo6rcco8rL+B+gvrVhQ0TfAFEF77WJfKG2XMlnEN/9Ri73J7+dA45kaw8CZRSfUBpIW6fb4N+6frXyIKwBaZnrT6qiy+Izu+ZH6RkaTFrBn5yOWvVyk7aBHE1eZ+3+eA3qBI4UPaeYFSwr3gY5dxfbPktlFgvpCI22ff4NAb/fzjAQsKRTkXkOVqAvBJcWI5d/g32IVMLq0ub13XLe+yHk0iCxyMaIRdN4+W6RYi3gvtTQh6LaOjncWDYLdsm+vN+YqXEqieY5TC1oC8kG9We9eHzKHdNquJnrju536DPqh4xYEDcb+PGvTr3sqYdSikA9v5FuWUGeiZD/ZEvw/p7F7DevD5NO1JaOtfWDwDwxFHEyn+iwTVq3QDEc4j+oyGnQJs5Spoyz3tJi31VMJk+EAKKUV66aVNynLM7Ce4Oj0M67o4pcnDd0uWBMSAg4lH8KIX0IsmMfLnirIqOOwrZ4UkPKlEjD+oZQf5IBukfdHob/bo4fW8q4eU/I8z9w3BTdV1yNVH/ANHg5AItoPabkr65oBTwY51j3FVq0gK+4xVrevcyIeY3A9XFzA18k/gX7O/kf/IrM0dcZWJnsW39byiWhUd4JetJaGeKg' + self.assertEqual('bfde8e8e062222abad43c8ddd44fa8ab48413ed5', self.cert_aki_pyopenssl_get(self.logger, cert)) + + @patch('acme_srv.helper.cert_aki_pyopenssl_get') + @patch('acme_srv.helper.cert_load') + def test_284_aki_get(self, mock_load, mock_aki): + """ test cert_ski_get() """ + cert = 'cert' + mock_aki.return_value = 'mock_aki' + mock_load.return_value = 'mock_load' + self.assertEqual('mock_aki', self.cert_aki_get(self.logger, cert)) + self.assertTrue(mock_aki.called) + + @patch('OpenSSL.crypto.load_certificate') + def test_281_aki_get(self, mock_load): + """ test cert_aki_get() """ + cert = 'cert' + mock_load.get_extension_count.return_value = 2 + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.cert_aki_pyopenssl_get(self.logger, cert)) + self.assertIn('ERROR:test_a2c:cert_ski_pyopenssl_get(): No AKI found in certificate', lcm.output) + + if __name__ == '__main__': unittest.main() diff --git a/test/test_renewalinfo.py b/test/test_renewalinfo.py index ebcdcc31..5d691db0 100644 --- a/test/test_renewalinfo.py +++ b/test/test_renewalinfo.py @@ -159,93 +159,33 @@ def test_011_config_enter(self, mock_load_cfg): self.renewalinfo.__enter__() self.assertTrue(mock_load_cfg.called) - def test_012_lookup(self): - """ test _lookup() """ - self.renewalinfo.dbstore.certificate_lookup.return_value = {'foo': 'bar'} - self.assertEqual({'foo': 'bar'}, self.renewalinfo._lookup('foo1')) - - def test_013_lookup(self): - """ test _lookup() """ - self.renewalinfo.dbstore.certificate_lookup.side_effect = Exception('cert_lookup') - with self.assertLogs('test_a2c', level='INFO') as lcm: - self.assertFalse(self.renewalinfo._lookup('foo1')) - self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Renewalinfo._lookup(): cert_lookup', lcm.output) - - @patch('acme_srv.renewalinfo.Renewalinfo._lookup') - def test_014_renewalinfo_get(self, mock_lookup): - """ test _renewalinfo_get() """ - mock_lookup.return_value = {} - self.assertFalse(self.renewalinfo._renewalinfo_get('1a2b3c4d5e6f')) - - @patch('acme_srv.renewalinfo.Renewalinfo._lookup') - def test_015_renewalinfo_get(self, mock_lookup): + @patch('acme_srv.renewalinfo.Renewalinfo._renewalinfo_generate') + @patch('acme_srv.renewalinfo.Renewalinfo._cert_dic_lookup') + def test_019_renewalinfo_get(self, mock_lookup, mock_gen): """ test _renewalinfo_get() """ - mock_lookup.return_value = {'foo': 'bar'} - self.assertFalse(self.renewalinfo._renewalinfo_get('1a2b3c4d5e6f')) - - @patch('acme_srv.renewalinfo.Renewalinfo._lookup') - def test_016_renewalinfo_get(self, mock_lookup): - """ test _renewalinfo_get() """ - mock_lookup.return_value = {'expire_uts': 0} - self.assertFalse(self.renewalinfo._renewalinfo_get('1a2b3c4d5e6f')) - - @patch('acme_srv.renewalinfo.Renewalinfo._lookup') - def test_017_renewalinfo_get(self, mock_lookup): - """ test _renewalinfo_get() """ - mock_lookup.return_value = {'expire_uts': 1000, 'issue_uts': 100} - self.assertEqual({'suggestedWindow': {'start': '1970-01-01T00:14:25Z', 'end': '1970-01-01T00:16:40Z'}}, self.renewalinfo._renewalinfo_get('1a2b3c4d5e6f')) - - @patch('acme_srv.renewalinfo.uts_now') - @patch('acme_srv.renewalinfo.Renewalinfo._lookup') - def test_018_renewalinfo_get(self, mock_lookup, mock_uts): - """ test _renewalinfo_get() """ - mock_uts.return_value = 100 - mock_lookup.return_value = {'expire_uts': 1000} - self.assertEqual({'suggestedWindow': {'start': '1970-01-01T00:14:25Z', 'end': '1970-01-01T00:16:40Z'}}, self.renewalinfo._renewalinfo_get('1a2b3c4d5e6f')) - self.assertTrue(mock_uts.called) - - @patch('acme_srv.renewalinfo.uts_now') - @patch('acme_srv.renewalinfo.Renewalinfo._lookup') - def test_019_renewalinfo_get(self, mock_lookup, mock_uts): - """ test _renewalinfo_get() """ - mock_uts.return_value = 86400000 - mock_lookup.return_value = {'expire_uts': 1000, 'issue_uts': 200} - self.renewalinfo.renewal_force = True - self.assertEqual({'suggestedWindow': {'start': '1971-09-29T00:00:00Z', 'end': '1972-09-28T00:00:00Z'}}, self.renewalinfo._renewalinfo_get('1a2b3c4d5e6f')) - self.assertTrue(mock_uts.called) + mock_gen.return_value = {'foo': 'bar'} + self.assertEqual({'foo': 'bar'}, self.renewalinfo._renewalinfo_get('1a2b3c4d5e6f')) + self.assertTrue(mock_lookup.called) @patch('acme_srv.renewalinfo.Renewalinfo._renewalinfo_get') - @patch('acme_srv.renewalinfo.certid_hex_get') - @patch('acme_srv.renewalinfo.string_sanitize') - def test_020_get(self, mock_sanitize, mock_hexget, mock_renget): + @patch('acme_srv.renewalinfo.Renewalinfo._renewalinfo_string_get') + @patch('acme_srv.renewalinfo.Renewalinfo._cert_table_update') + def test_020_get(self, mock_update, mock_renstr_get, mock_renget): """ test get() """ mock_renget.return_value = {'foo': 'bar'} - mock_hexget.return_value = ('300b0609608648016503040201', 'bar') + mock_renstr_get.return_value = 'mock_renstr_get' self.assertEqual({'code': 200, 'data': {'foo': 'bar'}, 'header': {'Retry-After': '86400'}}, self. renewalinfo.get('url')) - self.assertTrue(mock_sanitize.called) - self.assertTrue(mock_hexget.called) + self.assertTrue(mock_update.called) @patch('acme_srv.renewalinfo.Renewalinfo._renewalinfo_get') - @patch('acme_srv.renewalinfo.certid_hex_get') - @patch('acme_srv.renewalinfo.string_sanitize') - def test_021_get(self, mock_sanitize, mock_hexget, mock_renget): + @patch('acme_srv.renewalinfo.Renewalinfo._renewalinfo_string_get') + @patch('acme_srv.renewalinfo.Renewalinfo._cert_table_update') + def test_022_get(self, mock_update, mock_renstr_get, mock_renget): """ test get() """ mock_renget.return_value = None - mock_hexget.return_value = ('300b0609608648016503040201', 'bar') self.assertEqual({'code': 404, 'data': 'urn:ietf:params:acme:error:malformed'}, self. renewalinfo.get('url')) - self.assertTrue(mock_sanitize.called) - self.assertTrue(mock_hexget.called) - - @patch('acme_srv.renewalinfo.Renewalinfo._renewalinfo_get') - @patch('acme_srv.renewalinfo.certid_hex_get') - @patch('acme_srv.renewalinfo.string_sanitize') - def test_022_get(self, mock_sanitize, mock_hexget, mock_renget): - """ test get() """ - mock_renget.return_value = None - mock_hexget.return_value = (None, 'bar') - self.assertEqual({'code': 400, 'data': 'urn:ietf:params:acme:error:malformed'}, self. renewalinfo.get('url')) - self.assertTrue(mock_sanitize.called) - self.assertTrue(mock_hexget.called) + self.assertTrue(mock_update.called) + self.assertTrue(mock_renstr_get.called) @patch('acme_srv.message.Message.check') def test_023_update(self, mock_mcheck): @@ -259,44 +199,36 @@ def test_024_update(self, mock_mcheck): mock_mcheck.return_value = (200, 'message', 'detail', 'protected', {'certid': 'certid'}, 'account_name') self.assertEqual({'code': 400}, self.renewalinfo.update('content')) - @patch('acme_srv.renewalinfo.Renewalinfo._lookup') - @patch('acme_srv.renewalinfo.certid_hex_get') + @patch('acme_srv.renewalinfo.Renewalinfo._cert_dic_lookup') @patch('acme_srv.message.Message.check') - def test_025_update(self, mock_mcheck, mock_hex, mock_lookup): + def test_025_update(self, mock_mcheck, mock_lookup): """ test update() """ mock_mcheck.return_value = (200, 'message', 'detail', 'protected', {'certid': 'certid', 'replaced': True}, 'account_name') - mock_hex.return_value = ('300b0609608648016503040201', 'certhex') mock_lookup.return_value = None self.assertEqual({'code': 400}, self.renewalinfo.update('content')) - @patch('acme_srv.renewalinfo.Renewalinfo._lookup') - @patch('acme_srv.renewalinfo.certid_hex_get') + @patch('acme_srv.renewalinfo.Renewalinfo._cert_dic_lookup') @patch('acme_srv.message.Message.check') - def test_026_update(self, mock_mcheck, mock_hex, mock_lookup): + def test_026_update(self, mock_mcheck, mock_lookup): """ test update() """ mock_mcheck.return_value = (200, 'message', 'detail', 'protected', {'certid': 'certid', 'replaced': False}, 'account_name') - mock_hex.return_value = ('300b0609608648016503040201', 'certhex') mock_lookup.return_value = {'foo': 'bar'} self.assertEqual({'code': 400}, self.renewalinfo.update('content')) - @patch('acme_srv.renewalinfo.Renewalinfo._lookup') - @patch('acme_srv.renewalinfo.certid_hex_get') + @patch('acme_srv.renewalinfo.Renewalinfo._cert_dic_lookup') @patch('acme_srv.message.Message.check') - def test_027_update(self, mock_mcheck, mock_hex, mock_lookup): + def test_027_update(self, mock_mcheck, mock_lookup): """ test update() """ mock_mcheck.return_value = (200, 'message', 'detail', 'protected', {'certid': 'certid', 'replaced': True}, 'account_name') - mock_hex.return_value = ('300b0609608648016503040201', 'certhex') mock_lookup.return_value = {'foo': 'bar'} self.renewalinfo.dbstore.certificate_add.return_value = None self.assertEqual({'code': 400}, self.renewalinfo.update('content')) - @patch('acme_srv.renewalinfo.Renewalinfo._lookup') - @patch('acme_srv.renewalinfo.certid_hex_get') + @patch('acme_srv.renewalinfo.Renewalinfo._cert_dic_lookup') @patch('acme_srv.message.Message.check') - def test_028_update(self, mock_mcheck, mock_hex, mock_lookup): + def test_028_update(self, mock_mcheck, mock_lookup): """ test update() """ mock_mcheck.return_value = (200, 'message', 'detail', 'protected', {'certid': 'certid', 'replaced': True}, 'account_name') - mock_hex.return_value = ('300b0609608648016503040201', 'certhex') mock_lookup.return_value = {'foo': 'bar'} self.renewalinfo.dbstore.certificate_add.return_value = 1 self.assertEqual({'code': 200}, self.renewalinfo.update('content')) @@ -306,21 +238,197 @@ def test_029_renewalinfo_string_get(self): self.renewalinfo.server_name = 'http://server.name' self.renewalinfo.path_dic = {'renewalinfo': '/renewalinfo'} input_string = 'http://server.name/renewalinfo/foo' - self.assertEqual('foo', self.renewalinfo.renewalinfo_string_get(input_string)) + self.assertEqual('foo', self.renewalinfo._renewalinfo_string_get(input_string)) def test_030_renewalinfo_string_get(self): """ test update() """ self.renewalinfo.server_name = 'http://server.name' self.renewalinfo.path_dic = {'renewalinfo': '/renewalinfo'} input_string = 'http://server.name/renewalinfofoo' - self.assertEqual('foo', self.renewalinfo.renewalinfo_string_get(input_string)) + self.assertEqual('foo', self.renewalinfo._renewalinfo_string_get(input_string)) def test_031_renewalinfo_string_get(self): """ test update() """ self.renewalinfo.server_name = 'http://server.name' self.renewalinfo.path_dic = {'renewalinfo': '/renewalinfo/'} input_string = 'http://server.name/renewalinfo/foo' - self.assertEqual('foo', self.renewalinfo.renewalinfo_string_get(input_string)) + self.assertEqual('foo', self.renewalinfo._renewalinfo_string_get(input_string)) + + @patch('acme_srv.renewalinfo.Renewalinfo._draft02_lookup') + @patch('acme_srv.renewalinfo.Renewalinfo._draft01_lookup') + @patch('acme_srv.renewalinfo.certid_hex_get') + @patch('acme_srv.renewalinfo.Renewalinfo._serial_aki_get') + def test_032_cert_dic_lookup(self, mock_aki, mock_certid, mock_draft01, mock_draft02): + """ test _cert_dic_lookup() """ + mock_aki.return_value = ('serail', 'aki') + mock_draft01.return_value = {'foo': 'draft01'} + mock_draft02.return_value = {'foo': 'draft02'} + self.assertEqual({'foo': 'draft02'}, self.renewalinfo._cert_dic_lookup('cert.id')) + self.assertTrue(mock_aki.called) + self.assertFalse(mock_certid.called) + self.assertFalse(mock_draft01.called) + self.assertTrue(mock_draft02.called) + + @patch('acme_srv.renewalinfo.Renewalinfo._draft02_lookup') + @patch('acme_srv.renewalinfo.Renewalinfo._draft01_lookup') + @patch('acme_srv.renewalinfo.certid_hex_get') + @patch('acme_srv.renewalinfo.Renewalinfo._serial_aki_get') + def test_033_cert_dic_lookup(self, mock_aki, mock_certid, mock_draft01, mock_draft02): + """ test _cert_dic_lookup() """ + mock_aki.return_value = ('serail', 'aki') + mock_certid.return_value = ('mda', 'certid') + mock_draft01.return_value = {'foo': 'draft01'} + mock_draft02.return_value = {'foo': 'draft02'} + self.assertEqual({'foo': 'draft01'}, self.renewalinfo._cert_dic_lookup('certid')) + self.assertFalse(mock_aki.called) + self.assertTrue(mock_certid.called) + self.assertTrue(mock_draft01.called) + self.assertFalse(mock_draft02.called) + + def test_034_draft01_lookup(self): + """ test _draft01_lookup() """ + self.renewalinfo.dbstore.certificate_lookup.return_value = {'foo': 'bar'} + self.assertEqual({'foo': 'bar'}, self.renewalinfo._draft01_lookup('certid_hex')) + + def test_035_draft01_lookup(self): + """ test _draft01_lookup() """ + self.renewalinfo.dbstore.certificate_lookup.side_effect = Exception('cert_lookup') + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.renewalinfo._draft01_lookup('certid_hex')) + self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Renewalinfo._draft01_lookup(): cert_lookup', lcm.output) + + def test_036_draft02_lookup(self): + """ test _draft02_lookup() """ + self.renewalinfo.dbstore.certificates_search.return_value = [{'foo': 'bar01', 'aki': 'aki01'}, {'foo': 'bar02', 'aki': 'aki02'}] + self.assertEqual({'aki': 'aki01', 'foo': 'bar01'}, self.renewalinfo._draft02_lookup('serial', 'aki01')) + + def test_037_draft02_lookup(self): + """ test _draft02_lookup() """ + self.renewalinfo.dbstore.certificates_search.return_value = [{'foo': 'bar01', 'aki': 'aki01'}, {'foo': 'bar02', 'aki': 'aki02'}] + self.assertEqual({'aki': 'aki02', 'foo': 'bar02'}, self.renewalinfo._draft02_lookup('serial', 'aki02')) + + @patch('acme_srv.renewalinfo.cert_aki_get') + @patch('acme_srv.renewalinfo.cert_serial_get') + def test_038_cert_table_update(self, mock_serial, mock_aki): + """ test _cert_table_update() """ + self.renewalinfo.dbstore.certificates_search.return_value = [{'foo': 'bar', 'cert_raw': 'cert_raw', 'name': 'name', 'cert': 'cert'}] + self.assertFalse(self.renewalinfo._cert_table_update()) + self.assertTrue(mock_serial.called) + self.assertTrue(mock_aki.called) + + @patch('acme_srv.renewalinfo.cert_aki_get') + @patch('acme_srv.renewalinfo.cert_serial_get') + def test_039_cert_table_update(self, mock_serial, mock_aki): + """ test _cert_table_update() """ + self.renewalinfo.dbstore.certificates_search.return_value = [{'foo': 'bar', 'cert_raw': None, 'name': 'name', 'cert': 'cert'}] + self.assertFalse(self.renewalinfo._cert_table_update()) + self.assertFalse(mock_serial.called) + self.assertFalse(mock_aki.called) + + @patch('acme_srv.renewalinfo.cert_aki_get') + @patch('acme_srv.renewalinfo.cert_serial_get') + def test_040_cert_table_update(self, mock_serial, mock_aki): + """ test _cert_table_update() """ + self.renewalinfo.dbstore.certificates_search.return_value = [{'foo': 'bar', 'name': 'name', 'cert': 'cert'}] + self.assertFalse(self.renewalinfo._cert_table_update()) + self.assertFalse(mock_serial.called) + self.assertFalse(mock_aki.called) + + @patch('acme_srv.renewalinfo.cert_aki_get') + @patch('acme_srv.renewalinfo.cert_serial_get') + def test_041_cert_table_update(self, mock_serial, mock_aki): + """ test _cert_table_update() """ + self.renewalinfo.dbstore.certificates_search.return_value = Exception('certificates_search') + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.renewalinfo._cert_table_update()) + self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Renewalinfo._cert_table_update(): certificates_search', lcm.output) + self.assertFalse(mock_serial.called) + self.assertFalse(mock_aki.called) + + def test_038_draft02_lookup(self): + """ test _draft02_lookup() """ + self.renewalinfo.dbstore.certificates_search.return_value = [{'foo': 'bar01', 'aki': 'aki01'}, {'foo': 'bar02', 'aki': 'aki02'}] + self.assertFalse(self.renewalinfo._draft02_lookup('serial', 'aki03')) + + def test_039_draft02_lookup(self): + """ test _draft02_lookup() """ + self.renewalinfo.dbstore.certificates_search.return_value = [{'foo': 'bar01', }, {'foo': 'bar02', 'aki': 'aki02'}] + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.renewalinfo._draft02_lookup('serial', 'aki03')) + self.assertIn("CRITICAL:test_a2c:acme2certifier database error in Renewalinfo._draft02_lookup(): 'aki'", lcm.output) + + def test_040_draft02_lookup(self): + """ test _draft02_lookup() """ + self.renewalinfo.dbstore.certificates_search.side_effect = Exception('certificates_search') + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.renewalinfo._draft02_lookup('serial', 'aki03')) + self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Renewalinfo._draft02_lookup(): certificates_search', lcm.output) + + @patch('acme_srv.renewalinfo.b64_url_recode') + @patch('acme_srv.renewalinfo.b64_decode') + def test_041_serial_aki_get(self, mock_dec, mock_rec): + """ test _serial_aki_get() """ + mock_dec.side_effect = [b'aki', b'serial'] + mock_rec.side_effect = ['foo1', 'foo2'] + self.assertEqual(('616b69', '73657269616c'), self.renewalinfo._serial_aki_get('renewal.info')) + self.assertEqual(2, mock_dec.call_count) + self.assertEqual(2, mock_rec.call_count) + + @patch('acme_srv.renewalinfo.b64_url_recode') + @patch('acme_srv.renewalinfo.b64_decode') + def test_042_serial_aki_get(self, mock_dec, mock_rec): + """ test _serial_aki_get() """ + mock_dec.side_effect = [b'aki', b'serial'] + mock_rec.side_effect = ['foo1', 'foo2'] + self.assertEqual((None, None), self.renewalinfo._serial_aki_get('ren.ewal.info')) + self.assertFalse(mock_dec.called) + self.assertFalse(mock_rec.called) + + @patch('acme_srv.renewalinfo.b64_url_recode') + @patch('acme_srv.renewalinfo.b64_decode') + def test_043_serial_aki_get(self, mock_dec, mock_rec): + """ test _serial_aki_get() """ + mock_dec.side_effect = [b'aki', b'serial'] + mock_rec.side_effect = ['foo1', 'foo2'] + self.assertEqual((None, None), self.renewalinfo._serial_aki_get('renewalinfo')) + self.assertFalse(mock_dec.called) + self.assertFalse(mock_rec.called) + + def test_014_renewalinfo_generate(self): + """ test _renewalinfo_generate() """ + self.assertFalse(self.renewalinfo._renewalinfo_generate({})) + + def test_015_renewalinfo_generate(self): + """ test _renewalinfo_generate() """ + cert_dic = {'foo': 'bar'} + self.assertFalse(self.renewalinfo._renewalinfo_generate(cert_dic)) + + def test_016_renewalinfo_generate(self): + """ test _renewalinfo_generate() """ + cert_dic = {'expire_uts': 0} + self.assertFalse(self.renewalinfo._renewalinfo_generate(cert_dic)) + + def test_017_renewalinfo_generate(self): + """ test _renewalinfo_generate() """ + cert_dic = {'expire_uts': 1000, 'issue_uts': 100} + self.assertEqual({'suggestedWindow': {'start': '1970-01-01T00:14:25Z', 'end': '1970-01-01T00:16:40Z'}}, self.renewalinfo._renewalinfo_generate(cert_dic)) + + @patch('acme_srv.renewalinfo.uts_now') + def test_018_renewalinfo_generate(self, mock_uts): + """ test _renewalinfo_generate() """ + mock_uts.return_value = 100 + cert_dic = {'expire_uts': 1000} + self.assertEqual({'suggestedWindow': {'start': '1970-01-01T00:14:25Z', 'end': '1970-01-01T00:16:40Z'}}, self.renewalinfo._renewalinfo_generate(cert_dic)) + self.assertTrue(mock_uts.called) + + @patch('acme_srv.renewalinfo.uts_now') + def test_019_renewalinfo_generate(self, mock_uts): + """ test _renewalinfo_generate() """ + mock_uts.return_value = 86400000 + cert_dic = {'expire_uts': 1000, 'issue_uts': 200} + self.renewalinfo.renewal_force = True + self.assertEqual({'suggestedWindow': {'start': '1971-09-29T00:00:00Z', 'end': '1972-09-28T00:00:00Z'}}, self.renewalinfo._renewalinfo_generate(cert_dic)) + self.assertTrue(mock_uts.called) if __name__ == '__main__': unittest.main() From 8b4b68f540e87b08ed5edd4127561e6a1341e542 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 3 Feb 2024 09:14:01 +0100 Subject: [PATCH 046/460] [doc] Documentation update --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a8d5e1e8..d8964c4b 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ I am not a professional developer. Keep this in mind while laughing about my cod - ACME v2 [RFC 8555](https://www.rfc-editor.org/rfc/rfc8555.html) compliant server implementation including - Support [RFC 8737](https://www.rfc-editor.org/rfc/rfc8737.html): TLS Application‑Layer Protocol Negotiation (ALPN) Challenge Extension - Support [RFC 8738](https://www.rfc-editor.org/rfc/rfc8738.html): Certificates for IP addresses - - Support [draft-ietf-acme-ari-01](https://datatracker.ietf.org/doc/draft-ietf-acme-ari/): Renewal Information (ARI) Extension + - Support [draft-ietf-acme-ari-02](https://datatracker.ietf.org/doc/draft-ietf-acme-ari/02/) and [draft-ietf-acme-ari-01](https://datatracker.ietf.org/doc/draft-ietf-acme-ari/01/): Renewal Information (ARI) Extension - Support [TNAuthList identifiers](https://datatracker.ietf.org/doc/html/draft-ietf-acme-authority-token-tnauthlist-13): [TNAuthList profile](docs/tnauthlist.md) of ACME Authority Token - Support [tkauth-01](https://datatracker.ietf.org/doc/html/draft-ietf-acme-authority-token-09) ACME Challenges Using an Authority Token - [Certificate polling](docs/poll.md) and [Call backs](docs/trigger.md) from CA servers. These calls are not standardized but important to use acme2certifier together with classical enterprise CA From b9b9f1fa62941f98b3bb1230b22a0d38c3b9fa2f Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 3 Feb 2024 10:36:22 +0100 Subject: [PATCH 047/460] [wf] update packages information in msaca workflow --- .github/workflows/ca_handler_tests_msca.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ca_handler_tests_msca.yml b/.github/workflows/ca_handler_tests_msca.yml index ea8f32e4..61f3d9c3 100644 --- a/.github/workflows/ca_handler_tests_msca.yml +++ b/.github/workflows/ca_handler_tests_msca.yml @@ -154,6 +154,7 @@ jobs: - name: "Install dnsmasq" run: | + sudo apt-get update sudo apt-get install -y dnsmasq sudo systemctl disable systemd-resolved sudo systemctl stop systemd-resolved @@ -567,6 +568,7 @@ jobs: - name: "Install dnsmasq" run: | + sudo apt-get update sudo apt-get install -y dnsmasq sudo systemctl disable systemd-resolved sudo systemctl stop systemd-resolved From 02364be8b6b016409bf2be1e06781c819efc570f Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 3 Feb 2024 12:04:05 +0100 Subject: [PATCH 048/460] [wf] update to win-acme 2.2.7.1 --- .github/workflows/winacme-application-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/winacme-application-test.yml b/.github/workflows/winacme-application-test.yml index a52090dd..eb00ebeb 100644 --- a/.github/workflows/winacme-application-test.yml +++ b/.github/workflows/winacme-application-test.yml @@ -76,7 +76,7 @@ jobs: - name: "[ PREPARE ] Download win-acme" run: | - Invoke-RestMethod -Uri https://github.com/win-acme/win-acme/releases/download/v2.2.6.1571/win-acme.v2.2.6.1571.x64.trimmed.zip -OutFile win-acme.zip + Invoke-RestMethod -Uri https://github.com/win-acme/win-acme/releases/download/v2.2.7.1621/win-acme.v2.2.7.1621.x64.trimmed.zip -OutFile win-acme.zip Expand-Archive .\win-acme.zip mkdir win-acme\certs dir win-acme\* From 8a911124b44952b1923c6d59842e37499aafad18 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 3 Feb 2024 12:23:13 +0100 Subject: [PATCH 049/460] [wf] migration to juliangruber/sleep-action@v2.0.3 --- .../workflows/acme_sh-application-test.yml | 6 +- .github/workflows/ari-test.yml | 6 +- .github/workflows/ca_handler_tests_acme.yml | 8 +-- .github/workflows/ca_handler_tests_cmp.yml | 8 +-- .github/workflows/ca_handler_tests_ejbca.yml | 8 +-- .github/workflows/ca_handler_tests_msca.yml | 8 +-- .../workflows/ca_handler_tests_openxpki.yml | 12 ++-- .github/workflows/caddy-application-test.yml | 16 ++--- .../workflows/certbot-application-test.yml | 8 +-- .../certmanager-application-test.yml | 58 +++++++++---------- .github/workflows/container-tests.yml | 14 ++--- .github/workflows/django_tests..yml | 22 +++---- .github/workflows/ip-address-tests.yml | 8 +-- .github/workflows/lego-application-test.yml | 6 +- .github/workflows/proxy-test.yml | 4 +- .../workflows/push_images_to_dockerhub.yml | 2 +- .github/workflows/test_headerinfo.yml | 8 +-- .../workflows/traffic-application-test.yml | 2 +- .github/workflows/upgrade_tests..yml | 34 +++++------ .../workflows/winacme-application-test.yml | 4 +- 20 files changed, 121 insertions(+), 121 deletions(-) diff --git a/.github/workflows/acme_sh-application-test.yml b/.github/workflows/acme_sh-application-test.yml index af8d349d..917556e3 100644 --- a/.github/workflows/acme_sh-application-test.yml +++ b/.github/workflows/acme_sh-application-test.yml @@ -141,7 +141,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -258,7 +258,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -375,7 +375,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s diff --git a/.github/workflows/ari-test.yml b/.github/workflows/ari-test.yml index 2f7266e8..513f69b7 100644 --- a/.github/workflows/ari-test.yml +++ b/.github/workflows/ari-test.yml @@ -91,7 +91,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -162,7 +162,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -233,7 +233,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s diff --git a/.github/workflows/ca_handler_tests_acme.yml b/.github/workflows/ca_handler_tests_acme.yml index e5f832e2..23f4681a 100644 --- a/.github/workflows/ca_handler_tests_acme.yml +++ b/.github/workflows/ca_handler_tests_acme.yml @@ -34,7 +34,7 @@ jobs: docker run -d -p 80:80 --rm -id --network acme --name=acme-le-sim -v "$(pwd)/examples/Docker/data-le":/var/www/acme2certifier/volume/ grindsa/acme2certifier:apache2-wsgi - name: "[ WAIT ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -115,7 +115,7 @@ jobs: docker run -d -p 80:80 --rm -id --network acme --name=acme-le-sim -v "$(pwd)/examples/Docker/data-le":/var/www/acme2certifier/volume/ grindsa/acme2certifier:devel - name: "[ WAIT ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -208,7 +208,7 @@ jobs: docker run -d -p 80:80 --rm -id --network acme --name=acme-le-sim -v "$(pwd)/examples/Docker/data-le":/var/www/acme2certifier/volume/ grindsa/acme2certifier:apache2-wsgi - name: "[ WAIT ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -314,7 +314,7 @@ jobs: docker run -d -p 80:80 --rm -id --network acme --name=acme-le-sim -v "$(pwd)/examples/Docker/data-le":/var/www/acme2certifier/volume/ grindsa/acme2certifier:devel - name: "[ WAIT ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s diff --git a/.github/workflows/ca_handler_tests_cmp.yml b/.github/workflows/ca_handler_tests_cmp.yml index b90c79f6..7c660320 100644 --- a/.github/workflows/ca_handler_tests_cmp.yml +++ b/.github/workflows/ca_handler_tests_cmp.yml @@ -103,7 +103,7 @@ jobs: CMP_HOST: ${{ secrets.CMP_HOST }} - name: "[ PREPARE ] Sleep for 5s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 5s @@ -226,7 +226,7 @@ jobs: CMP_HOST: ${{ secrets.CMP_HOST }} - name: "[ PREPARE ] Sleep for 5s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 5s @@ -373,7 +373,7 @@ jobs: CMP_HOST: ${{ secrets.CMP_HOST }} - name: "[ PREPARE ] Sleep for 5s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 5s @@ -522,7 +522,7 @@ jobs: CMP_HOST: ${{ secrets.CMP_HOST }} - name: "[ PREPARE ] Sleep for 5s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 5s diff --git a/.github/workflows/ca_handler_tests_ejbca.yml b/.github/workflows/ca_handler_tests_ejbca.yml index eb367890..0417fb3b 100644 --- a/.github/workflows/ca_handler_tests_ejbca.yml +++ b/.github/workflows/ca_handler_tests_ejbca.yml @@ -43,7 +43,7 @@ jobs: docker run -id --rm -p 80:8080 -p 443:8443 -e TLS_SETUP_ENABLED=true -v $(pwd)/examples/ejbca:/tmp/data -v $(pwd)/examples/Docker/data:/tmp/store --name "ejbca" -h ejbca keyfactor/ejbca-ce - name: "Sleep for 180s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 180s @@ -75,7 +75,7 @@ jobs: CAID: ${{ env.CAID }} - name: "Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -220,7 +220,7 @@ jobs: docker run -id --rm -p 80:8080 -p 443:8443 -e TLS_SETUP_ENABLED=true -v $(pwd)/examples/ejbca:/tmp/data -v $(pwd)/data:/tmp/store --name "ejbca" -h ejbca keyfactor/ejbca-ce - name: "Sleep for 180s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 180s @@ -253,7 +253,7 @@ jobs: CAID: ${{ env.CAID }} - name: "Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s diff --git a/.github/workflows/ca_handler_tests_msca.yml b/.github/workflows/ca_handler_tests_msca.yml index 8de8a7ed..60988da7 100644 --- a/.github/workflows/ca_handler_tests_msca.yml +++ b/.github/workflows/ca_handler_tests_msca.yml @@ -97,7 +97,7 @@ jobs: WCCE_HOST: ${{ secrets.WCCE_HOST }} - name: "[ PREPARE ] Sleep for 5s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 5s @@ -257,7 +257,7 @@ jobs: WCCE_HOST: ${{ secrets.WCCE_HOST }} - name: "[ PREPARE ] Sleep for 5s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 5s @@ -512,7 +512,7 @@ jobs: WCCE_HOST: ${{ secrets.WCCE_HOST }} - name: "[ PREPARE ] Sleep for 5s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 5s @@ -705,7 +705,7 @@ jobs: WCCE_HOST: ${{ secrets.WCCE_HOST }} - name: "[ PREPARE ] Sleep for 5s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 5s diff --git a/.github/workflows/ca_handler_tests_openxpki.yml b/.github/workflows/ca_handler_tests_openxpki.yml index cb066b3e..7fb47698 100644 --- a/.github/workflows/ca_handler_tests_openxpki.yml +++ b/.github/workflows/ca_handler_tests_openxpki.yml @@ -58,7 +58,7 @@ jobs: docker-compose up & - name: "Sleep for 60s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 60s @@ -70,7 +70,7 @@ jobs: docker start openxpki-docker_openxpki-server_1 - name: "Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -82,7 +82,7 @@ jobs: docker exec -id openxpki-docker_openxpki-client_1 apt-get install -y libjson-pp-perl - name: "Sleep for 45s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 45s @@ -385,7 +385,7 @@ jobs: docker-compose up & - name: "Sleep for 60s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 60s @@ -397,7 +397,7 @@ jobs: docker start openxpki-docker_openxpki-server_1 - name: "Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -409,7 +409,7 @@ jobs: docker exec -id openxpki-docker_openxpki-client_1 apt-get install -y libjson-pp-perl - name: "Sleep for 45s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 45s diff --git a/.github/workflows/caddy-application-test.yml b/.github/workflows/caddy-application-test.yml index 2a9f1a15..2624156a 100644 --- a/.github/workflows/caddy-application-test.yml +++ b/.github/workflows/caddy-application-test.yml @@ -40,7 +40,7 @@ jobs: docker-compose logs - name: "Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -62,7 +62,7 @@ jobs: docker run -d --rm ${{ matrix.ports }} --network acme -v $PWD/caddy/Caddyfile:/etc/caddy/Caddyfile -v$PWD/caddy/acme2certifier_cabundle.pem:/tmp/acme2certifier_cabundle.pem -v $(pwd)/caddy/config:/config -v $(pwd)/caddy/data:/data --name=caddy caddy:2 - name: "Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -123,7 +123,7 @@ jobs: docker-compose logs - name: "Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -145,7 +145,7 @@ jobs: docker run -d --rm ${{ matrix.ports }} --network acme -v $PWD/caddy/Caddyfile:/etc/caddy/Caddyfile -v$PWD/caddy/acme2certifier_cabundle.pem:/tmp/acme2certifier_cabundle.pem -v $(pwd)/caddy/config:/config -v $(pwd)/caddy/data:/data --name=caddy caddy:2 - name: "Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -206,7 +206,7 @@ jobs: docker-compose logs - name: "Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -228,7 +228,7 @@ jobs: docker run -d --rm ${{ matrix.ports }} --network acme -v $PWD/caddy/Caddyfile:/etc/caddy/Caddyfile -v$PWD/caddy/acme2certifier_cabundle.pem:/tmp/acme2certifier_cabundle.pem -v $(pwd)/caddy/config:/config -v $(pwd)/caddy/data:/data --name=caddy caddy:2 - name: "Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -290,7 +290,7 @@ jobs: docker-compose logs - name: "Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -311,7 +311,7 @@ jobs: docker run -d --rm ${{ matrix.ports }} --network acme -v $PWD/caddy/Caddyfile:/etc/caddy/Caddyfile -v$PWD/caddy/acme2certifier_cabundle.pem:/tmp/acme2certifier_cabundle.pem -v $(pwd)/caddy/config:/config -v $(pwd)/caddy/data:/data --name=caddy caddy:2 - name: "Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s diff --git a/.github/workflows/certbot-application-test.yml b/.github/workflows/certbot-application-test.yml index da2668dd..df7d1b09 100644 --- a/.github/workflows/certbot-application-test.yml +++ b/.github/workflows/certbot-application-test.yml @@ -30,7 +30,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -121,7 +121,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -213,7 +213,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -305,7 +305,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s diff --git a/.github/workflows/certmanager-application-test.yml b/.github/workflows/certmanager-application-test.yml index ebdb0eff..1104d4b8 100644 --- a/.github/workflows/certmanager-application-test.yml +++ b/.github/workflows/certmanager-application-test.yml @@ -48,7 +48,7 @@ jobs: run: | sudo microk8s.kubectl apply -f data/dnsmasq.yml - name: "[ WAIT ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -98,7 +98,7 @@ jobs: sudo microk8s.kubectl apply -f data/k8s-acme-srv.yml sudo microk8s.kubectl get pods -n cert-manager-acme - name: "[ WAIT ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -119,7 +119,7 @@ jobs: sudo microk8s.kubectl apply -f data/k8s-cert-mgr-http-01.yml - name: "[ WAIT ] Sleep for 20s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 20s @@ -128,7 +128,7 @@ jobs: sudo microk8s.kubectl describe ClusterIssuer acme2certifier sudo microk8s.kubectl describe challenge - name: "[ WAIT ] Sleep for 20s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 20s @@ -137,7 +137,7 @@ jobs: sudo microk8s.kubectl describe ClusterIssuer acme2certifier sudo microk8s.kubectl describe challenge - name: "[ WAIT ] Sleep for 20s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 20s @@ -203,7 +203,7 @@ jobs: run: | sudo microk8s.kubectl apply -f data/dnsmasq.yml - name: "[ WAIT ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -255,7 +255,7 @@ jobs: sudo microk8s.kubectl get pods -n cert-manager-acme - name: "[ WAIT ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -276,7 +276,7 @@ jobs: sudo microk8s.kubectl apply -f data/k8s-cert-mgr-http-01.yml - name: "[ WAIT ] Sleep for 20s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 20s @@ -285,7 +285,7 @@ jobs: sudo microk8s.kubectl describe ClusterIssuer acme2certifier sudo microk8s.kubectl describe challenge - name: "[ WAIT ] Sleep for 20s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 20s @@ -294,7 +294,7 @@ jobs: sudo microk8s.kubectl describe ClusterIssuer acme2certifier sudo microk8s.kubectl describe challenge - name: "[ WAIT ] Sleep for 20s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 20s @@ -360,7 +360,7 @@ jobs: sudo microk8s.kubectl apply -f data/dnsmasq.yml - name: "[ WAIT ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -410,7 +410,7 @@ jobs: sudo microk8s.kubectl apply -f data/k8s-acme-srv.yml sudo microk8s.kubectl get pods -n cert-manager-acme - name: "[ WAIT ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -430,7 +430,7 @@ jobs: sudo sed -i "s/ACME_SRV/${{ env.ACME_IP }}/g" data/k8s-cert-mgr-http-01.yml sudo microk8s.kubectl apply -f data/k8s-cert-mgr-http-01.yml - name: "[ WAIT ] Sleep for 20s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 20s @@ -439,7 +439,7 @@ jobs: sudo microk8s.kubectl describe ClusterIssuer acme2certifier sudo microk8s.kubectl describe challenge - name: "[ WAIT ] Sleep for 20s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 20s @@ -448,7 +448,7 @@ jobs: sudo microk8s.kubectl describe ClusterIssuer acme2certifier sudo microk8s.kubectl describe challenge - name: "[ WAIT ] Sleep for 20s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 20s @@ -514,7 +514,7 @@ jobs: sudo microk8s.kubectl apply -f data/dnsmasq.yml - name: "[ WAIT ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -568,7 +568,7 @@ jobs: sudo microk8s.kubectl get pods -n cert-manager-acme - name: "[ WAIT ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -589,7 +589,7 @@ jobs: sudo microk8s.kubectl apply -f data/k8s-cert-mgr-http-01.yml - name: "[ WAIT ] Sleep for 20s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 20s @@ -599,7 +599,7 @@ jobs: sudo microk8s.kubectl describe challenge - name: "[ WAIT ] Sleep for 20s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 20s @@ -608,7 +608,7 @@ jobs: sudo microk8s.kubectl describe ClusterIssuer acme2certifier sudo microk8s.kubectl describe challenge - name: "[ WAIT ] Sleep for 20s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 20s @@ -695,7 +695,7 @@ jobs: sudo microk8s.kubectl get pods -n cert-manager-acme - name: "[ WAIT ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -721,7 +721,7 @@ jobs: sudo microk8s.kubectl apply -f data/k8s-cert-mgr-dns-01.yml - name: "[ WAIT ] Sleep for 20s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 20s @@ -731,7 +731,7 @@ jobs: sudo microk8s.kubectl describe challenge -n cert-manager-acme - name: "[ WAIT ] Sleep for 30s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 60s @@ -741,7 +741,7 @@ jobs: sudo microk8s.kubectl describe challenge -n cert-manager-acme - name: "[ WAIT ] Sleep for 60s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 60s @@ -751,7 +751,7 @@ jobs: sudo microk8s.kubectl describe challenge -n cert-manager-acme - name: "[ WAIT ] Sleep for 60s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 60s @@ -772,7 +772,7 @@ jobs: sudo microk8s.kubectl apply -f data/k8s-cert-mgr-dns-01.yml - name: "[ WAIT ] Sleep for 20s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 20s @@ -781,7 +781,7 @@ jobs: sudo microk8s.kubectl describe issuer acme2certifier -n cert-manager-acme sudo microk8s.kubectl describe challenge -n cert-manager-acme - name: "[ WAIT ] Sleep for 30s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 60s @@ -791,7 +791,7 @@ jobs: sudo microk8s.kubectl describe challenge -n cert-manager-acme - name: "[ WAIT ] Sleep for 60s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 60s @@ -801,7 +801,7 @@ jobs: sudo microk8s.kubectl describe challenge -n cert-manager-acme - name: "[ WAIT ] Sleep for 60s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 60s diff --git a/.github/workflows/container-tests.yml b/.github/workflows/container-tests.yml index a40d8ce5..a7d3b315 100644 --- a/.github/workflows/container-tests.yml +++ b/.github/workflows/container-tests.yml @@ -52,7 +52,7 @@ jobs: head -n 13 data/ca_handler.py docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s - name: "Test if http://acme-srv/directory is accessable" @@ -100,7 +100,7 @@ jobs: docker-compose restart docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s - name: "Test if http://acme-srv/directory is accessable" @@ -124,7 +124,7 @@ jobs: head -n 13 data/ca_handler.py docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s - name: "Test if http://acme-srv/directory is accessable" @@ -172,7 +172,7 @@ jobs: docker-compose restart docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s - name: "Test if http://acme-srv/directory is accessable" @@ -196,7 +196,7 @@ jobs: head -n 13 data/ca_handler.py docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s - name: "Test if http://acme-srv/directory is accessable" @@ -245,7 +245,7 @@ jobs: docker-compose restart docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s - name: "Test if http://acme-srv/directory is accessable" @@ -269,7 +269,7 @@ jobs: head -n 13 data/ca_handler.py docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s - name: "Test if http://acme-srv/directory is accessable" diff --git a/.github/workflows/django_tests..yml b/.github/workflows/django_tests..yml index 9041e418..1095909e 100644 --- a/.github/workflows/django_tests..yml +++ b/.github/workflows/django_tests..yml @@ -32,7 +32,7 @@ jobs: docker run --name mariadbsrv --network acme -e MARIADB_ROOT_PASSWORD=foobar -d mariadb - name: "[ PREPARE ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -136,7 +136,7 @@ jobs: docker run --name postgresdbsrv --network acme -e POSTGRES_PASSWORD=foobar -d postgres - name: "[ PREPARE ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -145,7 +145,7 @@ jobs: run: | docker run -v "$(pwd)/data/pgsql/a2c.psql":/tmp/a2c.psql -v "$(pwd)/data/pgsql/pgpass:/root/.pgpass" --rm --network acme postgres psql -U postgres -h postgresdbsrv -f /tmp/a2c.psql - name: "[ PREPARE ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -239,7 +239,7 @@ jobs: docker run --name mariadbsrv --network acme -e MARIADB_ROOT_PASSWORD=foobar -d mariadb - name: "[ PREPARE ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -268,7 +268,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -350,7 +350,7 @@ jobs: docker run --name postgresdbsrv --network acme -e POSTGRES_PASSWORD=foobar -d postgres - name: "[ PREPARE ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -359,7 +359,7 @@ jobs: run: | docker run -v "$(pwd)/data/pgsql/a2c.psql":/tmp/a2c.psql -v "$(pwd)/data/pgsql/pgpass:/root/.pgpass" --rm --network acme postgres psql -U postgres -h postgresdbsrv -f /tmp/a2c.psql - name: "[ PREPARE ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -382,7 +382,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -609,7 +609,7 @@ jobs: # docker run --name mariadbsrv --network acme -e MARIADB_ROOT_PASSWORD=foobar -d mariadb - name: "[ PREPARE ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -754,7 +754,7 @@ jobs: docker run --name postgresdbsrv -v /tmp/pgsql/data:/var/lib/postgresql/data --network acme -e POSTGRES_PASSWORD=foobar -d postgres - name: "[ PREPARE ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -763,7 +763,7 @@ jobs: docker run -v /tmp/pgsql/a2c.psql:/tmp/a2c.psql -v /tmp/pgsql/pgpass:/root/.pgpass --rm --network acme postgres psql -U postgres -h postgresdbsrv -f /tmp/a2c.psql - name: "[ PREPARE ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s diff --git a/.github/workflows/ip-address-tests.yml b/.github/workflows/ip-address-tests.yml index 44b92170..81cf8c9a 100644 --- a/.github/workflows/ip-address-tests.yml +++ b/.github/workflows/ip-address-tests.yml @@ -42,7 +42,7 @@ jobs: docker-compose logs - name: "Sleep for 5s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 5s @@ -116,7 +116,7 @@ jobs: docker-compose logs - name: "Sleep for 5s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 5s @@ -190,7 +190,7 @@ jobs: docker-compose logs - name: "Sleep for 5s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 5s @@ -266,7 +266,7 @@ jobs: docker-compose logs - name: "Sleep for 5s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 5s diff --git a/.github/workflows/lego-application-test.yml b/.github/workflows/lego-application-test.yml index 4e53bfb1..c188ac1c 100644 --- a/.github/workflows/lego-application-test.yml +++ b/.github/workflows/lego-application-test.yml @@ -112,7 +112,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -200,7 +200,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -288,7 +288,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s diff --git a/.github/workflows/proxy-test.yml b/.github/workflows/proxy-test.yml index f3ef7182..592841a6 100644 --- a/.github/workflows/proxy-test.yml +++ b/.github/workflows/proxy-test.yml @@ -29,7 +29,7 @@ jobs: docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & - name: "[ PREPARE ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -311,7 +311,7 @@ jobs: docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & - name: "[ PREPARE ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s diff --git a/.github/workflows/push_images_to_dockerhub.yml b/.github/workflows/push_images_to_dockerhub.yml index 70f5eead..fcd6965a 100644 --- a/.github/workflows/push_images_to_dockerhub.yml +++ b/.github/workflows/push_images_to_dockerhub.yml @@ -172,7 +172,7 @@ jobs: docker run -d -p 80:80 --rm -id --network acme --name=acme-srv -v "$(pwd)/examples/Docker/data":/var/www/acme2certifier/volume/ grindsa/acme2certifier:apache2-django - name: "[ PREPARE ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 5s diff --git a/.github/workflows/test_headerinfo.yml b/.github/workflows/test_headerinfo.yml index f9f0d6ba..ce2642a3 100644 --- a/.github/workflows/test_headerinfo.yml +++ b/.github/workflows/test_headerinfo.yml @@ -138,7 +138,7 @@ jobs: XCA_DB_NAME: ${{ secrets.XCA_DB_NAME }} - name: "[ WAIT ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -222,7 +222,7 @@ jobs: XCA_DB_NAME: ${{ secrets.XCA_DB_NAME }} - name: "[ WAIT ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -274,7 +274,7 @@ jobs: docker-compose logs - name: "[ WAIT ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -313,7 +313,7 @@ jobs: XCA_DB_NAME: ${{ secrets.XCA_DB_NAME }} - name: "[ WAIT ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s diff --git a/.github/workflows/traffic-application-test.yml b/.github/workflows/traffic-application-test.yml index cd7bb71c..e7d65ab7 100644 --- a/.github/workflows/traffic-application-test.yml +++ b/.github/workflows/traffic-application-test.yml @@ -60,7 +60,7 @@ jobs: docker-compose up -d - name: "Sleep for 30s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 30s diff --git a/.github/workflows/upgrade_tests..yml b/.github/workflows/upgrade_tests..yml index 76aa85e6..2a8b800e 100644 --- a/.github/workflows/upgrade_tests..yml +++ b/.github/workflows/upgrade_tests..yml @@ -39,7 +39,7 @@ jobs: docker logs acme-srv - name: "[ PREPARE ] Sleep for 5s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 5s @@ -86,7 +86,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 5s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 5s @@ -166,7 +166,7 @@ jobs: docker logs acme-srv - name: "[ PREPARE ] Sleep for 5s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 5s @@ -213,7 +213,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 5s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 5s @@ -284,7 +284,7 @@ jobs: docker run --name mariadbsrv --network acme -e MARIADB_ROOT_PASSWORD=foobar -d mariadb - name: "[ PREPARE ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -315,7 +315,7 @@ jobs: docker logs acme-srv - name: "[ PREPARE ] Sleep for 5s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 5s @@ -362,7 +362,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 5s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 5s @@ -432,7 +432,7 @@ jobs: docker run --name mariadbsrv --network acme -e MARIADB_ROOT_PASSWORD=foobar -d mariadb - name: "[ PREPARE ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -463,7 +463,7 @@ jobs: docker logs acme-srv - name: "[ PREPARE ] Sleep for 5s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 5s @@ -511,7 +511,7 @@ jobs: docker-compose logs - name: "[ PREPARE ] Sleep for 5s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 5s @@ -677,7 +677,7 @@ jobs: sudo rm -rf $PWD/acme-sh/* - name: "[ PREPARE ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -779,7 +779,7 @@ jobs: docker run --name mariadbsrv --network acme -e MARIADB_ROOT_PASSWORD=foobar -d mariadb - name: "[ PREPARE ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -860,7 +860,7 @@ jobs: sudo rm -rf $PWD/acme-sh/* - name: "[ PREPARE ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -1025,7 +1025,7 @@ jobs: sudo rm -rf $PWD/acme-sh/* - name: "[ PREPARE ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -1134,7 +1134,7 @@ jobs: docker run --name postgresdbsrv --network acme -e POSTGRES_PASSWORD=foobar -d postgres - name: "[ PREPARE ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -1144,7 +1144,7 @@ jobs: docker run -v "$(pwd)/data/pgsql/a2c.psql":/tmp/a2c.psql -v "$(pwd)/data/pgsql/pgpass:/root/.pgpass" --rm --network acme postgres psql -U postgres -h postgresdbsrv -f /tmp/a2c.psql - name: "[ PREPARE ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -1218,7 +1218,7 @@ jobs: sudo rm -rf $PWD/acme-sh/* - name: "[ PREPARE ] Sleep for 10s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 10s diff --git a/.github/workflows/winacme-application-test.yml b/.github/workflows/winacme-application-test.yml index eb00ebeb..ab8f615e 100644 --- a/.github/workflows/winacme-application-test.yml +++ b/.github/workflows/winacme-application-test.yml @@ -63,7 +63,7 @@ jobs: run: | Start-Process powershell {python .\manage.py runserver 0.0.0.0:8080 3>&1 2>&1 > volume\redirection.log} - name: "[ PREPARE ] Sleep for 5s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 5s @@ -90,7 +90,7 @@ jobs: Start-Process powershell {python .\manage.py runsslserver 0.0.0.0:443 --certificate acme2certifier/acme2certifier_cert.pem --key acme2certifier/acme2certifier_key.pem 3>&1 2>&1 > volume\redirection_ssl.log} - name: "[ PREPARE ] Sleep for 5s" - uses: grindsa/sleep-action@node20 + uses: juliangruber/sleep-action@v2.0.3 with: time: 5s From 3da984492f647865c9b4cf961f593f0e2270bb58 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 3 Feb 2024 16:23:30 +0100 Subject: [PATCH 050/460] [tst] unittests helper.py --- test/test_helper.py | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/test/test_helper.py b/test/test_helper.py index e16909f7..fc429ff3 100644 --- a/test/test_helper.py +++ b/test/test_helper.py @@ -2163,29 +2163,7 @@ def test_281_ski_get(self, mock_load): def test_282_cert_aki_get(self): """ test cert_san_get aki""" - cert = """MIIEOzCCAiOgAwIBAgIIKndYX0qdb04wDQYJKoZIhvcNAQELBQAwKjEXMBUGA1UE - CxMOYWNtZTJjZXJ0aWZpZXIxDzANBgNVBAMTBnN1Yi1jYTAeFw0yNDAxMjkyMDA0 - NTZaFw0yNTAxMjgyMDA0NTZaMD8xFzAVBgNVBAMTDmxlZ28uYmFyLmxvY2FsMRcw - FQYDVQQKDA5hY21lMmNlcnRpZmllcjELMAkGA1UEBhMCREUwWTATBgcqhkjOPQIB - BggqhkjOPQMBBwNCAAQKIqEIxeS0JIN+iqsJ+08IJFFmuvfpjFnH4wFD2OLlmeTv - fpDsnD00uw/orLvecDvjt48JvgYR8Wv+9C4ajIDfo4IBGTCCARUwHQYDVR0OBBYE - FCka80MPgj45/quHJ9oF8Cc1YlsXMB8GA1UdIwQYMBaAFL/ejo4GIiKrrUPI3dRP - qKtIQT7VMAsGA1UdDwQEAwID6DBRBgNVHSUBAf8ERzBFBggrBgEFBQcDAQYIKwYB - BQUHAwIGCCsGAQUFBwMDBggrBgEFBQcDBAYIKwYBBQUHAwgGCCsGAQUFBwMJBgcr - BgEFAgMFMEoGA1UdHwRDMEEwHqAcoBqGGFVSSTpodHRwOi8vZm9vLmJhci5sb2Nh - bDAfoB2gG4YZVVJJOmh0dHA6Ly9mb28xLmJhci5sb2NhbDAMBgNVHRMBAf8EAjAA - MBkGA1UdEQQSMBCCDmxlZ28uYmFyLmxvY2FsMA0GCSqGSIb3DQEBCwUAA4ICAQB4 - FxJwQ/aILMzh7jBSr358RA92mX8srPmzQrjPYoU7T2LxwMf+eb0z5x0PMFH8j5Fg - RvRGWo6rcco8rL+B+gvrVhQ0TfAFEF77WJfKG2XMlnEN/9Ri73J7+dA45kaw8CZR - SfUBpIW6fb4N+6frXyIKwBaZnrT6qiy+Izu+ZH6RkaTFrBn5yOWvVyk7aBHE1eZ+ - 3+eA3qBI4UPaeYFSwr3gY5dxfbPktlFgvpCI22ff4NAb/fzjAQsKRTkXkOVqAvBJ - cWI5d/g32IVMLq0ub13XLe+yHk0iCxyMaIRdN4+W6RYi3gvtTQh6LaOjncWDYLds - m+vN+YqXEqieY5TC1oC8kG9We9eHzKHdNquJnrju536DPqh4xYEDcb+PGvTr3sqY - dSikA9v5FuWUGeiZD/ZEvw/p7F7DevD5NO1JaOtfWDwDwxFHEyn+iwTVq3QDEc4j - +oyGnQJs5Spoyz3tJi31VMJk+EAKKUV66aVNynLM7Ce4Oj0M67o4pcnDd0uWBMSA - g4lH8KIX0IsmMfLnirIqOOwrZ4UkPKlEjD+oZQf5IBukfdHob/bo4fW8q4eU/I8z - 9w3BTdV1yNVH/ANHg5AItoPabkr65oBTwY51j3FVq0gK+4xVrevcyIeY3A9XFzA1 - 8k/gX7O/kf/IrM0dcZWJnsW39byiWhUd4JetJaGeKg""" + cert = 'MIIEOzCCAiOgAwIBAgIIKndYX0qdb04wDQYJKoZIhvcNAQELBQAwKjEXMBUGA1UECxMOYWNtZTJjZXJ0aWZpZXIxDzANBgNVBAMTBnN1Yi1jYTAeFw0yNDAxMjkyMDA0NTZaFw0yNTAxMjgyMDA0NTZaMD8xFzAVBgNVBAMTDmxlZ28uYmFyLmxvY2FsMRcwFQYDVQQKDA5hY21lMmNlcnRpZmllcjELMAkGA1UEBhMCREUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQKIqEIxeS0JIN+iqsJ+08IJFFmuvfpjFnH4wFD2OLlmeTvfpDsnD00uw/orLvecDvjt48JvgYR8Wv+9C4ajIDfo4IBGTCCARUwHQYDVR0OBBYEFCka80MPgj45/quHJ9oF8Cc1YlsXMB8GA1UdIwQYMBaAFL/ejo4GIiKrrUPI3dRPqKtIQT7VMAsGA1UdDwQEAwID6DBRBgNVHSUBAf8ERzBFBggrBgEFBQcDAQYIKwYBBQUHAwIGCCsGAQUFBwMDBggrBgEFBQcDBAYIKwYBBQUHAwgGCCsGAQUFBwMJBgcrBgEFAgMFMEoGA1UdHwRDMEEwHqAcoBqGGFVSSTpodHRwOi8vZm9vLmJhci5sb2NhbDAfoB2gG4YZVVJJOmh0dHA6Ly9mb28xLmJhci5sb2NhbDAMBgNVHRMBAf8EAjAAMBkGA1UdEQQSMBCCDmxlZ28uYmFyLmxvY2FsMA0GCSqGSIb3DQEBCwUAA4ICAQB4FxJwQ/aILMzh7jBSr358RA92mX8srPmzQrjPYoU7T2LxwMf+eb0z5x0PMFH8j5FgRvRGWo6rcco8rL+B+gvrVhQ0TfAFEF77WJfKG2XMlnEN/9Ri73J7+dA45kaw8CZRSfUBpIW6fb4N+6frXyIKwBaZnrT6qiy+Izu+ZH6RkaTFrBn5yOWvVyk7aBHE1eZ+3+eA3qBI4UPaeYFSwr3gY5dxfbPktlFgvpCI22ff4NAb/fzjAQsKRTkXkOVqAvBJcWI5d/g32IVMLq0ub13XLe+yHk0iCxyMaIRdN4+W6RYi3gvtTQh6LaOjncWDYLdsm+vN+YqXEqieY5TC1oC8kG9We9eHzKHdNquJnrju536DPqh4xYEDcb+PGvTr3sqYdSikA9v5FuWUGeiZD/ZEvw/p7F7DevD5NO1JaOtfWDwDwxFHEyn+iwTVq3QDEc4j+oyGnQJs5Spoyz3tJi31VMJk+EAKKUV66aVNynLM7Ce4Oj0M67o4pcnDd0uWBMSAg4lH8KIX0IsmMfLnirIqOOwrZ4UkPKlEjD+oZQf5IBukfdHob/bo4fW8q4eU/I8z9w3BTdV1yNVH/ANHg5AItoPabkr65oBTwY51j3FVq0gK+4xVrevcyIeY3A9XFzA18k/gX7O/kf/IrM0dcZWJnsW39byiWhUd4JetJaGeKg' self.assertEqual('bfde8e8e062222abad43c8ddd44fa8ab48413ed5', self.cert_aki_get(self.logger, cert)) def test_283_cert_aki_pyopenssl_get(self): From 20544aee9ac7e53edd3f0cac4e08570377a2d511 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 4 Feb 2024 07:10:17 +0100 Subject: [PATCH 051/460] [fix] logging statement in _serial_aki_get() --- acme_srv/renewalinfo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme_srv/renewalinfo.py b/acme_srv/renewalinfo.py index 825898f7..0de99446 100644 --- a/acme_srv/renewalinfo.py +++ b/acme_srv/renewalinfo.py @@ -189,7 +189,7 @@ def _serial_aki_get(self, renewalinfo_string: str) -> (str, str): serial = None aki = None - self.logger.debug('Renewalinfo._serial_aki_get() - serial: %s, aki: %s', serial, aki=aki) + self.logger.debug('Renewalinfo._serial_aki_get() - serial: %s, aki: %s', serial, aki) return (serial, aki) def get(self, url: str) -> Dict[str, str]: From 14ce432bf8d751074f03991e8c7ab0bfe3bd2574 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 4 Feb 2024 08:05:19 +0100 Subject: [PATCH 052/460] [wf] fix install scripts --- examples/install_scripts/a2c-ubuntu22-apache2.sh | 2 ++ examples/install_scripts/a2c-ubuntu22-nginx.sh | 1 + 2 files changed, 3 insertions(+) diff --git a/examples/install_scripts/a2c-ubuntu22-apache2.sh b/examples/install_scripts/a2c-ubuntu22-apache2.sh index 6a2ab7ef..10303212 100644 --- a/examples/install_scripts/a2c-ubuntu22-apache2.sh +++ b/examples/install_scripts/a2c-ubuntu22-apache2.sh @@ -6,6 +6,7 @@ # - execute this script with "sh ./examples/install_scripts/a2c-ubuntu22-apache2.sh" # 1 install needed packages +sudo apt-get update sudo apt-get install -y apache2 libapache2-mod-wsgi-py3 python3-pip apache2-data # 2 check if mod wsgi got activated @@ -13,6 +14,7 @@ apache2ctl -M | grep -i wsgi # 4 install needed python modules sudo pip3 install -r requirements.txt +sudo pip3 install pyopenssl --upgrade # 5 configure apache2 sudo cp examples/apache2/apache_wsgi.conf /etc/apache2/sites-available/acme2certifier.conf diff --git a/examples/install_scripts/a2c-ubuntu22-nginx.sh b/examples/install_scripts/a2c-ubuntu22-nginx.sh index 58982ffc..3a40b397 100644 --- a/examples/install_scripts/a2c-ubuntu22-nginx.sh +++ b/examples/install_scripts/a2c-ubuntu22-nginx.sh @@ -13,6 +13,7 @@ sudo apt-get install -y python3-pip nginx uwsgi uwsgi-plugin-python3 curl # 3 install needed python modules echo "## Install missing pythom modules" sudo pip3 install -r requirements.txt +sudo pip3 install pyopenssl --upgrade # 8 create data directory echo "## Create directory structure required by acme2certifier" From 0ddd6694b9c27fe8613a416c309507452c9a73f7 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 4 Feb 2024 08:23:05 +0100 Subject: [PATCH 053/460] [fiix] version bump to v0.33 --- CHANGES.md | 18 +++++++++++++++++- SECURITY.md | 4 ++-- acme_srv/version.py | 4 ++-- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index cf161358..e7178dc5 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,6 +5,22 @@ This is a high-level summary of the most important changes. For a full list of changes, see the [git commit log](https://github.com/grindsa/acme2certifier/commits) and pick the appropriate release branch. +# Changes in 0.33 + +**Upgrade notes**: + +- database scheme gets updated. Please run either + - `tools/db_update.py` when using the wsgi_handler or + - `tools/django_update.py` in case you are using the django_handler + +**Features and Improvements**: + +- Support [draft-ietf-acme-ari-02](https://datatracker.ietf.org/doc/draft-ietf-acme-ari/02): Renewal Information (ARI) Extension +- First version of [Insta ASA CA handler](docs/asa.md) +- [winacme renewal-info workaround](https://github.com/grindsa/acme2certifier/issues/127) +- better logging to ease troubleshootnig of eab +- code refactoring to improve [f-string handling](https://pylint.pycqa.org/en/latest/user_guide/messages/convention/consider-using-f-string.html) + # Changes in 0.32 **Features and Improvements**: @@ -56,7 +72,7 @@ and pick the appropriate release branch. **Features and Improvements**: - Support [RFC 8738](https://www.rfc-editor.org/rfc/rfc8738.html): Certificates for IP addresses -- Support [draft-ietf-acme-ari-01](https://datatracker.ietf.org/doc/draft-ietf-acme-ari/): Renewal Information (ARI) Extension +- Support [draft-ietf-acme-ari-01](https://datatracker.ietf.org/doc/draft-ietf-acme-ari/01): Renewal Information (ARI) Extension - Interoperability testing with [Caddy](https://caddyserver.com/docs/automatic-https) as part of regular regression # Changes in 0.28 diff --git a/SECURITY.md b/SECURITY.md index 3ba9ed39..d2afe494 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -6,9 +6,9 @@ | Version | Supported | | ------- | ------------------ | +| 0.33.x | :white_check_mark: | | 0.32.x | :white_check_mark: | -| 0.31.x | :white_check_mark: | -| < 0.31 | :x: | +| < 0.32 | :x: | ## Reporting a Vulnerability diff --git a/acme_srv/version.py b/acme_srv/version.py index 53e69b9a..c92a3981 100644 --- a/acme_srv/version.py +++ b/acme_srv/version.py @@ -3,5 +3,5 @@ # 1) we don't load dependencies by storing it in __init__.py # 2) we can import it in setup.py for the same reason # 3) we can import it into your module module -__version__ = '0.32' -__dbversion__ = '0.30' +__version__ = '0.33' +__dbversion__ = '0.33' From fd239cf1e4f2a27c23d2bb23dc33f942707e265e Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 4 Feb 2024 08:36:42 +0100 Subject: [PATCH 054/460] [fix] _cert_table_update() will be executed just once --- acme_srv/renewalinfo.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/acme_srv/renewalinfo.py b/acme_srv/renewalinfo.py index 0de99446..f1f1e8f2 100644 --- a/acme_srv/renewalinfo.py +++ b/acme_srv/renewalinfo.py @@ -197,7 +197,10 @@ def get(self, url: str) -> Dict[str, str]: self.logger.debug('Renewalinfo.get()') # shousekeeping - add serial and aki to certificate table - self._cert_table_update() + if not self.dbstore.hkparameter_get('cert_aki_serial_update'): + self._cert_table_update() + self.logger.debug('Renewalinfo.get() - update housekeeping') + self.dbstore.hkparameter_add({'name': 'cert_aki_serial_update', 'value': True}) # parse renewalinfo string renewalinfo_string = self._renewalinfo_string_get(url) From 291639b128d9b657d48ae391895e60f1c55ebc83 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 4 Feb 2024 11:02:30 +0100 Subject: [PATCH 055/460] [fix] unittests --- test/test_renewalinfo.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/test_renewalinfo.py b/test/test_renewalinfo.py index 5d691db0..df76db0c 100644 --- a/test/test_renewalinfo.py +++ b/test/test_renewalinfo.py @@ -174,15 +174,28 @@ def test_020_get(self, mock_update, mock_renstr_get, mock_renget): """ test get() """ mock_renget.return_value = {'foo': 'bar'} mock_renstr_get.return_value = 'mock_renstr_get' + self.renewalinfo.dbstore.hkparameter_get.return_value = None self.assertEqual({'code': 200, 'data': {'foo': 'bar'}, 'header': {'Retry-After': '86400'}}, self. renewalinfo.get('url')) self.assertTrue(mock_update.called) + @patch('acme_srv.renewalinfo.Renewalinfo._renewalinfo_get') + @patch('acme_srv.renewalinfo.Renewalinfo._renewalinfo_string_get') + @patch('acme_srv.renewalinfo.Renewalinfo._cert_table_update') + def test_021_get(self, mock_update, mock_renstr_get, mock_renget): + """ test get() """ + mock_renget.return_value = {'foo': 'bar'} + mock_renstr_get.return_value = 'mock_renstr_get' + self.renewalinfo.dbstore.hkparameter_get.return_value = {'foo': 'bar'} + self.assertEqual({'code': 200, 'data': {'foo': 'bar'}, 'header': {'Retry-After': '86400'}}, self. renewalinfo.get('url')) + self.assertFalse(mock_update.called) + @patch('acme_srv.renewalinfo.Renewalinfo._renewalinfo_get') @patch('acme_srv.renewalinfo.Renewalinfo._renewalinfo_string_get') @patch('acme_srv.renewalinfo.Renewalinfo._cert_table_update') def test_022_get(self, mock_update, mock_renstr_get, mock_renget): """ test get() """ mock_renget.return_value = None + self.renewalinfo.dbstore.hkparameter_get.return_value = None self.assertEqual({'code': 404, 'data': 'urn:ietf:params:acme:error:malformed'}, self. renewalinfo.get('url')) self.assertTrue(mock_update.called) self.assertTrue(mock_renstr_get.called) From b43b9107cda6cc0806cecdf15266c2d599e6d65e Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 4 Feb 2024 11:04:46 +0100 Subject: [PATCH 056/460] [fix] unittests --- test/test_helper.py | 2 +- test/test_renewalinfo.py | 70 ++++++++++++++++++++-------------------- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/test/test_helper.py b/test/test_helper.py index fc429ff3..deec7132 100644 --- a/test/test_helper.py +++ b/test/test_helper.py @@ -2182,7 +2182,7 @@ def test_284_aki_get(self, mock_load, mock_aki): self.assertTrue(mock_aki.called) @patch('OpenSSL.crypto.load_certificate') - def test_281_aki_get(self, mock_load): + def test_285_aki_get(self, mock_load): """ test cert_aki_get() """ cert = 'cert' mock_load.get_extension_count.return_value = 2 diff --git a/test/test_renewalinfo.py b/test/test_renewalinfo.py index df76db0c..90599a96 100644 --- a/test/test_renewalinfo.py +++ b/test/test_renewalinfo.py @@ -161,7 +161,7 @@ def test_011_config_enter(self, mock_load_cfg): @patch('acme_srv.renewalinfo.Renewalinfo._renewalinfo_generate') @patch('acme_srv.renewalinfo.Renewalinfo._cert_dic_lookup') - def test_019_renewalinfo_get(self, mock_lookup, mock_gen): + def test_012_renewalinfo_get(self, mock_lookup, mock_gen): """ test _renewalinfo_get() """ mock_gen.return_value = {'foo': 'bar'} self.assertEqual({'foo': 'bar'}, self.renewalinfo._renewalinfo_get('1a2b3c4d5e6f')) @@ -170,7 +170,7 @@ def test_019_renewalinfo_get(self, mock_lookup, mock_gen): @patch('acme_srv.renewalinfo.Renewalinfo._renewalinfo_get') @patch('acme_srv.renewalinfo.Renewalinfo._renewalinfo_string_get') @patch('acme_srv.renewalinfo.Renewalinfo._cert_table_update') - def test_020_get(self, mock_update, mock_renstr_get, mock_renget): + def test_013_get(self, mock_update, mock_renstr_get, mock_renget): """ test get() """ mock_renget.return_value = {'foo': 'bar'} mock_renstr_get.return_value = 'mock_renstr_get' @@ -181,7 +181,7 @@ def test_020_get(self, mock_update, mock_renstr_get, mock_renget): @patch('acme_srv.renewalinfo.Renewalinfo._renewalinfo_get') @patch('acme_srv.renewalinfo.Renewalinfo._renewalinfo_string_get') @patch('acme_srv.renewalinfo.Renewalinfo._cert_table_update') - def test_021_get(self, mock_update, mock_renstr_get, mock_renget): + def test_014_get(self, mock_update, mock_renstr_get, mock_renget): """ test get() """ mock_renget.return_value = {'foo': 'bar'} mock_renstr_get.return_value = 'mock_renstr_get' @@ -192,7 +192,7 @@ def test_021_get(self, mock_update, mock_renstr_get, mock_renget): @patch('acme_srv.renewalinfo.Renewalinfo._renewalinfo_get') @patch('acme_srv.renewalinfo.Renewalinfo._renewalinfo_string_get') @patch('acme_srv.renewalinfo.Renewalinfo._cert_table_update') - def test_022_get(self, mock_update, mock_renstr_get, mock_renget): + def test_015_get(self, mock_update, mock_renstr_get, mock_renget): """ test get() """ mock_renget.return_value = None self.renewalinfo.dbstore.hkparameter_get.return_value = None @@ -201,20 +201,20 @@ def test_022_get(self, mock_update, mock_renstr_get, mock_renget): self.assertTrue(mock_renstr_get.called) @patch('acme_srv.message.Message.check') - def test_023_update(self, mock_mcheck): + def test_016_update(self, mock_mcheck): """ test update() """ mock_mcheck.return_value = (400, 'message', 'detail', 'protected', 'payload', 'account_name') self.assertEqual({'code': 400}, self.renewalinfo.update('content')) @patch('acme_srv.message.Message.check') - def test_024_update(self, mock_mcheck): + def test_017_update(self, mock_mcheck): """ test update() """ mock_mcheck.return_value = (200, 'message', 'detail', 'protected', {'certid': 'certid'}, 'account_name') self.assertEqual({'code': 400}, self.renewalinfo.update('content')) @patch('acme_srv.renewalinfo.Renewalinfo._cert_dic_lookup') @patch('acme_srv.message.Message.check') - def test_025_update(self, mock_mcheck, mock_lookup): + def test_018_update(self, mock_mcheck, mock_lookup): """ test update() """ mock_mcheck.return_value = (200, 'message', 'detail', 'protected', {'certid': 'certid', 'replaced': True}, 'account_name') mock_lookup.return_value = None @@ -222,7 +222,7 @@ def test_025_update(self, mock_mcheck, mock_lookup): @patch('acme_srv.renewalinfo.Renewalinfo._cert_dic_lookup') @patch('acme_srv.message.Message.check') - def test_026_update(self, mock_mcheck, mock_lookup): + def test_019_update(self, mock_mcheck, mock_lookup): """ test update() """ mock_mcheck.return_value = (200, 'message', 'detail', 'protected', {'certid': 'certid', 'replaced': False}, 'account_name') mock_lookup.return_value = {'foo': 'bar'} @@ -230,7 +230,7 @@ def test_026_update(self, mock_mcheck, mock_lookup): @patch('acme_srv.renewalinfo.Renewalinfo._cert_dic_lookup') @patch('acme_srv.message.Message.check') - def test_027_update(self, mock_mcheck, mock_lookup): + def test_020_update(self, mock_mcheck, mock_lookup): """ test update() """ mock_mcheck.return_value = (200, 'message', 'detail', 'protected', {'certid': 'certid', 'replaced': True}, 'account_name') mock_lookup.return_value = {'foo': 'bar'} @@ -239,28 +239,28 @@ def test_027_update(self, mock_mcheck, mock_lookup): @patch('acme_srv.renewalinfo.Renewalinfo._cert_dic_lookup') @patch('acme_srv.message.Message.check') - def test_028_update(self, mock_mcheck, mock_lookup): + def test_021_update(self, mock_mcheck, mock_lookup): """ test update() """ mock_mcheck.return_value = (200, 'message', 'detail', 'protected', {'certid': 'certid', 'replaced': True}, 'account_name') mock_lookup.return_value = {'foo': 'bar'} self.renewalinfo.dbstore.certificate_add.return_value = 1 self.assertEqual({'code': 200}, self.renewalinfo.update('content')) - def test_029_renewalinfo_string_get(self): + def test_022_renewalinfo_string_get(self): """ test update() """ self.renewalinfo.server_name = 'http://server.name' self.renewalinfo.path_dic = {'renewalinfo': '/renewalinfo'} input_string = 'http://server.name/renewalinfo/foo' self.assertEqual('foo', self.renewalinfo._renewalinfo_string_get(input_string)) - def test_030_renewalinfo_string_get(self): + def test_023_renewalinfo_string_get(self): """ test update() """ self.renewalinfo.server_name = 'http://server.name' self.renewalinfo.path_dic = {'renewalinfo': '/renewalinfo'} input_string = 'http://server.name/renewalinfofoo' self.assertEqual('foo', self.renewalinfo._renewalinfo_string_get(input_string)) - def test_031_renewalinfo_string_get(self): + def test_024_renewalinfo_string_get(self): """ test update() """ self.renewalinfo.server_name = 'http://server.name' self.renewalinfo.path_dic = {'renewalinfo': '/renewalinfo/'} @@ -271,7 +271,7 @@ def test_031_renewalinfo_string_get(self): @patch('acme_srv.renewalinfo.Renewalinfo._draft01_lookup') @patch('acme_srv.renewalinfo.certid_hex_get') @patch('acme_srv.renewalinfo.Renewalinfo._serial_aki_get') - def test_032_cert_dic_lookup(self, mock_aki, mock_certid, mock_draft01, mock_draft02): + def test_025_cert_dic_lookup(self, mock_aki, mock_certid, mock_draft01, mock_draft02): """ test _cert_dic_lookup() """ mock_aki.return_value = ('serail', 'aki') mock_draft01.return_value = {'foo': 'draft01'} @@ -286,7 +286,7 @@ def test_032_cert_dic_lookup(self, mock_aki, mock_certid, mock_draft01, mock_dra @patch('acme_srv.renewalinfo.Renewalinfo._draft01_lookup') @patch('acme_srv.renewalinfo.certid_hex_get') @patch('acme_srv.renewalinfo.Renewalinfo._serial_aki_get') - def test_033_cert_dic_lookup(self, mock_aki, mock_certid, mock_draft01, mock_draft02): + def test_026_cert_dic_lookup(self, mock_aki, mock_certid, mock_draft01, mock_draft02): """ test _cert_dic_lookup() """ mock_aki.return_value = ('serail', 'aki') mock_certid.return_value = ('mda', 'certid') @@ -298,31 +298,31 @@ def test_033_cert_dic_lookup(self, mock_aki, mock_certid, mock_draft01, mock_dra self.assertTrue(mock_draft01.called) self.assertFalse(mock_draft02.called) - def test_034_draft01_lookup(self): + def test_027_draft01_lookup(self): """ test _draft01_lookup() """ self.renewalinfo.dbstore.certificate_lookup.return_value = {'foo': 'bar'} self.assertEqual({'foo': 'bar'}, self.renewalinfo._draft01_lookup('certid_hex')) - def test_035_draft01_lookup(self): + def test_028_draft01_lookup(self): """ test _draft01_lookup() """ self.renewalinfo.dbstore.certificate_lookup.side_effect = Exception('cert_lookup') with self.assertLogs('test_a2c', level='INFO') as lcm: self.assertFalse(self.renewalinfo._draft01_lookup('certid_hex')) self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Renewalinfo._draft01_lookup(): cert_lookup', lcm.output) - def test_036_draft02_lookup(self): + def test_029_draft02_lookup(self): """ test _draft02_lookup() """ self.renewalinfo.dbstore.certificates_search.return_value = [{'foo': 'bar01', 'aki': 'aki01'}, {'foo': 'bar02', 'aki': 'aki02'}] self.assertEqual({'aki': 'aki01', 'foo': 'bar01'}, self.renewalinfo._draft02_lookup('serial', 'aki01')) - def test_037_draft02_lookup(self): + def test_030_draft02_lookup(self): """ test _draft02_lookup() """ self.renewalinfo.dbstore.certificates_search.return_value = [{'foo': 'bar01', 'aki': 'aki01'}, {'foo': 'bar02', 'aki': 'aki02'}] self.assertEqual({'aki': 'aki02', 'foo': 'bar02'}, self.renewalinfo._draft02_lookup('serial', 'aki02')) @patch('acme_srv.renewalinfo.cert_aki_get') @patch('acme_srv.renewalinfo.cert_serial_get') - def test_038_cert_table_update(self, mock_serial, mock_aki): + def test_031_cert_table_update(self, mock_serial, mock_aki): """ test _cert_table_update() """ self.renewalinfo.dbstore.certificates_search.return_value = [{'foo': 'bar', 'cert_raw': 'cert_raw', 'name': 'name', 'cert': 'cert'}] self.assertFalse(self.renewalinfo._cert_table_update()) @@ -331,7 +331,7 @@ def test_038_cert_table_update(self, mock_serial, mock_aki): @patch('acme_srv.renewalinfo.cert_aki_get') @patch('acme_srv.renewalinfo.cert_serial_get') - def test_039_cert_table_update(self, mock_serial, mock_aki): + def test_032_cert_table_update(self, mock_serial, mock_aki): """ test _cert_table_update() """ self.renewalinfo.dbstore.certificates_search.return_value = [{'foo': 'bar', 'cert_raw': None, 'name': 'name', 'cert': 'cert'}] self.assertFalse(self.renewalinfo._cert_table_update()) @@ -340,7 +340,7 @@ def test_039_cert_table_update(self, mock_serial, mock_aki): @patch('acme_srv.renewalinfo.cert_aki_get') @patch('acme_srv.renewalinfo.cert_serial_get') - def test_040_cert_table_update(self, mock_serial, mock_aki): + def test_033_cert_table_update(self, mock_serial, mock_aki): """ test _cert_table_update() """ self.renewalinfo.dbstore.certificates_search.return_value = [{'foo': 'bar', 'name': 'name', 'cert': 'cert'}] self.assertFalse(self.renewalinfo._cert_table_update()) @@ -349,7 +349,7 @@ def test_040_cert_table_update(self, mock_serial, mock_aki): @patch('acme_srv.renewalinfo.cert_aki_get') @patch('acme_srv.renewalinfo.cert_serial_get') - def test_041_cert_table_update(self, mock_serial, mock_aki): + def test_034_cert_table_update(self, mock_serial, mock_aki): """ test _cert_table_update() """ self.renewalinfo.dbstore.certificates_search.return_value = Exception('certificates_search') with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -358,19 +358,19 @@ def test_041_cert_table_update(self, mock_serial, mock_aki): self.assertFalse(mock_serial.called) self.assertFalse(mock_aki.called) - def test_038_draft02_lookup(self): + def test_035_draft02_lookup(self): """ test _draft02_lookup() """ self.renewalinfo.dbstore.certificates_search.return_value = [{'foo': 'bar01', 'aki': 'aki01'}, {'foo': 'bar02', 'aki': 'aki02'}] self.assertFalse(self.renewalinfo._draft02_lookup('serial', 'aki03')) - def test_039_draft02_lookup(self): + def test_036_draft02_lookup(self): """ test _draft02_lookup() """ self.renewalinfo.dbstore.certificates_search.return_value = [{'foo': 'bar01', }, {'foo': 'bar02', 'aki': 'aki02'}] with self.assertLogs('test_a2c', level='INFO') as lcm: self.assertFalse(self.renewalinfo._draft02_lookup('serial', 'aki03')) self.assertIn("CRITICAL:test_a2c:acme2certifier database error in Renewalinfo._draft02_lookup(): 'aki'", lcm.output) - def test_040_draft02_lookup(self): + def test_037_draft02_lookup(self): """ test _draft02_lookup() """ self.renewalinfo.dbstore.certificates_search.side_effect = Exception('certificates_search') with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -379,7 +379,7 @@ def test_040_draft02_lookup(self): @patch('acme_srv.renewalinfo.b64_url_recode') @patch('acme_srv.renewalinfo.b64_decode') - def test_041_serial_aki_get(self, mock_dec, mock_rec): + def test_038_serial_aki_get(self, mock_dec, mock_rec): """ test _serial_aki_get() """ mock_dec.side_effect = [b'aki', b'serial'] mock_rec.side_effect = ['foo1', 'foo2'] @@ -389,7 +389,7 @@ def test_041_serial_aki_get(self, mock_dec, mock_rec): @patch('acme_srv.renewalinfo.b64_url_recode') @patch('acme_srv.renewalinfo.b64_decode') - def test_042_serial_aki_get(self, mock_dec, mock_rec): + def test_039_serial_aki_get(self, mock_dec, mock_rec): """ test _serial_aki_get() """ mock_dec.side_effect = [b'aki', b'serial'] mock_rec.side_effect = ['foo1', 'foo2'] @@ -399,7 +399,7 @@ def test_042_serial_aki_get(self, mock_dec, mock_rec): @patch('acme_srv.renewalinfo.b64_url_recode') @patch('acme_srv.renewalinfo.b64_decode') - def test_043_serial_aki_get(self, mock_dec, mock_rec): + def test_040_serial_aki_get(self, mock_dec, mock_rec): """ test _serial_aki_get() """ mock_dec.side_effect = [b'aki', b'serial'] mock_rec.side_effect = ['foo1', 'foo2'] @@ -407,27 +407,27 @@ def test_043_serial_aki_get(self, mock_dec, mock_rec): self.assertFalse(mock_dec.called) self.assertFalse(mock_rec.called) - def test_014_renewalinfo_generate(self): + def test_041_renewalinfo_generate(self): """ test _renewalinfo_generate() """ self.assertFalse(self.renewalinfo._renewalinfo_generate({})) - def test_015_renewalinfo_generate(self): + def test_042_renewalinfo_generate(self): """ test _renewalinfo_generate() """ cert_dic = {'foo': 'bar'} self.assertFalse(self.renewalinfo._renewalinfo_generate(cert_dic)) - def test_016_renewalinfo_generate(self): + def test_043_renewalinfo_generate(self): """ test _renewalinfo_generate() """ cert_dic = {'expire_uts': 0} self.assertFalse(self.renewalinfo._renewalinfo_generate(cert_dic)) - def test_017_renewalinfo_generate(self): + def test_044_renewalinfo_generate(self): """ test _renewalinfo_generate() """ cert_dic = {'expire_uts': 1000, 'issue_uts': 100} self.assertEqual({'suggestedWindow': {'start': '1970-01-01T00:14:25Z', 'end': '1970-01-01T00:16:40Z'}}, self.renewalinfo._renewalinfo_generate(cert_dic)) @patch('acme_srv.renewalinfo.uts_now') - def test_018_renewalinfo_generate(self, mock_uts): + def test_045_renewalinfo_generate(self, mock_uts): """ test _renewalinfo_generate() """ mock_uts.return_value = 100 cert_dic = {'expire_uts': 1000} @@ -435,7 +435,7 @@ def test_018_renewalinfo_generate(self, mock_uts): self.assertTrue(mock_uts.called) @patch('acme_srv.renewalinfo.uts_now') - def test_019_renewalinfo_generate(self, mock_uts): + def test_046_renewalinfo_generate(self, mock_uts): """ test _renewalinfo_generate() """ mock_uts.return_value = 86400000 cert_dic = {'expire_uts': 1000, 'issue_uts': 200} From 28c47af4593626a2ed8f481d68301ceccbfec1d7 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 4 Feb 2024 11:10:36 +0100 Subject: [PATCH 057/460] [fix] unittests --- test/test_renewalinfo.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/test_renewalinfo.py b/test/test_renewalinfo.py index 90599a96..5074e1e4 100644 --- a/test/test_renewalinfo.py +++ b/test/test_renewalinfo.py @@ -347,28 +347,28 @@ def test_033_cert_table_update(self, mock_serial, mock_aki): self.assertFalse(mock_serial.called) self.assertFalse(mock_aki.called) + def test_034_draft02_lookup(self): + """ test _draft02_lookup() """ + self.renewalinfo.dbstore.certificates_search.return_value = [{'foo': 'bar01', 'aki': 'aki01'}, {'foo': 'bar02', 'aki': 'aki02'}] + self.assertFalse(self.renewalinfo._draft02_lookup('serial', 'aki03')) + @patch('acme_srv.renewalinfo.cert_aki_get') @patch('acme_srv.renewalinfo.cert_serial_get') - def test_034_cert_table_update(self, mock_serial, mock_aki): + def test_035_cert_table_update(self, mock_serial, mock_aki): """ test _cert_table_update() """ - self.renewalinfo.dbstore.certificates_search.return_value = Exception('certificates_search') + self.renewalinfo.dbstore.certificates_search.side_effect = Exception('certificates_search') with self.assertLogs('test_a2c', level='INFO') as lcm: self.assertFalse(self.renewalinfo._cert_table_update()) self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Renewalinfo._cert_table_update(): certificates_search', lcm.output) self.assertFalse(mock_serial.called) self.assertFalse(mock_aki.called) - def test_035_draft02_lookup(self): - """ test _draft02_lookup() """ - self.renewalinfo.dbstore.certificates_search.return_value = [{'foo': 'bar01', 'aki': 'aki01'}, {'foo': 'bar02', 'aki': 'aki02'}] - self.assertFalse(self.renewalinfo._draft02_lookup('serial', 'aki03')) - def test_036_draft02_lookup(self): """ test _draft02_lookup() """ self.renewalinfo.dbstore.certificates_search.return_value = [{'foo': 'bar01', }, {'foo': 'bar02', 'aki': 'aki02'}] with self.assertLogs('test_a2c', level='INFO') as lcm: self.assertFalse(self.renewalinfo._draft02_lookup('serial', 'aki03')) - self.assertIn("CRITICAL:test_a2c:acme2certifier database error in Renewalinfo._draft02_lookup(): 'aki'", lcm.output) + self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Renewalinfo._draft02_lookup(): certificates_search', lcm.output) def test_037_draft02_lookup(self): """ test _draft02_lookup() """ From 860caf9b8710759cd8184b799cd9e0dda9c183e9 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 4 Feb 2024 12:55:53 +0100 Subject: [PATCH 058/460] bump --- .github/workflows/push_rpm.yml | 174 +++++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 .github/workflows/push_rpm.yml diff --git a/.github/workflows/push_rpm.yml b/.github/workflows/push_rpm.yml new file mode 100644 index 00000000..b093bbaf --- /dev/null +++ b/.github/workflows/push_rpm.yml @@ -0,0 +1,174 @@ +name: build and upload rpm +on: + push: + branches: + - "rpm_min" +jobs: + + build_and_upload_rpm: + name: build_and_upload_rpm + runs-on: ubuntu-latest + steps: + + - name: Checkout code + uses: actions/checkout@v3 + + - name: "[ PREPARE ] Retrieve Version from version.py" + run: | + echo APP_NAME=$(echo ${{ github.repository }} | awk -F / '{print $2}') >> $GITHUB_ENV + echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV + + - run: echo "Repo is at version ${{ steps.acme2certifier_ver.outputs.tag }}" + - run: echo "APP tag is ${{ env.APP_NAME }}" + - run: echo "Latest tag is ${{ env.TAG_NAME }}" + + - name: "[ PREPARE ] update version number in spec file" + run: | + sudo sed -i "s/__version__/${{ env.TAG_NAME }}/g" examples/install_scripts/rpm/acme2certifier.spec + sudo sed -i "s/\/var\/www\/acme2certifier\/volume/\/etc\/nginx/g" examples/nginx/nginx_acme_srv_ssl.conf + # sudo sed -i "s/projname acme2certifier/projname acme2certifier-min\n%define _rpmfilename %%{ARCH}\/%%{NAME}-min-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm/g" examples/install_scripts/rpm/acme2certifier.spec + sudo sed -i "s/projname acme2certifier/projname acme2certifier-min/g" examples/install_scripts/rpm/acme2certifier.spec + sudo sed -i "s/Name: acme2certifier/Name: acme2certifier-min/g" examples/install_scripts/rpm/acme2certifier.spec + git config --global user.email "grindelsack@gmail.com" + git config --global user.name "rpm update" + git add examples/nginx + git commit -a -m "rpm update" + + - name: build RPM package + id: rpm_build + uses: grindsa/rpmbuild@alma9 + with: + spec_file: "examples/install_scripts/rpm/acme2certifier.spec" + + - name: "[ PREPARE ] setup environment for alma installation" + run: | + docker network create acme + sudo mkdir -p data/volume + sudo mkdir -p data/acme2certifier + sudo mkdir -p data/nginx/conf.d + sudo chmod -R 777 data + sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data + ls -la cp ${{ steps.rpm_build.outputs.rpm_dir_path }} + sudo cp ${{ steps.rpm_build.outputs.rpm_dir_path }}noarch/acme2certifier-min-${{ env.TAG_NAME }}-1.0.noarch.rpm data + sudo cp .github/acme2certifier_cert.pem data/nginx/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem data/nginx/acme2certifier_key.pem + sudo cp examples/nginx/nginx_acme_srv_ssl.conf data/nginx/conf.d + sudo sed -i "s/\/var\/www\/acme2certifier\/volume/\/etc\/nginx/g" data/nginx/conf.d/nginx_acme_srv_ssl.conf + + - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + run: | + mkdir -p data/acme_ca + sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem + sudo touch data/acme_srv.cfg + sudo chmod 777 data/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/acme_srv.cfg + sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> data/acme_srv.cfg + sudo echo "api_host: $NCM_API_HOST" >> data/acme_srv.cfg + sudo echo "api_user: $NCM_API_USER" >> data/acme_srv.cfg + sudo echo "api_password: $NCM_API_PASSWORD" >> data/acme_srv.cfg + sudo echo "ca_name: $NCM_CA_NAME" >> data/acme_srv.cfg + sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> data/acme_srv.cfg + sudo echo "profile_id: 101" >> data/acme_srv.cfg + env: + NCM_API_HOST: ${{ secrets.NCM_API_HOST }} + NCM_API_USER: ${{ secrets.NCM_API_USER }} + NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} + NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} + NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} + + - name: "[ PREPARE ] Almalinux instance" + run: | + cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd + + - name: "[ PREPARE ] Execute install scipt" + run: | + docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh + + - name: "[ TEST ] create client directories" + run: | + mkdir -p acme-sh + + - name: "[ TEST ] http://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "[ TEST ] https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "[ TEST ] prepare acme.sh container" + run: | + docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + + - name: "[ HTTP ] acme.sh using http01 challenge" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + + - name: "[ HTTP ] acme.sh using tls-alpn01 challenge" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + + - name: "[ HTTP ] revoke via acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure + + - name: "[ HTTPS ] register via https" + run: | + docker exec -i acme-sh acme.sh --server https://acme-srv --register-account --accountemail 'acme-sh@example.com' --accountkeylength ec-256 --insecure --debug 2 + + - name: "[ HTTPS ] acme.sh using http01 challenge" + run: | + docker exec -i acme-sh acme.sh --server https://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --insecure --debug 3 --output-insecure --force + + - name: "[ HTTPS ] acme.sh using tls-alpn01 challenge" + run: | + docker exec -i acme-sh acme.sh --server https://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --insecure --debug 3 --output-insecure --force + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + + - name: "[ HTTPS ] revoke via acme.sh" + run: | + docker exec -i acme-sh acme.sh --server https://acme-srv --revoke -d acme-sh.acme --standalone --insecure --debug 3 --output-insecure + + - run: echo "srpm path ${{ steps.rpm_build.outputs.source_rpm_path }}" + - run: echo "srpm name ${{ steps.rpm_build.outputs.source_rpm_path }}" + - run: echo "rpm path ${{ steps.rpm_build.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm" + - run: echo "rpm name acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm" + + - name: "[ FINALIZE ] copy rpm" + run: | + git reset --hard HEAD~1 + mkdir -p examples/install_scripts/rpm/packages + cp ${{ steps.rpm_build.outputs.rpm_dir_path }}noarch/acme2certifier-min-${{ env.TAG_NAME }}-1.0.noarch.rpm examples/install_scripts/rpm/packages + cp ${{ steps.rpm_build.outputs.source_rpm_path }} examples/install_scripts/rpm/packages + ls -la examples/install_scripts/rpm/packages + + - name: "[ FINALIZE ] cleanup before commit" + run: | + sudo rm -rf rpmbuild + sudo rm -rf acme-sh + sudo rm -rf data + sudo rm -rf *.pem + + - uses: stefanzweifel/git-auto-commit-action@v5 + with: + commit_message: rpm update + + - name: "[ * ] collecting test logs" + if: ${{ failure() }} + run: | + mkdir -p ${{ github.workspace }}/artifact/upload + docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier + docker exec acme-srv tar cvfz /tmp/acme2certifier/nginx.tgz /etc/nginx + sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh + + - name: "[ * ] uploading artificates" + uses: actions/upload-artifact@v3 + if: ${{ failure() }} + with: + name: rpm_wsgi_upgrade_nginx.tar.gz + path: ${{ github.workspace }}/artifact/upload/ From 6b6d6a96e7d482149200b8dcbb52e45254a8d2f8 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 4 Feb 2024 13:16:47 +0100 Subject: [PATCH 059/460] [fix] delete push_rpm wf --- .github/workflows/push_rpm.yml | 174 --------------------------------- 1 file changed, 174 deletions(-) delete mode 100644 .github/workflows/push_rpm.yml diff --git a/.github/workflows/push_rpm.yml b/.github/workflows/push_rpm.yml deleted file mode 100644 index b093bbaf..00000000 --- a/.github/workflows/push_rpm.yml +++ /dev/null @@ -1,174 +0,0 @@ -name: build and upload rpm -on: - push: - branches: - - "rpm_min" -jobs: - - build_and_upload_rpm: - name: build_and_upload_rpm - runs-on: ubuntu-latest - steps: - - - name: Checkout code - uses: actions/checkout@v3 - - - name: "[ PREPARE ] Retrieve Version from version.py" - run: | - echo APP_NAME=$(echo ${{ github.repository }} | awk -F / '{print $2}') >> $GITHUB_ENV - echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV - - - run: echo "Repo is at version ${{ steps.acme2certifier_ver.outputs.tag }}" - - run: echo "APP tag is ${{ env.APP_NAME }}" - - run: echo "Latest tag is ${{ env.TAG_NAME }}" - - - name: "[ PREPARE ] update version number in spec file" - run: | - sudo sed -i "s/__version__/${{ env.TAG_NAME }}/g" examples/install_scripts/rpm/acme2certifier.spec - sudo sed -i "s/\/var\/www\/acme2certifier\/volume/\/etc\/nginx/g" examples/nginx/nginx_acme_srv_ssl.conf - # sudo sed -i "s/projname acme2certifier/projname acme2certifier-min\n%define _rpmfilename %%{ARCH}\/%%{NAME}-min-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm/g" examples/install_scripts/rpm/acme2certifier.spec - sudo sed -i "s/projname acme2certifier/projname acme2certifier-min/g" examples/install_scripts/rpm/acme2certifier.spec - sudo sed -i "s/Name: acme2certifier/Name: acme2certifier-min/g" examples/install_scripts/rpm/acme2certifier.spec - git config --global user.email "grindelsack@gmail.com" - git config --global user.name "rpm update" - git add examples/nginx - git commit -a -m "rpm update" - - - name: build RPM package - id: rpm_build - uses: grindsa/rpmbuild@alma9 - with: - spec_file: "examples/install_scripts/rpm/acme2certifier.spec" - - - name: "[ PREPARE ] setup environment for alma installation" - run: | - docker network create acme - sudo mkdir -p data/volume - sudo mkdir -p data/acme2certifier - sudo mkdir -p data/nginx/conf.d - sudo chmod -R 777 data - sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data - ls -la cp ${{ steps.rpm_build.outputs.rpm_dir_path }} - sudo cp ${{ steps.rpm_build.outputs.rpm_dir_path }}noarch/acme2certifier-min-${{ env.TAG_NAME }}-1.0.noarch.rpm data - sudo cp .github/acme2certifier_cert.pem data/nginx/acme2certifier_cert.pem - sudo cp .github/acme2certifier_key.pem data/nginx/acme2certifier_key.pem - sudo cp examples/nginx/nginx_acme_srv_ssl.conf data/nginx/conf.d - sudo sed -i "s/\/var\/www\/acme2certifier\/volume/\/etc\/nginx/g" data/nginx/conf.d/nginx_acme_srv_ssl.conf - - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" - run: | - mkdir -p data/acme_ca - sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem - sudo touch data/acme_srv.cfg - sudo chmod 777 data/acme_srv.cfg - sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/acme_srv.cfg - sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> data/acme_srv.cfg - sudo echo "api_host: $NCM_API_HOST" >> data/acme_srv.cfg - sudo echo "api_user: $NCM_API_USER" >> data/acme_srv.cfg - sudo echo "api_password: $NCM_API_PASSWORD" >> data/acme_srv.cfg - sudo echo "ca_name: $NCM_CA_NAME" >> data/acme_srv.cfg - sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> data/acme_srv.cfg - sudo echo "profile_id: 101" >> data/acme_srv.cfg - env: - NCM_API_HOST: ${{ secrets.NCM_API_HOST }} - NCM_API_USER: ${{ secrets.NCM_API_USER }} - NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} - NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} - NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - - name: "[ PREPARE ] Almalinux instance" - run: | - cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache - docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - - - name: "[ PREPARE ] Execute install scipt" - run: | - docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh - - - name: "[ TEST ] create client directories" - run: | - mkdir -p acme-sh - - - name: "[ TEST ] http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ TEST ] https://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - - name: "[ TEST ] prepare acme.sh container" - run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - - name: "[ HTTP ] acme.sh using http01 challenge" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force - awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer - openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - - name: "[ HTTP ] acme.sh using tls-alpn01 challenge" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force - openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - - name: "[ HTTP ] revoke via acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure - - - name: "[ HTTPS ] register via https" - run: | - docker exec -i acme-sh acme.sh --server https://acme-srv --register-account --accountemail 'acme-sh@example.com' --accountkeylength ec-256 --insecure --debug 2 - - - name: "[ HTTPS ] acme.sh using http01 challenge" - run: | - docker exec -i acme-sh acme.sh --server https://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --insecure --debug 3 --output-insecure --force - - - name: "[ HTTPS ] acme.sh using tls-alpn01 challenge" - run: | - docker exec -i acme-sh acme.sh --server https://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --insecure --debug 3 --output-insecure --force - openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - - name: "[ HTTPS ] revoke via acme.sh" - run: | - docker exec -i acme-sh acme.sh --server https://acme-srv --revoke -d acme-sh.acme --standalone --insecure --debug 3 --output-insecure - - - run: echo "srpm path ${{ steps.rpm_build.outputs.source_rpm_path }}" - - run: echo "srpm name ${{ steps.rpm_build.outputs.source_rpm_path }}" - - run: echo "rpm path ${{ steps.rpm_build.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm" - - run: echo "rpm name acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm" - - - name: "[ FINALIZE ] copy rpm" - run: | - git reset --hard HEAD~1 - mkdir -p examples/install_scripts/rpm/packages - cp ${{ steps.rpm_build.outputs.rpm_dir_path }}noarch/acme2certifier-min-${{ env.TAG_NAME }}-1.0.noarch.rpm examples/install_scripts/rpm/packages - cp ${{ steps.rpm_build.outputs.source_rpm_path }} examples/install_scripts/rpm/packages - ls -la examples/install_scripts/rpm/packages - - - name: "[ FINALIZE ] cleanup before commit" - run: | - sudo rm -rf rpmbuild - sudo rm -rf acme-sh - sudo rm -rf data - sudo rm -rf *.pem - - - uses: stefanzweifel/git-auto-commit-action@v5 - with: - commit_message: rpm update - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier - docker exec acme-srv tar cvfz /tmp/acme2certifier/nginx.tgz /etc/nginx - sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ - docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v3 - if: ${{ failure() }} - with: - name: rpm_wsgi_upgrade_nginx.tar.gz - path: ${{ github.workspace }}/artifact/upload/ From 05f0b23ed976454674adb53b8298753454b7cbf3 Mon Sep 17 00:00:00 2001 From: grindsa Date: Tue, 6 Feb 2024 08:10:58 +0100 Subject: [PATCH 060/460] [fix] #132 - return serial numbers with leading zero --- acme_srv/helper.py | 2 ++ test/test_helper.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/acme_srv/helper.py b/acme_srv/helper.py index da43f11f..33423cfd 100644 --- a/acme_srv/helper.py +++ b/acme_srv/helper.py @@ -411,6 +411,8 @@ def cert_serial_get(logger: logging.Logger, certificate: str, hexformat: bool = cert = cert_load(logger, certificate, recode=True) if hexformat: serial_number = f'{cert.serial_number:x}' + # add leading zero if needed + serial_number = serial_number.zfill(len(serial_number) + len(serial_number) % 2) else: serial_number = cert.serial_number logger.debug('cert_serial_get() ended with: %s', serial_number) diff --git a/test/test_helper.py b/test/test_helper.py index deec7132..1f4401cc 100644 --- a/test/test_helper.py +++ b/test/test_helper.py @@ -376,7 +376,7 @@ def test_043_helper_cert_serial_get(self): bta75ocePrurdNxsxKJhLlXbnKD6lurCb4khRhrmLmpK8JxhuaevEVklSQX0gqlR fxAH4XQsaqcaedPNI+W5OUITMz40ezDCbUqxS9KEMCGPoOTXNRAjbr72sc4Vkw7H t+eRUDECE+0UnjyeCjTn3EU=""" - self.assertEqual('a', self.cert_serial_get(self.logger, cert, hexformat=True)) + self.assertEqual('0a', self.cert_serial_get(self.logger, cert, hexformat=True)) def test_044_helper_cert_issuer_get(self): """ test cert_issuer_get """ From 1afbf664882b98ed5a48f16331a59fe9ab4e1d55 Mon Sep 17 00:00:00 2001 From: grindsa Date: Tue, 6 Feb 2024 08:43:52 +0100 Subject: [PATCH 061/460] [rel] bump to v0.33.1 --- CHANGES.md | 6 ++++++ acme_srv/version.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index e7178dc5..44d57e95 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,6 +5,12 @@ This is a high-level summary of the most important changes. For a full list of changes, see the [git commit log](https://github.com/grindsa/acme2certifier/commits) and pick the appropriate release branch. +# Changes in 0.33.1 + +**Bugfixes** + +- [132](https://github.com/grindsa/acme2certifier/issues/132) - returning serial numbers in hex-format with leading zero + # Changes in 0.33 **Upgrade notes**: diff --git a/acme_srv/version.py b/acme_srv/version.py index c92a3981..e2879d3c 100644 --- a/acme_srv/version.py +++ b/acme_srv/version.py @@ -3,5 +3,5 @@ # 1) we don't load dependencies by storing it in __init__.py # 2) we can import it in setup.py for the same reason # 3) we can import it into your module module -__version__ = '0.33' +__version__ = '0.33.1' __dbversion__ = '0.33' From 904ccd7c0f51e966b8ae857da62d6a5f09704e23 Mon Sep 17 00:00:00 2001 From: grindsa Date: Tue, 6 Feb 2024 08:54:05 +0100 Subject: [PATCH 062/460] [fix] md linting --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 44d57e95..131b5714 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,7 +7,7 @@ and pick the appropriate release branch. # Changes in 0.33.1 -**Bugfixes** +**Bugfixes**: - [132](https://github.com/grindsa/acme2certifier/issues/132) - returning serial numbers in hex-format with leading zero From 56550d01c7525a66802ee66fc6f7e7767a3a171a Mon Sep 17 00:00:00 2001 From: grindsa Date: Tue, 6 Feb 2024 09:31:31 +0100 Subject: [PATCH 063/460] [fix] md linting --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 44d57e95..131b5714 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,7 +7,7 @@ and pick the appropriate release branch. # Changes in 0.33.1 -**Bugfixes** +**Bugfixes**: - [132](https://github.com/grindsa/acme2certifier/issues/132) - returning serial numbers in hex-format with leading zero From b33be856c2e99e0995585b4c62270fce966bf564 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 18 Feb 2024 09:52:28 +0100 Subject: [PATCH 064/460] [wf] dns-tests on rh8 --- .github/workflows/dns-test.yml | 28 ++++++++++++++++--- .../Docker/almalinux-systemd/rpm_tester.sh | 4 +++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/.github/workflows/dns-test.yml b/.github/workflows/dns-test.yml index bc0a1f27..b31666be 100644 --- a/.github/workflows/dns-test.yml +++ b/.github/workflows/dns-test.yml @@ -32,8 +32,10 @@ jobs: sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py sudo mkdir -p examples/Docker/data/acme_ca/certs sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler_dns.cfg examples/Docker/data/acme_srv.cfg + # sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler_dns.cfg examples/Docker/data/acme_srv.cfg + sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg sudo chmod 777 examples/Docker/data/acme_srv.cfg + sudo sed -i "s/challenge_validation_disable: False/challenge_validation_disable: False\ndns_server_list: [\"DNS-IP\"]/g" examples/Docker/data/acme_srv.cfg cd examples/Docker/ docker-compose restart docker-compose logs @@ -118,6 +120,11 @@ jobs: dns_challenge_tests_rpm: name: "dns_challenge_tests_rpm" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] + steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -149,12 +156,21 @@ jobs: sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/*el${{ matrix.rhversion }}*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + - name: "[ PREPARE ] prepare acme_srv.cfg with openssl_ca_handler" run: | mkdir -p data/acme_ca sudo mkdir -p examples/Docker/data/acme_ca/certs sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler_dns.cfg data/acme_srv.cfg + sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg data/acme_srv.cfg + sudo sed -i "s/challenge_validation_disable: False/challenge_validation_disable: False\ndns_server_list: [\"DNS-IP\"]/g" data/acme_srv.cfg sudo sed -i "s/\[CAhandler\]/\[CAhandler\]\nhandler_file: \/opt\/acme2certifier\/examples\/ca_handler\/openssl_ca_handler.py/g" data/acme_srv.cfg - name: "[ PREPARE ] prepare acme.sh container" @@ -173,7 +189,9 @@ jobs: - name: "[ PREPARE ] Almalinux instance" run: | - cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - name: "[ RUN ] Execute install scipt" @@ -229,6 +247,8 @@ jobs: docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh @@ -236,5 +256,5 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: eab.tar.gz + name: dns-rpm-rh${{ matrix.rhversion }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ diff --git a/examples/Docker/almalinux-systemd/rpm_tester.sh b/examples/Docker/almalinux-systemd/rpm_tester.sh index c4ef36f2..ed06f2ed 100644 --- a/examples/Docker/almalinux-systemd/rpm_tester.sh +++ b/examples/Docker/almalinux-systemd/rpm_tester.sh @@ -34,6 +34,10 @@ case "$1" in yes | cp -R /tmp/acme2certifier/nginx/* /etc/nginx/ fi + cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.orig + head -n 37 /etc/nginx/nginx.conf.orig > /etc/nginx/nginx.conf + echo "}" >> /etc/nginx/nginx.conf + chown -R nginx.nginx /opt/acme2certifier/volume/ ls -la /opt/acme2certifier/ ls -la /opt/acme2certifier/volume From a73448154f31d747f3b73c5c09687a375cdcc9e9 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 18 Feb 2024 09:53:12 +0100 Subject: [PATCH 065/460] [doc] documentation update --- docs/install_rpm.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/install_rpm.md b/docs/install_rpm.md index 8c3ec5f5..d91a07ca 100644 --- a/docs/install_rpm.md +++ b/docs/install_rpm.md @@ -17,7 +17,13 @@ $ sudo yum update -y $ sudo yum -y localinstall /tmp/acme2certifier/acme2certifier-0.23.1-1.0.noarch.rpm ``` -In case you install on Redhat 8.x you need to upgrade the [python3-jwcrypto package](https://jwcrypto.readthedocs.io/en/latest/) to version 0.8 or higher. A backport of the package being part of [RHEL9](https://rpmfind.net/linux/RPM/centos-stream/9/appstream/x86_64/python3-jwcrypto-0.8-4.el9.noarch.html) can be found in the [the a2c rpm repository](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/python3-jwcrypto-0.8-4.el8.noarch.rpm) +In case you install on Redhat 8.x you need to upgrade following packages +- [python3-dns](https://www.dnspython.org/) to version 2.1 or higher. +- [python3-jwcrypto package](https://jwcrypto.readthedocs.io/en/latest/) to version 0.8 or higher. + +Backports of these packages being part of can be found in the [the a2c rpm repository](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/) +- [python3-dns-2.1.0-6.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/python3-dns-2.1.0-6.el8.noarch.rpm) +- [python3-jwcrypto-0.8-4.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/python3-jwcrypto-0.8-4.el8.noarch.rpm) 4. Copy NGINX configuration file From 8bcf80be69390fc7b90bd635cc500c0b82d914b4 Mon Sep 17 00:00:00 2001 From: grindsa Date: Mon, 19 Feb 2024 07:41:40 +0100 Subject: [PATCH 066/460] [doc] refer to python3-cryptography update during RPM installation --- docs/install_rpm.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/install_rpm.md b/docs/install_rpm.md index d91a07ca..d54b7bd6 100644 --- a/docs/install_rpm.md +++ b/docs/install_rpm.md @@ -18,10 +18,12 @@ $ sudo yum -y localinstall /tmp/acme2certifier/acme2certifier-0.23.1-1.0.noarch. ``` In case you install on Redhat 8.x you need to upgrade following packages +- [python3-cryptography](https://cryptography.io/en/latest/) to version 36.0.1 or higher - [python3-dns](https://www.dnspython.org/) to version 2.1 or higher. - [python3-jwcrypto package](https://jwcrypto.readthedocs.io/en/latest/) to version 0.8 or higher. -Backports of these packages being part of can be found in the [the a2c rpm repository](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/) +Backports of these packages being part of RHEL9 can be found in the [the a2c rpm repository](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/) +- [rpm-repo/RPMs/python3-cryptography-36.0.1-4.el8.x86_64.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/python3-cryptography-36.0.1-4.el8.x86_64.rpm) - [python3-dns-2.1.0-6.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/python3-dns-2.1.0-6.el8.noarch.rpm) - [python3-jwcrypto-0.8-4.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/python3-jwcrypto-0.8-4.el8.noarch.rpm) From 2cd6027cc195ea43097a7a99dbbd45c5aa99623a Mon Sep 17 00:00:00 2001 From: grindsa Date: Mon, 19 Feb 2024 11:50:31 +0100 Subject: [PATCH 067/460] [fix] linting --- docs/install_rpm.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/install_rpm.md b/docs/install_rpm.md index d54b7bd6..da5ccf67 100644 --- a/docs/install_rpm.md +++ b/docs/install_rpm.md @@ -18,11 +18,13 @@ $ sudo yum -y localinstall /tmp/acme2certifier/acme2certifier-0.23.1-1.0.noarch. ``` In case you install on Redhat 8.x you need to upgrade following packages + - [python3-cryptography](https://cryptography.io/en/latest/) to version 36.0.1 or higher - [python3-dns](https://www.dnspython.org/) to version 2.1 or higher. - [python3-jwcrypto package](https://jwcrypto.readthedocs.io/en/latest/) to version 0.8 or higher. Backports of these packages being part of RHEL9 can be found in the [the a2c rpm repository](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/) + - [rpm-repo/RPMs/python3-cryptography-36.0.1-4.el8.x86_64.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/python3-cryptography-36.0.1-4.el8.x86_64.rpm) - [python3-dns-2.1.0-6.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/python3-dns-2.1.0-6.el8.noarch.rpm) - [python3-jwcrypto-0.8-4.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/python3-jwcrypto-0.8-4.el8.noarch.rpm) From 3f24611c9ce6d992e5b53eae7e1a9e4d15dd54d4 Mon Sep 17 00:00:00 2001 From: grindsa Date: Mon, 19 Feb 2024 18:50:19 +0100 Subject: [PATCH 068/460] #134 - db schema update --- acme_srv/version.py | 2 +- examples/db_handler/wsgi_handler.py | 15 +++++++++++++-- examples/django/acme_srv/models.py | 2 +- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/acme_srv/version.py b/acme_srv/version.py index e2879d3c..9ac4632b 100644 --- a/acme_srv/version.py +++ b/acme_srv/version.py @@ -4,4 +4,4 @@ # 2) we can import it in setup.py for the same reason # 3) we can import it into your module module __version__ = '0.33.1' -__dbversion__ = '0.33' +__dbversion__ = '0.33.2' diff --git a/examples/db_handler/wsgi_handler.py b/examples/db_handler/wsgi_handler.py index f2240a3c..197bb371 100644 --- a/examples/db_handler/wsgi_handler.py +++ b/examples/db_handler/wsgi_handler.py @@ -285,7 +285,7 @@ def _db_create(self): CREATE TABLE "certificate" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(15) NOT NULL UNIQUE, "cert" text, "cert_raw" text, "error" text, "order_id" integer NOT NULL REFERENCES "order" ("id"), "csr" text NOT NULL, "poll_identifier" text, "header_info" text, "created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, "renewal_info" text, "aki" text, "serial" text, "issue_uts" integer DEFAULT 0, "expire_uts" integer DEFAULT 0, "replaced" bolean DEFAULT 0) ''') self.cursor.execute(''' - CREATE TABLE "housekeeping" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(15) NOT NULL UNIQUE, "value" text, "modified_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL) + CREATE TABLE "housekeeping" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(30) NOT NULL UNIQUE, "value" text, "modified_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL) ''') self.cursor.execute(''' CREATE TRIGGER [UpdateLastTime] @@ -421,7 +421,7 @@ def _db_update_housekeeping(self): if self.cursor.fetchone()[0] != 1: self.logger.info('create housekeeping table and trigger') self.cursor.execute(''' - CREATE TABLE "housekeeping" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(15) NOT NULL UNIQUE, "value" text, "modified_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL) + CREATE TABLE "housekeeping" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(30) NOT NULL UNIQUE, "value" text, "modified_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL) ''') self.cursor.execute(''' CREATE TRIGGER [UpdateLastTime] @@ -434,6 +434,17 @@ def _db_update_housekeeping(self): update housekeeping set modified_at=CURRENT_TIMESTAMP where id=OLD.id; END ''') + else: + self.cursor.execute('''PRAGMA table_info(housekeeping)''') + for column in self.cursor.fetchall(): + if column[1] == 'name' and column[2].lower() == 'varchar(15)': + self.logger.info('alter housekeeping table - change size of the name field to 30') + self.cursor.execute('''ALTER TABLE housekeeping RENAME TO tmp_hk''') + self.cursor.execute(''' + CREATE TABLE "housekeeping" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(30) NOT NULL UNIQUE, "value" text, "modified_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL) + ''') + self.cursor.execute('''INSERT INTO housekeeping(id, name, value, modified_at) SELECT id, name, value, modified_at FROM tmp_hk''') + self.cursor.execute('''DROP TABLE tmp_hk''') def _db_update_orders(self): """ alter orders table """ diff --git a/examples/django/acme_srv/models.py b/examples/django/acme_srv/models.py index 1f574df7..6738b15f 100644 --- a/examples/django/acme_srv/models.py +++ b/examples/django/acme_srv/models.py @@ -116,7 +116,7 @@ def __unicode__(self): class Housekeeping(models.Model): """ housekeeping """ - name = models.CharField(max_length=15, unique=True) + name = models.CharField(max_length=30, unique=True) value = models.CharField(max_length=30, blank=True) modified_at = models.DateTimeField('value', auto_now_add=True, null=True) From a4b798ebf030d15f07f53ff61bccc96bced923fd Mon Sep 17 00:00:00 2001 From: grindsa Date: Mon, 19 Feb 2024 20:33:25 +0100 Subject: [PATCH 069/460] [fix] linting --- examples/db_handler/wsgi_handler.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/examples/db_handler/wsgi_handler.py b/examples/db_handler/wsgi_handler.py index 197bb371..e347378b 100644 --- a/examples/db_handler/wsgi_handler.py +++ b/examples/db_handler/wsgi_handler.py @@ -435,16 +435,16 @@ def _db_update_housekeeping(self): END ''') else: - self.cursor.execute('''PRAGMA table_info(housekeeping)''') - for column in self.cursor.fetchall(): - if column[1] == 'name' and column[2].lower() == 'varchar(15)': - self.logger.info('alter housekeeping table - change size of the name field to 30') - self.cursor.execute('''ALTER TABLE housekeeping RENAME TO tmp_hk''') - self.cursor.execute(''' - CREATE TABLE "housekeeping" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(30) NOT NULL UNIQUE, "value" text, "modified_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL) - ''') - self.cursor.execute('''INSERT INTO housekeeping(id, name, value, modified_at) SELECT id, name, value, modified_at FROM tmp_hk''') - self.cursor.execute('''DROP TABLE tmp_hk''') + self.cursor.execute('''PRAGMA table_info(housekeeping)''') + for column in self.cursor.fetchall(): + if column[1] == 'name' and column[2].lower() == 'varchar(15)': + self.logger.info('alter housekeeping table - change size of the name field to 30') + self.cursor.execute('''ALTER TABLE housekeeping RENAME TO tmp_hk''') + self.cursor.execute(''' + CREATE TABLE "housekeeping" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(30) NOT NULL UNIQUE, "value" text, "modified_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL) + ''') + self.cursor.execute('''INSERT INTO housekeeping(id, name, value, modified_at) SELECT id, name, value, modified_at FROM tmp_hk''') + self.cursor.execute('''DROP TABLE tmp_hk''') def _db_update_orders(self): """ alter orders table """ From 1ec4ef0e406af5cf3f0ee8233ac79c32e05bad9a Mon Sep 17 00:00:00 2001 From: grindsa Date: Tue, 20 Feb 2024 05:57:20 +0100 Subject: [PATCH 070/460] [fix] better excaption handing in case of invalid base64 encoding --- acme_srv/renewalinfo.py | 15 +++++++++++---- test/test_renewalinfo.py | 13 +++++++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/acme_srv/renewalinfo.py b/acme_srv/renewalinfo.py index f1f1e8f2..f93d76ad 100644 --- a/acme_srv/renewalinfo.py +++ b/acme_srv/renewalinfo.py @@ -206,17 +206,24 @@ def get(self, url: str) -> Dict[str, str]: renewalinfo_string = self._renewalinfo_string_get(url) # get renewal information - rewalinfo_dic = self._renewalinfo_get(renewalinfo_string) + try: + rewalinfo_dic = self._renewalinfo_get(renewalinfo_string) + if rewalinfo_dic: + rc_code = 200 + else: + rc_code = 404 + except Exception as err_: + self.logger.error('Renewalinfo.get() - error: %s', err_) + rewalinfo_dic = {} + rc_code = 400 - response_dic = {} + response_dic = {'code': rc_code} if rewalinfo_dic: - response_dic['code'] = 200 # filter certificate and decode it response_dic['data'] = rewalinfo_dic # order status is processing - ratelimiting response_dic['header'] = {'Retry-After': f'{self.retry_after_timeout}'.format()} else: - response_dic['code'] = 404 response_dic['data'] = self.err_msg_dic['malformed'] return response_dic diff --git a/test/test_renewalinfo.py b/test/test_renewalinfo.py index 5074e1e4..7828ea0d 100644 --- a/test/test_renewalinfo.py +++ b/test/test_renewalinfo.py @@ -200,6 +200,19 @@ def test_015_get(self, mock_update, mock_renstr_get, mock_renget): self.assertTrue(mock_update.called) self.assertTrue(mock_renstr_get.called) + @patch('acme_srv.renewalinfo.Renewalinfo._renewalinfo_get') + @patch('acme_srv.renewalinfo.Renewalinfo._renewalinfo_string_get') + @patch('acme_srv.renewalinfo.Renewalinfo._cert_table_update') + def test_016_get(self, mock_update, mock_renstr_get, mock_renget): + """ test get() """ + mock_renget.side_effect = Exception('renewalinfo_get') + self.renewalinfo.dbstore.hkparameter_get.return_value = None + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertEqual({'code': 400, 'data': 'urn:ietf:params:acme:error:malformed'}, self. renewalinfo.get('url')) + self.assertTrue(mock_update.called) + self.assertTrue(mock_renstr_get.called) + self.assertIn('ERROR:test_a2c:Renewalinfo.get() - error: renewalinfo_get', lcm.output) + @patch('acme_srv.message.Message.check') def test_016_update(self, mock_mcheck): """ test update() """ From 7c7d8dd840236275c90865ca46cc874584d8d0c4 Mon Sep 17 00:00:00 2001 From: grindsa Date: Tue, 20 Feb 2024 06:08:16 +0100 Subject: [PATCH 071/460] [fix] #135 - dbversion reset after container restart --- examples/django/acme_srv/fixture/status.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/django/acme_srv/fixture/status.yaml b/examples/django/acme_srv/fixture/status.yaml index a669d6ef..b556473d 100644 --- a/examples/django/acme_srv/fixture/status.yaml +++ b/examples/django/acme_srv/fixture/status.yaml @@ -34,4 +34,4 @@ pk: 1 fields: name: dbversion - value: 0.23.1 + value: 0.33.1 From 2ab9b11c856998c346352dd1a2908c0a19caf721 Mon Sep 17 00:00:00 2001 From: grindsa Date: Tue, 20 Feb 2024 06:10:43 +0100 Subject: [PATCH 072/460] [fix] fixture update due to schema update --- examples/django/acme_srv/fixture/status.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/django/acme_srv/fixture/status.yaml b/examples/django/acme_srv/fixture/status.yaml index b556473d..d0622951 100644 --- a/examples/django/acme_srv/fixture/status.yaml +++ b/examples/django/acme_srv/fixture/status.yaml @@ -34,4 +34,4 @@ pk: 1 fields: name: dbversion - value: 0.33.1 + value: 0.33.2 From 4d84c9fb34b16c70849c4f3a03318ab3a6067ecb Mon Sep 17 00:00:00 2001 From: grindsa Date: Tue, 20 Feb 2024 06:14:27 +0100 Subject: [PATCH 073/460] [rel] bump to 0.33.2 --- CHANGES.md | 13 +++++++++++++ acme_srv/version.py | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 131b5714..ff3f7e43 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,6 +7,19 @@ and pick the appropriate release branch. # Changes in 0.33.1 +**Upgrade notes**: + +- database scheme gets updated. Please run either + - `tools/db_update.py` when using the wsgi_handler or + - `tools/django_update.py` in case you are using the django_handler + +**Bugfixes**: + +- [134](https://github.com/grindsa/acme2certifier/issues/134) - acme_srv_housekeeping" -> value too long for "name" field +- [135](https://github.com/grindsa/acme2certifier/issues/134) - acme_srv_housekeeping dbversion ist set back to 0.23.1 after container restart + +# Changes in 0.33.1 + **Bugfixes**: - [132](https://github.com/grindsa/acme2certifier/issues/132) - returning serial numbers in hex-format with leading zero diff --git a/acme_srv/version.py b/acme_srv/version.py index 9ac4632b..163eeff4 100644 --- a/acme_srv/version.py +++ b/acme_srv/version.py @@ -3,5 +3,5 @@ # 1) we don't load dependencies by storing it in __init__.py # 2) we can import it in setup.py for the same reason # 3) we can import it into your module module -__version__ = '0.33.1' +__version__ = '0.33.2' __dbversion__ = '0.33.2' From 51d997fbbc7978f9e15f4b225423ea357a290c80 Mon Sep 17 00:00:00 2001 From: grindsa Date: Tue, 20 Feb 2024 06:16:10 +0100 Subject: [PATCH 074/460] [fix] update Changes.md --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index ff3f7e43..adfbfea7 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,7 +5,7 @@ This is a high-level summary of the most important changes. For a full list of changes, see the [git commit log](https://github.com/grindsa/acme2certifier/commits) and pick the appropriate release branch. -# Changes in 0.33.1 +# Changes in 0.33.2 **Upgrade notes**: From 526b0e8915747c18bb284415a8eb1a1aaec1af7f Mon Sep 17 00:00:00 2001 From: grindsa Date: Tue, 20 Feb 2024 07:02:01 +0100 Subject: [PATCH 075/460] [fix] remove dead link from changes.md --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 131b5714..44a24ba2 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -310,7 +310,7 @@ and pick the appropriate release branch. **Features**: - [Generic ACME protocol handler](docs/acme_ca.md) -- CA handler for [acme2dfn](https://github.com/pfisterer/acme2dfn) (external; ACME proxy for the [German research network's SOAP API](https://blog.pki.dfn.de/tag/soap-api/)) +- CA handler for [acme2dfn](https://github.com/pfisterer/acme2dfn) - wsgi_db_handler: allow DB file path configuration - allow setting config file location via environment variable From 6203f658cddc4d1f8e96cfa5de32ad79f8da20d7 Mon Sep 17 00:00:00 2001 From: grindsa Date: Tue, 20 Feb 2024 07:25:42 +0100 Subject: [PATCH 076/460] [wf] renewal info check in django workflow --- .github/workflows/django_tests..yml | 70 +++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/.github/workflows/django_tests..yml b/.github/workflows/django_tests..yml index 1095909e..9773c8a7 100644 --- a/.github/workflows/django_tests..yml +++ b/.github/workflows/django_tests..yml @@ -90,6 +90,16 @@ jobs: docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem + - name: "[ ENROLL ] HTTP-01 single domain lego" + run: | + mkdir -p $PWD/lego + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + + - name: "[ RENEW ] HTTP-01 single domain lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep + - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | @@ -197,6 +207,16 @@ jobs: docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem + - name: "[ ENROLL ] HTTP-01 single domain lego" + run: | + mkdir -p $PWD/lego + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + + - name: "[ RENEW ] HTTP-01 single domain lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep + - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | @@ -303,6 +323,16 @@ jobs: docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem + - name: "[ ENROLL ] HTTP-01 single domain lego" + run: | + mkdir -p $PWD/lego + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + + - name: "[ RENEW ] HTTP-01 single domain lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep + - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | @@ -417,6 +447,16 @@ jobs: docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem + - name: "[ ENROLL ] HTTP-01 single domain lego" + run: | + mkdir -p $PWD/lego + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + + - name: "[ RENEW ] HTTP-01 single domain lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep + - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | @@ -540,6 +580,16 @@ jobs: docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile data/volume/acme_ca/root-ca-cert.pem -untrusted data/volume/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem + - name: "[ ENROLL ] HTTP-01 single domain lego" + run: | + mkdir -p $PWD/lego + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + sudo openssl verify -CAfile data/volume/acme_ca/root-ca-cert.pem -untrusted data/volume/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + + - name: "[ RENEW ] HTTP-01 single domain lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep + - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | @@ -680,6 +730,16 @@ jobs: docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile data/volume/acme_ca/root-ca-cert.pem -untrusted data/volume/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem + - name: "[ ENROLL ] HTTP-01 single domain lego" + run: | + mkdir -p $PWD/lego + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + sudo openssl verify -CAfile data/volume/acme_ca/root-ca-cert.pem -untrusted data/volume/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + + - name: "[ RENEW ] HTTP-01 single domain lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep + - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | @@ -828,6 +888,16 @@ jobs: docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile data/volume/acme_ca/root-ca-cert.pem -untrusted data/volume/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem + - name: "[ ENROLL ] HTTP-01 single domain lego" + run: | + mkdir -p $PWD/lego + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + sudo openssl verify -CAfile data/volume/acme_ca/root-ca-cert.pem -untrusted data/volume/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + + - name: "[ RENEW ] HTTP-01 single domain lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep + - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | From 5e23a1aff78c847af38947a7fb17ab790470ab3c Mon Sep 17 00:00:00 2001 From: grindsa Date: Tue, 20 Feb 2024 11:32:32 +0100 Subject: [PATCH 077/460] [fix] backwards compability with redhat8 --- acme_srv/helper.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/acme_srv/helper.py b/acme_srv/helper.py index 33423cfd..6d4ab66c 100644 --- a/acme_srv/helper.py +++ b/acme_srv/helper.py @@ -1200,7 +1200,11 @@ def servercert_get(logger: logging.Logger, hostname: str, port: int = 443, proxy context.options |= ssl.PROTOCOL_TLS_CLIENT context.set_alpn_protocols(["acme-tls/1"]) # reject insecure ssl version - context.minimum_version = ssl.TLSVersion.TLSv1_2 + try: + # this does not work on RH8 + context.minimum_version = ssl.TLSVersion.TLSv1_2 + except Exception: + pass context.options |= ssl.OP_NO_SSLv3 context.options |= ssl.OP_NO_TLSv1 context.options |= ssl.OP_NO_TLSv1_1 From ee921f100db30c4237d3526a59c4ada067831752 Mon Sep 17 00:00:00 2001 From: grindsa Date: Wed, 21 Feb 2024 08:01:49 +0100 Subject: [PATCH 078/460] [fix] django_handler.py - adoptions to RH8 --- .../Docker/almalinux-systemd/django_tester.sh | 4 ++++ examples/db_handler/django_handler.py | 24 +++++++++---------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/examples/Docker/almalinux-systemd/django_tester.sh b/examples/Docker/almalinux-systemd/django_tester.sh index 05819539..2bd5a9d4 100644 --- a/examples/Docker/almalinux-systemd/django_tester.sh +++ b/examples/Docker/almalinux-systemd/django_tester.sh @@ -43,6 +43,10 @@ case "$1" in yes | cp -R /tmp/acme2certifier/nginx/* /etc/nginx/ fi + cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.orig + head -n 37 /etc/nginx/nginx.conf.orig > /etc/nginx/nginx.conf + echo "}" >> /etc/nginx/nginx.conf + cd /opt/acme2certifier python3 manage.py makemigrations python3 manage.py migrate diff --git a/examples/db_handler/django_handler.py b/examples/db_handler/django_handler.py index 7311619d..72ca77c0 100644 --- a/examples/db_handler/django_handler.py +++ b/examples/db_handler/django_handler.py @@ -33,12 +33,12 @@ def __init__(self, _debug: bool = False, logger: object = None): """ init """ self.logger = logger - def _account_getinstance(self, aname: str) -> QuerySet[Account]: + def _account_getinstance(self, aname: str) -> QuerySet: """ get account instance """ self.logger.debug('DBStore._account_getinstance(%s)', aname) return Account.objects.get(name=aname) - def _authorization_getinstance(self, name: str) -> QuerySet[Authorization]: + def _authorization_getinstance(self, name: str) -> QuerySet: """ get authorization instance """ self.logger.debug('DBStore._authorization_getinstance(%s)', name) return Authorization.objects.get(name=name) @@ -53,12 +53,12 @@ def _modify_key(self, mkey: str, operant: str) -> str: self.logger.debug('DBStore._modify_key() ended with: %s', mkey) return mkey - def _order_getinstance(self, value: str = id, mkey: id = 'id') -> QuerySet[Order]: + def _order_getinstance(self, value: str = id, mkey: id = 'id') -> QuerySet: """ get order instance """ self.logger.debug('DBStore._order_getinstance(%s:%s)', mkey, value) return Order.objects.get(**{mkey: value}) - def _status_getinstance(self, value: str, mkey: str = 'id') -> QuerySet[Status]: + def _status_getinstance(self, value: str, mkey: str = 'id') -> QuerySet: """ get account instance """ self.logger.debug('DBStore._status_getinstance(%s:%s)', mkey, value) return Status.objects.get(**{mkey: value}) @@ -100,7 +100,7 @@ def account_update(self, data_dic: Dict[str, str]) -> int: self.logger.debug('acct_id(%s)', obj.id) return obj.id - def accountlist_get(self) -> Tuple[List[str], QuerySet[Account]]: + def accountlist_get(self) -> Tuple[List[str], QuerySet]: """ accountlist_get """ self.logger.debug('DBStore.accountlist_get()') vlist = [ @@ -130,13 +130,13 @@ def authorization_add(self, data_dic: Dict[str, str]) -> int: self.logger.debug('auth_id(%s)', obj.id) return obj.id - def authorization_lookup(self, mkey: str, value: str, vlist: List[str] = ('type', 'value')) -> QuerySet[Authorization]: + def authorization_lookup(self, mkey: str, value: str, vlist: List[str] = ('type', 'value')) -> QuerySet: """ search account for a given id """ self.logger.debug('authorization_lookup(%s:%s:%s)', mkey, value, vlist) authz_list = Authorization.objects.filter(**{mkey: value}).values(*vlist)[::1] return authz_list - def authorizations_expired_search(self, mkey: str, value: str, vlist: List[str] = ('id', 'name', 'expires', 'identifiers', 'created_at', 'status__id', 'status__name', 'account__id', 'account__name', 'acccount__contact'), operant: str = 'LIKE') -> QuerySet[Authorization]: + def authorizations_expired_search(self, mkey: str, value: str, vlist: List[str] = ('id', 'name', 'expires', 'identifiers', 'created_at', 'status__id', 'status__name', 'account__id', 'account__name', 'acccount__contact'), operant: str = 'LIKE') -> QuerySet: """ search order table for a certain key/value pair """ self.logger.debug('DBStore.authorizations_invalid_search(column:%s, pattern:%s)', mkey, value) @@ -244,12 +244,12 @@ def certificate_account_check(self, account_name: str, certificate: str) -> str: self.logger.debug('DBStore.certificate_account_check() ended with: %s', result) return result - def certificate_delete(self, mkey: str, value: str) -> QuerySet[Certificate]: + def certificate_delete(self, mkey: str, value: str) -> QuerySet: """ delete certificate from table """ self.logger.debug('DBStore.certificate_delete(%s:%s)', mkey, value) Certificate.objects.filter(**{mkey: value}).delete() - def certificatelist_get(self) -> Tuple[List[str], List[QuerySet[Certificate]]]: + def certificatelist_get(self) -> Tuple[List[str], List[QuerySet]]: """ certificatelist_get """ self.logger.debug('DBStore.certificatelist_get()') vlist = [ @@ -273,7 +273,7 @@ def certificate_lookup(self, mkey: str, value: str, vlist: List[str] = ('name', self.logger.debug('DBStore.certificate_lookup() ended with: %s', result) return result - def certificates_search(self, mkey: str, value: str, vlist: List[str] = ('name', 'csr', 'cert', 'order__name'), operant=None) -> QuerySet[Certificate]: + def certificates_search(self, mkey: str, value: str, vlist: List[str] = ('name', 'csr', 'cert', 'order__name'), operant=None) -> QuerySet: """ search certificate based on "something" """ self.logger.debug('DBStore.certificates_search(%s:%s)', mkey, value) mkey = self._modify_key(mkey, operant) @@ -295,7 +295,7 @@ def challenge_lookup(self, mkey: str, value: str, vlist: List[str] = ('type', 't result = None return result - def challenges_search(self, mkey: str, value: str, vlist: List[str] = ('name', 'type', 'cert', 'status__name', 'token')) -> QuerySet[Challenge]: + def challenges_search(self, mkey: str, value: str, vlist: List[str] = ('name', 'type', 'cert', 'status__name', 'token')) -> QuerySet: """ search challenges based on "something" """ self.logger.debug('DBStore.challenges_search(%s:%s)', mkey, value) return Challenge.objects.filter(**{mkey: value}).values(*vlist) @@ -433,7 +433,7 @@ def order_update(self, data_dic: Dict[str, str]): obj, _created = Order.objects.update_or_create(name=data_dic['name'], defaults=data_dic) obj.save() - def orders_invalid_search(self, mkey: str, value: str, vlist: List[str] = ('id', 'name', 'expires', 'identifiers', 'created_at', 'status__id', 'status__name', 'account__id', 'account__name', 'acccount__contact'), operant='LIKE') -> QuerySet[Order]: + def orders_invalid_search(self, mkey: str, value: str, vlist: List[str] = ('id', 'name', 'expires', 'identifiers', 'created_at', 'status__id', 'status__name', 'account__id', 'account__name', 'acccount__contact'), operant='LIKE') -> QuerySet: """ search order table for a certain key/value pair """ self.logger.debug('DBStore.orders_search(column:%s, pattern:%s)', mkey, value) mkey = self._modify_key(mkey, operant) From b970848ade7b02c84f8eab1bd6ceb37ceee9f509 Mon Sep 17 00:00:00 2001 From: grindsa Date: Fri, 23 Feb 2024 08:22:05 +0100 Subject: [PATCH 079/460] [fix] python3-sqlparse in django_tester.sh --- examples/Docker/almalinux-systemd/django_tester.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/Docker/almalinux-systemd/django_tester.sh b/examples/Docker/almalinux-systemd/django_tester.sh index 2bd5a9d4..12dc233d 100644 --- a/examples/Docker/almalinux-systemd/django_tester.sh +++ b/examples/Docker/almalinux-systemd/django_tester.sh @@ -18,7 +18,7 @@ case "$1" in yum -y install epel-release yum -y localinstall /tmp/acme2certifier/*.rpm - yum -y install python3-PyMySQL python3-psycopg2 python3-pyyaml python3-mysqlclient + yum -y install python3-PyMySQL python3-sqlparse python3-psycopg2 python3-pyyaml python3-mysqlclient yes | cp /opt/acme2certifier/examples/db_handler/django_handler.py /opt/acme2certifier/acme_srv/db_handler.py yes | cp -R /opt/acme2certifier/examples/django/* /opt/acme2certifier/ From 6305cbd60c20e6802f0ae01a17bb0d45498ae57d Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 25 Feb 2024 07:58:18 +0100 Subject: [PATCH 080/460] [wf] fixture check in create release workflow --- .github/workflows/create_release.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.github/workflows/create_release.yml b/.github/workflows/create_release.yml index 0074fe51..a52ef251 100644 --- a/.github/workflows/create_release.yml +++ b/.github/workflows/create_release.yml @@ -31,6 +31,20 @@ jobs: - run: echo "APP tag is ${{ env.APP_NAME }}" - run: echo "Latest tag is ${{ env.TAG_NAME }}" + - name: Retrieve dbversion numbers from version.py and fixture.xml + run: | + echo DB_VERSION=$(cat acme_srv/version.py | grep -i __dbversion__ | head -n 1 | sed 's/__dbversion__ = //g' | sed s/\'//g) >> $GITHUB_ENV + echo FIXTURE_VERSION=$(awk '/name: dbversion/{getline; print $2}' examples/django/acme_srv/fixture/status.yaml | tr -d "'") >> $GITHUB_ENV + + - run: echo "db verion is ${{ env.DB_VERSION }}" + - run: echo "fixture verion is ${{ env.FIXTURE_VERSION }}" + + - name: Check fixture version + if: env.DB_VERSION != env.FIXTURE_VERSION + run: | + echo "Fixture version is not equal to db version" + exit 1 + - name: Create Release id: create_release if: steps.acme2certifier_ver.outputs.tag != env.TAG_NAME From f01684ce486e53d0e9644f18298a755921e1a14c Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 25 Feb 2024 08:02:13 +0100 Subject: [PATCH 081/460] [wf] fixture check in push_rpm workflow --- .github/workflows/push_rpm.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.github/workflows/push_rpm.yml b/.github/workflows/push_rpm.yml index f3934de4..9e04959e 100644 --- a/.github/workflows/push_rpm.yml +++ b/.github/workflows/push_rpm.yml @@ -22,6 +22,20 @@ jobs: - run: echo "APP tag is ${{ env.APP_NAME }}" - run: echo "Latest tag is ${{ env.TAG_NAME }}" + - name: Retrieve dbversion numbers from version.py and fixture.xml + run: | + echo DB_VERSION=$(cat acme_srv/version.py | grep -i __dbversion__ | head -n 1 | sed 's/__dbversion__ = //g' | sed s/\'//g) >> $GITHUB_ENV + echo FIXTURE_VERSION=$(awk '/name: dbversion/{getline; print $2}' examples/django/acme_srv/fixture/status.yaml | tr -d "'") >> $GITHUB_ENV + + - run: echo "db verion is ${{ env.DB_VERSION }}" + - run: echo "fixture verion is ${{ env.FIXTURE_VERSION }}" + + - name: Check fixture version + if: env.DB_VERSION != env.FIXTURE_VERSION + run: | + echo "Fixture version is not equal to db version" + exit 1 + - name: "[ PREPARE ] update version number in spec file" run: | sudo sed -i "s/__version__/${{ env.TAG_NAME }}/g" examples/install_scripts/rpm/acme2certifier.spec From 7a4b6a055cd0ff734eb94a81c9640661c6745992 Mon Sep 17 00:00:00 2001 From: grindsa Date: Tue, 27 Feb 2024 10:44:37 +0100 Subject: [PATCH 082/460] [fix] wsgi_handler.py variable assignment in _account_search() --- examples/db_handler/wsgi_handler.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/db_handler/wsgi_handler.py b/examples/db_handler/wsgi_handler.py index f2240a3c..c92c0e86 100644 --- a/examples/db_handler/wsgi_handler.py +++ b/examples/db_handler/wsgi_handler.py @@ -48,6 +48,7 @@ def _account_search(self, column: str, string: str) -> List[str]: """ search account table for a certain key/value pair """ self.logger.debug('DBStore._account_search(column:%s, pattern:%s)', column, string) self._db_open() + result = None try: pre_statement = f'SELECT * from account WHERE {column} LIKE ?' self.cursor.execute(pre_statement, [string]) @@ -312,6 +313,7 @@ def _db_open(self): self.dbs = sqlite3.connect(self.db_name) self.dbs.row_factory = sqlite3.Row self.cursor = self.dbs.cursor() + # self.cursor.execute('''PRAGMA journal_mode=WAL''') # self.logger.debug('DBStore._db_open() ended') def _db_update_account(self): From b7d5e93ee6f1c60c9ee3b7256a025a22941d7c26 Mon Sep 17 00:00:00 2001 From: grindsa Date: Tue, 27 Feb 2024 13:30:17 +0100 Subject: [PATCH 083/460] [fix] method names in logfile --- examples/db_handler/wsgi_handler.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/db_handler/wsgi_handler.py b/examples/db_handler/wsgi_handler.py index c92c0e86..6bcc70cb 100644 --- a/examples/db_handler/wsgi_handler.py +++ b/examples/db_handler/wsgi_handler.py @@ -1310,7 +1310,7 @@ def order_update(self, data_dic: Dict[str, str]): def orders_invalid_search(self, column: str, string: str, vlist: List[str] = ('id', 'name', 'expires', 'identifiers', 'created_at', 'status__id', 'status__name', 'account__id', 'account__name', 'account__contact'), operant='LIKE') -> List[str]: """ search order table for a certain key/value pair """ - self.logger.debug('DBStore.orders_search(column:%s, pattern:%s)', column, string) + self.logger.debug('DBStore.orders_invalid_search(column:%s, pattern:%s)', column, string) self._db_open() pre_statement = f'''SELECT @@ -1338,5 +1338,5 @@ def orders_invalid_search(self, column: str, string: str, vlist: List[str] = ('i order_list.append(result) self._db_close() - self.logger.debug('DBStore.orders_search() ended') + self.logger.debug('DBStore.orders_invalid_search() ended') return order_list From 2df011ce03c42e95b4fcd15888e4b94fcd25e9f2 Mon Sep 17 00:00:00 2001 From: grindsa Date: Tue, 27 Feb 2024 14:41:16 +0100 Subject: [PATCH 084/460] [fix] documenation update and function names --- acme_srv/certificate.py | 8 ++++---- docs/acme_srv.md | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/acme_srv/certificate.py b/acme_srv/certificate.py index 2c8162fb..9bb41409 100644 --- a/acme_srv/certificate.py +++ b/acme_srv/certificate.py @@ -335,18 +335,18 @@ def _store(self, certificate: str, certificate_raw: str, poll_identifier: str, c def _enrollerror_handler(self, error: str, poll_identifier: str, order_name: str, certificate_name: str) -> Tuple[None, str, str]: """ store error message for later analysis """ - self.logger.error('Certificate._enroll_and_store(%s)', error) + self.logger.debug('Certificate._enrollerror_handler(%s)', error) result = None detail = None try: if not poll_identifier: - self.logger.debug('Certificate._enroll_and_store(): invalidating order as there is no certificate and no poll_identifier: %s/%s', error, order_name) + self.logger.debug('Certificate._enrollerror_handler(): invalidating order as there is no certificate and no poll_identifier: %s/%s', error, order_name) self._order_update({'name': order_name, 'status': 'invalid'}) self._store_cert_error(certificate_name, error, poll_identifier) except Exception as err_: result = None - self.logger.critical('acme2certifier database error in Certificate._enroll_and_store() _store_cert_error: %s', err_) + self.logger.critical('acme2certifier database error in Certificate._enrollerror_handler() _store_cert_error: %s', err_) # cover polling cases if poll_identifier: @@ -354,7 +354,7 @@ def _enrollerror_handler(self, error: str, poll_identifier: str, order_name: str else: error = self.err_msg_dic['serverinternal'] - self.logger.error('Certificate._enroll_and_store() ended with: %s', result) + self.logger.debug('Certificate._enrollerror_handler() ended with: %s', result) return (result, error, detail) def _pre_hooks_process(self, certificate_name: str, order_name: str, csr: str) -> List[str]: diff --git a/docs/acme_srv.md b/docs/acme_srv.md index 5626f824..fb158f48 100644 --- a/docs/acme_srv.md +++ b/docs/acme_srv.md @@ -16,7 +16,7 @@ | `CAhandler` | `handler_file` | path and name of ca_handler file to be loaded. If not specified `acme_srv/ca_handler.py` will be loaded | examples/ca_handler/openssl_handler.py | `acme_srv/ca_handler.py`| | `Certificate` | `revocation_reason_check_disable` | disable the check of revocation reason | True/False | False| | `Certificate` | `cert_reusage_timeframe` | in case a csr will be resend within this timeframe (in seconds) the certificate already stored in the database will be returned and no enrollment will be triggered| Integer |0 (disabled)| -| `Certificate` | `enrollment_timeout` | timeout in second for asynchronous ca_handler threat| Integer |5| +| `Certificate` | `enrollment_timeout` | timeout in seconds for asynchronous ca_handler threat| Integer |5| | `Challenge` | `challenge_validation_disable` | disable challenge validation via http or dns. THIS IS A SEVERE SECURITY ISSUE! Please enable for testing/debugging purposes only. | True/False | False| | `Challenge` | `challenge_validation_timeout` | Timeout in seconds for challenge validation | Integer | 10 | | `Challenge` | `dns_server_list` | Use own dns servers for name resolution during challenge verification| ["ip1", "ip2"] | []| From 6daa5a371fae4fec682aeff62577e3b80e87702b Mon Sep 17 00:00:00 2001 From: grindsa Date: Tue, 27 Feb 2024 17:56:57 +0100 Subject: [PATCH 085/460] [fix] rrename logging statements --- acme_srv/certificate.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/acme_srv/certificate.py b/acme_srv/certificate.py index 9bb41409..93bc9b8b 100644 --- a/acme_srv/certificate.py +++ b/acme_srv/certificate.py @@ -363,9 +363,9 @@ def _pre_hooks_process(self, certificate_name: str, order_name: str, csr: str) - if self.hooks: try: self.hooks.pre_hook(certificate_name, order_name, csr) - self.logger.debug('Certificate._enroll_and_store(): pre_hook successful') + self.logger.debug('Certificate._pre_hooks_process(): pre_hook successful') except Exception as err: - self.logger.error('Certificate._enroll_and_store(): pre_hook exception: %s', err) + self.logger.error('Certificate._pre_hooks_process(): pre_hook exception: %s', err) if not self.ignore_pre_hook_failure: hook_error = (None, 'pre_hook_error', str(err)) @@ -379,9 +379,9 @@ def _post_hooks_process(self, certificate_name: str, order_name: str, csr: str, if self.hooks: try: self.hooks.post_hook(certificate_name, order_name, csr, error) - self.logger.debug('Certificate._enroll_and_store(): post_hook successful') + self.logger.debug('Certificate._pre_hooks_process(): post_hook successful') except Exception as err: - self.logger.error('Certificate._enroll_and_store(): post_hook exception: %s', err) + self.logger.error('Certificate._pre_hooks_process(): post_hook exception: %s', err) if not self.ignore_post_hook_failure: hook_error = (None, 'post_hook_error', str(err)) From 6acc50b6b233377188ee8d675d60452c3839f749 Mon Sep 17 00:00:00 2001 From: grindsa Date: Tue, 27 Feb 2024 18:01:16 +0100 Subject: [PATCH 086/460] [fix] certificate.py improved logging --- acme_srv/certificate.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/acme_srv/certificate.py b/acme_srv/certificate.py index 93bc9b8b..088a4e00 100644 --- a/acme_srv/certificate.py +++ b/acme_srv/certificate.py @@ -363,9 +363,9 @@ def _pre_hooks_process(self, certificate_name: str, order_name: str, csr: str) - if self.hooks: try: self.hooks.pre_hook(certificate_name, order_name, csr) - self.logger.debug('Certificate._pre_hooks_process(): pre_hook successful') + self.logger.debug('Certificate._enroll_and_store(): pre_hook successful') except Exception as err: - self.logger.error('Certificate._pre_hooks_process(): pre_hook exception: %s', err) + self.logger.error('Certificate._enroll_and_store(): pre_hook exception: %s', err) if not self.ignore_pre_hook_failure: hook_error = (None, 'pre_hook_error', str(err)) @@ -379,9 +379,9 @@ def _post_hooks_process(self, certificate_name: str, order_name: str, csr: str, if self.hooks: try: self.hooks.post_hook(certificate_name, order_name, csr, error) - self.logger.debug('Certificate._pre_hooks_process(): post_hook successful') + self.logger.debug('Certificate._enroll_and_store(): post_hook successful') except Exception as err: - self.logger.error('Certificate._pre_hooks_process(): post_hook exception: %s', err) + self.logger.error('Certificate._enroll_and_store(): post_hook exception: %s', err) if not self.ignore_post_hook_failure: hook_error = (None, 'post_hook_error', str(err)) @@ -790,6 +790,7 @@ def enroll_and_store(self, certificate_name: str, csr: str, order_name: str = No twrv = ThreadWithReturnValue(target=self._enroll_and_store, args=(certificate_name, csr, order_name)) twrv.start() enroll_result = twrv.join(timeout=self.enrollment_timeout) + self.logger.debug('Certificate.enroll_and_store() ThreadWithReturnValue ended', certificate_name, order_name) if enroll_result: try: (result, error, detail) = enroll_result From f1b034d3042158340b5d3d9136979534245bdde1 Mon Sep 17 00:00:00 2001 From: grindsa Date: Thu, 29 Feb 2024 07:12:49 +0100 Subject: [PATCH 087/460] [wf] update winacme to 2.2.8 --- .github/workflows/winacme-application-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/winacme-application-test.yml b/.github/workflows/winacme-application-test.yml index ab8f615e..fc1393ab 100644 --- a/.github/workflows/winacme-application-test.yml +++ b/.github/workflows/winacme-application-test.yml @@ -76,7 +76,7 @@ jobs: - name: "[ PREPARE ] Download win-acme" run: | - Invoke-RestMethod -Uri https://github.com/win-acme/win-acme/releases/download/v2.2.7.1621/win-acme.v2.2.7.1621.x64.trimmed.zip -OutFile win-acme.zip + Invoke-RestMethod -Uri https://github.com/win-acme/win-acme/releases/download/v2.2.8.1635/win-acme.v2.2.8.1635.x64.trimmed.zip -OutFile win-acme.zip Expand-Archive .\win-acme.zip mkdir win-acme\certs dir win-acme\* From b44dcaadfbb1735baf8fc6019653e5cfeee13b18 Mon Sep 17 00:00:00 2001 From: grindsa Date: Thu, 29 Feb 2024 07:23:08 +0100 Subject: [PATCH 088/460] update winacme to v2.2.8 --- .github/workflows/winacme-application-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/winacme-application-test.yml b/.github/workflows/winacme-application-test.yml index eddf492e..98dfc2c9 100644 --- a/.github/workflows/winacme-application-test.yml +++ b/.github/workflows/winacme-application-test.yml @@ -89,7 +89,7 @@ jobs: - name: "[ PREPARE ] Download win-acme" run: | - Invoke-RestMethod -Uri https://github.com/win-acme/win-acme/releases/download/v2.2.7.1621/win-acme.v2.2.7.1621.x64.trimmed.zip -OutFile win-acme.zip + Invoke-RestMethod -Uri https://github.com/win-acme/win-acme/releases/download/v2.2.8.1635/win-acme.v2.2.8.1635.x64.trimmed.zip -OutFile win-acme.zip Expand-Archive .\win-acme.zip mkdir win-acme\certs dir win-acme\* From a21126da71d3a830448e6fe643a3fe643e38d42b Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 2 Mar 2024 07:59:52 +0100 Subject: [PATCH 089/460] [doc] links and unittests --- docs/install_rpm.md | 15 +++++++++++---- test/test_certificate.py | 2 +- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/docs/install_rpm.md b/docs/install_rpm.md index da5ccf67..f0e43d97 100644 --- a/docs/install_rpm.md +++ b/docs/install_rpm.md @@ -23,11 +23,18 @@ In case you install on Redhat 8.x you need to upgrade following packages - [python3-dns](https://www.dnspython.org/) to version 2.1 or higher. - [python3-jwcrypto package](https://jwcrypto.readthedocs.io/en/latest/) to version 0.8 or higher. -Backports of these packages being part of RHEL9 can be found in the [the a2c rpm repository](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/) +Backports of these packages being part of RHEL9 can be found in the [the a2c rpm repository](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/rhel8) + +- [python3-cryptography-36.0.1-4.el8.x86_64.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/rhel8/python3-cryptography-36.0.1-4.el8.x86_64.rpm) +- [python3-dns-2.1.0-6.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/rhel8/python3-dns-2.1.0-6.el8.noarch.rpm) +- [python3-jwcrypto-0.8-4.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/rhel8/python3-jwcrypto-0.8-4.el8.noarch.rpm) + + +Depending on your packages would be needed as well: + - [python3-impacket-0.11.0-1.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/rhel8/python3-impacket-0.11.0-1.el8.noarch.rpm) for the [MS wcce handler](https://github.com/grindsa/acme2certifier/blob/master/docs/mswcce.md) + - [python3-ntlm-auth-1.5.0-2.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/rhel8/python3-ntlm-auth-1.5.0-2.el8.noarch.rpm) for the [MS wes handler](https://github.com/grindsa/acme2certifier/blob/master/docs/mscertsrv.md) + - [python3-requests-pkcs12-1.16-1.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/rhel8/python3-requests_ntlm-1.1.0-14.el8.noarch.rpm) for the [EST](https://github.com/grindsa/acme2certifier/blob/master/docs/est.md) and [Ejbca](https://github.com/grindsa/acme2certifier/blob/master/docs/ejbca.md) handler -- [rpm-repo/RPMs/python3-cryptography-36.0.1-4.el8.x86_64.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/python3-cryptography-36.0.1-4.el8.x86_64.rpm) -- [python3-dns-2.1.0-6.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/python3-dns-2.1.0-6.el8.noarch.rpm) -- [python3-jwcrypto-0.8-4.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/python3-jwcrypto-0.8-4.el8.noarch.rpm) 4. Copy NGINX configuration file diff --git a/test/test_certificate.py b/test/test_certificate.py index 63e052f9..2f2c1424 100644 --- a/test/test_certificate.py +++ b/test/test_certificate.py @@ -946,7 +946,7 @@ def test_107_certificate_enroll_and_store(self, mock_store_err, mock_store, mock csr = 'csr' with self.assertLogs('test_a2c', level='INFO') as lcm: self.assertEqual((None, 'error', 'poll_identifier'), self.certificate._enroll_and_store(certificate_name, csr)) - self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Certificate._enroll_and_store() _store_cert_error: ex_cert_error_store', lcm.output) + self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Certificate._enrollerror_handler() _store_cert_error: ex_cert_error_store', lcm.output) self.assertIn('ERROR:test_a2c:acme2certifier enrollment error: error', lcm.output) self.assertFalse(mock_chk.called) self.assertFalse(mock_oupd.called) From 2c6f540e2f50d059ed311cd69d0d489728452b5f Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 3 Mar 2024 07:38:09 +0100 Subject: [PATCH 090/460] [tst] tests and link fixes --- docs/install_rpm.md | 14 +++++++++++--- test/test_certificate.py | 2 +- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/docs/install_rpm.md b/docs/install_rpm.md index da5ccf67..ab5749f0 100644 --- a/docs/install_rpm.md +++ b/docs/install_rpm.md @@ -25,9 +25,17 @@ In case you install on Redhat 8.x you need to upgrade following packages Backports of these packages being part of RHEL9 can be found in the [the a2c rpm repository](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/) -- [rpm-repo/RPMs/python3-cryptography-36.0.1-4.el8.x86_64.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/python3-cryptography-36.0.1-4.el8.x86_64.rpm) -- [python3-dns-2.1.0-6.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/python3-dns-2.1.0-6.el8.noarch.rpm) -- [python3-jwcrypto-0.8-4.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/python3-jwcrypto-0.8-4.el8.noarch.rpm) +- [rpm-repo/RPMs/python3-cryptography-36.0.1-4.el8.x86_64.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/rhel8/python3-cryptography-36.0.1-4.el8.x86_64.rpm) +- [python3-dns-2.1.0-6.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/rhel8/python3-dns-2.1.0-6.el8.noarch.rpm) +- [python3-jwcrypto-0.8-4.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/rhel8/python3-jwcrypto-0.8-4.el8.noarch.rpm) + + +Depending on your ca_handler you may need additional modules: + +- [python3-impacket-0.11.0-1.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/rhel8/python3-impacket-0.11.0-1.el8.noarch.rpm) when using [MS wcce handler](https://github.com/grindsa/acme2certifier/blob/master/docs/mswcce.md) +- [python3-ntlm-auth-1.5.0-2.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/rhel8/python3-ntlm-auth-1.5.0-2.el8.noarch.rpm) when using [MS wse handler](https://github.com/grindsa/acme2certifier/blob/master/docs/mscertsrv.md) +- [python3-requests_ntlm-1.1.0-14.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/rhel8/python3-requests_ntlm-1.1.0-14.el8.noarch.rpm) when using [MS wse handler](https://github.com/grindsa/acme2certifier/blob/master/docs/mscertsrv.md) +- [python3-requests-pkcs12-1.16-1.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/rhel8/python3-requests-pkcs12-1.16-1.el8.noarch.rpm) when using [EST](https://github.com/grindsa/acme2certifier/blob/master/docs/est.md) or [EJBCA](https://github.com/grindsa/acme2certifier/blob/master/docs/ejbca.md) handler 4. Copy NGINX configuration file diff --git a/test/test_certificate.py b/test/test_certificate.py index 63e052f9..2f2c1424 100644 --- a/test/test_certificate.py +++ b/test/test_certificate.py @@ -946,7 +946,7 @@ def test_107_certificate_enroll_and_store(self, mock_store_err, mock_store, mock csr = 'csr' with self.assertLogs('test_a2c', level='INFO') as lcm: self.assertEqual((None, 'error', 'poll_identifier'), self.certificate._enroll_and_store(certificate_name, csr)) - self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Certificate._enroll_and_store() _store_cert_error: ex_cert_error_store', lcm.output) + self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Certificate._enrollerror_handler() _store_cert_error: ex_cert_error_store', lcm.output) self.assertIn('ERROR:test_a2c:acme2certifier enrollment error: error', lcm.output) self.assertFalse(mock_chk.called) self.assertFalse(mock_oupd.called) From 23fc5aeb96546f2f39412dc5608a8411b3d63d1d Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 3 Mar 2024 07:39:04 +0100 Subject: [PATCH 091/460] [wf] redhat 8 tests --- .github/workflows/alpn-test.yml | 25 +- .github/workflows/ari-test.yml | 223 ++++ .github/workflows/ca_handler_tests_acme.yml | 48 +- .github/workflows/ca_handler_tests_asa.yml | 21 +- .../workflows/ca_handler_tests_certifier.yml | 21 +- .github/workflows/ca_handler_tests_cmp.yml | 2 + .github/workflows/ca_handler_tests_ejbca.yml | 23 +- .github/workflows/ca_handler_tests_est.yml | 21 +- .github/workflows/ca_handler_tests_msca.yml | 190 +++- .github/workflows/ca_handler_tests_nclm.yml | 21 +- .../workflows/ca_handler_tests_openssl.yml | 23 +- .../workflows/ca_handler_tests_openxpki.yml | 32 +- .github/workflows/ca_handler_tests_xca.yml | 42 +- .github/workflows/django_tests..yml | 121 +-- .github/workflows/dns-test.yml | 3 +- .github/workflows/eab-test.yml | 578 ++++++++++- .github/workflows/enrollment-timeout.yml | 408 +++++++- .github/workflows/hooks-test.yml | 981 ++++++++++++++++-- .github/workflows/ip-address-tests.yml | 223 ++++ .github/workflows/ipv6-test.yml | 255 ++++- .github/workflows/proxy-test.yml | 264 +++-- .github/workflows/test_headerinfo.yml | 202 +++- .github/workflows/tnauth-test.yml | 25 +- .github/workflows/wsgi_handler-test.yml | 119 ++- 24 files changed, 3555 insertions(+), 316 deletions(-) diff --git a/.github/workflows/alpn-test.yml b/.github/workflows/alpn-test.yml index 3ce013ac..e8c79ec0 100644 --- a/.github/workflows/alpn-test.yml +++ b/.github/workflows/alpn-test.yml @@ -1,4 +1,4 @@ -name: TLS-ALPN-01 challenge tests +name: tls-alpn-01 challenge tests on: push: @@ -75,6 +75,10 @@ jobs: alpn_apache2_wsgi_rpm: name: "alpn_apache2_wsgi_rpm" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -111,6 +115,14 @@ jobs: mkdir acmme-sh mkdir lego + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + - name: "[ PREPARE ] prepare acme_srv.cfg with openssl_ca_handler" run: | mkdir -p data/acme_ca @@ -120,7 +132,9 @@ jobs: - name: "[ PREPARE ] Almalinux instance" run: | - cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - name: "[ RUN ] Execute install scipt" @@ -151,13 +165,16 @@ jobs: mkdir -p ${{ github.workspace }}/artifact/upload docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log # acme-sh - name: "[ * ] uploading artificates" uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: alpn-rpm.tar.gz + name: alpn-rpm-rh${{ matrix.rhversion }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ \ No newline at end of file diff --git a/.github/workflows/ari-test.yml b/.github/workflows/ari-test.yml index 513f69b7..9cb3d3ce 100644 --- a/.github/workflows/ari-test.yml +++ b/.github/workflows/ari-test.yml @@ -286,3 +286,226 @@ jobs: with: name: ari_nginx_django.tar.gz path: ${{ github.workspace }}/artifact/upload/ + + ari_wsgi_rpm: + name: "ari_wsgi_rpm" + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] + steps: + - name: "checkout GIT" + uses: actions/checkout@v4 + + - name: Retrieve Version from version.py + run: | + echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV + - run: echo "Latest tag is ${{ env.TAG_NAME }}" + + - name: update version number in spec file + run: | + # sudo sed -i "s/Source0:.*/Source0: %{name}-%{version}.tar.gz/g" examples/install_scripts/rpm/acme2certifier.spec + sudo sed -i "s/__version__/${{ env.TAG_NAME }}/g" examples/install_scripts/rpm/acme2certifier.spec + cat examples/install_scripts/rpm/acme2certifier.spec + + - name: build RPM package + id: rpm + uses: grindsa/rpmbuild@alma9 + with: + spec_file: "examples/install_scripts/rpm/acme2certifier.spec" + + - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" + + - name: "[ PREPARE ] setup environment for alma installation" + run: | + docker network create acme + sudo mkdir -p data + sudo chmod -R 777 data + sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data + sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data + + - name: "[ PREPARE ] create lego folder" + run: | + mkdir lego + + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + + - name: "[ PREPARE ] prepare acme_srv.cfg with openssl_ca_handler" + run: | + mkdir -p data/acme_ca + sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem data/acme_ca + sudo cp .github/openssl_ca_handler.py_acme_srv_choosen_handler.cfg data/acme_srv.cfg + sudo chmod 777 data/acme_srv.cfg + sudo echo -e "\n\n[Renewalinfo]" >> data/acme_srv.cfg + sudo echo "renewal_force: True" >> data/acme_srv.cfg + + - name: "[ PREPARE ] Almalinux instance" + run: | + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd + + - name: "[ RUN ] Execute install scipt" + run: | + docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh + + - name: "[ ENROLL ] HTTP-01 single domain lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + sudo openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + + - name: "[ RENEW ] HTTP-01 single domain lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep 2> ari.txt + grep "renewalInfo endpoint indicates that renewal is needed" ari.txt + cat ari.txt + sudo openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + + - name: "[ * ] collecting test logs" + if: ${{ failure() }} + run: | + mkdir -p ${{ github.workspace }}/artifact/upload + docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier + sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf + docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log lego + + - name: "[ * ] uploading artificates" + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: ari_wsgi_rpm-rh${{ matrix.rhversion }}.tar.gz + path: ${{ github.workspace }}/artifact/upload/ + + + ari_django_rpm: + name: "ari_django_rpm" + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] + steps: + - name: "checkout GIT" + uses: actions/checkout@v4 + + - name: Retrieve Version from version.py + run: | + echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV + - run: echo "Latest tag is ${{ env.TAG_NAME }}" + + - name: update version number in spec file and path in nginx ssl config + run: | + sudo sed -i "s/__version__/${{ env.TAG_NAME }}/g" examples/install_scripts/rpm/acme2certifier.spec + sudo sed -i "s/\/var\/www\/acme2certifier\/volume/\/etc\/nginx/g" examples/nginx/nginx_acme_srv_ssl.conf + git config --global user.email "grindelsack@gmail.com" + git config --global user.name "rpm update" + git add examples/nginx + git commit -a -m "rpm update" + + - name: build RPM package + id: rpm + uses: grindsa/rpmbuild@alma9 + with: + spec_file: "examples/install_scripts/rpm/acme2certifier.spec" + + - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" + + - name: "[ PREPARE ] setup environment for alma installation" + run: | + docker network create acme + sudo mkdir -p data/volume + sudo mkdir -p data/acme2certifier + sudo mkdir -p data/nginx + sudo chmod -R 777 data + sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data + sudo cp examples/Docker/almalinux-systemd/django_tester.sh data + sudo cp .github/acme2certifier_cert.pem data/nginx/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem data/nginx/acme2certifier_key.pem + sudo cp .github/django_settings.py data/acme2certifier/settings.py + sudo sed -i "s/\/var\/www\//\/opt\//g" data/acme2certifier/settings.py + sudo sed -i "s/USE_I18N = True/USE_I18N = False/g" data/acme2certifier/settings.py + + - name: "[ PREPARE ] create lego folder" + run: | + mkdir lego + + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + + - name: "[ PREPARE ] prepare acme_srv.cfg with openssl_ca_handler" + run: | + sudo mkdir -p data/volume/acme_ca/certs + sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem data/volume/acme_ca/ + sudo cp .github/openssl_ca_handler.py_acme_srv_choosen_handler.cfg data/volume/acme_srv.cfg + sudo chmod 777 data/volume/acme_srv.cfg + sudo echo -e "\n\n[Renewalinfo]" >> data/volume/acme_srv.cfg + sudo echo "renewal_force: True" >> data/volume/acme_srv.cfg + + - name: "[ PREPARE ] Almalinux instance" + run: | + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + docker run -d -id --privileged --network acme -p 22280:80 --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd + + - name: "[ RUN ] Execute install scipt" + run: | + docker exec acme-srv sh /tmp/acme2certifier/django_tester.sh + + - name: "Test http://acme-srv/directory is accessible" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "[ ENROLL ] HTTP-01 single domain lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + sudo openssl verify -CAfile data/volume/acme_ca/root-ca-cert.pem -untrusted data/volume/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + + - name: "[ RENEW ] HTTP-01 single domain lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep 2> ari.txt + grep "renewalInfo endpoint indicates that renewal is needed" ari.txt + cat ari.txt + sudo openssl verify -CAfile data/volume/acme_ca/root-ca-cert.pem -untrusted data/volume/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + + - name: "[ * ] collecting test logs" + if: ${{ failure() }} + run: | + mkdir -p ${{ github.workspace }}/artifact/upload + docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier + docker exec acme-srv tar cvfz /tmp/acme2certifier/nginx.tgz /etc/nginx + sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf + docker exec acme-srv rpm -qa > ${{ github.workspace }}/artifact/data/packages.txt + docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log lego + + - name: "[ * ] uploading artificates" + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: ari_django_rpm-rh${{ matrix.rhversion }}.tar.gz + path: ${{ github.workspace }}/artifact/upload/ diff --git a/.github/workflows/ca_handler_tests_acme.yml b/.github/workflows/ca_handler_tests_acme.yml index 23f4681a..da92b7b4 100644 --- a/.github/workflows/ca_handler_tests_acme.yml +++ b/.github/workflows/ca_handler_tests_acme.yml @@ -172,6 +172,10 @@ jobs: rpm_acme_ca_handler_test: name: "ACME CAhandler Tests - RPM" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -221,6 +225,15 @@ jobs: sudo chmod -R 777 data sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data + + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + - name: "[ PREPARE ] setup acme_ca_handler" run: | sudo mkdir -p data/acme @@ -232,10 +245,14 @@ jobs: sudo echo "acme_url: http://acme-le-sim" >> data/acme_srv.cfg sudo echo "acme_account_email: grindsa@foo.bar" >> data/acme_srv.cfg sudo sed -i "s/challenge_validation_disable: False/challenge_validation_disable: True/g" data/acme_srv.cfg + - name: "[ PREPARE ] Almalinux instance" run: | - cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd + - name: "[ RUN ] Execute install scipt" run: | docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh @@ -257,6 +274,7 @@ jobs: docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --debug 3 --output-insecure & sleep 30 openssl verify -CAfile test/ca/root-ca-cert.pem -untrusted test/ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | @@ -264,19 +282,28 @@ jobs: mkdir -p ${{ github.workspace }}/artifact/upload docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh + - name: "[ * ] uploading artificates" uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: acme_ca_handler_rpm.tar.gz + name: acme_ca_handler_rpm-rh${{ matrix.rhversion }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ rpm_acme_ca_handler_sectigo_test: name: "ACME CAhandler sectigo Tests - RPM" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] + steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -328,6 +355,14 @@ jobs: sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + - name: "[ PREPARE ] setup acme_ca_handler" run: | sudo mkdir -p data/acme @@ -342,7 +377,9 @@ jobs: - name: "[ PREPARE ] Almalinux instance" run: | - cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - name: "[ RUN ] Execute install scipt" @@ -377,7 +414,10 @@ jobs: mkdir -p ${{ github.workspace }}/artifact/upload docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh @@ -385,5 +425,5 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: acme_ca_handler_sectigo_rpm.tar.gz + name: acme_ca_handler_sectigo_rpm-rh${{ matrix.rhversion }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ \ No newline at end of file diff --git a/.github/workflows/ca_handler_tests_asa.yml b/.github/workflows/ca_handler_tests_asa.yml index 12bdd312..3541fb07 100644 --- a/.github/workflows/ca_handler_tests_asa.yml +++ b/.github/workflows/ca_handler_tests_asa.yml @@ -199,6 +199,10 @@ jobs: asa_handler_tests_rpm: name: "asa_handler_tests_rpm" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -236,6 +240,14 @@ jobs: mkdir lego mkdir acme-sh + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + - name: "[ PREPARE ] prepare acme_srv.cfg with certifier_ca_handler" run: | mkdir -p data/acme_ca @@ -263,7 +275,9 @@ jobs: - name: "[ PREPARE ] Almalinux instance" run: | - cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - name: "[ RUN ] Execute install scipt" @@ -393,7 +407,10 @@ jobs: mkdir -p ${{ github.workspace }}/artifact/upload docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh @@ -401,7 +418,7 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: asa_handler_tests_rpm.tar.gz + name: asa_handler_tests_rpm-rh${{ matrix.rhversion }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ diff --git a/.github/workflows/ca_handler_tests_certifier.yml b/.github/workflows/ca_handler_tests_certifier.yml index f7ba39ad..f1c13fd2 100644 --- a/.github/workflows/ca_handler_tests_certifier.yml +++ b/.github/workflows/ca_handler_tests_certifier.yml @@ -330,6 +330,10 @@ jobs: certifier_handler_tests_rpm: name: "certifier_handler_tests_rpm" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -366,6 +370,14 @@ jobs: mkdir certbot mkdir lego + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + - name: "[ PREPARE ] prepare acme_srv.cfg with certifier_ca_handler" run: | mkdir -p data/acme_ca @@ -388,7 +400,9 @@ jobs: - name: "[ PREPARE ] Almalinux instance" run: | - cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - name: "[ RUN ] Execute install scipt" @@ -445,7 +459,10 @@ jobs: mkdir -p ${{ github.workspace }}/artifact/upload docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh @@ -453,7 +470,7 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: certifier_ca_handler_rpm.tar.gz + name: certifier_ca_handler_rpm-rh${{ matrix.rhversion }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ diff --git a/.github/workflows/ca_handler_tests_cmp.yml b/.github/workflows/ca_handler_tests_cmp.yml index 7c660320..1e48e41d 100644 --- a/.github/workflows/ca_handler_tests_cmp.yml +++ b/.github/workflows/ca_handler_tests_cmp.yml @@ -393,6 +393,7 @@ jobs: mkdir -p ${{ github.workspace }}/artifact/upload docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh @@ -542,6 +543,7 @@ jobs: mkdir -p ${{ github.workspace }}/artifact/upload docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh diff --git a/.github/workflows/ca_handler_tests_ejbca.yml b/.github/workflows/ca_handler_tests_ejbca.yml index 0417fb3b..784e7180 100644 --- a/.github/workflows/ca_handler_tests_ejbca.yml +++ b/.github/workflows/ca_handler_tests_ejbca.yml @@ -189,6 +189,10 @@ jobs: ejbca_ca_handler_tests_rpm: name: " ejbca_ca_handler_tests_rpm" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] steps: - name: "checkout GIT" @@ -297,6 +301,14 @@ jobs: sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + - name: "setup a2c with ejbca_ca_handler" run: | sudo touch data/acme_srv.cfg @@ -315,9 +327,11 @@ jobs: env: SAEC: ${{ env.SAEC }} - - name: "prepare Almalinux instance" + - name: "[ PREPARE ] Almalinux instance" run: | - cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - name: "[ RUN ] Execute install scipt" @@ -370,7 +384,10 @@ jobs: docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier docker logs ejbca > ${{ github.workspace }}/artifact/ejbca.log sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data ejbca.log acme-srv.log acme-sh @@ -378,5 +395,5 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: ejb_rpm.tar.gz + name: ejb_rpm-rh${{ matrix.rhversion }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ \ No newline at end of file diff --git a/.github/workflows/ca_handler_tests_est.yml b/.github/workflows/ca_handler_tests_est.yml index 885e7e1d..a165a049 100644 --- a/.github/workflows/ca_handler_tests_est.yml +++ b/.github/workflows/ca_handler_tests_est.yml @@ -143,6 +143,10 @@ jobs: est_handler_tests_rpm: name: "est_handler_tests_rpm" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -179,6 +183,14 @@ jobs: mkdir acme-sh mkdir lego + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + - name: "[ PREPARE ] setup esthandler using http-basic-auth" run: | sudo mkdir -p data/acme_ca @@ -205,7 +217,9 @@ jobs: - name: "[ PREPARE ] Almalinux instance" run: | - cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - name: "[ RUN ] Execute install scipt" @@ -288,7 +302,10 @@ jobs: mkdir -p ${{ github.workspace }}/artifact/upload docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh @@ -296,5 +313,5 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: est-rpm.tar.gz + name: est-rpm-rh${{ matrix.rhversion }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ \ No newline at end of file diff --git a/.github/workflows/ca_handler_tests_msca.yml b/.github/workflows/ca_handler_tests_msca.yml index 60988da7..eac4195f 100644 --- a/.github/workflows/ca_handler_tests_msca.yml +++ b/.github/workflows/ca_handler_tests_msca.yml @@ -1,4 +1,4 @@ -name: CA handler tests - Microsoft CA +name: CA handler tests - MicrosoftCA on: push: @@ -317,6 +317,38 @@ jobs: - name: "checkout GIT" uses: actions/checkout@v4 + - name: "[ PREPARE ] get runner ip" + run: | + echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV + echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV + + - run: echo "runner IP is ${{ env.RUNNER_IP }}" + + - name: "Install dnsmasq" + run: | + sudo apt-get update + sudo apt-get install -y dnsmasq + sudo systemctl disable systemd-resolved + sudo systemctl stop systemd-resolved + sudo mkdir -p dnsmasq + sudo cp .github/dnsmasq.conf dnsmasq/ + sudo chmod -R 777 dnsmasq/dnsmasq.conf + sudo sed -i "s/RUNNER_IP/$RUNNER_IP/g" dnsmasq/dnsmasq.conf + sudo echo "address=/$WES_HOST/$RUNNER_IP" >> dnsmasq/dnsmasq.conf + cat dnsmasq/dnsmasq.conf + sudo cp dnsmasq/dnsmasq.conf /etc/ + sudo systemctl enable dnsmasq + sudo systemctl start dnsmasq + env: + RUNNER_IP: ${{ env.RUNNER_IP }} + WES_HOST: ${{ secrets.WES_HOST }} + + - name: "[ PREPARE ] test dns resulution" + run: | + host $WES_HOST 127.0.0.1 + env: + WES_HOST: ${{ secrets.WES_HOST }} + - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" working-directory: examples/Docker/ run: | @@ -359,9 +391,32 @@ jobs: - name: "Test http://acme-srv/directory is accessable again" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + - name: "[ PREPARE ] ssh environment on ramdisk" + run: | + sudo mkdir -p /tmp/rd + sudo mount -t tmpfs -o size=5M none /tmp/rd + sudo echo "$SSH_KEY" > /tmp/rd/ak.tmp + sudo chmod 600 /tmp/rd/ak.tmp + sudo echo "$KNOWN_HOSTS" > /tmp/rd/known_hosts + env: + SSH_KEY: ${{ secrets.WCCE_SSH_ACCESS_KEY }} + KNOWN_HOSTS: ${{ secrets.WCCE_SSH_KNOWN_HOSTS }} + + - name: "[ PREPARE ] establish SSH connection" + run: sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -p $SSH_PORT -o UserKnownHostsFile=/tmp/rd/known_hosts -L 443:$WES_IP:443 -g ping -c 180 $WES_IP & + env: + SSH_USER: ${{ secrets.CMP_SSH_USER }} + SSH_HOST: ${{ secrets.CMP_SSH_HOST }} + SSH_PORT: ${{ secrets.CMP_SSH_PORT }} + WES_IP: ${{ secrets.WES_IP }} + + - name: "[ PREPARE ] Sleep for 5s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 5s + - name: "[ PREPARE ] prepare acme.sh container" run: | - sudo mkdir acme-sh docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - name: "[ ENROLL ] acme.sh" @@ -399,12 +454,16 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: wse.${{ matrix.authscheme }}.tar.gz + name: wes_handler_tests.${{ matrix.authscheme }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ wcce_handler_ntlm_tests_rpm: name: "wcce_handler_ntlm_tests_rpm" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -444,6 +503,14 @@ jobs: sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + - name: "[ PREPARE ] prepare acme_srv.cfg with ms_wcce_ca_handler" run: | mkdir -p data/acme_ca @@ -472,24 +539,26 @@ jobs: - name: "[ PREPARE ] Almalinux instance" run: | - cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - - name: "[ RUN ] Execute install scipt" - run: | - docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh - - name: "[ PREPARE ] create letsencrypt and lego folder" run: | mkdir certbot mkdir lego + mkdir acme-sh + + - name: "[ RUN ] Execute install scipt" + run: | + docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh - name: "Test http://acme-srv/directory is accessable " run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - name: "[ PREPARE ] prepare acme.sh container" run: | - sudo mkdir acme-sh docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - name: "[ PREPARE ] ssh environment on ramdisk " @@ -540,8 +609,11 @@ jobs: run: | mkdir -p ${{ github.workspace }}/artifact/upload docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier + sudo rm -rf data/*.rpm sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + # docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + # docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh @@ -549,12 +621,16 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: wcce_ntlm_rpm.tar.gz + name: wcce_ntlm_rpm-rh${{ matrix.rhversion }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ wcce_handler_krb_tests_rpm: name: "wcce_handler_krb_tests_rpm" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -629,7 +705,7 @@ jobs: - name: "Retrieve rpms from SBOM repo" run: | git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom - cp /tmp/sbom/rpm-repo/RPMs/*impacket*.rpm data + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data env: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} @@ -665,24 +741,26 @@ jobs: - name: "[ PREPARE ] Almalinux instance" run: | - cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - - name: "[ RUN ] Execute install scipt" - run: | - docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh - - name: "[ PREPARE ] create letsencrypt and lego folder" run: | mkdir certbot mkdir lego + mkdir acme-sh + + - name: "[ RUN ] Execute install scipt" + run: | + docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh - name: "Test http://acme-srv/directory is accessable " run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - name: "[ PREPARE ] prepare acme.sh container" run: | - sudo mkdir acme-sh docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - name: "[ PREPARE ] ssh environment on ramdisk " @@ -734,9 +812,11 @@ jobs: sudo tail -n 200 /var/log/syslog mkdir -p ${{ github.workspace }}/artifact/upload docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier - rm data/*impacket*.rpm + sudo rm -rf data/*.rpm sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + # docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + # docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh @@ -744,7 +824,7 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: wcce_handler_krb_tests_rpm.tar.gz + name: wcce_handler_krb_tests_rpm-rh${{ matrix.rhversion }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ wes_handler_tests_rpm: @@ -754,6 +834,7 @@ jobs: fail-fast: false matrix: authscheme: ['ntlm'] + rhversion: [8, 9] steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -765,6 +846,32 @@ jobs: - run: echo "runner IP is ${{ env.RUNNER_IP }}" + - name: "Install dnsmasq" + run: | + sudo apt-get update + sudo apt-get install -y dnsmasq + sudo systemctl disable systemd-resolved + sudo systemctl stop systemd-resolved + sudo mkdir -p dnsmasq + sudo cp .github/dnsmasq.conf dnsmasq/ + sudo chmod -R 777 dnsmasq/dnsmasq.conf + sudo sed -i "s/RUNNER_IP/$RUNNER_IP/g" dnsmasq/dnsmasq.conf + sudo echo "address=/$WES_HOST/$RUNNER_IP" >> dnsmasq/dnsmasq.conf + cat dnsmasq/dnsmasq.conf + sudo cp dnsmasq/dnsmasq.conf /etc/ + sudo systemctl enable dnsmasq + sudo systemctl start dnsmasq + env: + RUNNER_IP: ${{ env.RUNNER_IP }} + WES_HOST: ${{ secrets.WES_HOST }} + + - name: "[ PREPARE ] test dns resulution" + run: | + host $WES_HOST 127.0.0.1 + env: + WES_HOST: ${{ secrets.WES_HOST }} + + - name: Retrieve Version from version.py run: | echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV @@ -797,7 +904,7 @@ jobs: - name: "Retrieve rpms from SBOM repo" run: | git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom - cp /tmp/sbom/rpm-repo/RPMs/*ntlm*.rpm data + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data env: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} @@ -825,24 +932,50 @@ jobs: - name: "[ PREPARE ] Almalinux instance" run: | - cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - - name: "[ RUN ] Execute install scipt" - run: | - docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh - - name: "[ PREPARE ] create letsencrypt and lego folder" run: | mkdir certbot mkdir lego + mkdir acme-sh + + - name: "[ RUN ] Execute install scipt" + run: | + docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + - name: "[ PREPARE ] ssh environment on ramdisk" + run: | + sudo mkdir -p /tmp/rd + sudo mount -t tmpfs -o size=5M none /tmp/rd + sudo echo "$SSH_KEY" > /tmp/rd/ak.tmp + sudo chmod 600 /tmp/rd/ak.tmp + sudo echo "$KNOWN_HOSTS" > /tmp/rd/known_hosts + env: + SSH_KEY: ${{ secrets.WCCE_SSH_ACCESS_KEY }} + KNOWN_HOSTS: ${{ secrets.WCCE_SSH_KNOWN_HOSTS }} + + - name: "[ PREPARE ] establish SSH connection" + run: sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -p $SSH_PORT -o UserKnownHostsFile=/tmp/rd/known_hosts -L 443:$WES_IP:443 -g ping -c 180 $WES_IP & + env: + SSH_USER: ${{ secrets.CMP_SSH_USER }} + SSH_HOST: ${{ secrets.CMP_SSH_HOST }} + SSH_PORT: ${{ secrets.CMP_SSH_PORT }} + WES_IP: ${{ secrets.WES_IP }} + + - name: "[ PREPARE ] Sleep for 5s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 5s + - name: "[ PREPARE ] prepare acme.sh container" run: | - sudo mkdir acme-sh docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - name: "[ ENROLL ] acme.sh" @@ -869,8 +1002,11 @@ jobs: run: | mkdir -p ${{ github.workspace }}/artifact/upload docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier + sudo rm -rf data/*.rpm sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + # docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + # docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh @@ -878,5 +1014,5 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: wes_rpm.tar.gz + name: wes_handler_tests_rpm-rh${{ matrix.rhversion }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ diff --git a/.github/workflows/ca_handler_tests_nclm.yml b/.github/workflows/ca_handler_tests_nclm.yml index d1df4ecb..5226ed94 100644 --- a/.github/workflows/ca_handler_tests_nclm.yml +++ b/.github/workflows/ca_handler_tests_nclm.yml @@ -128,6 +128,10 @@ jobs: nclm_handler_tests_rpm: name: "nclm_handler_tests_rpm" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -164,6 +168,14 @@ jobs: mkdir certbot mkdir lego + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + - name: "[ PREPARE ] prepare acme_srv.cfg with nclm_ca_handler" run: | mkdir -p data/acme_ca @@ -190,7 +202,9 @@ jobs: - name: "[ PREPARE ] Almalinux instance" run: | - cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - name: "[ RUN ] Execute install scipt" @@ -236,6 +250,9 @@ jobs: docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh @@ -243,5 +260,5 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: nclm_ca_handler_rpm.tar.gz + name: nclm_ca_handler_rpm-rh${{ matrix.rhversion }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ \ No newline at end of file diff --git a/.github/workflows/ca_handler_tests_openssl.yml b/.github/workflows/ca_handler_tests_openssl.yml index a174bce2..624c341d 100644 --- a/.github/workflows/ca_handler_tests_openssl.yml +++ b/.github/workflows/ca_handler_tests_openssl.yml @@ -367,8 +367,11 @@ jobs: openssl_ca_handler_no_tmpl_tests_rpm: name: "openssl_ca_handler_no_tmpl_tests_rpm" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] steps: - - name: "checkout GIT" uses: actions/checkout@v4 @@ -404,6 +407,14 @@ jobs: mkdir certbot mkdir lego + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + - name: "[ PREPARE ] prepare acme_srv.cfg with openssl_ca_handler" run: | mkdir -p data/acme_ca @@ -413,7 +424,9 @@ jobs: - name: "[ PREPARE ] Almalinux instance" run: | - cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - name: "[ RUN ] Execute install scipt" @@ -477,9 +490,13 @@ jobs: mkdir -p ${{ github.workspace }}/artifact/upload docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ sudo cp -rp certbot/ ${{ github.workspace }}/artifact/certbot/ sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh certbot lego @@ -487,5 +504,5 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: openssl-rpmopenssl_ca_handler_no_tmpl_tests_rpm.tar.gz + name: openssl-rpmopenssl_ca_handler_no_tmpl_tests_rpm-rh${{ matrix.rhversion }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ diff --git a/.github/workflows/ca_handler_tests_openxpki.yml b/.github/workflows/ca_handler_tests_openxpki.yml index 7fb47698..67e31a57 100644 --- a/.github/workflows/ca_handler_tests_openxpki.yml +++ b/.github/workflows/ca_handler_tests_openxpki.yml @@ -5,7 +5,7 @@ on: pull_request: branches: [ devel ] schedule: - # * is a special character in YAML so you have to quote this string + # * is a special character in YAML so you have to quote the string - cron: '0 2 * * 6' jobs: @@ -340,6 +340,10 @@ jobs: openxpki_ca_handler_tests_rpm: name: " openxpki_ca_handler_tests_rpm" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] steps: - name: "checkout GIT" @@ -456,6 +460,14 @@ jobs: sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + - name: "setup a2c with est_ca_handler" run: | sudo touch data/acme_srv.cfg @@ -470,9 +482,11 @@ jobs: env: OPENXPKI_IP: ${{ env.RUNNER_IP }} - - name: "prepare Almalinux instance" + - name: "[ PREPARE ] Almalinux instance" run: | - cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - name: "[ RUN ] Execute install scipt" @@ -510,7 +524,6 @@ jobs: sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/acme_srv.cfg sudo echo "handler_file: /opt/acme2certifier/examples/ca_handler/est_ca_handler.py" >> data/acme_srv.cfg sudo echo "est_host: https://openxpki:8443" >> data/acme_srv.cfg - # sudo echo "est_host: https://$OPENXPKI_IP:8443" >> data/acme_srv.cfg sudo echo "est_client_cert: /opt/acme2certifier/volume/acme_ca/client_crt.p12" >> data/acme_srv.cfg sudo echo "cert_passphrase: Test1234" >> data/acme_srv.cfg sudo echo "ca_bundle: /opt/acme2certifier/volume/acme_ca/ca_bundle.pem" >> data/acme_srv.cfg @@ -661,10 +674,6 @@ jobs: docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem - #- name: "revoke HTTP-01 single domain certbot" - # run: | - # docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - - name: "enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run @@ -683,11 +692,16 @@ jobs: docker logs openxpki-docker_openxpki-client_1 > ${{ github.workspace }}/artifact/openxpki_client.log sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv rpm -qa > ${{ github.workspace }}/artifact/data/packages.txt + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data openxpki_server.log openxpki_client.log acme-srv.log acme-sh + - name: "[ * ] uploading artificates" uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: openxpki_rpm.tar.gz + name: openxpki_rpm-rh${{ matrix.rhversion }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ diff --git a/.github/workflows/ca_handler_tests_xca.yml b/.github/workflows/ca_handler_tests_xca.yml index 83299824..556006f4 100644 --- a/.github/workflows/ca_handler_tests_xca.yml +++ b/.github/workflows/ca_handler_tests_xca.yml @@ -245,6 +245,10 @@ jobs: xca_handler_no_tmpl_tests_rpm: name: "xca_handler_no_tmpl_tests_rpm" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -281,6 +285,14 @@ jobs: mkdir certbot mkdir lego + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + - name: "[ PREPARE ] prepare acme_srv.cfg with xca_ca_handler" run: | mkdir -p data/acme_ca @@ -304,7 +316,9 @@ jobs: - name: "[ PREPARE ] Almalinux instance" run: | - cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - name: "[ RUN ] Execute install scipt" @@ -369,6 +383,9 @@ jobs: docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh @@ -376,12 +393,16 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: xca_handler_no_tmpl_tests_rpm.tar.gz + name: xca_handler_no_tmpl_tests_rpm-rh${{ matrix.rhversion }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ xca_handler_tmpl_tests_rpm: name: "xca_handler_tmpl_tests_rpm" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -418,6 +439,14 @@ jobs: mkdir certbot mkdir lego + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + - name: "[ PREPARE ] prepare acme_srv.cfg with xca_ca_handler" run: | mkdir -p data/acme_ca @@ -441,7 +470,9 @@ jobs: - name: "[ PREPARE ] Almalinux instance" run: | - cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - name: "[ RUN ] Execute install scipt" @@ -503,6 +534,9 @@ jobs: docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh @@ -510,5 +544,5 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: xca_handler_tmpl_tests_rpm.tar.gz + name: xca_handler_tmpl_tests_rpm-rh${{ matrix.rhversion }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ diff --git a/.github/workflows/django_tests..yml b/.github/workflows/django_tests..yml index 9773c8a7..180afaf6 100644 --- a/.github/workflows/django_tests..yml +++ b/.github/workflows/django_tests..yml @@ -5,7 +5,7 @@ on: pull_request: branches: [ devel ] schedule: - # * is a special character in YAML so you have to quote this string + # * is a special character in YAML so you have to quote this string. - cron: '0 2 * * 6' jobs: @@ -90,16 +90,6 @@ jobs: docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem - - name: "[ ENROLL ] HTTP-01 single domain lego" - run: | - mkdir -p $PWD/lego - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - - name: "[ RENEW ] HTTP-01 single domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep - - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | @@ -207,16 +197,6 @@ jobs: docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem - - name: "[ ENROLL ] HTTP-01 single domain lego" - run: | - mkdir -p $PWD/lego - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - - name: "[ RENEW ] HTTP-01 single domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep - - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | @@ -323,16 +303,6 @@ jobs: docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem - - name: "[ ENROLL ] HTTP-01 single domain lego" - run: | - mkdir -p $PWD/lego - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - - name: "[ RENEW ] HTTP-01 single domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep - - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | @@ -447,16 +417,6 @@ jobs: docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem - - name: "[ ENROLL ] HTTP-01 single domain lego" - run: | - mkdir -p $PWD/lego - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - - name: "[ RENEW ] HTTP-01 single domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep - - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | @@ -478,6 +438,10 @@ jobs: nginx_django_rpm_sqlite: name: "nginx_django_rpm_sqlite" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -522,7 +486,7 @@ jobs: - name: "Retrieve rpms from SBOM repo" run: | git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom - cp /tmp/sbom/rpm-repo/RPMs/*el9*.rpm data + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data env: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} @@ -536,7 +500,9 @@ jobs: - name: "[ PREPARE ] Almalinux instance" run: | - cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme -p 22280:80 --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - name: "[ RUN ] Execute install scipt" @@ -580,16 +546,6 @@ jobs: docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile data/volume/acme_ca/root-ca-cert.pem -untrusted data/volume/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem - - name: "[ ENROLL ] HTTP-01 single domain lego" - run: | - mkdir -p $PWD/lego - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - sudo openssl verify -CAfile data/volume/acme_ca/root-ca-cert.pem -untrusted data/volume/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - - name: "[ RENEW ] HTTP-01 single domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep - - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | @@ -598,6 +554,10 @@ jobs: docker exec acme-srv tar cvfz /tmp/acme2certifier/nginx.tgz /etc/nginx sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf + docker exec acme-srv rpm -qa > ${{ github.workspace }}/artifact/data/packages.txt docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh @@ -605,12 +565,16 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: nginx_django_rpm_sqlite.tar.gz + name: nginx_django_rpm_sqlite-rh${{ matrix.rhversion }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ nginx_django_rpm_mariadb: name: "nginx_django_rpm_mariadb" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [9] steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -672,7 +636,7 @@ jobs: - name: "Retrieve rpms from SBOM repo" run: | git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom - cp /tmp/sbom/rpm-repo/RPMs/*el9*.rpm data + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data env: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} @@ -686,7 +650,9 @@ jobs: - name: "[ PREPARE ] Almalinux instance" run: | - cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme -p 22280:80 --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - name: "[ RUN ] Execute install scipt" @@ -730,16 +696,6 @@ jobs: docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile data/volume/acme_ca/root-ca-cert.pem -untrusted data/volume/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem - - name: "[ ENROLL ] HTTP-01 single domain lego" - run: | - mkdir -p $PWD/lego - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - sudo openssl verify -CAfile data/volume/acme_ca/root-ca-cert.pem -untrusted data/volume/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - - name: "[ RENEW ] HTTP-01 single domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep - - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | @@ -748,6 +704,11 @@ jobs: docker exec acme-srv tar cvfz /tmp/acme2certifier/nginx.tgz /etc/nginx sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf + docker exec acme-srv rpm -qa | sort -n > ${{ github.workspace }}/artifact/data/packages.txt + docker exec mariadbsrv mariadb-dump -u root --password=foobar acme2certifier > ${{ github.workspace }}/artifact/data/acme2certifer.sql docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh /tmp/mysql @@ -755,12 +716,16 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: nginx_django_rpm_mariadb.tar.gz + name: nginx_django_rpm_mariadb-rh${{ matrix.rhversion }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ nginx_django_rpm_psql: name: "nginx_django_rpm_psql" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -830,7 +795,7 @@ jobs: - name: "Retrieve rpms from SBOM repo" run: | git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom - cp /tmp/sbom/rpm-repo/RPMs/*el9*.rpm data + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data env: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} @@ -844,7 +809,9 @@ jobs: - name: "[ PREPARE ] Almalinux instance" run: | - cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme -p 22280:80 --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - name: "[ RUN ] Execute install scipt" @@ -888,16 +855,6 @@ jobs: docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile data/volume/acme_ca/root-ca-cert.pem -untrusted data/volume/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem - - name: "[ ENROLL ] HTTP-01 single domain lego" - run: | - mkdir -p $PWD/lego - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - sudo openssl verify -CAfile data/volume/acme_ca/root-ca-cert.pem -untrusted data/volume/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - - name: "[ RENEW ] HTTP-01 single domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep - - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | @@ -906,6 +863,10 @@ jobs: docker exec acme-srv tar cvfz /tmp/acme2certifier/nginx.tgz /etc/nginx sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf + docker exec acme-srv rpm -qa > ${{ github.workspace }}/artifact/data/packages.txt docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh /tmp/pgsql @@ -913,5 +874,5 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: nginx_django_rpm_psql.tar.gz + name: nginx_django_rpm_psql-rh${{ matrix.rhversion }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ \ No newline at end of file diff --git a/.github/workflows/dns-test.yml b/.github/workflows/dns-test.yml index b31666be..63d12ac9 100644 --- a/.github/workflows/dns-test.yml +++ b/.github/workflows/dns-test.yml @@ -159,7 +159,7 @@ jobs: - name: "Retrieve rpms from SBOM repo" run: | git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom - cp /tmp/sbom/rpm-repo/RPMs/*el${{ matrix.rhversion }}*.rpm data + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data env: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} @@ -246,6 +246,7 @@ jobs: mkdir -p ${{ github.workspace }}/artifact/upload docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf diff --git a/.github/workflows/eab-test.yml b/.github/workflows/eab-test.yml index c7b6ed37..b6126e08 100644 --- a/.github/workflows/eab-test.yml +++ b/.github/workflows/eab-test.yml @@ -126,16 +126,390 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: eab-${{ matrix.keylength }}.tar.gz + name: eab_apache2_wsgi.tar.gz path: ${{ github.workspace }}/artifact/upload/ - eab_apache2_wsgi_rpm: - name: "eab_apache2_wsgi_rpm" + eab_apache2_django: + name: "eab_apache2_django" runs-on: ubuntu-latest steps: - name: "checkout GIT" uses: actions/checkout@v4 + - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + working-directory: examples/Docker/ + run: | + sed -i "s/wsgi/django/g" .env + sudo mkdir -p data + docker network create acme + docker-compose up -d + docker-compose logs + + - name: "[ PREPARE ] setup openssl ca_handler" + run: | + sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py + sudo mkdir -p examples/Docker/data/acme_ca/certs + sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ + sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg + sudo chmod 777 examples/Docker/data/acme_srv.cfg + sudo echo -e "\n\n[EABhandler]" >> examples/Docker/data/acme_srv.cfg + sudo echo "eab_handler_file: /var/www/acme2certifier/examples/eab_handler/json_handler.py" >> examples/Docker/data/acme_srv.cfg + sudo echo "key_file: examples/eab_handler/key_file.json" >> examples/Docker/data/acme_srv.cfg + sudo cp .github/django_settings.py examples/Docker/data/settings.py + cd examples/Docker/ + docker-compose restart + docker-compose logs + + - name: "Sleep for 5s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 5s + + - name: "Test http://acme-srv/directory is accessable again" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "[ PREPARE ] create letsencrypt folder" + run: | + mkdir certbot + + - name: "[ FAIL ] certbot without eab-credentials" + id: certbotfail + continue-on-error: true + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email + + - name: "[ CHECK ] certbot result " + if: steps.certbotfail.outcome != 'failure' + run: | + echo "certbot outcome is ${{steps.certbotfail.outcome }}" + exit 1 + + - name: "[ REGISTER] certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email --eab-kid keyid_02 --eab-hmac-key=bWFjXzAy + + - name: "[ ENROLL ] HTTP-01 single domain certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot + sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem + + - name: "[ PREPARE ] prepare acme.sh container" + run: | + docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + + - name: "[ FAIL] acme.sh" + id: acmeshfail + continue-on-error: true + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 + + - name: "[ CHECK ] acme.sh result " + if: steps.acmeshfail.outcome != 'failure' + run: | + echo "acmeshfail outcome is ${{steps.acmeshfail.outcome }}" + exit 1 + + - name: "[ REGISTER] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key bWFjXzAy --debug 3 + + - name: "[ ENROLL] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --debug 3 --output-insecure + openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + + - name: "[ FAIL ] lego" + id: legofail + continue-on-error: true + run: | + mkdir lego + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + + - name: "[ CHECK ] lego result " + if: steps.legofail.outcome != 'failure' + run: | + echo "legofail outcome is ${{steps.legofail.outcome }}" + exit 1 + + - name: "[ ENROLL ] lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac bWFjXzAy -d lego.acme --http run + sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + + - name: "[ * ] collecting test logs" + if: ${{ failure() }} + run: | + mkdir -p ${{ github.workspace }}/artifact/upload + sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ + cd examples/Docker + docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data + + - name: "[ * ] uploading artificates" + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: eab_apache2_django.tar.gz + path: ${{ github.workspace }}/artifact/upload/ + + eab_nginx_wsgi: + name: "eab_nginx_wsgi" + runs-on: ubuntu-latest + steps: + - name: "checkout GIT" + uses: actions/checkout@v4 + + - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + working-directory: examples/Docker/ + run: | + sed -i "s/apache2/nginx/g" .env + sudo mkdir -p data + docker network create acme + docker-compose up -d + docker-compose logs + + - name: "[ PREPARE ] setup openssl ca_handler" + run: | + sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py + sudo mkdir -p examples/Docker/data/acme_ca/certs + sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ + sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg + sudo chmod 777 examples/Docker/data/acme_srv.cfg + sudo echo -e "\n\n[EABhandler]" >> examples/Docker/data/acme_srv.cfg + sudo echo "eab_handler_file: /var/www/acme2certifier/examples/eab_handler/json_handler.py" >> examples/Docker/data/acme_srv.cfg + sudo echo "key_file: examples/eab_handler/key_file.json" >> examples/Docker/data/acme_srv.cfg + # sudo cat examples/Docker/data/acme_srv.cfg + cd examples/Docker/ + docker-compose restart + docker-compose logs + + - name: "Sleep for 5s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 5s + + - name: "Test http://acme-srv/directory is accessable again" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "[ PREPARE ] create letsencrypt folder" + run: | + mkdir certbot + + - name: "[ FAIL ] certbot without eab-credentials" + id: certbotfail + continue-on-error: true + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email + + - name: "[ CHECK ] certbot result " + if: steps.certbotfail.outcome != 'failure' + run: | + echo "certbot outcome is ${{steps.certbotfail.outcome }}" + exit 1 + + - name: "[ REGISTER] certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email --eab-kid keyid_02 --eab-hmac-key=bWFjXzAy + + - name: "[ ENROLL ] HTTP-01 single domain certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot + sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem + + - name: "[ PREPARE ] prepare acme.sh container" + run: | + docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + + - name: "[ FAIL] acme.sh" + id: acmeshfail + continue-on-error: true + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 + + - name: "[ CHECK ] acme.sh result " + if: steps.acmeshfail.outcome != 'failure' + run: | + echo "acmeshfail outcome is ${{steps.acmeshfail.outcome }}" + exit 1 + + - name: "[ REGISTER] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key bWFjXzAy --debug 3 + + - name: "[ ENROLL] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --debug 3 --output-insecure + openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + + - name: "[ FAIL ] lego" + id: legofail + continue-on-error: true + run: | + mkdir lego + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + + - name: "[ CHECK ] lego result " + if: steps.legofail.outcome != 'failure' + run: | + echo "legofail outcome is ${{steps.legofail.outcome }}" + exit 1 + + - name: "[ ENROLL ] lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac bWFjXzAy -d lego.acme --http run + sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + + - name: "[ * ] collecting test logs" + if: ${{ failure() }} + run: | + mkdir -p ${{ github.workspace }}/artifact/upload + sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ + cd examples/Docker + docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data + + - name: "[ * ] uploading artificates" + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: eab_nginx_wsgi.tar.gz + path: ${{ github.workspace }}/artifact/upload/ + + eab_nginx_django: + name: "eab_nginx_django" + runs-on: ubuntu-latest + steps: + - name: "checkout GIT" + uses: actions/checkout@v4 + + - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + working-directory: examples/Docker/ + run: | + sed -i "s/apache2/nginx/g" .env + sed -i "s/apache2/nginx/g" .env + sudo mkdir -p data + docker network create acme + docker-compose up -d + docker-compose logs + + - name: "[ PREPARE ] setup openssl ca_handler" + run: | + sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py + sudo mkdir -p examples/Docker/data/acme_ca/certs + sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ + sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg + sudo chmod 777 examples/Docker/data/acme_srv.cfg + sudo echo -e "\n\n[EABhandler]" >> examples/Docker/data/acme_srv.cfg + sudo echo "eab_handler_file: /var/www/acme2certifier/examples/eab_handler/json_handler.py" >> examples/Docker/data/acme_srv.cfg + sudo echo "key_file: examples/eab_handler/key_file.json" >> examples/Docker/data/acme_srv.cfg + sudo cp .github/django_settings.py examples/Docker/data/settings.py + cd examples/Docker/ + docker-compose restart + docker-compose logs + + - name: "Sleep for 5s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 5s + + - name: "Test http://acme-srv/directory is accessable again" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "[ PREPARE ] create letsencrypt folder" + run: | + mkdir certbot + + - name: "[ FAIL ] certbot without eab-credentials" + id: certbotfail + continue-on-error: true + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email + + - name: "[ CHECK ] certbot result " + if: steps.certbotfail.outcome != 'failure' + run: | + echo "certbot outcome is ${{steps.certbotfail.outcome }}" + exit 1 + + - name: "[ REGISTER] certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email --eab-kid keyid_02 --eab-hmac-key=bWFjXzAy + + - name: "[ ENROLL ] HTTP-01 single domain certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot + sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem + + - name: "[ PREPARE ] prepare acme.sh container" + run: | + docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + + - name: "[ FAIL] acme.sh" + id: acmeshfail + continue-on-error: true + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 + + - name: "[ CHECK ] acme.sh result " + if: steps.acmeshfail.outcome != 'failure' + run: | + echo "acmeshfail outcome is ${{steps.acmeshfail.outcome }}" + exit 1 + + - name: "[ REGISTER] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key bWFjXzAy --debug 3 + + - name: "[ ENROLL] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --debug 3 --output-insecure + openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + + - name: "[ FAIL ] lego" + id: legofail + continue-on-error: true + run: | + mkdir lego + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + + - name: "[ CHECK ] lego result " + if: steps.legofail.outcome != 'failure' + run: | + echo "legofail outcome is ${{steps.legofail.outcome }}" + exit 1 + + - name: "[ ENROLL ] lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac bWFjXzAy -d lego.acme --http run + sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + + - name: "[ * ] collecting test logs" + if: ${{ failure() }} + run: | + mkdir -p ${{ github.workspace }}/artifact/upload + sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ + cd examples/Docker + docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data + + - name: "[ * ] uploading artificates" + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: eab_nginx_django.tar.gz + path: ${{ github.workspace }}/artifact/upload/ + + eab_wsgi_rpm: + name: "eab_wsgi_rpm" + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] + steps: + - name: "checkout GIT" + uses: actions/checkout@v4 + - name: Retrieve Version from version.py run: | echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV @@ -168,6 +542,14 @@ jobs: mkdir certbot mkdir lego + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + - name: "[ PREPARE ] prepare acme_srv.cfg with openssl_ca_handler" run: | sudo mkdir -p data/acme_ca/certs/ @@ -180,7 +562,9 @@ jobs: - name: "[ PREPARE ] Almalinux instance" run: | - cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - name: "[ RUN ] Execute install scipt" @@ -261,6 +645,9 @@ jobs: docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh @@ -268,5 +655,186 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: eab-rpm.tar.gz + name: eab-rpm-rh${{ matrix.rhversion }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ + + eab_django_rpm: + name: "eab_django_rpm" + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] + steps: + - name: "checkout GIT" + uses: actions/checkout@v4 + + - name: "[ PREPARE ] get runner ip" + run: | + echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV + echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV + - run: echo "runner IP is ${{ env.RUNNER_IP }}" + + - name: Retrieve Version from version.py + run: | + echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV + - run: echo "Latest tag is ${{ env.TAG_NAME }}" + + - name: update version number in spec file and path in nginx ssl config + run: | + sudo sed -i "s/__version__/${{ env.TAG_NAME }}/g" examples/install_scripts/rpm/acme2certifier.spec + sudo sed -i "s/\/var\/www\/acme2certifier\/volume/\/etc\/nginx/g" examples/nginx/nginx_acme_srv_ssl.conf + git config --global user.email "grindelsack@gmail.com" + git config --global user.name "rpm update" + git add examples/nginx + git commit -a -m "rpm update" + + - name: build RPM package + id: rpm + uses: grindsa/rpmbuild@alma9 + with: + spec_file: "examples/install_scripts/rpm/acme2certifier.spec" + + - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" + + - name: "[ PREPARE ] setup environment for alma installation" + run: | + docker network create acme + sudo mkdir -p data/volume + sudo mkdir -p data/acme2certifier + sudo mkdir -p data/nginx + sudo chmod -R 777 data + sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data + sudo cp examples/Docker/almalinux-systemd/django_tester.sh data + sudo cp .github/acme2certifier_cert.pem data/nginx/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem data/nginx/acme2certifier_key.pem + sudo cp .github/django_settings.py data/acme2certifier/settings.py + sudo sed -i "s/\/var\/www\//\/opt\//g" data/acme2certifier/settings.py + sudo sed -i "s/USE_I18N = True/USE_I18N = False/g" data/acme2certifier/settings.py + + - name: "[ PREPARE ] create lego folder" + run: | + mkdir lego + + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + + - name: "[ PREPARE ] prepare acme_srv.cfg with openssl_ca_handler" + run: | + sudo mkdir -p data/volume/acme_ca/certs + sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem data/volume/acme_ca/ + sudo cp .github/openssl_ca_handler.py_acme_srv_choosen_handler.cfg data/volume/acme_srv.cfg + sudo chmod 777 data/volume/acme_srv.cfg + sudo echo -e "\n\n[EABhandler]" >> data/volume/acme_srv.cfg + sudo echo "eab_handler_file: /opt/acme2certifier/examples/eab_handler/json_handler.py" >>data/volume/acme_srv.cfg + sudo echo "key_file: /opt/acme2certifier/examples/eab_handler/key_file.json" >> data/volume/acme_srv.cfg + + - name: "[ PREPARE ] Almalinux instance" + run: | + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + docker run -d -id --privileged --network acme -p 22280:80 --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd + + - name: "[ RUN ] Execute install scipt" + run: | + docker exec acme-srv sh /tmp/acme2certifier/django_tester.sh + + - name: "Test http://acme-srv/directory is accessible" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "[ FAIL ] certbot without eab-credentials" + id: certbotfail + continue-on-error: true + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email + + - name: "[ CHECK ] certbot result " + if: steps.certbotfail.outcome != 'failure' + run: | + echo "certbot outcome is ${{steps.certbotfail.outcome }}" + exit 1 + + - name: "[ REGISTER] certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email --eab-kid keyid_02 --eab-hmac-key=bWFjXzAy + + - name: "[ ENROLL ] HTTP-01 single domain certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot + sudo openssl verify -CAfile data/volume/acme_ca/root-ca-cert.pem -untrusted data/volume/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem + + - name: "[ PREPARE ] prepare acme.sh container" + run: | + docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + + - name: "[ FAIL] acme.sh" + id: acmeshfail + continue-on-error: true + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 + + - name: "[ CHECK ] acme.sh result " + if: steps.acmeshfail.outcome != 'failure' + run: | + echo "acmeshfail outcome is ${{steps.acmeshfail.outcome }}" + exit 1 + + - name: "[ REGISTER] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key bWFjXzAy --debug 3 + + - name: "[ ENROLL] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --debug 3 --output-insecure + openssl verify -CAfile data/volume/acme_ca/root-ca-cert.pem -untrusted data/volume/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + + - name: "[ FAIL ] lego" + id: legofail + continue-on-error: true + run: | + mkdir lego + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + + - name: "[ CHECK ] lego result " + if: steps.legofail.outcome != 'failure' + run: | + echo "legofail outcome is ${{steps.legofail.outcome }}" + exit 1 + + - name: "[ ENROLL ] lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac bWFjXzAy -d lego.acme --http run + sudo openssl verify -CAfile data/volume/acme_ca/root-ca-cert.pem -untrusted data/volume/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + + - name: "[ * ] collecting test logs" + if: ${{ failure() }} + run: | + mkdir -p ${{ github.workspace }}/artifact/upload + docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier + docker exec acme-srv tar cvfz /tmp/acme2certifier/nginx.tgz /etc/nginx + sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ + sudo cp -rp lego/ ${{ github.workspace }}/artifact/certbot/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf + docker exec acme-srv rpm -qa > ${{ github.workspace }}/artifact/data/packages.txt + docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log lego certbot + + - name: "[ * ] uploading artificates" + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: eab_django_rpm-rh${{ matrix.rhversion }}.tar.gz + path: ${{ github.workspace }}/artifact/upload/ \ No newline at end of file diff --git a/.github/workflows/enrollment-timeout.yml b/.github/workflows/enrollment-timeout.yml index a659905d..42259e3f 100644 --- a/.github/workflows/enrollment-timeout.yml +++ b/.github/workflows/enrollment-timeout.yml @@ -1,4 +1,4 @@ -name: Asynchronous enrollment and certificate reusage +name: Asynchronous enrollment and certificate re-usage on: push: @@ -9,8 +9,8 @@ on: - cron: '0 2 * * 6' jobs: - async_enrollment_cert_reusage: - name: "Async_enrollment_cert_reusage" + ap_wsgi_async_enrollment_cert_reusage: + name: ap_wsgi_async_enrollment_cert_reusage runs-on: ubuntu-latest steps: - name: "checkout GIT" @@ -106,5 +106,405 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: async_enrollment_cert_reusage.tar.gz + name: ap_wsgi_async_enrollment_cert_reusage.tar.gz + path: ${{ github.workspace }}/artifact/upload/ + + ap_django_async_enrollment_cert_reusage: + name: ap_django_async_enrollment_cert_reusage + runs-on: ubuntu-latest + steps: + - name: "checkout GIT" + uses: actions/checkout@v4 + + - name: "Build docker-compose (apache2_django)" + working-directory: examples/Docker/ + run: | + sed -i "s/wsgi/django/g" .env + sudo mkdir -p data + docker network create acme + docker-compose up -d + docker-compose logs + + - name: "Test http://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "[ PREPARE ] setup openssl ca_handler" + run: | + sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py + sudo chmod 777 examples/Docker/data/ca_handler.py + sudo sed -i "s/import uuid/import uuid\\nimport time/g" examples/Docker/data/ca_handler.py + sudo sed -i "s/ cert_raw = None/ cert_raw = None\\n time.sleep(30)/g" examples/Docker/data/ca_handler.py + sudo mkdir -p examples/Docker/data/acme_ca/certs + sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ + sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg + sudo chmod 777 examples/Docker/data/acme_srv.cfg + sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\\ncert_reusage_timeframe: 300/g" examples/Docker/data/acme_srv.cfg + sudo cp .github/django_settings.py examples/Docker/data/settings.py + cd examples/Docker/ + docker-compose restart + docker-compose logs + + - name: "[ PREPARE ] prepare acme.sh container" + run: | + docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + + - name: "[ ENROLL ] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure + openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + + - name: "[ VERIFY ] Check timeout" + working-directory: examples/Docker/ + run: | + docker-compose logs | grep "Certificate.enroll_and_store() ended with: None:timeout" + sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) + + - name: "[ ENROLL ] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force + + - name: "[ VERIFY ] Check certificate reusage" + working-directory: examples/Docker/ + run: | + docker-compose logs | grep "Certificate._enroll(): reuse existing certificate" + + - name: "[ ENROL] lego" + run: | + mkdir lego + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --cert.timeout 180 --http run + + - name: "[ VERIFY ] Check timeout" + working-directory: examples/Docker/ + run: | + docker-compose logs | grep "Certificate.enroll_and_store() ended with: None:timeout" + sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) + + - name: "[ REGISTER ] certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email + + - name: "[ ENROLL ] certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot + + - name: "[ VERIFY ] Check timeout" + working-directory: examples/Docker/ + run: | + docker-compose logs | grep "Certificate.enroll_and_store() ended with: None:timeout" + sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) + + + - name: "[ * ] collecting test data" + if: ${{ failure() }} + run: | + mkdir -p ${{ github.workspace }}/artifact/upload + sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ + sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + cd examples/Docker + docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh + + - name: "[ * ] uploading artifacts" + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: ap_django_async_enrollment_cert_reusage.tar.gz + path: ${{ github.workspace }}/artifact/upload/ + + + rpm_wsgi_async_enrollment_cert_reusage: + name: "rpm_wsgi_async_enrollment_cert_reusage" + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] + steps: + - name: "checkout GIT" + uses: actions/checkout@v4 + + - name: Retrieve Version from version.py + run: | + echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV + - run: echo "Latest tag is ${{ env.TAG_NAME }}" + + - name: update version number in spec file + run: | + # sudo sed -i "s/Source0:.*/Source0: %{name}-%{version}.tar.gz/g" examples/install_scripts/rpm/acme2certifier.spec + sudo sed -i "s/__version__/${{ env.TAG_NAME }}/g" examples/install_scripts/rpm/acme2certifier.spec + cat examples/install_scripts/rpm/acme2certifier.spec + + - name: build RPM package + id: rpm + uses: grindsa/rpmbuild@alma9 + with: + spec_file: "examples/install_scripts/rpm/acme2certifier.spec" + + - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" + + - name: "[ PREPARE ] setup environment for alma installation" + run: | + docker network create acme + sudo mkdir -p data + sudo chmod -R 777 data + sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data + sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data + + - name: "[ PREPARE ] create lego and certbot folder" + run: | + mkdir lego + mkdir certbot + + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + + - name: "[ PREPARE ] setup openssl ca_handler" + run: | + mkdir -p data/acme_ca + sudo cp examples/ca_handler/openssl_ca_handler.py data/acme_ca/ca_handler.py + sudo chmod 777 data/acme_ca/ca_handler.py + sudo sed -i "s/import uuid/import uuid\\nimport time/g" data/acme_ca/ca_handler.py + sudo sed -i "s/ cert_raw = None/ cert_raw = None\\n time.sleep(22)\\n self.logger.debug('CAhandler.enroll(): timeout done')/g" data/acme_ca/ca_handler.py + sudo mkdir -p data/acme_ca/certs + sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem data/acme_ca/ + sudo cp .github/openssl_ca_handler.py_acme_srv_choosen_handler.cfg data/acme_srv.cfg + sudo chmod 777 data/acme_srv.cfg + sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\\ncert_reusage_timeframe: 1800/g" data/acme_srv.cfg + sudo sed -i "s/retry_after_timeout: 15/retry_after_timeout: 30\\nenrollment_timeout: 15/g" data/acme_srv.cfg + sudo sed -i "s/handler_file: examples\/ca_handler\/openssl_ca_handler.py/handler_file: \/opt\/acme2certifier\/volume\/acme_ca\/ca_handler.py/g" data/acme_srv.cfg + + - name: "[ PREPARE ] Almalinux instance" + run: | + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd + + - name: "[ RUN ] Execute install scipt" + run: | + docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh + + - name: "[ PREPARE ] prepare acme.sh container" + run: | + docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + + - name: "[ ENROLL ] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure + openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + + - name: "[ VERIFY ] Check timeout" + run: | + docker exec acme-srv grep "Certificate.enroll_and_store() ended with: None:timeout" /var/log/messages + + - name: "[ ENROLL ] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force + + - name: "[ VERIFY ] Check certificate reusage" + run: | + docker exec acme-srv grep "Certificate._enroll(): reuse existing certificate" /var/log/messages + + - name: "[ * ] collecting test logs" + if: ${{ failure() }} + run: | + mkdir -p ${{ github.workspace }}/artifact/upload + docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier + sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf + docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log + + - name: "[ * ] uploading artificates" + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: rpm_wsgi_async_enrollment_cert_reusage-rh${{ matrix.rhversion }}.tar.gz + path: ${{ github.workspace }}/artifact/upload/ + + rpm_django_async_enrollment_cert_reusage: + name: "rpm_django_async_enrollment_cert_reusage" + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] + steps: + - name: "checkout GIT" + uses: actions/checkout@v4 + + - name: "[ PREPARE ] get runner ip" + run: | + echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV + echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV + - run: echo "runner IP is ${{ env.RUNNER_IP }}" + + - name: "[ PREPARE ] postgres environment" + run: | + docker network create acme + sudo mkdir -p examples/Docker/data/pgsql/ + sudo cp .github/a2c.psql examples/Docker/data/pgsql/a2c.psql + sudo cp .github/pgpass examples/Docker/data/pgsql/pgpass + sudo chmod 600 examples/Docker/data/pgsql/pgpass + + - name: "[ PREPARE ] postgres environment" + run: | + sudo cp .github/a2c.psql examples/Docker/data/pgsql/a2c.psql + sudo cp .github/pgpass examples/Docker/data/pgsql/pgpass + sudo chmod 600 examples/Docker/data/pgsql/pgpass + + - name: "[ PREPARE ] install postgres" + working-directory: examples/Docker/ + run: | + docker run --name postgresdbsrv --network acme -e POSTGRES_PASSWORD=foobar -d postgres + + - name: "[ PREPARE ] Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "[ PREPARE ] configure postgres" + working-directory: examples/Docker/ + run: | + docker run -v "$(pwd)/data/pgsql/a2c.psql":/tmp/a2c.psql -v "$(pwd)/data/pgsql/pgpass:/root/.pgpass" --rm --network acme postgres psql -U postgres -h postgresdbsrv -f /tmp/a2c.psql + + - name: "[ PREPARE ] Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: Retrieve Version from version.py + run: | + echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV + - run: echo "Latest tag is ${{ env.TAG_NAME }}" + + - name: update version number in spec file and path in nginx ssl config + run: | + sudo sed -i "s/__version__/${{ env.TAG_NAME }}/g" examples/install_scripts/rpm/acme2certifier.spec + sudo sed -i "s/\/var\/www\/acme2certifier\/volume/\/etc\/nginx/g" examples/nginx/nginx_acme_srv_ssl.conf + git config --global user.email "grindelsack@gmail.com" + git config --global user.name "rpm update" + git add examples/nginx + git commit -a -m "rpm update" + + - name: build RPM package + id: rpm + uses: grindsa/rpmbuild@alma9 + with: + spec_file: "examples/install_scripts/rpm/acme2certifier.spec" + + - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" + + - name: "[ PREPARE ] setup environment for alma installation" + run: | + sudo mkdir -p data/volume + sudo mkdir -p data/acme2certifier + sudo mkdir -p data/nginx + sudo chmod -R 777 data + sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data + sudo cp examples/Docker/almalinux-systemd/django_tester.sh data + sudo cp .github/acme2certifier_cert.pem data/nginx/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem data/nginx/acme2certifier_key.pem + sudo cp .github/django_settings_psql.py data/acme2certifier/settings.py + sudo sed -i "s/USE_I18N = True/USE_I18N = False/g" data/acme2certifier/settings.py + + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + + - name: "[ PREPARE ] setup openssl ca_handler" + run: | + mkdir -p data/volume/acme_ca/certs + sudo cp examples/ca_handler/openssl_ca_handler.py data/volume/acme_ca/ca_handler.py + sudo chmod 777 data/volume/acme_ca/ca_handler.py + sudo sed -i "s/import uuid/import uuid\\nimport time/g" data/volume/acme_ca/ca_handler.py + # sudo sed -i "s/ cert_raw = None/ cert_raw = None\\n time.sleep(15)/g" data/volume/acme_ca/ca_handler.py + sudo sed -i "s/ cert_raw = None/ cert_raw = None\\n self.logger.debug('CAhandler.enroll(): timeout start')\\n time.sleep(30)\\n self.logger.debug('CAhandler.enroll(): timeout done')/g" data/volume/acme_ca/ca_handler.py + sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem data/volume/acme_ca/ + sudo cp .github/openssl_ca_handler.py_acme_srv_choosen_handler.cfg data/volume/acme_srv.cfg + sudo chmod 777 data/volume/acme_srv.cfg + sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\\ncert_reusage_timeframe: 1800/g" data/volume/acme_srv.cfg + sudo sed -i "s/retry_after_timeout: 15/retry_after_timeout: 30\\nenrollment_timeout: 15/g" data/volume/acme_srv.cfg + sudo sed -i "s/handler_file: examples\/ca_handler\/openssl_ca_handler.py/handler_file: \/opt\/acme2certifier\/volume\/acme_ca\/ca_handler.py/g" data/volume/acme_srv.cfg + + - name: "[ PREPARE ] Almalinux instance" + run: | + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + docker run -d -id --privileged --network acme -p 22280:80 --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd + + - name: "[ RUN ] Execute install scipt" + run: | + docker exec acme-srv sh /tmp/acme2certifier/django_tester.sh + + - name: "Test http://acme-srv/directory is accessible" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + + - name: "[ PREPARE ] prepare acme.sh container" + run: | + docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + + - name: "[ ENROLL ] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure + openssl verify -CAfile data/volume/acme_ca/root-ca-cert.pem -untrusted data/volume/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + + - name: "[ PREPARE ] Sleep for 5s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 5s + + - name: "[ VERIFY ] Check timeout" + run: | + docker exec acme-srv grep "Certificate.enroll_and_store() ended with: None:timeout" /var/log/messages + + - name: "[ ENROLL ] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force + + - name: "[ PREPARE ] Sleep for 5s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 5s + + - name: "[ VERIFY ] Check certificate reusage" + run: | + docker exec acme-srv grep "Certificate._enroll(): reuse existing certificate" /var/log/messages + + - name: "[ * ] collecting test logs" + if: ${{ failure() }} + run: | + mkdir -p ${{ github.workspace }}/artifact/upload + docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier + docker exec acme-srv tar cvfz /tmp/acme2certifier/nginx.tgz /etc/nginx + sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec postgresdbsrv pg_dump -U postgres acme2certifier > data/acme2certifier.sql + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf + docker exec acme-srv rpm -qa > ${{ github.workspace }}/artifact/data/packages.txt + docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log + + - name: "[ * ] uploading artificates" + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: rpm_django_async_enrollment_cert_reusage-rh${{ matrix.rhversion }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ diff --git a/.github/workflows/hooks-test.yml b/.github/workflows/hooks-test.yml index 838e3e55..0f3bf481 100644 --- a/.github/workflows/hooks-test.yml +++ b/.github/workflows/hooks-test.yml @@ -9,8 +9,8 @@ on: - cron: '0 2 * * 6' jobs: - hooks_test: - name: "hooks_test" + hooks_ap_wsgi: + name: "hooks_ap_wsgi" runs-on: ubuntu-latest steps: - name: "checkout GIT" @@ -98,83 +98,808 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: hooks.tar.gz + name: hooks_ap_wsgi.tar.gz + path: ${{ github.workspace }}/artifact/upload/ + + hooks_ap_django: + name: "hooks_ap_django" + runs-on: ubuntu-latest + steps: + - name: "checkout GIT" + uses: actions/checkout@v4 + + - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + working-directory: examples/Docker/ + run: | + sed -i "s/wsgi/django/g" .env + sudo mkdir -p data/hooks + sudo chmod -R 777 data/hooks + docker network create acme + docker-compose up -d + docker-compose logs + + - name: "[ PREPARE ] setup openssl ca_handler" + run: | + sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py + sudo mkdir -p examples/Docker/data/acme_ca/certs + sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ + sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg + sudo chmod 777 examples/Docker/data/acme_srv.cfg + sudo echo -e "\n\n[Hooks]" >> examples/Docker/data/acme_srv.cfg + sudo echo "hooks_file: /var/www/acme2certifier/examples/hooks/cn_dump_hooks.py" >> examples/Docker/data/acme_srv.cfg + sudo echo "save_path: volume/hooks" >> examples/Docker/data/acme_srv.cfg + sudo echo "$HOOKS_CHECKSUM" > examples/Docker/data/hooks/checksums.sha256 + # sudo cat examples/Docker/data/acme_srv.cfg + sudo cp .github/django_settings.py examples/Docker/data/settings.py + cd examples/Docker/ + docker-compose restart + docker-compose logs + env: + HOOKS_CHECKSUM: ${{ secrets.HOOKS_CHECKSUM }} + + - name: "Sleep for 5s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 5s + + - name: "Test http://acme-srv/directory is accessable again" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "[ PREPARE ] create letsencrypt folder" + run: | + mkdir certbot + + - name: "[ REGISTER] certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email + + - name: "[ ENROLL ] HTTP-01 single domain certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot + sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem + + - name: "[ PREPARE ] prepare acme.sh container" + run: | + docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + + - name: "[ REGISTER] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 + + - name: "[ ENROLL] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --debug 3 --output-insecure + openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + + - name: "[ ENROLL ] lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + + - name: "[ CHECK ] compare checksums to validate hook file content" + working-directory: examples/Docker/data/hooks + run: | + sha256sum -c checksums.sha256 + + - name: "[ * ] collecting test logs" + if: ${{ failure() }} + run: | + mkdir -p ${{ github.workspace }}/artifact/upload + sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ + cd examples/Docker + docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data + + - name: "[ * ] uploading artificates" + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: hooks_ap_django.tar.gz + path: ${{ github.workspace }}/artifact/upload/ + + hooks_nginx_wsgi: + name: "hooks_nginx_wsgi" + runs-on: ubuntu-latest + steps: + - name: "checkout GIT" + uses: actions/checkout@v4 + + - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + working-directory: examples/Docker/ + run: | + sed -i "s/apache2/nginx/g" .env + sudo mkdir -p data/hooks + sudo chmod -R 777 data/hooks + docker network create acme + docker-compose up -d + docker-compose logs + + - name: "[ PREPARE ] setup openssl ca_handler" + run: | + sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py + sudo mkdir -p examples/Docker/data/acme_ca/certs + sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ + sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg + sudo chmod 777 examples/Docker/data/acme_srv.cfg + sudo echo -e "\n\n[Hooks]" >> examples/Docker/data/acme_srv.cfg + sudo echo "hooks_file: /var/www/acme2certifier/examples/hooks/cn_dump_hooks.py" >> examples/Docker/data/acme_srv.cfg + sudo echo "save_path: volume/hooks" >> examples/Docker/data/acme_srv.cfg + sudo echo "$HOOKS_CHECKSUM" > examples/Docker/data/hooks/checksums.sha256 + # sudo cat examples/Docker/data/acme_srv.cfg + cd examples/Docker/ + docker-compose restart + docker-compose logs + env: + HOOKS_CHECKSUM: ${{ secrets.HOOKS_CHECKSUM }} + + - name: "Sleep for 5s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 5s + + - name: "Test http://acme-srv/directory is accessable again" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "[ PREPARE ] create letsencrypt folder" + run: | + mkdir certbot + + - name: "[ REGISTER] certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email + + - name: "[ ENROLL ] HTTP-01 single domain certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot + sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem + + - name: "[ PREPARE ] prepare acme.sh container" + run: | + docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + + - name: "[ REGISTER] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 + + - name: "[ ENROLL] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --debug 3 --output-insecure + openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + + - name: "[ ENROLL ] lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + + - name: "[ CHECK ] compare checksums to validate hook file content" + working-directory: examples/Docker/data/hooks + run: | + sha256sum -c checksums.sha256 + + - name: "[ * ] collecting test logs" + if: ${{ failure() }} + run: | + mkdir -p ${{ github.workspace }}/artifact/upload + sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ + cd examples/Docker + docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data + + - name: "[ * ] uploading artificates" + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: hooks_nginx_wsgi.tar.gz + path: ${{ github.workspace }}/artifact/upload/ + + hooks_nginx_django: + name: "hooks_nginx_django" + runs-on: ubuntu-latest + steps: + - name: "checkout GIT" + uses: actions/checkout@v4 + + - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + working-directory: examples/Docker/ + run: | + sed -i "s/apache2/nginx/g" .env + sed -i "s/wsgi/django/g" .env + sudo mkdir -p data/hooks + sudo chmod -R 777 data/hooks + docker network create acme + docker-compose up -d + docker-compose logs + + - name: "[ PREPARE ] setup openssl ca_handler" + run: | + sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py + sudo mkdir -p examples/Docker/data/acme_ca/certs + sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ + sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg + sudo chmod 777 examples/Docker/data/acme_srv.cfg + sudo echo -e "\n\n[Hooks]" >> examples/Docker/data/acme_srv.cfg + sudo echo "hooks_file: /var/www/acme2certifier/examples/hooks/cn_dump_hooks.py" >> examples/Docker/data/acme_srv.cfg + sudo echo "save_path: volume/hooks" >> examples/Docker/data/acme_srv.cfg + sudo echo "$HOOKS_CHECKSUM" > examples/Docker/data/hooks/checksums.sha256 + # sudo cat examples/Docker/data/acme_srv.cfg + sudo cp .github/django_settings.py examples/Docker/data/settings.py + cd examples/Docker/ + docker-compose restart + docker-compose logs + env: + HOOKS_CHECKSUM: ${{ secrets.HOOKS_CHECKSUM }} + + - name: "Sleep for 5s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 5s + + - name: "Test http://acme-srv/directory is accessable again" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "[ PREPARE ] create letsencrypt folder" + run: | + mkdir certbot + + - name: "[ REGISTER] certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email + + - name: "[ ENROLL ] HTTP-01 single domain certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot + sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem + + - name: "[ PREPARE ] prepare acme.sh container" + run: | + docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + + - name: "[ REGISTER] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 + + - name: "[ ENROLL] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --debug 3 --output-insecure + openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + + - name: "[ ENROLL ] lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + + - name: "[ CHECK ] compare checksums to validate hook file content" + working-directory: examples/Docker/data/hooks + run: | + sha256sum -c checksums.sha256 + + - name: "[ * ] collecting test logs" + if: ${{ failure() }} + run: | + mkdir -p ${{ github.workspace }}/artifact/upload + sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ + cd examples/Docker + docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data + + - name: "[ * ] uploading artificates" + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: hooks_nginx_django.tar.gz path: ${{ github.workspace }}/artifact/upload/ hooks_test_rpm: name: "hooks_test_rpm" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] + steps: + - name: "checkout GIT" + uses: actions/checkout@v4 + + - name: Retrieve Version from version.py + run: | + echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV + - run: echo "Latest tag is ${{ env.TAG_NAME }}" + + - name: update version number in spec file + run: | + # sudo sed -i "s/Source0:.*/Source0: %{name}-%{version}.tar.gz/g" examples/install_scripts/rpm/acme2certifier.spec + sudo sed -i "s/__version__/${{ env.TAG_NAME }}/g" examples/install_scripts/rpm/acme2certifier.spec + cat examples/install_scripts/rpm/acme2certifier.spec + + - name: build RPM package + id: rpm + uses: grindsa/rpmbuild@alma9 + with: + spec_file: "examples/install_scripts/rpm/acme2certifier.spec" + + - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" + + - name: "[ PREPARE ] setup environment for alma installation" + run: | + docker network create acme + sudo mkdir -p data + sudo chmod -R 777 data + sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data + sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data + + - name: "[ PREPARE ] create letsencrypt and lego folder" + run: | + mkdir acmme-sh + mkdir lego + + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + + - name: "[ PREPARE ] prepare acme_srv.cfg with openssl_ca_handler" + run: | + sudo mkdir -p data/acme_ca/certs + sudo mkdir -p data/acme_ca/hooks + sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem data/acme_ca/ + sudo cp .github/openssl_ca_handler.py_acme_srv_choosen_handler.cfg data/acme_srv.cfg + sudo chmod 777 data/acme_srv.cfg + sudo chmod -R 777 data/acme_ca/hooks + sudo echo -e "\n\n[Hooks]" >> data/acme_srv.cfg + sudo echo "hooks_file: /opt/acme2certifier/examples/hooks/cn_dump_hooks.py" >> data/acme_srv.cfg + sudo echo "save_path: /tmp/acme2certifier/acme_ca/hooks" >> data/acme_srv.cfg + sudo echo "$HOOKS_CHECKSUM" > data/acme_ca/hooks/checksums.sha256 + env: + HOOKS_CHECKSUM: ${{ secrets.HOOKS_CHECKSUM }} + + - name: "[ PREPARE ] Almalinux instance" + run: | + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd + + - name: "[ RUN ] Execute install scipt" + run: | + docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh + + - name: "Test http://acme-srv/directory is accessible" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "[ REGISTER] certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email + + - name: "[ ENROLL ] HTTP-01 single domain certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot + sudo openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem + + - name: "[ PREPARE ] prepare acme.sh container" + run: | + docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + + - name: "[ REGISTER] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 + + - name: "[ ENROLL] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --debug 3 --output-insecure + openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + + - name: "[ ENROLL ] lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + sudo openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + + - name: "[ CHECK ] compare checksums to validate hook file content" + working-directory: data/acme_ca/hooks + run: | + sha256sum -c checksums.sha256 + + - name: "[ * ] collecting test logs" + if: ${{ failure() }} + run: | + mkdir -p ${{ github.workspace }}/artifact/upload + docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier + sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf + docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh + + - name: "[ * ] uploading artificates" + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: hooks-rpm-rh${{ matrix.rhversion }}.tar.gz + path: ${{ github.workspace }}/artifact/upload/ + + hooks_ap_wsgi_exception_handling: + name: "hooks_ap_wsgi_exception_handling" + runs-on: ubuntu-latest + steps: + - name: "checkout GIT" + uses: actions/checkout@v4 + + - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + working-directory: examples/Docker/ + run: | + sudo mkdir -p data/hooks + sudo chmod -R 777 data/hooks + docker network create acme + docker-compose up -d + docker-compose logs + + - name: "Test http://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "[ PREPARE ] setup openssl ca_handler" + run: | + sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py + sudo mkdir -p examples/Docker/data/acme_ca/certs + sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ + sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg + sudo chmod 777 examples/Docker/data/acme_srv.cfg + sudo echo -e "\n\n[Hooks]" >> examples/Docker/data/acme_srv.cfg + sudo echo "hooks_file: /var/www/acme2certifier/examples/hooks/exception_test_hooks.py" >> examples/Docker/data/acme_srv.cfg + sudo echo "raise_pre_hook_exception: False" >> examples/Docker/data/acme_srv.cfg + sudo echo "raise_post_hook_exception: False" >> examples/Docker/data/acme_srv.cfg + sudo echo "raise_success_hook_exception: False" >> examples/Docker/data/acme_srv.cfg + # sudo cat examples/Docker/data/acme_srv.cfg + cd examples/Docker/ + docker-compose restart + docker-compose logs + env: + HOOKS_CHECKSUM: ${{ secrets.HOOKS_CHECKSUM }} + + - name: "Test http://acme-srv/directory is accessable again" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "[ PREPARE ] prepare acme.sh container" + run: | + docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + + - name: "[ REGISTER] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 + + - name: "[ ENROLL] acme.sh - *_pre_hook_failure not configured " + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --debug 3 --output-insecure + openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + + - name: "[ PREPARE ] reconfigure hook handler to trigger pre hook exception " + run: | + sudo sed -i "s/raise_pre_hook_exception: False/raise_pre_hook_exception: True/g" examples/Docker/data/acme_srv.cfg + cd examples/Docker/ + sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) + docker-compose restart + + - name: "[ FAIL ] acme.sh enrollment fails due to pre-hook exception (default behaviour)" + id: prehookfailure + continue-on-error: true + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure + + - name: "[ CHECK ] result - acme.sh enrollment failed due to pre-hook exception " + if: steps.prehookfailure.outcome != 'failure' + run: | + echo "prehookfailure outcome is ${{steps.prehookfailure.outcome }}" + exit 1 + + - name: "[ PREPARE ] reconfigure a2c to ignore pre-hook failures " + run: | + sudo echo "ignore_pre_hook_failure: True" >> examples/Docker/data/acme_srv.cfg + cd examples/Docker/ + sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) + docker-compose restart + + - name: "[ ENROLL] acme.sh - ignore pre_hook_failures " + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure + openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + + - name: "[ PREPARE ] reconfigure hook handler to trigger success hook exception " + run: | + sudo sed -i "s/raise_pre_hook_exception: True/raise_pre_hook_exception: False/g" examples/Docker/data/acme_srv.cfg + sudo sed -i "s/raise_success_hook_exception: False/raise_success_hook_exception: True/g" examples/Docker/data/acme_srv.cfg + cd examples/Docker/ + sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) + docker-compose restart + + - name: "[ FAIL ] acme.sh enrollment fails due to success-hook exception (default behaviour) " + id: successhookfailure + continue-on-error: true + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure + + - name: "[ CHECK ] result - acme.sh enrollment failed due to success-hook exception " + if: steps.successhookfailure.outcome != 'failure' + run: | + echo "successhookfailure outcome is ${{steps.successhookfailure.outcome }}" + exit 1 + + - name: "[ PREPARE ] reconfigure a2c to ignore success-hook failures " + run: | + sudo sed -i "s/ignore_pre_hook_failure: True/ignore_success_hook_failure: True/g" examples/Docker/data/acme_srv.cfg + cd examples/Docker/ + sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) + docker-compose restart + + - name: "[ ENROLL] acme.sh - ignore sucess_hook_failures " + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure + openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + + - name: "[ PREPARE ] reconfigure hook handler to trigger post hook exception " + run: | + sudo sed -i "s/raise_success_hook_exception: True/raise_success_hook_exception: False/g" examples/Docker/data/acme_srv.cfg + sudo sed -i "s/raise_post_hook_exception: False/raise_post_hook_exception: True/g" examples/Docker/data/acme_srv.cfg + cd examples/Docker/ + sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) + docker-compose restart + + - name: "[ ENROLL] acme.sh - ignore post_hook_failures (default behaviour) " + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure + openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + + - name: "[ PREPARE ] reconfigure a2c to detect success-hook failures " + run: | + sudo sed -i "s/ignore_success_hook_failure: True/ignore_post_hook_failure: False/g" examples/Docker/data/acme_srv.cfg + cd examples/Docker/ + sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) + docker-compose restart + + - name: "[ FAIL ] acme.sh enrollment fails due to post-hook exception " + id: posthookfailure + continue-on-error: true + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure + + - name: "[ CHECK ] result - acme.sh enrollment failed due to post-hook exception " + if: steps.posthookfailure.outcome != 'failure' + run: | + echo "posthookfailure outcome is ${{steps.posthookfailure.outcome }}" + exit 1 + + - name: "[ * ] collecting test logs" + if: ${{ failure() }} + run: | + mkdir -p ${{ github.workspace }}/artifact/upload + sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ + cd examples/Docker + docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data + + - name: "[ * ] uploading artificates" + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: hooks_ap_wsgi_exception_handling.tar.gz + path: ${{ github.workspace }}/artifact/upload/ + + hooks_ap_django_exception_handling: + name: "hooks_ap_django_exception_handling" + runs-on: ubuntu-latest steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: Retrieve Version from version.py + - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + working-directory: examples/Docker/ + run: | + sed -i "s/wsgi/django/g" .env + sudo mkdir -p data/hooks + sudo chmod -R 777 data/hooks + docker network create acme + docker-compose up -d + docker-compose logs + + - name: "[ PREPARE ] setup openssl ca_handler" + run: | + sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py + sudo mkdir -p examples/Docker/data/acme_ca/certs + sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ + sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg + sudo chmod 777 examples/Docker/data/acme_srv.cfg + sudo echo -e "\n\n[Hooks]" >> examples/Docker/data/acme_srv.cfg + sudo echo "hooks_file: /var/www/acme2certifier/examples/hooks/exception_test_hooks.py" >> examples/Docker/data/acme_srv.cfg + sudo echo "raise_pre_hook_exception: False" >> examples/Docker/data/acme_srv.cfg + sudo echo "raise_post_hook_exception: False" >> examples/Docker/data/acme_srv.cfg + sudo echo "raise_success_hook_exception: False" >> examples/Docker/data/acme_srv.cfg + sudo cp .github/django_settings.py examples/Docker/data/settings.py + cd examples/Docker/ + docker-compose restart + docker-compose logs + env: + HOOKS_CHECKSUM: ${{ secrets.HOOKS_CHECKSUM }} + + - name: "Sleep for 5s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 5s + + - name: "Test http://acme-srv/directory is accessable again" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "[ PREPARE ] prepare acme.sh container" + run: | + docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + + - name: "[ REGISTER] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 + + - name: "[ ENROLL] acme.sh - *_pre_hook_failure not configured " + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --debug 3 --output-insecure + openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + + - name: "[ PREPARE ] reconfigure hook handler to trigger pre hook exception " + run: | + sudo sed -i "s/raise_pre_hook_exception: False/raise_pre_hook_exception: True/g" examples/Docker/data/acme_srv.cfg + cd examples/Docker/ + sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) + docker-compose restart + + - name: "[ FAIL ] acme.sh enrollment fails due to pre-hook exception (default behaviour)" + id: prehookfailure + continue-on-error: true + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure + + - name: "[ CHECK ] result - acme.sh enrollment failed due to pre-hook exception " + if: steps.prehookfailure.outcome != 'failure' + run: | + echo "prehookfailure outcome is ${{steps.prehookfailure.outcome }}" + exit 1 + + - name: "[ PREPARE ] reconfigure a2c to ignore pre-hook failures " + run: | + sudo echo "ignore_pre_hook_failure: True" >> examples/Docker/data/acme_srv.cfg + cd examples/Docker/ + sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) + docker-compose restart + + - name: "[ ENROLL] acme.sh - ignore pre_hook_failures " + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure + openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + + - name: "[ PREPARE ] reconfigure hook handler to trigger success hook exception " + run: | + sudo sed -i "s/raise_pre_hook_exception: True/raise_pre_hook_exception: False/g" examples/Docker/data/acme_srv.cfg + sudo sed -i "s/raise_success_hook_exception: False/raise_success_hook_exception: True/g" examples/Docker/data/acme_srv.cfg + cd examples/Docker/ + sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) + docker-compose restart + + - name: "[ FAIL ] acme.sh enrollment fails due to success-hook exception (default behaviour) " + id: successhookfailure + continue-on-error: true + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure + + - name: "[ CHECK ] result - acme.sh enrollment failed due to success-hook exception " + if: steps.successhookfailure.outcome != 'failure' run: | - echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV - - run: echo "Latest tag is ${{ env.TAG_NAME }}" + echo "successhookfailure outcome is ${{steps.successhookfailure.outcome }}" + exit 1 - - name: update version number in spec file + - name: "[ PREPARE ] reconfigure a2c to ignore success-hook failures " run: | - # sudo sed -i "s/Source0:.*/Source0: %{name}-%{version}.tar.gz/g" examples/install_scripts/rpm/acme2certifier.spec - sudo sed -i "s/__version__/${{ env.TAG_NAME }}/g" examples/install_scripts/rpm/acme2certifier.spec - cat examples/install_scripts/rpm/acme2certifier.spec + sudo sed -i "s/ignore_pre_hook_failure: True/ignore_success_hook_failure: True/g" examples/Docker/data/acme_srv.cfg + cd examples/Docker/ + sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) + docker-compose restart - - name: build RPM package - id: rpm - uses: grindsa/rpmbuild@alma9 - with: - spec_file: "examples/install_scripts/rpm/acme2certifier.spec" + - name: "[ ENROLL] acme.sh - ignore sucess_hook_failures " + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure + openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" + - name: "[ PREPARE ] reconfigure hook handler to trigger post hook exception " + run: | + sudo sed -i "s/raise_success_hook_exception: True/raise_success_hook_exception: False/g" examples/Docker/data/acme_srv.cfg + sudo sed -i "s/raise_post_hook_exception: False/raise_post_hook_exception: True/g" examples/Docker/data/acme_srv.cfg + cd examples/Docker/ + sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) + docker-compose restart - - name: "[ PREPARE ] setup environment for alma installation" + - name: "[ ENROLL] acme.sh - ignore post_hook_failures (default behaviour) " run: | - docker network create acme - sudo mkdir -p data - sudo chmod -R 777 data - sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data - sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data + docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure + openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ PREPARE ] create letsencrypt and lego folder" + - name: "[ PREPARE ] reconfigure a2c to detect success-hook failures " run: | - mkdir acmme-sh - mkdir lego + sudo sed -i "s/ignore_success_hook_failure: True/ignore_post_hook_failure: False/g" examples/Docker/data/acme_srv.cfg + cd examples/Docker/ + sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) + docker-compose restart - - name: "[ PREPARE ] prepare acme_srv.cfg with openssl_ca_handler" + - name: "[ FAIL ] acme.sh enrollment fails due to post-hook exception " + id: posthookfailure + continue-on-error: true run: | - sudo mkdir -p data/acme_ca/certs - sudo mkdir -p data/acme_ca/hooks - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_choosen_handler.cfg data/acme_srv.cfg - sudo chmod 777 data/acme_srv.cfg - sudo chmod -R 777 data/acme_ca/hooks - sudo echo -e "\n\n[Hooks]" >> data/acme_srv.cfg - sudo echo "hooks_file: /opt/acme2certifier/examples/hooks/cn_dump_hooks.py" >> data/acme_srv.cfg - sudo echo "save_path: /tmp/acme2certifier/acme_ca/hooks" >> data/acme_srv.cfg - sudo echo "$HOOKS_CHECKSUM" > data/acme_ca/hooks/checksums.sha256 - env: - HOOKS_CHECKSUM: ${{ secrets.HOOKS_CHECKSUM }} + docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure - - name: "[ PREPARE ] Almalinux instance" + - name: "[ CHECK ] result - acme.sh enrollment failed due to post-hook exception " + if: steps.posthookfailure.outcome != 'failure' run: | - cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache - docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd + echo "posthookfailure outcome is ${{steps.posthookfailure.outcome }}" + exit 1 - - name: "[ RUN ] Execute install scipt" + - name: "[ * ] collecting test logs" + if: ${{ failure() }} run: | - docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh + mkdir -p ${{ github.workspace }}/artifact/upload + sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ + cd examples/Docker + docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data - - name: "Test http://acme-srv/directory is accessible" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + - name: "[ * ] uploading artificates" + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: hooks_ap_django_exception_handling.tar.gz + path: ${{ github.workspace }}/artifact/upload/ - - name: "[ REGISTER] certbot" + hooks_mgomx_wsgi_exception_handling: + name: "hooks_mgomx_wsgi_exception_handling" + runs-on: ubuntu-latest + steps: + - name: "checkout GIT" + uses: actions/checkout@v4 + + - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + working-directory: examples/Docker/ run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email + sed -i "s/apache2/nginx/g" .env + sudo mkdir -p data/hooks + sudo chmod -R 777 data/hooks + docker network create acme + docker-compose up -d + docker-compose logs - - name: "[ ENROLL ] HTTP-01 single domain certbot" + - name: "Test http://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "[ PREPARE ] setup openssl ca_handler" run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - sudo openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem + sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py + sudo mkdir -p examples/Docker/data/acme_ca/certs + sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ + sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg + sudo chmod 777 examples/Docker/data/acme_srv.cfg + sudo echo -e "\n\n[Hooks]" >> examples/Docker/data/acme_srv.cfg + sudo echo "hooks_file: /var/www/acme2certifier/examples/hooks/exception_test_hooks.py" >> examples/Docker/data/acme_srv.cfg + sudo echo "raise_pre_hook_exception: False" >> examples/Docker/data/acme_srv.cfg + sudo echo "raise_post_hook_exception: False" >> examples/Docker/data/acme_srv.cfg + sudo echo "raise_success_hook_exception: False" >> examples/Docker/data/acme_srv.cfg + # sudo cat examples/Docker/data/acme_srv.cfg + cd examples/Docker/ + docker-compose restart + docker-compose logs + env: + HOOKS_CHECKSUM: ${{ secrets.HOOKS_CHECKSUM }} + + - name: "Sleep for 5s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 5s + + - name: "Test http://acme-srv/directory is accessable again" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - name: "[ PREPARE ] prepare acme.sh container" run: | @@ -184,40 +909,124 @@ jobs: run: | docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 - - name: "[ ENROLL] acme.sh" + - name: "[ ENROLL] acme.sh - *_pre_hook_failure not configured " run: | docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --debug 3 --output-insecure - openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ ENROLL ] lego" + - name: "[ PREPARE ] reconfigure hook handler to trigger pre hook exception " run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - sudo openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + sudo sed -i "s/raise_pre_hook_exception: False/raise_pre_hook_exception: True/g" examples/Docker/data/acme_srv.cfg + cd examples/Docker/ + sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) + docker-compose restart - - name: "[ CHECK ] compare checksums to validate hook file content" - working-directory: data/acme_ca/hooks + - name: "[ FAIL ] acme.sh enrollment fails due to pre-hook exception (default behaviour)" + id: prehookfailure + continue-on-error: true run: | - sha256sum -c checksums.sha256 + docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure + + - name: "[ CHECK ] result - acme.sh enrollment failed due to pre-hook exception " + if: steps.prehookfailure.outcome != 'failure' + run: | + echo "prehookfailure outcome is ${{steps.prehookfailure.outcome }}" + exit 1 + + - name: "[ PREPARE ] reconfigure a2c to ignore pre-hook failures " + run: | + sudo echo "ignore_pre_hook_failure: True" >> examples/Docker/data/acme_srv.cfg + cd examples/Docker/ + sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) + docker-compose restart + + - name: "[ ENROLL] acme.sh - ignore pre_hook_failures " + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure + openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + + - name: "[ PREPARE ] reconfigure hook handler to trigger success hook exception " + run: | + sudo sed -i "s/raise_pre_hook_exception: True/raise_pre_hook_exception: False/g" examples/Docker/data/acme_srv.cfg + sudo sed -i "s/raise_success_hook_exception: False/raise_success_hook_exception: True/g" examples/Docker/data/acme_srv.cfg + cd examples/Docker/ + sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) + docker-compose restart + + - name: "[ FAIL ] acme.sh enrollment fails due to success-hook exception (default behaviour) " + id: successhookfailure + continue-on-error: true + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure + + - name: "[ CHECK ] result - acme.sh enrollment failed due to success-hook exception " + if: steps.successhookfailure.outcome != 'failure' + run: | + echo "successhookfailure outcome is ${{steps.successhookfailure.outcome }}" + exit 1 + + - name: "[ PREPARE ] reconfigure a2c to ignore success-hook failures " + run: | + sudo sed -i "s/ignore_pre_hook_failure: True/ignore_success_hook_failure: True/g" examples/Docker/data/acme_srv.cfg + cd examples/Docker/ + sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) + docker-compose restart + + - name: "[ ENROLL] acme.sh - ignore sucess_hook_failures " + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure + openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + + - name: "[ PREPARE ] reconfigure hook handler to trigger post hook exception " + run: | + sudo sed -i "s/raise_success_hook_exception: True/raise_success_hook_exception: False/g" examples/Docker/data/acme_srv.cfg + sudo sed -i "s/raise_post_hook_exception: False/raise_post_hook_exception: True/g" examples/Docker/data/acme_srv.cfg + cd examples/Docker/ + sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) + docker-compose restart + + - name: "[ ENROLL] acme.sh - ignore post_hook_failures (default behaviour) " + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure + openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + + - name: "[ PREPARE ] reconfigure a2c to detect success-hook failures " + run: | + sudo sed -i "s/ignore_success_hook_failure: True/ignore_post_hook_failure: False/g" examples/Docker/data/acme_srv.cfg + cd examples/Docker/ + sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) + docker-compose restart + + - name: "[ FAIL ] acme.sh enrollment fails due to post-hook exception " + id: posthookfailure + continue-on-error: true + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure + + - name: "[ CHECK ] result - acme.sh enrollment failed due to post-hook exception " + if: steps.posthookfailure.outcome != 'failure' + run: | + echo "posthookfailure outcome is ${{steps.posthookfailure.outcome }}" + exit 1 - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | mkdir -p ${{ github.workspace }}/artifact/upload - docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier - sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ - docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh + sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ + cd examples/Docker + docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data - name: "[ * ] uploading artificates" uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: hooks-rpm.tar.gz + name: hooks_mgomx_wsgi_exception_handling.tar.gz path: ${{ github.workspace }}/artifact/upload/ - hooks_exception_handling: - name: "hooks_exception_handling" + hooks_nginx_django_exception_handling: + name: "hooks_nginx_django_exception_handling" runs-on: ubuntu-latest steps: - name: "checkout GIT" @@ -226,15 +1035,14 @@ jobs: - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" working-directory: examples/Docker/ run: | + sed -i "s/apache2/nginx/g" .env + sed -i "s/apache2/nginx/g" .env sudo mkdir -p data/hooks sudo chmod -R 777 data/hooks docker network create acme docker-compose up -d docker-compose logs - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] setup openssl ca_handler" run: | sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py @@ -247,13 +1055,18 @@ jobs: sudo echo "raise_pre_hook_exception: False" >> examples/Docker/data/acme_srv.cfg sudo echo "raise_post_hook_exception: False" >> examples/Docker/data/acme_srv.cfg sudo echo "raise_success_hook_exception: False" >> examples/Docker/data/acme_srv.cfg - # sudo cat examples/Docker/data/acme_srv.cfg + sudo cp .github/django_settings.py examples/Docker/data/settings.py cd examples/Docker/ docker-compose restart docker-compose logs env: HOOKS_CHECKSUM: ${{ secrets.HOOKS_CHECKSUM }} + - name: "Sleep for 5s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 5s + - name: "Test http://acme-srv/directory is accessable again" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory @@ -378,17 +1191,24 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: hooks_exception_handling.tar.gz + name: hooks_nginx_django_exception_handling.tar.gz path: ${{ github.workspace }}/artifact/upload/ + + + + hooks_exception_handling_rpm: name: "hooks_exception_handling_rpm" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: Retrieve Version from version.py run: | echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV @@ -421,6 +1241,14 @@ jobs: mkdir acmme-sh mkdir lego + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + - name: "[ PREPARE ] prepare acme_srv.cfg with openssl_ca_handler" run: | sudo mkdir -p data/acme_ca/certs @@ -439,7 +1267,9 @@ jobs: - name: "[ PREPARE ] Almalinux instance" run: | - cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - name: "[ RUN ] Execute install scipt" @@ -552,6 +1382,9 @@ jobs: docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh @@ -559,5 +1392,5 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: hooks-rpm.tar.gz + name: hooks-rpm-rh${{ matrix.rhversion }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ \ No newline at end of file diff --git a/.github/workflows/ip-address-tests.yml b/.github/workflows/ip-address-tests.yml index 81cf8c9a..f2a4980f 100644 --- a/.github/workflows/ip-address-tests.yml +++ b/.github/workflows/ip-address-tests.yml @@ -304,3 +304,226 @@ jobs: with: name: ip_nginx_django.tar.gz path: ${{ github.workspace }}/artifact/upload/ + + ip_wsgi_rpm: + name: "ip_wsgi_rpm" + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] + steps: + - name: "checkout GIT" + uses: actions/checkout@v4 + + - name: "[ PREPARE ] get runner ip" + run: | + echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV + echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV + - run: echo "runner IP is ${{ env.RUNNER_IP }}" + + - name: Retrieve Version from version.py + run: | + echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV + - run: echo "Latest tag is ${{ env.TAG_NAME }}" + + - name: update version number in spec file + run: | + # sudo sed -i "s/Source0:.*/Source0: %{name}-%{version}.tar.gz/g" examples/install_scripts/rpm/acme2certifier.spec + sudo sed -i "s/__version__/${{ env.TAG_NAME }}/g" examples/install_scripts/rpm/acme2certifier.spec + cat examples/install_scripts/rpm/acme2certifier.spec + + - name: build RPM package + id: rpm + uses: grindsa/rpmbuild@alma9 + with: + spec_file: "examples/install_scripts/rpm/acme2certifier.spec" + + - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" + + - name: "[ PREPARE ] setup environment for alma installation" + run: | + docker network create acme + sudo mkdir -p data + sudo chmod -R 777 data + sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data + sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data + + - name: "[ PREPARE ] create lego folder" + run: | + mkdir lego + + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + + - name: "[ PREPARE ] prepare acme_srv.cfg with openssl_ca_handler" + run: | + mkdir -p data/acme_ca + sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem data/acme_ca + sudo cp .github/openssl_ca_handler.py_acme_srv_choosen_handler.cfg data/acme_srv.cfg + + - name: "[ PREPARE ] Almalinux instance" + run: | + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd + + - name: "[ RUN ] Execute install scipt" + run: | + docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh + + - name: "Enroll HTTP-01 single domain and ip address " + run: | + docker run -i -p 80:80 -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme -d $RUNNER_IP --http run + sudo openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt --text --noout | grep "IP Address" + env: + RUNNER_IP: ${{ env.RUNNER_IP }} + + - name: "[ * ] collecting test logs" + if: ${{ failure() }} + run: | + mkdir -p ${{ github.workspace }}/artifact/upload + docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier + sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf + docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log lego + + - name: "[ * ] uploading artificates" + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: ip_wsgi_rpm-rh${{ matrix.rhversion }}.tar.gz + path: ${{ github.workspace }}/artifact/upload/ + + + ip_django_rpm: + name: "ip_django_rpm" + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] + steps: + - name: "checkout GIT" + uses: actions/checkout@v4 + + - name: "[ PREPARE ] get runner ip" + run: | + echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV + echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV + - run: echo "runner IP is ${{ env.RUNNER_IP }}" + + - name: Retrieve Version from version.py + run: | + echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV + - run: echo "Latest tag is ${{ env.TAG_NAME }}" + + - name: update version number in spec file and path in nginx ssl config + run: | + sudo sed -i "s/__version__/${{ env.TAG_NAME }}/g" examples/install_scripts/rpm/acme2certifier.spec + sudo sed -i "s/\/var\/www\/acme2certifier\/volume/\/etc\/nginx/g" examples/nginx/nginx_acme_srv_ssl.conf + git config --global user.email "grindelsack@gmail.com" + git config --global user.name "rpm update" + git add examples/nginx + git commit -a -m "rpm update" + + - name: build RPM package + id: rpm + uses: grindsa/rpmbuild@alma9 + with: + spec_file: "examples/install_scripts/rpm/acme2certifier.spec" + + - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" + + - name: "[ PREPARE ] setup environment for alma installation" + run: | + docker network create acme + sudo mkdir -p data/volume + sudo mkdir -p data/acme2certifier + sudo mkdir -p data/nginx + sudo chmod -R 777 data + sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data + sudo cp examples/Docker/almalinux-systemd/django_tester.sh data + sudo cp .github/acme2certifier_cert.pem data/nginx/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem data/nginx/acme2certifier_key.pem + sudo cp .github/django_settings.py data/acme2certifier/settings.py + sudo sed -i "s/\/var\/www\//\/opt\//g" data/acme2certifier/settings.py + sudo sed -i "s/USE_I18N = True/USE_I18N = False/g" data/acme2certifier/settings.py + + - name: "[ PREPARE ] create lego folder" + run: | + mkdir lego + + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + + - name: "[ PREPARE ] prepare acme_srv.cfg with openssl_ca_handler" + run: | + sudo mkdir -p data/volume/acme_ca/certs + sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem data/volume/acme_ca/ + sudo cp .github/openssl_ca_handler.py_acme_srv_choosen_handler.cfg data/volume/acme_srv.cfg + + - name: "[ PREPARE ] Almalinux instance" + run: | + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + docker run -d -id --privileged --network acme -p 22280:80 --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd + + - name: "[ RUN ] Execute install scipt" + run: | + docker exec acme-srv sh /tmp/acme2certifier/django_tester.sh + + - name: "Test http://acme-srv/directory is accessible" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "Enroll HTTP-01 single domain and ip address " + run: | + docker run -i -p 80:80 -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme -d $RUNNER_IP --http run + sudo openssl verify -CAfile data/volume/acme_ca/root-ca-cert.pem -untrusted data/volume/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt --text --noout | grep "IP Address" + env: + RUNNER_IP: ${{ env.RUNNER_IP }} + + - name: "[ * ] collecting test logs" + if: ${{ failure() }} + run: | + mkdir -p ${{ github.workspace }}/artifact/upload + docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier + docker exec acme-srv tar cvfz /tmp/acme2certifier/nginx.tgz /etc/nginx + sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf + docker exec acme-srv rpm -qa > ${{ github.workspace }}/artifact/data/packages.txt + docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log lego + + - name: "[ * ] uploading artificates" + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: ip_django_rpm-rh${{ matrix.rhversion }}.tar.gz + path: ${{ github.workspace }}/artifact/upload/ + + diff --git a/.github/workflows/ipv6-test.yml b/.github/workflows/ipv6-test.yml index 5567e07b..b40c1f45 100644 --- a/.github/workflows/ipv6-test.yml +++ b/.github/workflows/ipv6-test.yml @@ -53,7 +53,7 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: lego_key-${{ matrix.keylength }}.tar.gz + name: ipv6_apache2_wsgi.tar.gz path: ${{ github.workspace }}/artifact/upload/ ipv6_nginx_wsgi: @@ -102,7 +102,7 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: lego_key-${{ matrix.keylength }}.tar.gz + name: ipv6_nginx_wsgi.tar.gz path: ${{ github.workspace }}/artifact/upload/ ipv6_apache2_django: @@ -152,7 +152,7 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: lego_key-${{ matrix.keylength }}.tar.gz + name: ipv6_apache2_django.tar.gz path: ${{ github.workspace }}/artifact/upload/ ipv6_nginx_django: @@ -180,6 +180,7 @@ jobs: cd examples/Docker/ docker-compose restart docker-compose logs + - name: "[ PREPARE ] prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon @@ -191,6 +192,8 @@ jobs: run: | docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --listen-v4 --debug 3 --output-insecure --force openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer + + - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | @@ -199,9 +202,253 @@ jobs: cd examples/Docker docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data + + - name: "[ * ] uploading artificates" + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: ipv6_nginx_django.tar.gz + path: ${{ github.workspace }}/artifact/upload/ + + + rpm_wsgi_ipv6: + name: "rpm_wsgi_ipv6" + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] + steps: + - name: "checkout GIT" + uses: actions/checkout@v4 + + - name: Retrieve Version from version.py + run: | + echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV + - run: echo "Latest tag is ${{ env.TAG_NAME }}" + + - name: update version number in spec file + run: | + # sudo sed -i "s/Source0:.*/Source0: %{name}-%{version}.tar.gz/g" examples/install_scripts/rpm/acme2certifier.spec + sudo sed -i "s/__version__/${{ env.TAG_NAME }}/g" examples/install_scripts/rpm/acme2certifier.spec + cat examples/install_scripts/rpm/acme2certifier.spec + + - name: build RPM package + id: rpm + uses: grindsa/rpmbuild@alma9 + with: + spec_file: "examples/install_scripts/rpm/acme2certifier.spec" + + - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" + + - name: "[ PREPARE ] setup environment for alma installation" + run: | + docker network create acme --ipv6 --subnet "fdbb:6445:65b4:0a60::/64" + sudo mkdir -p data + sudo chmod -R 777 data + sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data + sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data + + - name: "[ PREPARE ] create lego and certbot folder" + run: | + mkdir lego + mkdir certbot + + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + + - name: "[ PREPARE ] setup openssl ca_handler" + run: | + mkdir -p data/acme_ca + sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem data/acme_ca/ + sudo cp .github/openssl_ca_handler.py_acme_srv_choosen_handler.cfg data/acme_srv.cfg + + - name: "[ PREPARE ] Almalinux instance" + run: | + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd + + - name: "[ RUN ] Execute install scipt" + run: | + docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh + + - name: "[ PREPARE ] prepare acme.sh container" + run: | + docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + + - name: "[ ENROLL ] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure + openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + + - name: "[ ENROL] lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --cert.timeout 180 --http run + + - name: "[ REGISTER ] certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email + + - name: "[ ENROLL ] certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot + + - name: "[ * ] collecting test logs" + if: ${{ failure() }} + run: | + mkdir -p ${{ github.workspace }}/artifact/upload + docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier + sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf + docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log + + - name: "[ * ] uploading artificates" + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: rpm_wsgi_ipv6-rh${{ matrix.rhversion }}.tar.gz + path: ${{ github.workspace }}/artifact/upload/ + + + rpm_django_ipv6: + name: "rpm_django_ipv6" + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] + steps: + - name: "checkout GIT" + uses: actions/checkout@v4 + + - name: "[ PREPARE ] get runner ip" + run: | + echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV + echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV + - run: echo "runner IP is ${{ env.RUNNER_IP }}" + + - name: Retrieve Version from version.py + run: | + echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV + - run: echo "Latest tag is ${{ env.TAG_NAME }}" + + - name: update version number in spec file and path in nginx ssl config + run: | + sudo sed -i "s/__version__/${{ env.TAG_NAME }}/g" examples/install_scripts/rpm/acme2certifier.spec + sudo sed -i "s/\/var\/www\/acme2certifier\/volume/\/etc\/nginx/g" examples/nginx/nginx_acme_srv_ssl.conf + git config --global user.email "grindelsack@gmail.com" + git config --global user.name "rpm update" + git add examples/nginx + git commit -a -m "rpm update" + + - name: build RPM package + id: rpm + uses: grindsa/rpmbuild@alma9 + with: + spec_file: "examples/install_scripts/rpm/acme2certifier.spec" + + - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" + + - name: "[ PREPARE ] setup environment for alma installation" + run: | + docker network create acme --ipv6 --subnet "fdbb:6445:65b4:0a60::/64" + sudo mkdir -p data/volume + sudo mkdir -p data/acme2certifier + sudo mkdir -p data/nginx + sudo chmod -R 777 data + sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data + sudo cp examples/Docker/almalinux-systemd/django_tester.sh data + sudo cp .github/acme2certifier_cert.pem data/nginx/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem data/nginx/acme2certifier_key.pem + sudo cp .github/django_settings.py data/acme2certifier/settings.py + sudo sed -i "s/\/var\/www\//\/opt\//g" data/acme2certifier/settings.py + sudo sed -i "s/USE_I18N = True/USE_I18N = False/g" data/acme2certifier/settings.py + + - name: "[ PREPARE ] create lego folder" + run: | + mkdir lego + + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + + - name: "[ PREPARE ] setup openssl ca_handler" + run: | + sudo mkdir -p data/volume/acme_ca/certs + sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem data/volume/acme_ca/ + sudo cp .github/openssl_ca_handler.py_acme_srv_choosen_handler.cfg data/volume/acme_srv.cfg + + - name: "[ PREPARE ] Almalinux instance" + run: | + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + docker run -d -id --privileged --network acme -p 22280:80 --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd + + - name: "[ RUN ] Execute install scipt" + run: | + docker exec acme-srv sh /tmp/acme2certifier/django_tester.sh + + - name: "Test http://acme-srv/directory is accessible" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + + - name: "[ PREPARE ] prepare acme.sh container" + run: | + docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + + - name: "[ ENROLL ] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure + openssl verify -CAfile data/volume/acme_ca/root-ca-cert.pem -untrusted data/volume/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + + - name: "[ ENROL] lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --cert.timeout 180 --http run + + - name: "[ REGISTER ] certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email + + - name: "[ ENROLL ] certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot + + - name: "[ * ] collecting test logs" + if: ${{ failure() }} + run: | + mkdir -p ${{ github.workspace }}/artifact/upload + docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier + docker exec acme-srv tar cvfz /tmp/acme2certifier/nginx.tgz /etc/nginx + sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf + docker exec acme-srv rpm -qa > ${{ github.workspace }}/artifact/data/packages.txt + docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log lego + - name: "[ * ] uploading artificates" uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: lego_key-${{ matrix.keylength }}.tar.gz + name: rpm_django_ipv6-rh${{ matrix.rhversion }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ diff --git a/.github/workflows/proxy-test.yml b/.github/workflows/proxy-test.yml index 592841a6..88133bc5 100644 --- a/.github/workflows/proxy-test.yml +++ b/.github/workflows/proxy-test.yml @@ -12,13 +12,43 @@ jobs: proxy_tests: name: "proxy_tests" runs-on: ubuntu-latest - strategy: - fail-fast: false steps: - name: "checkout GIT" uses: actions/checkout@v4 + - name: "[ PREPARE ] get runner ip" + run: | + echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV + echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV + + - run: echo "runner IP is ${{ env.RUNNER_IP }}" + + - name: "Install dnsmasq" + run: | + sudo apt-get update + sudo apt-get install -y dnsmasq + sudo systemctl disable systemd-resolved + sudo systemctl stop systemd-resolved + sudo mkdir -p dnsmasq + sudo cp .github/dnsmasq.conf dnsmasq/ + sudo chmod -R 777 dnsmasq/dnsmasq.conf + sudo sed -i "s/RUNNER_IP/$RUNNER_IP/g" dnsmasq/dnsmasq.conf + sudo echo "address=/$WES_HOST/$RUNNER_IP" >> dnsmasq/dnsmasq.conf + cat dnsmasq/dnsmasq.conf + sudo cp dnsmasq/dnsmasq.conf /etc/ + sudo systemctl enable dnsmasq + sudo systemctl start dnsmasq + env: + RUNNER_IP: ${{ env.RUNNER_IP }} + WES_HOST: ${{ secrets.WES_HOST }} + + - name: "[ PREPARE ] test dns resulution" + run: | + host $WES_HOST 127.0.0.1 + env: + WES_HOST: ${{ secrets.WES_HOST }} + - name: "[ PREPARE ] create network" run: | docker network create acme @@ -118,35 +148,6 @@ jobs: docker stop proxy docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & - - name: "[ PREPARE ] setup msca ca_handler for proxy usage" - run: | - sudo cp examples/ca_handler/mscertsrv_ca_handler.py examples/Docker/data/ca_handler.py - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg - sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg - sudo echo "host: ${{ secrets.WES_HOST }}" >> examples/Docker/data/acme_srv.cfg - sudo echo "user: ${{ secrets.WES_USER }}" >> examples/Docker/data/acme_srv.cfg - sudo echo "password: ${{ secrets.WES_PASSWORD }}" >> examples/Docker/data/acme_srv.cfg - sudo echo "auth_method: ${{ secrets.WES_AUTHMETHOD }}" >> examples/Docker/data/acme_srv.cfg - sudo echo "template: ${{ secrets.WES_TEMPLATE }}" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_bundle: volume/ca_certs.pem" >> examples/Docker/data/acme_srv.cfg - sudo sed -i "s/debug: True/debug: True\nproxy_server_list: {\"amazonaws.com\$\": \"socks5:\/\/proxy.acme:8080\"}/g" examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - docker-compose restart - docker-compose logs - - - name: "[ ENROLL ] via msca ca_handler" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force - # openssl verify -CAfile acme.sh/acme-sh.acme/ca.cer acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - - name: "[ CHECK ] proxy logs" - run: | - docker logs proxy | grep socks5 | grep -- "->" - docker stop proxy - docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & - - name: "[ PREPARE ] patch est_ca handler for testrfc7030.com" run: | sudo apt-get install curl openssl patch @@ -238,6 +239,59 @@ jobs: docker stop proxy docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & + - name: "[ PREPARE ] setup msca ca_handler for proxy usage" + run: | + sudo cp examples/ca_handler/mscertsrv_ca_handler.py examples/Docker/data/ca_handler.py + sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg + sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem + sudo chmod 777 examples/Docker/data/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg + sudo echo "host: ${{ secrets.WES_HOST }}" >> examples/Docker/data/acme_srv.cfg + sudo echo "user: ${{ secrets.WES_USER }}" >> examples/Docker/data/acme_srv.cfg + sudo echo "password: ${{ secrets.WES_PASSWORD }}" >> examples/Docker/data/acme_srv.cfg + sudo echo "auth_method: ${{ secrets.WES_AUTHMETHOD }}" >> examples/Docker/data/acme_srv.cfg + sudo echo "template: ${{ secrets.WES_TEMPLATE }}" >> examples/Docker/data/acme_srv.cfg + sudo echo "ca_bundle: volume/ca_certs.pem" >> examples/Docker/data/acme_srv.cfg + sudo sed -i "s/debug: True/debug: True\nproxy_server_list: {\"amazonaws.com\$\": \"socks5:\/\/proxy.acme:8080\"}/g" examples/Docker/data/acme_srv.cfg + cd examples/Docker/ + docker-compose restart + docker-compose logs + + - name: "[ PREPARE ] ssh environment on ramdisk" + run: | + sudo mkdir -p /tmp/rd + sudo mount -t tmpfs -o size=5M none /tmp/rd + sudo echo "$SSH_KEY" > /tmp/rd/ak.tmp + sudo chmod 600 /tmp/rd/ak.tmp + sudo echo "$KNOWN_HOSTS" > /tmp/rd/known_hosts + env: + SSH_KEY: ${{ secrets.WCCE_SSH_ACCESS_KEY }} + KNOWN_HOSTS: ${{ secrets.WCCE_SSH_KNOWN_HOSTS }} + + - name: "[ PREPARE ] establish SSH connection" + run: sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -p $SSH_PORT -o UserKnownHostsFile=/tmp/rd/known_hosts -L 443:$WES_IP:443 -g ping -c 180 $WES_IP & + env: + SSH_USER: ${{ secrets.CMP_SSH_USER }} + SSH_HOST: ${{ secrets.CMP_SSH_HOST }} + SSH_PORT: ${{ secrets.CMP_SSH_PORT }} + WES_IP: ${{ secrets.WES_IP }} + + - name: "[ PREPARE ] Sleep for 5s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 5s + + - name: "[ ENROLL ] via msca ca_handler" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force + # openssl verify -CAfile acme.sh/acme-sh.acme/ca.cer acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + + - name: "[ CHECK ] proxy logs" + run: | + docker logs proxy | grep socks5 | grep -- "->" + docker stop proxy + docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & + - name: "[ stop ] proxy container" run: | docker stop proxy @@ -264,11 +318,45 @@ jobs: runs-on: ubuntu-latest strategy: fail-fast: false + matrix: + rhversion: [8, 9] steps: - name: "checkout GIT" uses: actions/checkout@v4 + - name: "[ PREPARE ] get runner ip" + run: | + echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV + echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV + + - run: echo "runner IP is ${{ env.RUNNER_IP }}" + + - name: "Install dnsmasq" + run: | + sudo apt-get update + sudo apt-get install -y dnsmasq + sudo systemctl disable systemd-resolved + sudo systemctl stop systemd-resolved + sudo mkdir -p dnsmasq + sudo cp .github/dnsmasq.conf dnsmasq/ + sudo chmod -R 777 dnsmasq/dnsmasq.conf + sudo sed -i "s/RUNNER_IP/$RUNNER_IP/g" dnsmasq/dnsmasq.conf + sudo echo "address=/$WES_HOST/$RUNNER_IP" >> dnsmasq/dnsmasq.conf + cat dnsmasq/dnsmasq.conf + sudo cp dnsmasq/dnsmasq.conf /etc/ + sudo systemctl enable dnsmasq + sudo systemctl start dnsmasq + env: + RUNNER_IP: ${{ env.RUNNER_IP }} + WES_HOST: ${{ secrets.WES_HOST }} + + - name: "[ PREPARE ] test dns resulution" + run: | + host $WES_HOST 127.0.0.1 + env: + WES_HOST: ${{ secrets.WES_HOST }} + - name: Retrieve Version from version.py run: | echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV @@ -300,7 +388,7 @@ jobs: - name: "Retrieve rpms from SBOM repo" run: | git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom - cp /tmp/sbom/rpm-repo/RPMs/*ntlm*.rpm data + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data env: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} @@ -330,7 +418,9 @@ jobs: - name: "[ PREPARE ] Almalinux instance" run: | - cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - name: "[ RUN ] Execute install scipt" @@ -410,44 +500,6 @@ jobs: docker stop proxy docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & - - name: "[ PREPARE ] setup msca ca_handler for proxy usage" - run: | - mkdir -p data/acme_ca - sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem - sudo touch data/acme_srv.cfg - sudo chmod 777 data/acme_srv.cfg - sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/acme_srv.cfg - sudo echo "handler_file: /opt/acme2certifier/examples/ca_handler/mscertsrv_ca_handler.py" >> data/acme_srv.cfg - sudo echo "host: $WES_HOST" >> data/acme_srv.cfg - sudo echo "user: $WES_USER" >> data/acme_srv.cfg - sudo echo "password: $WES_PASSWORD" >> data/acme_srv.cfg - sudo echo "auth_method: $WES_AUTHMETHOD" >> data/acme_srv.cfg - sudo echo "template: $WES_TEMPLATE" >> data/acme_srv.cfg - sudo echo "ca_bundle: volume/acme_ca/ca_certs.pem" >> data/acme_srv.cfg - sudo sed -i "s/debug: True/debug: True\nproxy_server_list: {\"amazonaws.com\$\": \"socks5:\/\/proxy.acme:8080\"}/g" data/acme_srv.cfg - env: - WES_HOST: ${{ secrets.WES_HOST }} - WES_USER: ${{ secrets.WES_USER }} - WES_PASSWORD: ${{ secrets.WES_PASSWORD }} - WES_AUTHMETHOD: ${{ secrets.WES_AUTHMETHOD }} - WES_TEMPLATE: ${{ secrets.WES_TEMPLATE }} - - - name: "[ PREPARE ] reconfigure a2c " - run: | - docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart - - - name: "[ ENROLL ] via msca ca_handler" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force & - sleep 45 - openssl verify -CAfile data/acme_ca/ca_certs.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - - name: "[ CHECK ] proxy logs" - run: | - docker logs proxy | grep socks5 | grep -- "->" - docker stop proxy - docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & - - name: "[ PREPARE ] setup esthandler using http-basic-auth" run: | sudo mkdir -p data/acme_ca @@ -541,12 +593,75 @@ jobs: - name: "[ ENROLL ] via nclm_ca_handler" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force & - sleep 45 + docker stop proxy + docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & #- name: "[ CHECK ] proxy logs" # run: | # docker logs proxy | grep socks5 | grep -- "->" + - name: "[ PREPARE ] ssh environment on ramdisk" + run: | + sudo mkdir -p /tmp/rd + sudo mount -t tmpfs -o size=5M none /tmp/rd + sudo echo "$SSH_KEY" > /tmp/rd/ak.tmp + sudo chmod 600 /tmp/rd/ak.tmp + sudo echo "$KNOWN_HOSTS" > /tmp/rd/known_hosts + env: + SSH_KEY: ${{ secrets.WCCE_SSH_ACCESS_KEY }} + KNOWN_HOSTS: ${{ secrets.WCCE_SSH_KNOWN_HOSTS }} + + - name: "[ PREPARE ] establish SSH connection" + run: sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -p $SSH_PORT -o UserKnownHostsFile=/tmp/rd/known_hosts -L 443:$WES_IP:443 -g ping -c 180 $WES_IP & + env: + SSH_USER: ${{ secrets.CMP_SSH_USER }} + SSH_HOST: ${{ secrets.CMP_SSH_HOST }} + SSH_PORT: ${{ secrets.CMP_SSH_PORT }} + WES_IP: ${{ secrets.WES_IP }} + + - name: "[ PREPARE ] Sleep for 5s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 5s + + - name: "[ PREPARE ] setup msca ca_handler for proxy usage" + run: | + mkdir -p data/acme_ca + sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem + sudo touch data/acme_srv.cfg + sudo chmod 777 data/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/acme_srv.cfg + sudo echo "handler_file: /opt/acme2certifier/examples/ca_handler/mscertsrv_ca_handler.py" >> data/acme_srv.cfg + sudo echo "host: $WES_HOST" >> data/acme_srv.cfg + sudo echo "user: $WES_USER" >> data/acme_srv.cfg + sudo echo "password: $WES_PASSWORD" >> data/acme_srv.cfg + sudo echo "auth_method: $WES_AUTHMETHOD" >> data/acme_srv.cfg + sudo echo "template: $WES_TEMPLATE" >> data/acme_srv.cfg + sudo echo "ca_bundle: volume/acme_ca/ca_certs.pem" >> data/acme_srv.cfg + sudo sed -i "s/debug: True/debug: True\nproxy_server_list: {\"amazonaws.com\$\": \"socks5:\/\/proxy.acme:8080\"}/g" data/acme_srv.cfg + env: + WES_HOST: ${{ secrets.WES_HOST }} + WES_USER: ${{ secrets.WES_USER }} + WES_PASSWORD: ${{ secrets.WES_PASSWORD }} + WES_AUTHMETHOD: ${{ secrets.WES_AUTHMETHOD }} + WES_TEMPLATE: ${{ secrets.WES_TEMPLATE }} + + - name: "[ PREPARE ] reconfigure a2c " + run: | + docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart + + - name: "[ ENROLL ] via msca ca_handler" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force & + # sleep 45 + # openssl verify -CAfile data/acme_ca/ca_certs.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + + - name: "[ CHECK ] proxy logs" + run: | + docker logs proxy | grep socks5 | grep -- "->" + docker stop proxy + docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & + - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | @@ -554,6 +669,9 @@ jobs: docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log docker logs proxy > ${{ github.workspace }}/artifact/proxy.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data proxy.log acme-srv.log acme-sh @@ -562,5 +680,5 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: proxy-rpm.tar.gz + name: proxy-rpm-rh${{ matrix.rhversion }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ \ No newline at end of file diff --git a/.github/workflows/test_headerinfo.yml b/.github/workflows/test_headerinfo.yml index ce2642a3..04d1725a 100644 --- a/.github/workflows/test_headerinfo.yml +++ b/.github/workflows/test_headerinfo.yml @@ -65,6 +65,11 @@ jobs: docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent foo-bar-doo -d lego.acme --http run sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + - name: "[ WAIT ] Sleep for 15s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 15s + - name: "check header info" run: | cd examples/Docker/ @@ -150,6 +155,11 @@ jobs: docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent foo-bar-doo -d lego.acme --http run sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + - name: "[ WAIT ] Sleep for 15s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 15s + - name: "check header info" run: | cd examples/Docker/ @@ -221,10 +231,10 @@ jobs: XCA_TEMPLATE: ${{ secrets.XCA_TEMPLATE }} XCA_DB_NAME: ${{ secrets.XCA_DB_NAME }} - - name: "[ WAIT ] Sleep for 10s" + - name: "[ WAIT ] Sleep for 15s" uses: juliangruber/sleep-action@v2.0.3 with: - time: 10s + time: 15s - name: "Test http://acme-srv/directory is accessable again" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory @@ -234,6 +244,11 @@ jobs: docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent foo-bar-doo -d lego.acme --http run sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + - name: "[ WAIT ] Sleep for 15s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 15s + - name: "check header info" run: | cd examples/Docker/ @@ -325,6 +340,11 @@ jobs: docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent foo-bar-doo -d lego.acme --http run sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + - name: "[ WAIT ] Sleep for 15s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 15s + - name: "check header info" run: | cd examples/Docker/ @@ -350,6 +370,10 @@ jobs: header_info_tests_rpm: name: "header_info_tests_rpm" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -385,7 +409,15 @@ jobs: run: | mkdir lego - - name: "[ PREPARE ] prepare acme_srv.cfg with openssl_ca_handler" + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + + - name: "[ PREPARE ] prepare acme_srv.cfg with xca_ca_handler" run: | mkdir -p data/acme_ca sudo cp test/ca/acme2certifier-clean.xdb data/acme_ca/$XCA_DB_NAME @@ -409,9 +441,12 @@ jobs: - name: "[ PREPARE ] Almalinux instance" run: | - cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd + - name: "[ RUN ] Execute install scipt" run: | docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh @@ -421,6 +456,11 @@ jobs: docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent foo-bar-doo -d lego.acme --http run sudo openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + - name: "[ WAIT ] Sleep for 15s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 15s + - name: "check header info" run: | docker exec acme-srv grep foo-bar-doo /var/log/messages @@ -431,6 +471,9 @@ jobs: mkdir -p ${{ github.workspace }}/artifact/upload docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log @@ -438,7 +481,156 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: rpm_header_info.ap_wsgi.tar.gz + name: rpm_header_info.ap_wsgi-rh${{ matrix.rhversion }}.tar.gz + path: ${{ github.workspace }}/artifact/upload/ + + headerinfo_django_rpm: + name: "headerinfo_django_rpm" + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] + steps: + - name: "checkout GIT" + uses: actions/checkout@v4 + + - name: "[ PREPARE ] get runner ip" + run: | + echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV + echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV + - run: echo "runner IP is ${{ env.RUNNER_IP }}" + + - name: Retrieve Version from version.py + run: | + echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV + - run: echo "Latest tag is ${{ env.TAG_NAME }}" + + - name: update version number in spec file and path in nginx ssl config + run: | + sudo sed -i "s/__version__/${{ env.TAG_NAME }}/g" examples/install_scripts/rpm/acme2certifier.spec + sudo sed -i "s/\/var\/www\/acme2certifier\/volume/\/etc\/nginx/g" examples/nginx/nginx_acme_srv_ssl.conf + git config --global user.email "grindelsack@gmail.com" + git config --global user.name "rpm update" + git add examples/nginx + git commit -a -m "rpm update" + + - name: build RPM package + id: rpm + uses: grindsa/rpmbuild@alma9 + with: + spec_file: "examples/install_scripts/rpm/acme2certifier.spec" + + - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" + + - name: "[ PREPARE ] setup environment for alma installation" + run: | + docker network create acme + sudo mkdir -p data/volume + sudo mkdir -p data/acme2certifier + sudo mkdir -p data/nginx + sudo chmod -R 777 data + sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data + sudo cp examples/Docker/almalinux-systemd/django_tester.sh data + sudo cp .github/acme2certifier_cert.pem data/nginx/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem data/nginx/acme2certifier_key.pem + sudo cp .github/django_settings.py data/acme2certifier/settings.py + sudo sed -i "s/\/var\/www\//\/opt\//g" data/acme2certifier/settings.py + sudo sed -i "s/USE_I18N = True/USE_I18N = False/g" data/acme2certifier/settings.py + + - name: "[ PREPARE ] create lego folder" + run: | + mkdir lego + + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + + #- name: "[ PREPARE ] prepare acme_srv.cfg with openssl_ca_handler" + # run: | + # sudo mkdir -p data/volume/acme_ca/certs + # sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem data/volume/acme_ca/ + # sudo cp .github/openssl_ca_handler.py_acme_srv_choosen_handler.cfg data/volume/acme_srv.cfg + # sudo chmod 777 data/volume/acme_srv.cfg + # sudo sed -i "s/tnauthlist_support: False/tnauthlist_support: False\nheader_info_list: [\"HTTP_USER_AGENT\"]/g" data/volume/acme_srv.cfg + + - name: "[ PREPARE ] prepare acme_srv.cfg with xca_ca_handler" + run: | + mkdir -p data/volume/acme_ca/certs + sudo cp test/ca/acme2certifier-clean.xdb data/volume/acme_ca/$XCA_DB_NAME + sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem data/volume/acme_ca/ + sudo touch data/volume/acme_srv.cfg + sudo chmod 777 data/volume/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/volume/acme_srv.cfg + sudo echo "handler_file: /opt/acme2certifier/examples/ca_handler/xca_ca_handler.py" >> data/volume/acme_srv.cfg + sudo echo "xdb_file: volume/acme_ca/$XCA_DB_NAME" >> data/volume/acme_srv.cfg + sudo echo "issuing_ca_name: $XCA_ISSUING_CA" >> data/volume/acme_srv.cfg + sudo echo "passphrase: $XCA_PASSPHRASE" >> data/volume/acme_srv.cfg + sudo echo "ca_cert_chain_list: [\"root-ca\"]" >> data/volume/acme_srv.cfg + sudo echo "template_name: $XCA_TEMPLATE" >> data/volume/acme_srv.cfg + sudo sed -i "s/tnauthlist_support: False/tnauthlist_support: False\nheader_info_list: [\"HTTP_USER_AGENT\"]/g" data/volume/acme_srv.cfg + env: + XCA_PASSPHRASE: ${{ secrets.XCA_PASSPHRASE }} + XCA_ISSUING_CA: ${{ secrets.XCA_ISSUING_CA }} + XCA_TEMPLATE: ${{ secrets.XCA_TEMPLATE }} + XCA_DB_NAME: ${{ secrets.XCA_DB_NAME }} + + - name: "[ PREPARE ] Almalinux instance" + run: | + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + docker run -d -id --privileged --network acme -p 22280:80 --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd + + - name: "[ RUN ] Execute install scipt" + run: | + docker exec acme-srv sh /tmp/acme2certifier/django_tester.sh + + - name: "Test http://acme-srv/directory is accessible" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "[ ENROLL ] lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent foo-bar-doo -d lego.acme --http run + sudo openssl verify -CAfile data/volume/acme_ca/root-ca-cert.pem -untrusted data/volume/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + + - name: "[ WAIT ] Sleep for 15s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 15s + + - name: "check header info" + run: | + docker exec acme-srv grep foo-bar-doo /var/log/messages + + - name: "[ * ] collecting test logs" + if: ${{ failure() }} + run: | + mkdir -p ${{ github.workspace }}/artifact/upload + docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier + docker exec acme-srv tar cvfz /tmp/acme2certifier/nginx.tgz /etc/nginx + sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf + docker exec acme-srv rpm -qa > ${{ github.workspace }}/artifact/data/packages.txt + docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log lego + + - name: "[ * ] uploading artificates" + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: headerinfo_django_rpm-rh${{ matrix.rhversion }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ + diff --git a/.github/workflows/tnauth-test.yml b/.github/workflows/tnauth-test.yml index c3253734..2ca6b83f 100644 --- a/.github/workflows/tnauth-test.yml +++ b/.github/workflows/tnauth-test.yml @@ -73,6 +73,10 @@ jobs: tnauth_rpm_tests: name: "tnauth_rpm_tests" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -104,6 +108,14 @@ jobs: sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + - name: "[ PREPARE ] prepare acme_srv.cfg with openssl_ca_handler" run: | mkdir -p data/acme_ca @@ -114,7 +126,9 @@ jobs: - name: "[ PREPARE ] Almalinux instance" run: | - cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme -p 22280:80 --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - name: "[ RUN ] Execute install scipt" @@ -145,13 +159,16 @@ jobs: mkdir -p ${{ github.workspace }}/artifact/upload docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp /tmp/acme_sh/ ${{ github.workspace }}/artifact/acme_sh/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + # sudo cp -rp /tmp/acme_sh/ ${{ github.workspace }}/artifact/acme_sh/ + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme_sh + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log - name: "[ * ] uploading artificates" uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: tnauth-rpm.tar.gz + name: tnauth-rpm-rh${{ matrix.rhversion }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ diff --git a/.github/workflows/wsgi_handler-test.yml b/.github/workflows/wsgi_handler-test.yml index b9fedf1b..fd2f3e86 100644 --- a/.github/workflows/wsgi_handler-test.yml +++ b/.github/workflows/wsgi_handler-test.yml @@ -12,8 +12,6 @@ jobs: a2_cust_db_file: name: "a2_cust_db_file" runs-on: ubuntu-latest - strategy: - fail-fast: false steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -82,8 +80,6 @@ jobs: nginx_cust_db_file: name: "nginx_cust__db_file" runs-on: ubuntu-latest - strategy: - fail-fast: false steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -151,3 +147,118 @@ jobs: with: name: nginx_cust_db.tar.gz path: ${{ github.workspace }}/artifact/upload/ + + rpm_cust_db_file: + name: "rpm_cust_db_file" + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] + steps: + - name: "checkout GIT" + uses: actions/checkout@v4 + + - name: Retrieve Version from version.py + run: | + echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV + - run: echo "Latest tag is ${{ env.TAG_NAME }}" + + - name: update version number in spec file + run: | + # sudo sed -i "s/Source0:.*/Source0: %{name}-%{version}.tar.gz/g" examples/install_scripts/rpm/acme2certifier.spec + sudo sed -i "s/__version__/${{ env.TAG_NAME }}/g" examples/install_scripts/rpm/acme2certifier.spec + cat examples/install_scripts/rpm/acme2certifier.spec + + - name: build RPM package + id: rpm + uses: grindsa/rpmbuild@alma9 + with: + spec_file: "examples/install_scripts/rpm/acme2certifier.spec" + + - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" + + - name: "[ PREPARE ] setup environment for alma installation" + run: | + docker network create acme + sudo mkdir -p data + sudo chmod -R 777 data + sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data + sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data + + - name: "[ PREPARE ] create letsencrypt and lego folder" + run: | + mkdir certbot + mkdir lego + + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + + - name: "[ PREPARE ] prepare acme_srv.cfg with openssl_ca_handler" + run: | + sudo mkdir -p data/acme_ca/certs/ + sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem data/acme_ca/ + sudo cp .github/openssl_ca_handler.py_acme_srv_choosen_handler.cfg data/acme_srv.cfg + sudo chmod 777 data/acme_srv.cfg + sudo echo "[DBhandler]" >> data/acme_srv.cfg + sudo echo "dbfile: volume/a2c.db" >> data/acme_srv.cfg + sudo echo "[Directory]" >> data/acme_srv.cfg + sudo echo "url_prefix: /foo" >> data/acme_srv.cfg + + - name: "[ PREPARE ] Almalinux instance" + run: | + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd + + - name: "[ RUN ] Execute install scipt" + run: | + docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh + + - name: "Sleep for 5s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 5s + + - name: "Test http://acme-srv/directory is accessible" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "[ PREPARE ] prepare acme.sh container" + run: | + docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + + - name: "[ ENROLL ] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force + openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + + - name: "[ ENROLL ] lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + sudo openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + + - name: "[ * ] collecting test logs" + if: ${{ failure() }} + run: | + mkdir -p ${{ github.workspace }}/artifact/upload + docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier + sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf + docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh + + - name: "[ * ] uploading artificates" + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: rpm_cust_db_file-rh${{ matrix.rhversion }}.tar.gz + path: ${{ github.workspace }}/artifact/upload/ \ No newline at end of file From 04797e2f6803a09ba415ce8f0347d03645e978ef Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 3 Mar 2024 08:04:33 +0100 Subject: [PATCH 092/460] [rel] bump to v0.33.3 --- CHANGES.md | 7 +++++++ acme_srv/version.py | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index adfbfea7..91f6ee0e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,6 +5,13 @@ This is a high-level summary of the most important changes. For a full list of changes, see the [git commit log](https://github.com/grindsa/acme2certifier/commits) and pick the appropriate release branch. +# Changes in 0.33.3 + +**Features and Improvements**: +- some smaller modifications run flawless on Redhat8 and derivates +- Workflows to test rpm-deployment on RHEL8 and RHEL9 + + # Changes in 0.33.2 **Upgrade notes**: diff --git a/acme_srv/version.py b/acme_srv/version.py index 163eeff4..499cbcf9 100644 --- a/acme_srv/version.py +++ b/acme_srv/version.py @@ -3,5 +3,5 @@ # 1) we don't load dependencies by storing it in __init__.py # 2) we can import it in setup.py for the same reason # 3) we can import it into your module module -__version__ = '0.33.2' +__version__ = '0.33.3' __dbversion__ = '0.33.2' From 3f26c8b43add8f13eb51e5091044b455c3ef651e Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 3 Mar 2024 08:09:54 +0100 Subject: [PATCH 093/460] {wf] fixes in upgrade tests --- .github/workflows/upgrade_tests..yml | 8 ++++---- docs/install_rpm.md | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/upgrade_tests..yml b/.github/workflows/upgrade_tests..yml index 2a8b800e..9e376be9 100644 --- a/.github/workflows/upgrade_tests..yml +++ b/.github/workflows/upgrade_tests..yml @@ -608,7 +608,7 @@ jobs: - name: "Retrieve rpms from SBOM repo" run: | git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom - cp /tmp/sbom/rpm-repo/RPMs/*el9*.rpm data + cp /tmp/sbom/rpm-repo/RPMs/rhel9/*.rpm data env: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} @@ -793,7 +793,7 @@ jobs: - name: "Retrieve rpms from SBOM repo" run: | git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom - cp /tmp/sbom/rpm-repo/RPMs/*el9*.rpm data + cp /tmp/sbom/rpm-repo/RPMs/rhel9/*.rpm data env: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} @@ -958,7 +958,7 @@ jobs: - name: "Retrieve rpms from SBOM repo" run: | git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom - cp /tmp/sbom/rpm-repo/RPMs/*el9*.rpm data + cp /tmp/sbom/rpm-repo/RPMs/rhel9/*.rpm data env: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} @@ -1151,7 +1151,7 @@ jobs: - name: "Retrieve rpms from SBOM repo" run: | git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom - cp /tmp/sbom/rpm-repo/RPMs/*el9*.rpm data + cp /tmp/sbom/rpm-repo/RPMs/rhel9/*.rpm data env: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} diff --git a/docs/install_rpm.md b/docs/install_rpm.md index ab5749f0..d88cb9fd 100644 --- a/docs/install_rpm.md +++ b/docs/install_rpm.md @@ -29,7 +29,6 @@ Backports of these packages being part of RHEL9 can be found in the [the a2c rpm - [python3-dns-2.1.0-6.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/rhel8/python3-dns-2.1.0-6.el8.noarch.rpm) - [python3-jwcrypto-0.8-4.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/rhel8/python3-jwcrypto-0.8-4.el8.noarch.rpm) - Depending on your ca_handler you may need additional modules: - [python3-impacket-0.11.0-1.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/rhel8/python3-impacket-0.11.0-1.el8.noarch.rpm) when using [MS wcce handler](https://github.com/grindsa/acme2certifier/blob/master/docs/mswcce.md) From 226fe5e49a1610743cdb2c0070ced87bfa4210e7 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 3 Mar 2024 08:21:17 +0100 Subject: [PATCH 094/460] [rel] version bump --- CHANGES.md | 13 +++++++++++++ acme_srv/version.py | 4 ++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 131b5714..adfbfea7 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,6 +5,19 @@ This is a high-level summary of the most important changes. For a full list of changes, see the [git commit log](https://github.com/grindsa/acme2certifier/commits) and pick the appropriate release branch. +# Changes in 0.33.2 + +**Upgrade notes**: + +- database scheme gets updated. Please run either + - `tools/db_update.py` when using the wsgi_handler or + - `tools/django_update.py` in case you are using the django_handler + +**Bugfixes**: + +- [134](https://github.com/grindsa/acme2certifier/issues/134) - acme_srv_housekeeping" -> value too long for "name" field +- [135](https://github.com/grindsa/acme2certifier/issues/134) - acme_srv_housekeeping dbversion ist set back to 0.23.1 after container restart + # Changes in 0.33.1 **Bugfixes**: diff --git a/acme_srv/version.py b/acme_srv/version.py index e2879d3c..163eeff4 100644 --- a/acme_srv/version.py +++ b/acme_srv/version.py @@ -3,5 +3,5 @@ # 1) we don't load dependencies by storing it in __init__.py # 2) we can import it in setup.py for the same reason # 3) we can import it into your module module -__version__ = '0.33.1' -__dbversion__ = '0.33' +__version__ = '0.33.2' +__dbversion__ = '0.33.2' From 595974365ea67dec5a11c5e3e85d10533493caae Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 3 Mar 2024 08:21:59 +0100 Subject: [PATCH 095/460] [doc] install_rpm update --- docs/install_rpm.md | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/docs/install_rpm.md b/docs/install_rpm.md index 8c3ec5f5..d88cb9fd 100644 --- a/docs/install_rpm.md +++ b/docs/install_rpm.md @@ -17,7 +17,24 @@ $ sudo yum update -y $ sudo yum -y localinstall /tmp/acme2certifier/acme2certifier-0.23.1-1.0.noarch.rpm ``` -In case you install on Redhat 8.x you need to upgrade the [python3-jwcrypto package](https://jwcrypto.readthedocs.io/en/latest/) to version 0.8 or higher. A backport of the package being part of [RHEL9](https://rpmfind.net/linux/RPM/centos-stream/9/appstream/x86_64/python3-jwcrypto-0.8-4.el9.noarch.html) can be found in the [the a2c rpm repository](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/python3-jwcrypto-0.8-4.el8.noarch.rpm) +In case you install on Redhat 8.x you need to upgrade following packages + +- [python3-cryptography](https://cryptography.io/en/latest/) to version 36.0.1 or higher +- [python3-dns](https://www.dnspython.org/) to version 2.1 or higher. +- [python3-jwcrypto package](https://jwcrypto.readthedocs.io/en/latest/) to version 0.8 or higher. + +Backports of these packages being part of RHEL9 can be found in the [the a2c rpm repository](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/) + +- [rpm-repo/RPMs/python3-cryptography-36.0.1-4.el8.x86_64.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/rhel8/python3-cryptography-36.0.1-4.el8.x86_64.rpm) +- [python3-dns-2.1.0-6.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/rhel8/python3-dns-2.1.0-6.el8.noarch.rpm) +- [python3-jwcrypto-0.8-4.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/rhel8/python3-jwcrypto-0.8-4.el8.noarch.rpm) + +Depending on your ca_handler you may need additional modules: + +- [python3-impacket-0.11.0-1.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/rhel8/python3-impacket-0.11.0-1.el8.noarch.rpm) when using [MS wcce handler](https://github.com/grindsa/acme2certifier/blob/master/docs/mswcce.md) +- [python3-ntlm-auth-1.5.0-2.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/rhel8/python3-ntlm-auth-1.5.0-2.el8.noarch.rpm) when using [MS wse handler](https://github.com/grindsa/acme2certifier/blob/master/docs/mscertsrv.md) +- [python3-requests_ntlm-1.1.0-14.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/rhel8/python3-requests_ntlm-1.1.0-14.el8.noarch.rpm) when using [MS wse handler](https://github.com/grindsa/acme2certifier/blob/master/docs/mscertsrv.md) +- [python3-requests-pkcs12-1.16-1.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/rhel8/python3-requests-pkcs12-1.16-1.el8.noarch.rpm) when using [EST](https://github.com/grindsa/acme2certifier/blob/master/docs/est.md) or [EJBCA](https://github.com/grindsa/acme2certifier/blob/master/docs/ejbca.md) handler 4. Copy NGINX configuration file From 5fe35ca507e5b620f51b7165cad70a9702f77038 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 3 Mar 2024 08:38:25 +0100 Subject: [PATCH 096/460] [fix] linting --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index aca74210..db5e8bd5 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,10 +8,10 @@ and pick the appropriate release branch. # Changes in 0.33.3 **Features and Improvements**: + - some smaller modifications run flawless on Redhat8 and derivates - Workflows to test rpm-deployment on RHEL8 and RHEL9 - # Changes in 0.33.2 **Upgrade notes**: From bccff41c0be482b45df7e8af6ed4285138e1815c Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 3 Mar 2024 08:44:14 +0100 Subject: [PATCH 097/460] bump --- .github/workflows/alpn-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/alpn-test.yml b/.github/workflows/alpn-test.yml index e8c79ec0..71f329b6 100644 --- a/.github/workflows/alpn-test.yml +++ b/.github/workflows/alpn-test.yml @@ -166,7 +166,7 @@ jobs: docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ sudo rm ${{ github.workspace }}/artifact/data/*.rpm - sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + # sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log From 2896ba3007c8c8b6e1dff671a6a8aec64d922bc0 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 3 Mar 2024 08:46:12 +0100 Subject: [PATCH 098/460] [fix] revert change --- .github/workflows/alpn-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/alpn-test.yml b/.github/workflows/alpn-test.yml index 71f329b6..e8c79ec0 100644 --- a/.github/workflows/alpn-test.yml +++ b/.github/workflows/alpn-test.yml @@ -166,7 +166,7 @@ jobs: docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ sudo rm ${{ github.workspace }}/artifact/data/*.rpm - # sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log From 6e5a516c51457952b4e9b25d3296ae8c759671c4 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 3 Mar 2024 08:57:32 +0100 Subject: [PATCH 099/460] [rel] bump to v0.33.3 --- docs/install_rpm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/install_rpm.md b/docs/install_rpm.md index d88cb9fd..63b5185a 100644 --- a/docs/install_rpm.md +++ b/docs/install_rpm.md @@ -1,5 +1,5 @@ - + # RPM installation on AlmaLinux/Redhat EL/CentOS Stream 9 1. Download the latest [RPM package](https://github.com/grindsa/acme2certifier/releases). From ad8d2cb5164bc1b46b29987e25f7c0bb84b47b04 Mon Sep 17 00:00:00 2001 From: grindsa Date: Mon, 4 Mar 2024 06:32:40 +0100 Subject: [PATCH 100/460] [wf] workflows for rh8 testing --- .github/workflows/alpn-test.yml | 39 +- .github/workflows/ari-test.yml | 270 +++++++++++ .../workflows/ca_handler_tests_certifier.yml | 22 +- .github/workflows/ca_handler_tests_nclm.yml | 24 +- .github/workflows/django_tests..yml | 56 ++- .github/workflows/dns-test.yml | 22 +- .github/workflows/eab-test.yml | 227 ++++++++- .github/workflows/enrollment-timeout.yml | 430 +++++++++++++++++- .github/workflows/hooks-test.yml | 48 +- .github/workflows/ip-address-tests.yml | 260 +++++++++++ .github/workflows/ipv6-test.yml | 279 ++++++++++++ .github/workflows/proxy-test.yml | 14 +- .github/workflows/tnauth-test.yml | 18 +- .github/workflows/wsgi_handler-test.yml | 131 +++++- 14 files changed, 1792 insertions(+), 48 deletions(-) diff --git a/.github/workflows/alpn-test.yml b/.github/workflows/alpn-test.yml index 575478cf..3b08611f 100644 --- a/.github/workflows/alpn-test.yml +++ b/.github/workflows/alpn-test.yml @@ -91,9 +91,14 @@ jobs: name: alpn.tar.gz path: ${{ github.workspace }}/artifact/upload/ + alpn_apache2_wsgi_rpm: name: "alpn_apache2_wsgi_rpm" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -109,11 +114,6 @@ jobs: sudo sed -i "s/__version__/${{ env.TAG_NAME }}/g" examples/install_scripts/rpm/acme2certifier.spec cat examples/install_scripts/rpm/acme2certifier.spec - - name: "[ PREPARE ] create letsencrypt and lego folder" - run: | - mkdir acmme-sh - mkdir lego - - name: build RPM package id: rpm uses: grindsa/rpmbuild@alma9 @@ -130,6 +130,19 @@ jobs: sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data + - name: "[ PREPARE ] create letsencrypt and lego folder" + run: | + mkdir acmme-sh + mkdir lego + + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + - name: "[ PREPARE ] setup a2c with certifier_ca_handler" run: | mkdir -p data/acme_ca @@ -153,7 +166,9 @@ jobs: - name: "[ PREPARE ] Almalinux instance" run: | - cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - name: "[ RUN ] Execute install scipt" @@ -178,19 +193,23 @@ jobs: docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --tls run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | mkdir -p ${{ github.workspace }}/artifact/upload docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + # sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log # acme-sh - name: "[ * ] uploading artificates" uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: alpn-rpm.tar.gz - path: ${{ github.workspace }}/artifact/upload/ \ No newline at end of file + name: alpn-rpm-rh${{ matrix.rhversion }}.tar.gz + path: ${{ github.workspace }}/artifact/upload/ diff --git a/.github/workflows/ari-test.yml b/.github/workflows/ari-test.yml index b48194fe..0cc05ace 100644 --- a/.github/workflows/ari-test.yml +++ b/.github/workflows/ari-test.yml @@ -342,3 +342,273 @@ jobs: with: name: ari_nginx_django.tar.gz path: ${{ github.workspace }}/artifact/upload/ + + + ari_wsgi_rpm: + name: "ari_wsgi_rpm" + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] + steps: + - name: "checkout GIT" + uses: actions/checkout@v4 + + - name: Retrieve Version from version.py + run: | + echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV + - run: echo "Latest tag is ${{ env.TAG_NAME }}" + + - name: update version number in spec file + run: | + # sudo sed -i "s/Source0:.*/Source0: %{name}-%{version}.tar.gz/g" examples/install_scripts/rpm/acme2certifier.spec + sudo sed -i "s/__version__/${{ env.TAG_NAME }}/g" examples/install_scripts/rpm/acme2certifier.spec + cat examples/install_scripts/rpm/acme2certifier.spec + + - name: build RPM package + id: rpm + uses: grindsa/rpmbuild@alma9 + with: + spec_file: "examples/install_scripts/rpm/acme2certifier.spec" + + - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" + + - name: "[ PREPARE ] setup environment for alma installation" + run: | + docker network create acme + sudo mkdir -p data + sudo chmod -R 777 data + sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data + sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data + + - name: "[ PREPARE ] create lego folder" + run: | + mkdir lego + + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + + - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + run: | + mkdir -p data/acme_ca + sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem + sudo touch data/acme_srv.cfg + sudo chmod 777 data/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/acme_srv.cfg + sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> data/acme_srv.cfg + sudo echo "api_host: $NCM_API_HOST" >> data/acme_srv.cfg + sudo echo "api_user: $NCM_API_USER" >> data/acme_srv.cfg + sudo echo "api_password: $NCM_API_PASSWORD" >> data/acme_srv.cfg + sudo echo "ca_name: $NCM_CA_NAME" >> data/acme_srv.cfg + sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> data/acme_srv.cfg + sudo echo "profile_id: 101" >> data/acme_srv.cfg + sudo echo -e "\n\n[Renewalinfo]" >> data/acme_srv.cfg + sudo echo "renewal_force: True" >> data/acme_srv.cfg + + env: + NCM_API_HOST: ${{ secrets.NCM_API_HOST }} + NCM_API_USER: ${{ secrets.NCM_API_USER }} + NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} + NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} + NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} + + - name: "[ PREPARE ] Almalinux instance" + run: | + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd + + - name: "[ RUN ] Execute install scipt" + run: | + docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh + + - name: "[ ENROLL ] HTTP-01 single domain lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + sudo chmod 777 lego/certificates/lego.acme.issuer.crt + sudo cp lego/certificates/lego.acme.issuer.crt lego.acme.issuer.crt + sudo awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < lego.acme.issuer.crt + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + + - name: "[ RENEW ] HTTP-01 single domain lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep 2> ari.txt + grep "renewalInfo endpoint indicates that renewal is needed" ari.txt + cat ari.txt + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + + - name: "[ * ] collecting test logs" + if: ${{ failure() }} + run: | + mkdir -p ${{ github.workspace }}/artifact/upload + docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier + sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf + docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log lego + + - name: "[ * ] uploading artificates" + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: ari_wsgi_rpm-rh${{ matrix.rhversion }}.tar.gz + path: ${{ github.workspace }}/artifact/upload/ + + + ari_django_rpm: + name: "ari_django_rpm" + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] + steps: + - name: "checkout GIT" + uses: actions/checkout@v4 + + - name: Retrieve Version from version.py + run: | + echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV + - run: echo "Latest tag is ${{ env.TAG_NAME }}" + + - name: update version number in spec file and path in nginx ssl config + run: | + sudo sed -i "s/__version__/${{ env.TAG_NAME }}/g" examples/install_scripts/rpm/acme2certifier.spec + sudo sed -i "s/\/var\/www\/acme2certifier\/volume/\/etc\/nginx/g" examples/nginx/nginx_acme_srv_ssl.conf + git config --global user.email "grindelsack@gmail.com" + git config --global user.name "rpm update" + git add examples/nginx + git commit -a -m "rpm update" + + - name: build RPM package + id: rpm + uses: grindsa/rpmbuild@alma9 + with: + spec_file: "examples/install_scripts/rpm/acme2certifier.spec" + + - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" + + - name: "[ PREPARE ] setup environment for alma installation" + run: | + docker network create acme + sudo mkdir -p data/volume + sudo mkdir -p data/acme2certifier + sudo mkdir -p data/nginx + sudo chmod -R 777 data + sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data + sudo cp examples/Docker/almalinux-systemd/django_tester.sh data + sudo cp .github/acme2certifier_cert.pem data/nginx/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem data/nginx/acme2certifier_key.pem + sudo cp .github/django_settings.py data/acme2certifier/settings.py + sudo sed -i "s/\/var\/www\//\/opt\//g" data/acme2certifier/settings.py + sudo sed -i "s/USE_I18N = True/USE_I18N = False/g" data/acme2certifier/settings.py + + - name: "[ PREPARE ] create lego folder" + run: | + mkdir lego + + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + + - name: "[ PREPARE ] prepare acme_srv.cfg with openssl_ca_handler" + run: | + sudo mkdir -p data/volume/acme_ca/certs + sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem data/volume/acme_ca/ + sudo cp .github/openssl_ca_handler.py_acme_srv_choosen_handler.cfg data/volume/acme_srv.cfg + sudo chmod 777 data/volume/acme_srv.cfg + sudo echo -e "\n\n[Renewalinfo]" >> data/volume/acme_srv.cfg + sudo echo "renewal_force: True" >> data/volume/acme_srv.cfg + + + - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + run: | + mkdir -p data/volume/acme_ca + sudo cp test/ca/certsrv_ca_certs.pem data/volume/acme_ca/ca_certs.pem + sudo touch data/volume/acme_srv.cfg + sudo chmod 777 data/volume/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/volume/acme_srv.cfg + sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> data/volume/acme_srv.cfg + sudo echo "api_host: $NCM_API_HOST" >> data/volume/acme_srv.cfg + sudo echo "api_user: $NCM_API_USER" >> data/volume/acme_srv.cfg + sudo echo "api_password: $NCM_API_PASSWORD" >> data/volume/acme_srv.cfg + sudo echo "ca_name: $NCM_CA_NAME" >> data/volume/acme_srv.cfg + sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> data/volume/acme_srv.cfg + sudo echo "profile_id: 101" >> data/volume/acme_srv.cfg + sudo echo -e "\n\n[Renewalinfo]" >> data/volume/acme_srv.cfg + sudo echo "renewal_force: True" >> data/volume/acme_srv.cfg + env: + NCM_API_HOST: ${{ secrets.NCM_API_HOST }} + NCM_API_USER: ${{ secrets.NCM_API_USER }} + NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} + NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} + NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} + + + - name: "[ PREPARE ] Almalinux instance" + run: | + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + docker run -d -id --privileged --network acme -p 22280:80 --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd + + - name: "[ RUN ] Execute install scipt" + run: | + docker exec acme-srv sh /tmp/acme2certifier/django_tester.sh + + - name: "Test http://acme-srv/directory is accessible" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "[ ENROLL ] HTTP-01 single domain lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + sudo chmod 777 lego/certificates/lego.acme.issuer.crt + sudo cp lego/certificates/lego.acme.issuer.crt lego.acme.issuer.crt + sudo awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < lego.acme.issuer.crt + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + + - name: "[ RENEW ] HTTP-01 single domain lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep 2> ari.txt + grep "renewalInfo endpoint indicates that renewal is needed" ari.txt + cat ari.txt + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + + - name: "[ * ] collecting test logs" + if: ${{ failure() }} + run: | + mkdir -p ${{ github.workspace }}/artifact/upload + docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier + docker exec acme-srv tar cvfz /tmp/acme2certifier/nginx.tgz /etc/nginx + sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf + docker exec acme-srv rpm -qa > ${{ github.workspace }}/artifact/data/packages.txt + docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log lego + + - name: "[ * ] uploading artificates" + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: ari_django_rpm-rh${{ matrix.rhversion }}.tar.gz + path: ${{ github.workspace }}/artifact/upload/ \ No newline at end of file diff --git a/.github/workflows/ca_handler_tests_certifier.yml b/.github/workflows/ca_handler_tests_certifier.yml index f7ba39ad..349b859d 100644 --- a/.github/workflows/ca_handler_tests_certifier.yml +++ b/.github/workflows/ca_handler_tests_certifier.yml @@ -330,6 +330,10 @@ jobs: certifier_handler_tests_rpm: name: "certifier_handler_tests_rpm" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -366,6 +370,14 @@ jobs: mkdir certbot mkdir lego + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + - name: "[ PREPARE ] prepare acme_srv.cfg with certifier_ca_handler" run: | mkdir -p data/acme_ca @@ -388,7 +400,9 @@ jobs: - name: "[ PREPARE ] Almalinux instance" run: | - cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - name: "[ RUN ] Execute install scipt" @@ -445,7 +459,10 @@ jobs: mkdir -p ${{ github.workspace }}/artifact/upload docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh @@ -453,10 +470,9 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: certifier_ca_handler_rpm.tar.gz + name: certifier_ca_handler_rpm-rh${{ matrix.rhversion }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ - certifier_handler_headerinfo_tests: name: "certifier_handler_headerinfo_tests" runs-on: ubuntu-latest diff --git a/.github/workflows/ca_handler_tests_nclm.yml b/.github/workflows/ca_handler_tests_nclm.yml index d1df4ecb..d1b16f2e 100644 --- a/.github/workflows/ca_handler_tests_nclm.yml +++ b/.github/workflows/ca_handler_tests_nclm.yml @@ -128,6 +128,10 @@ jobs: nclm_handler_tests_rpm: name: "nclm_handler_tests_rpm" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -164,6 +168,14 @@ jobs: mkdir certbot mkdir lego + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + - name: "[ PREPARE ] prepare acme_srv.cfg with nclm_ca_handler" run: | mkdir -p data/acme_ca @@ -190,7 +202,9 @@ jobs: - name: "[ PREPARE ] Almalinux instance" run: | - cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - name: "[ RUN ] Execute install scipt" @@ -236,6 +250,9 @@ jobs: docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh @@ -243,5 +260,6 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: nclm_ca_handler_rpm.tar.gz - path: ${{ github.workspace }}/artifact/upload/ \ No newline at end of file + name: nclm_ca_handler_rpm-rh${{ matrix.rhversion }}.tar.gz + path: ${{ github.workspace }}/artifact/upload/ + diff --git a/.github/workflows/django_tests..yml b/.github/workflows/django_tests..yml index 07cb9dee..d31d1a0b 100644 --- a/.github/workflows/django_tests..yml +++ b/.github/workflows/django_tests..yml @@ -496,9 +496,14 @@ jobs: name: nginx-django-psql.tar.gz path: ${{ github.workspace }}/artifact/upload/ + nginx_django_rpm_sqlite: name: "nginx_django_rpm_sqlite" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -543,7 +548,7 @@ jobs: - name: "Retrieve rpms from SBOM repo" run: | git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom - cp /tmp/sbom/rpm-repo/RPMs/*el9*.rpm data + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data env: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} @@ -569,10 +574,11 @@ jobs: NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "[ PREPARE ] Almalinux instance" run: | - cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme -p 22280:80 --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - name: "[ RUN ] Execute install scipt" @@ -629,6 +635,10 @@ jobs: docker exec acme-srv tar cvfz /tmp/acme2certifier/nginx.tgz /etc/nginx sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf + docker exec acme-srv rpm -qa > ${{ github.workspace }}/artifact/data/packages.txt docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh @@ -636,12 +646,16 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: nginx_django_rpm_sqlite.tar.gz + name: nginx_django_rpm_sqlite-rh${{ matrix.rhversion }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ nginx_django_rpm_mariadb: name: "nginx_django_rpm_mariadb" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [9] steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -703,7 +717,7 @@ jobs: - name: "Retrieve rpms from SBOM repo" run: | git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom - cp /tmp/sbom/rpm-repo/RPMs/*el9*.rpm data + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data env: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} @@ -732,7 +746,9 @@ jobs: - name: "[ PREPARE ] Almalinux instance" run: | - cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme -p 22280:80 --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - name: "[ RUN ] Execute install scipt" @@ -788,6 +804,11 @@ jobs: docker exec acme-srv tar cvfz /tmp/acme2certifier/nginx.tgz /etc/nginx sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf + docker exec acme-srv rpm -qa | sort -n > ${{ github.workspace }}/artifact/data/packages.txt + docker exec mariadbsrv mariadb-dump -u root --password=foobar acme2certifier > ${{ github.workspace }}/artifact/data/acme2certifer.sql docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh /tmp/mysql @@ -795,12 +816,16 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: nginx_django_rpm_mariadb.tar.gz + name: nginx_django_rpm_mariadb-rh${{ matrix.rhversion }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ nginx_django_rpm_psql: name: "nginx_django_rpm_psql" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -870,12 +895,11 @@ jobs: - name: "Retrieve rpms from SBOM repo" run: | git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom - cp /tmp/sbom/rpm-repo/RPMs/*el9*.rpm data + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data env: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" run: | sudo mkdir -p acme-sh @@ -900,7 +924,9 @@ jobs: - name: "[ PREPARE ] Almalinux instance" run: | - cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme -p 22280:80 --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - name: "[ RUN ] Execute install scipt" @@ -953,6 +979,10 @@ jobs: docker exec acme-srv tar cvfz /tmp/acme2certifier/nginx.tgz /etc/nginx sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf + docker exec acme-srv rpm -qa > ${{ github.workspace }}/artifact/data/packages.txt docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh /tmp/pgsql @@ -960,5 +990,7 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: nginx_django_rpm_psql.tar.gz - path: ${{ github.workspace }}/artifact/upload/ \ No newline at end of file + name: nginx_django_rpm_psql-rh${{ matrix.rhversion }}.tar.gz + path: ${{ github.workspace }}/artifact/upload/ + + diff --git a/.github/workflows/dns-test.yml b/.github/workflows/dns-test.yml index 8132723d..4a470425 100644 --- a/.github/workflows/dns-test.yml +++ b/.github/workflows/dns-test.yml @@ -130,6 +130,11 @@ jobs: dns_challenge_tests_rpm: name: "dns_challenge_tests_rpm" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] + steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -161,6 +166,14 @@ jobs: sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + - name: "[ PREPARE ] setup a2c with certifier_ca_handler" run: | mkdir -p data/acme_ca @@ -198,7 +211,9 @@ jobs: - name: "[ PREPARE ] Almalinux instance" run: | - cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - name: "[ RUN ] Execute install scipt" @@ -254,7 +269,10 @@ jobs: mkdir -p ${{ github.workspace }}/artifact/upload docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh @@ -262,5 +280,5 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: dns_challenge_tests_rpm.tar.gz + name: dns-rpm-rh${{ matrix.rhversion }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ diff --git a/.github/workflows/eab-test.yml b/.github/workflows/eab-test.yml index 395a57df..de3aac1e 100644 --- a/.github/workflows/eab-test.yml +++ b/.github/workflows/eab-test.yml @@ -142,9 +142,14 @@ jobs: name: eab-${{ matrix.keylength }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ - eab_apache2_wsgi_rpm: - name: "eab_apache2_wsgi_rpm" + + eab_wsgi_rpm: + name: "eab_wsgi_rpm" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -181,6 +186,14 @@ jobs: mkdir certbot mkdir lego + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + - name: "[ PREPARE ] setup a2c with certifier_ca_handler" run: | mkdir -p data/acme_ca @@ -207,7 +220,9 @@ jobs: - name: "[ PREPARE ] Almalinux instance" run: | - cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - name: "[ RUN ] Execute install scipt" @@ -291,6 +306,9 @@ jobs: docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh @@ -298,5 +316,206 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: eab-rpm.tar.gz + name: eab-rpm-rh${{ matrix.rhversion }}.tar.gz + path: ${{ github.workspace }}/artifact/upload/ + + eab_django_rpm: + name: "eab_django_rpm" + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] + steps: + - name: "checkout GIT" + uses: actions/checkout@v4 + + - name: "[ PREPARE ] get runner ip" + run: | + echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV + echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV + - run: echo "runner IP is ${{ env.RUNNER_IP }}" + + - name: Retrieve Version from version.py + run: | + echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV + - run: echo "Latest tag is ${{ env.TAG_NAME }}" + + - name: update version number in spec file and path in nginx ssl config + run: | + sudo sed -i "s/__version__/${{ env.TAG_NAME }}/g" examples/install_scripts/rpm/acme2certifier.spec + sudo sed -i "s/\/var\/www\/acme2certifier\/volume/\/etc\/nginx/g" examples/nginx/nginx_acme_srv_ssl.conf + git config --global user.email "grindelsack@gmail.com" + git config --global user.name "rpm update" + git add examples/nginx + git commit -a -m "rpm update" + + - name: build RPM package + id: rpm + uses: grindsa/rpmbuild@alma9 + with: + spec_file: "examples/install_scripts/rpm/acme2certifier.spec" + + - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" + + - name: "[ PREPARE ] setup environment for alma installation" + run: | + docker network create acme + sudo mkdir -p data/volume + sudo mkdir -p data/acme2certifier + sudo mkdir -p data/nginx + sudo chmod -R 777 data + sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data + sudo cp examples/Docker/almalinux-systemd/django_tester.sh data + sudo cp .github/acme2certifier_cert.pem data/nginx/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem data/nginx/acme2certifier_key.pem + sudo cp .github/django_settings.py data/acme2certifier/settings.py + sudo sed -i "s/\/var\/www\//\/opt\//g" data/acme2certifier/settings.py + sudo sed -i "s/USE_I18N = True/USE_I18N = False/g" data/acme2certifier/settings.py + + - name: "[ PREPARE ] create lego folder" + run: | + mkdir lego + + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + + - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + run: | + mkdir -p data/volume/acme_ca + sudo cp test/ca/certsrv_ca_certs.pem data/volume/acme_ca/ca_certs.pem + sudo touch data/volume/acme_srv.cfg + sudo chmod 777 data/volume/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/volume/acme_srv.cfg + sudo echo "handler_file: /opt/acme2certifier/examples/ca_handler/certifier_ca_handler.py" >> data/volume/acme_srv.cfg + sudo echo "api_host: $NCM_API_HOST" >> data/volume/acme_srv.cfg + sudo echo "api_user: $NCM_API_USER" >> data/volume/acme_srv.cfg + sudo echo "api_password: $NCM_API_PASSWORD" >> data/volume/acme_srv.cfg + sudo echo "ca_name: $NCM_CA_NAME" >> data/volume/acme_srv.cfg + sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> data/volume/acme_srv.cfg + sudo echo "profile_id: 101" >> data/volume/acme_srv.cfg + sudo echo -e "\n\n[EABhandler]" >> data/volume/acme_srv.cfg + sudo echo "eab_handler_file: /opt/acme2certifier/examples/eab_handler/json_handler.py" >> data/volume/acme_srv.cfg + sudo echo "key_file: /opt/acme2certifier/examples/eab_handler/key_file.json" >> data/volume/acme_srv.cfg + env: + NCM_API_HOST: ${{ secrets.NCM_API_HOST }} + NCM_API_USER: ${{ secrets.NCM_API_USER }} + NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} + NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} + NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} + + - name: "[ PREPARE ] Almalinux instance" + run: | + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + docker run -d -id --privileged --network acme -p 22280:80 --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd + + - name: "[ RUN ] Execute install scipt" + run: | + docker exec acme-srv sh /tmp/acme2certifier/django_tester.sh + + - name: "Test http://acme-srv/directory is accessible" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "[ FAIL ] certbot without eab-credentials" + id: certbotfail + continue-on-error: true + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email + + - name: "[ CHECK ] certbot result " + if: steps.certbotfail.outcome != 'failure' + run: | + echo "certbot outcome is ${{steps.certbotfail.outcome }}" + exit 1 + + - name: "[ REGISTER] certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email --eab-kid keyid_02 --eab-hmac-key=bWFjXzAy + + - name: "[ ENROLL ] HTTP-01 single domain certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot + sudo chmod 777 certbot/archive/certbot/chain1.pem + sudo cp certbot/archive/certbot/chain1.pem chain1.pem + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < chain1.pem + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem + + - name: "[ PREPARE ] prepare acme.sh container" + run: | + docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + + - name: "[ FAIL] acme.sh" + id: acmeshfail + continue-on-error: true + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 + + - name: "[ CHECK ] acme.sh result " + if: steps.acmeshfail.outcome != 'failure' + run: | + echo "acmeshfail outcome is ${{steps.acmeshfail.outcome }}" + exit 1 + + - name: "[ REGISTER] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key bWFjXzAy --debug 3 + + - name: "[ ENROLL] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --debug 3 --output-insecure + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + + - name: "[ FAIL ] lego" + id: legofail + continue-on-error: true + run: | + mkdir lego + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + + - name: "[ CHECK ] lego result " + if: steps.legofail.outcome != 'failure' + run: | + echo "legofail outcome is ${{steps.legofail.outcome }}" + exit 1 + + - name: "[ ENROLL ] lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac bWFjXzAy -d lego.acme --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + + - name: "[ * ] collecting test logs" + if: ${{ failure() }} + run: | + mkdir -p ${{ github.workspace }}/artifact/upload + docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier + docker exec acme-srv tar cvfz /tmp/acme2certifier/nginx.tgz /etc/nginx + sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ + sudo cp -rp lego/ ${{ github.workspace }}/artifact/certbot/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf + docker exec acme-srv rpm -qa > ${{ github.workspace }}/artifact/data/packages.txt + docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log lego certbot + + - name: "[ * ] uploading artificates" + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: eab_django_rpm-rh${{ matrix.rhversion }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ + + + diff --git a/.github/workflows/enrollment-timeout.yml b/.github/workflows/enrollment-timeout.yml index 0630619d..b8e0afb2 100644 --- a/.github/workflows/enrollment-timeout.yml +++ b/.github/workflows/enrollment-timeout.yml @@ -10,7 +10,7 @@ on: jobs: async_enrollment_cert_reusage: - name: "Async_enrollment_cert_reusage" + name: "async_enrollment_cert_reusage" runs-on: ubuntu-latest steps: - name: "checkout GIT" @@ -119,3 +119,431 @@ jobs: with: name: async_enrollment_cert_reusage.tar.gz path: ${{ github.workspace }}/artifact/upload/ + + + ap_django_async_enrollment_cert_reusage: + name: ap_django_async_enrollment_cert_reusage + runs-on: ubuntu-latest + steps: + - name: "checkout GIT" + uses: actions/checkout@v4 + + - name: "Build docker-compose (apache2_django)" + working-directory: examples/Docker/ + run: | + sed -i "s/wsgi/django/g" .env + sudo mkdir -p data + docker network create acme + docker-compose up -d + docker-compose logs + + - name: "Test http://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + run: | + sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem + sudo touch examples/Docker/data/acme_srv.cfg + sudo chmod 777 examples/Docker/data/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg + # sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> examples/Docker/data/acme_srv.cfg + sudo echo "api_host: $NCM_API_HOST" >> examples/Docker/data/acme_srv.cfg + sudo echo "api_user: $NCM_API_USER" >> examples/Docker/data/acme_srv.cfg + sudo echo "api_password: $NCM_API_PASSWORD" >> examples/Docker/data/acme_srv.cfg + sudo echo "ca_name: $NCM_CA_NAME" >> examples/Docker/data/acme_srv.cfg + sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> examples/Docker/data/acme_srv.cfg + sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\\ncert_reusage_timeframe: 300/g" examples/Docker/data/acme_srv.cfg + sudo cp examples/ca_handler/certifier_ca_handler.py examples/Docker/data/ca_handler.py + sudo sed -i "s/ cert_dic = self._cert_get(csr)/ cert_dic = self._cert_get(csr)\\n time.sleep(30)/g" examples/Docker/data/ca_handler.py + sudo cp .github/django_settings.py examples/Docker/data/settings.py + cd examples/Docker/ + docker-compose restart + docker-compose logs + env: + NCM_API_HOST: ${{ secrets.NCM_API_HOST }} + NCM_API_USER: ${{ secrets.NCM_API_USER }} + NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} + NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} + NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} + + - name: "[ PREPARE ] prepare acme.sh container" + run: | + docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + + - name: "[ ENROLL ] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh//acme-sh.acme/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + + - name: "[ VERIFY ] Check timeout" + working-directory: examples/Docker/ + run: | + docker-compose logs | grep "Certificate.enroll_and_store() ended with: None:timeout" + sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) + + - name: "[ ENROLL ] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force + + - name: "[ VERIFY ] Check certificate reusage" + working-directory: examples/Docker/ + run: | + docker-compose logs | grep "Certificate._enroll(): reuse existing certificate" + + - name: "[ ENROL] lego" + run: | + mkdir lego + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --cert.timeout 150 --http run + + - name: "[ VERIFY ] Check timeout" + working-directory: examples/Docker/ + run: | + docker-compose logs | grep "Certificate.enroll_and_store() ended with: None:timeout" + sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) + + - name: "[ REGISTER ] certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email + + - name: "[ ENROLL ] certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot + + - name: "[ VERIFY ] Check timeout" + working-directory: examples/Docker/ + run: | + docker-compose logs | grep "Certificate.enroll_and_store() ended with: None:timeout" + sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) + + - name: "[ * ] collecting test data" + if: ${{ failure() }} + run: | + mkdir -p ${{ github.workspace }}/artifact/upload + sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ + sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + cd examples/Docker + docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh + + - name: "[ * ] uploading artifacts" + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: ap_django_async_enrollment_cert_reusage.tar.gz + path: ${{ github.workspace }}/artifact/upload/ + + rpm_wsgi_async_enrollment_cert_reusage: + name: "rpm_wsgi_async_enrollment_cert_reusage" + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] + steps: + - name: "checkout GIT" + uses: actions/checkout@v4 + + - name: Retrieve Version from version.py + run: | + echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV + - run: echo "Latest tag is ${{ env.TAG_NAME }}" + + - name: update version number in spec file + run: | + # sudo sed -i "s/Source0:.*/Source0: %{name}-%{version}.tar.gz/g" examples/install_scripts/rpm/acme2certifier.spec + sudo sed -i "s/__version__/${{ env.TAG_NAME }}/g" examples/install_scripts/rpm/acme2certifier.spec + cat examples/install_scripts/rpm/acme2certifier.spec + + - name: build RPM package + id: rpm + uses: grindsa/rpmbuild@alma9 + with: + spec_file: "examples/install_scripts/rpm/acme2certifier.spec" + + - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" + + - name: "[ PREPARE ] setup environment for alma installation" + run: | + docker network create acme + sudo mkdir -p data + sudo chmod -R 777 data + sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data + sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data + + - name: "[ PREPARE ] create lego and certbot folder" + run: | + mkdir lego + mkdir certbot + + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + + - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + run: | + mkdir -p data/acme_ca + sudo cp test/ca/certsrv_ca_certs.pem data/ca_certs.pem + sudo touch data/acme_srv.cfg + sudo chmod 777 data/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/acme_srv.cfg + sudo echo "handler_file: /opt/acme2certifier/volume/acme_ca/ca_handler.py" >> data/acme_srv.cfg + sudo echo "api_host: $NCM_API_HOST" >> data/acme_srv.cfg + sudo echo "api_user: $NCM_API_USER" >> data/acme_srv.cfg + sudo echo "api_password: $NCM_API_PASSWORD" >> data/acme_srv.cfg + sudo echo "ca_name: $NCM_CA_NAME" >> data/acme_srv.cfg + sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> data/acme_srv.cfg + sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\\ncert_reusage_timeframe: 1800/g" data/acme_srv.cfg + sudo sed -i "s/retry_after_timeout: 15/retry_after_timeout: 30\\nenrollment_timeout: 15/g" data/acme_srv.cfg + sudo cp examples/ca_handler/certifier_ca_handler.py data/acme_ca/ca_handler.py + sudo sed -i "s/ self.logger.debug('Certificate.enroll() ended')/ time.sleep(22)\\n self.logger.debug('Certificate.enroll() ended')/g" data/acme_ca/ca_handler.py + sudo sed -i "s/ self.logger.debug('CAhandler.enroll() ended')/ time.sleep(22)\\n self.logger.debug('CAhandler.enroll() ended')/g" data/acme_ca/ca_handler.py + env: + NCM_API_HOST: ${{ secrets.NCM_API_HOST }} + NCM_API_USER: ${{ secrets.NCM_API_USER }} + NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} + NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} + NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} + + - name: "[ PREPARE ] Almalinux instance" + run: | + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd + + - name: "[ RUN ] Execute install scipt" + run: | + docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh + + - name: "[ PREPARE ] prepare acme.sh container" + run: | + docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + + - name: "[ ENROLL ] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure + + - name: "[ VERIFY ] Check timeout" + run: | + docker exec acme-srv grep "Certificate.enroll_and_store() ended with: None:timeout" /var/log/messages + + - name: "[ ENROLL ] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force + + - name: "[ VERIFY ] Check certificate reusage" + run: | + docker exec acme-srv grep "Certificate._enroll(): reuse existing certificate" /var/log/messages + + - name: "[ * ] collecting test logs" + if: ${{ failure() }} + run: | + mkdir -p ${{ github.workspace }}/artifact/upload + docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier + sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf + docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log + + - name: "[ * ] uploading artificates" + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: rpm_wsgi_async_enrollment_cert_reusage-rh${{ matrix.rhversion }}.tar.gz + path: ${{ github.workspace }}/artifact/upload/ + + + rpm_django_async_enrollment_cert_reusage: + name: "rpm_django_async_enrollment_cert_reusage" + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] + steps: + - name: "checkout GIT" + uses: actions/checkout@v4 + + - name: "[ PREPARE ] get runner ip" + run: | + echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV + echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV + - run: echo "runner IP is ${{ env.RUNNER_IP }}" + + - name: "[ PREPARE ] postgres environment" + run: | + docker network create acme + sudo mkdir -p examples/Docker/data/pgsql/ + sudo cp .github/a2c.psql examples/Docker/data/pgsql/a2c.psql + sudo cp .github/pgpass examples/Docker/data/pgsql/pgpass + sudo chmod 600 examples/Docker/data/pgsql/pgpass + + - name: "[ PREPARE ] postgres environment" + run: | + sudo cp .github/a2c.psql examples/Docker/data/pgsql/a2c.psql + sudo cp .github/pgpass examples/Docker/data/pgsql/pgpass + sudo chmod 600 examples/Docker/data/pgsql/pgpass + + - name: "[ PREPARE ] install postgres" + working-directory: examples/Docker/ + run: | + docker run --name postgresdbsrv --network acme -e POSTGRES_PASSWORD=foobar -d postgres + + - name: "[ PREPARE ] Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "[ PREPARE ] configure postgres" + working-directory: examples/Docker/ + run: | + docker run -v "$(pwd)/data/pgsql/a2c.psql":/tmp/a2c.psql -v "$(pwd)/data/pgsql/pgpass:/root/.pgpass" --rm --network acme postgres psql -U postgres -h postgresdbsrv -f /tmp/a2c.psql + + - name: "[ PREPARE ] Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: Retrieve Version from version.py + run: | + echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV + - run: echo "Latest tag is ${{ env.TAG_NAME }}" + + - name: update version number in spec file and path in nginx ssl config + run: | + sudo sed -i "s/__version__/${{ env.TAG_NAME }}/g" examples/install_scripts/rpm/acme2certifier.spec + sudo sed -i "s/\/var\/www\/acme2certifier\/volume/\/etc\/nginx/g" examples/nginx/nginx_acme_srv_ssl.conf + git config --global user.email "grindelsack@gmail.com" + git config --global user.name "rpm update" + git add examples/nginx + git commit -a -m "rpm update" + + - name: build RPM package + id: rpm + uses: grindsa/rpmbuild@alma9 + with: + spec_file: "examples/install_scripts/rpm/acme2certifier.spec" + + - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" + + - name: "[ PREPARE ] setup environment for alma installation" + run: | + sudo mkdir -p data/volume + sudo mkdir -p data/acme2certifier + sudo mkdir -p data/nginx + sudo chmod -R 777 data + sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data + sudo cp examples/Docker/almalinux-systemd/django_tester.sh data + sudo cp .github/acme2certifier_cert.pem data/nginx/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem data/nginx/acme2certifier_key.pem + sudo cp .github/django_settings_psql.py data/acme2certifier/settings.py + sudo sed -i "s/USE_I18N = True/USE_I18N = False/g" data/acme2certifier/settings.py + + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + + - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + run: | + sudo cp test/ca/certsrv_ca_certs.pem data/volume/ca_certs.pem + sudo touch data/volume/acme_srv.cfg + sudo chmod 777 data/volume/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/volume/acme_srv.cfg + sudo echo "handler_file: /opt/acme2certifier/volume/ca_handler.py" >> data/volume/acme_srv.cfg + sudo echo "api_host: $NCM_API_HOST" >> data/volume/acme_srv.cfg + sudo echo "api_user: $NCM_API_USER" >> data/volume/acme_srv.cfg + sudo echo "api_password: $NCM_API_PASSWORD" >> data/volume/acme_srv.cfg + sudo echo "ca_name: $NCM_CA_NAME" >> data/volume/acme_srv.cfg + sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> data/volume/acme_srv.cfg + sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\\ncert_reusage_timeframe: 1800/g" data/volume/acme_srv.cfg + sudo sed -i "s/retry_after_timeout: 15/retry_after_timeout: 30\\nenrollment_timeout: 15/g" data/volume/acme_srv.cfg + sudo cp examples/ca_handler/certifier_ca_handler.py data/volume/ca_handler.py + sudo sed -i "s/ self.logger.debug('Certificate.enroll() ended')/ time.sleep(22)\\n self.logger.debug('Certificate.enroll() ended')/g" data/volume/ca_handler.py + sudo sed -i "s/ self.logger.debug('CAhandler.enroll() ended')/ time.sleep(22)\\n self.logger.debug('CAhandler.enroll() ended')/g" data/volume/ca_handler.py + env: + NCM_API_HOST: ${{ secrets.NCM_API_HOST }} + NCM_API_USER: ${{ secrets.NCM_API_USER }} + NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} + NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} + NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} + + - name: "[ PREPARE ] Almalinux instance" + run: | + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + docker run -d -id --privileged --network acme -p 22280:80 --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd + + - name: "[ RUN ] Execute install scipt" + run: | + docker exec acme-srv sh /tmp/acme2certifier/django_tester.sh + + - name: "Test http://acme-srv/directory is accessible" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + + - name: "[ PREPARE ] prepare acme.sh container" + run: | + docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + + - name: "[ ENROLL ] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure + + - name: "[ PREPARE ] Sleep for 5s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 5s + + - name: "[ VERIFY ] Check timeout" + run: | + docker exec acme-srv grep "Certificate.enroll_and_store() ended with: None:timeout" /var/log/messages + + - name: "[ ENROLL ] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force + + - name: "[ PREPARE ] Sleep for 5s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 5s + + - name: "[ VERIFY ] Check certificate reusage" + run: | + docker exec acme-srv grep "Certificate._enroll(): reuse existing certificate" /var/log/messages + + - name: "[ * ] collecting test logs" + if: ${{ failure() }} + run: | + mkdir -p ${{ github.workspace }}/artifact/upload + docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier + docker exec acme-srv tar cvfz /tmp/acme2certifier/nginx.tgz /etc/nginx + sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec postgresdbsrv pg_dump -U postgres acme2certifier > data/acme2certifier.sql + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf + docker exec acme-srv rpm -qa > ${{ github.workspace }}/artifact/data/packages.txt + docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log + + - name: "[ * ] uploading artificates" + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: rpm_django_async_enrollment_cert_reusage-rh${{ matrix.rhversion }}.tar.gz + path: ${{ github.workspace }}/artifact/upload/ \ No newline at end of file diff --git a/.github/workflows/hooks-test.yml b/.github/workflows/hooks-test.yml index 67459094..ca39360b 100644 --- a/.github/workflows/hooks-test.yml +++ b/.github/workflows/hooks-test.yml @@ -118,6 +118,10 @@ jobs: hooks_test_rpm: name: "hooks_test_rpm" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -154,6 +158,14 @@ jobs: mkdir acmme-sh mkdir lego + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + - name: "[ PREPARE ] setup a2c with certifier_ca_handler" run: | mkdir -p data/acme_ca @@ -184,7 +196,9 @@ jobs: - name: "[ PREPARE ] Almalinux instance" run: | - cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - name: "[ RUN ] Execute install scipt" @@ -236,6 +250,9 @@ jobs: docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh @@ -243,7 +260,7 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: hooks-rpm.tar.gz + name: hooks-rpm-rh${{ matrix.rhversion }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ hooks_exception_handling: @@ -425,11 +442,14 @@ jobs: hooks_exception_handling_rpm: name: "hooks_exception_handling_rpm" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: Retrieve Version from version.py run: | echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV @@ -462,6 +482,14 @@ jobs: mkdir acmme-sh mkdir lego + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + - name: "[ PREPARE ] setup a2c with certifier_ca_handler" run: | mkdir -p data/acme_ca @@ -493,7 +521,9 @@ jobs: - name: "[ PREPARE ] Almalinux instance" run: | - cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - name: "[ RUN ] Execute install scipt" @@ -503,6 +533,7 @@ jobs: - name: "Test http://acme-srv/directory is accessible" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + - name: "[ PREPARE ] prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon @@ -607,6 +638,9 @@ jobs: docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh @@ -614,5 +648,7 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: hooks-rpm.tar.gz - path: ${{ github.workspace }}/artifact/upload/ \ No newline at end of file + name: hooks-rpm-rh${{ matrix.rhversion }}.tar.gz + path: ${{ github.workspace }}/artifact/upload/ + + diff --git a/.github/workflows/ip-address-tests.yml b/.github/workflows/ip-address-tests.yml index 152bc37a..28b2e3b0 100644 --- a/.github/workflows/ip-address-tests.yml +++ b/.github/workflows/ip-address-tests.yml @@ -364,3 +364,263 @@ jobs: with: name: ip_nginx_django.tar.gz path: ${{ github.workspace }}/artifact/upload/ + + ip_wsgi_rpm: + name: "ip_wsgi_rpm" + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] + steps: + - name: "checkout GIT" + uses: actions/checkout@v4 + + - name: "[ PREPARE ] get runner ip" + run: | + echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV + echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV + - run: echo "runner IP is ${{ env.RUNNER_IP }}" + + - name: Retrieve Version from version.py + run: | + echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV + - run: echo "Latest tag is ${{ env.TAG_NAME }}" + + - name: update version number in spec file + run: | + # sudo sed -i "s/Source0:.*/Source0: %{name}-%{version}.tar.gz/g" examples/install_scripts/rpm/acme2certifier.spec + sudo sed -i "s/__version__/${{ env.TAG_NAME }}/g" examples/install_scripts/rpm/acme2certifier.spec + cat examples/install_scripts/rpm/acme2certifier.spec + + - name: build RPM package + id: rpm + uses: grindsa/rpmbuild@alma9 + with: + spec_file: "examples/install_scripts/rpm/acme2certifier.spec" + + - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" + + - name: "[ PREPARE ] setup environment for alma installation" + run: | + docker network create acme + sudo mkdir -p data + sudo chmod -R 777 data + sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data + sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data + + - name: "[ PREPARE ] create lego folder" + run: | + mkdir lego + + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + + - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + run: | + mkdir -p data/acme_ca + sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem + sudo touch data/acme_srv.cfg + sudo chmod 777 data/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/acme_srv.cfg + sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> data/acme_srv.cfg + sudo echo "api_host: $NCM_API_HOST" >> data/acme_srv.cfg + sudo echo "api_user: $NCM_API_USER" >> data/acme_srv.cfg + sudo echo "api_password: $NCM_API_PASSWORD" >> data/acme_srv.cfg + sudo echo "ca_name: $NCM_CA_NAME" >> data/acme_srv.cfg + sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> data/acme_srv.cfg + sudo echo "profile_id: 101" >> data/acme_srv.cfg + env: + NCM_API_HOST: ${{ secrets.NCM_API_HOST }} + NCM_API_USER: ${{ secrets.NCM_API_USER }} + NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} + NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} + NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} + + - name: "[ PREPARE ] Almalinux instance" + run: | + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd + + - name: "[ RUN ] Execute install scipt" + run: | + docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh + + - name: "Enroll HTTP-01 single domain and ip address " + run: | + docker run -i -p 80:80 -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme -d $RUNNER_IP --http run + sudo chmod 777 lego/certificates/lego.acme.issuer.crt + sudo cp lego/certificates/lego.acme.issuer.crt lego.acme.issuer.crt + sudo awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < lego.acme.issuer.crt + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt --text --noout | grep "IP Address" + env: + RUNNER_IP: ${{ env.RUNNER_IP }} + + - name: "[ * ] collecting test logs" + if: ${{ failure() }} + run: | + mkdir -p ${{ github.workspace }}/artifact/upload + docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier + sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf + docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log lego + + - name: "[ * ] uploading artificates" + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: ip_wsgi_rpm-rh${{ matrix.rhversion }}.tar.gz + path: ${{ github.workspace }}/artifact/upload/ + + + ip_django_rpm: + name: "ip_django_rpm" + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] + steps: + - name: "checkout GIT" + uses: actions/checkout@v4 + + - name: "[ PREPARE ] get runner ip" + run: | + echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV + echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV + - run: echo "runner IP is ${{ env.RUNNER_IP }}" + + - name: Retrieve Version from version.py + run: | + echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV + - run: echo "Latest tag is ${{ env.TAG_NAME }}" + + - name: update version number in spec file and path in nginx ssl config + run: | + sudo sed -i "s/__version__/${{ env.TAG_NAME }}/g" examples/install_scripts/rpm/acme2certifier.spec + sudo sed -i "s/\/var\/www\/acme2certifier\/volume/\/etc\/nginx/g" examples/nginx/nginx_acme_srv_ssl.conf + git config --global user.email "grindelsack@gmail.com" + git config --global user.name "rpm update" + git add examples/nginx + git commit -a -m "rpm update" + + - name: build RPM package + id: rpm + uses: grindsa/rpmbuild@alma9 + with: + spec_file: "examples/install_scripts/rpm/acme2certifier.spec" + + - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" + + - name: "[ PREPARE ] setup environment for alma installation" + run: | + docker network create acme + sudo mkdir -p data/volume + sudo mkdir -p data/acme2certifier + sudo mkdir -p data/nginx + sudo chmod -R 777 data + sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data + sudo cp examples/Docker/almalinux-systemd/django_tester.sh data + sudo cp .github/acme2certifier_cert.pem data/nginx/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem data/nginx/acme2certifier_key.pem + sudo cp .github/django_settings.py data/acme2certifier/settings.py + sudo sed -i "s/\/var\/www\//\/opt\//g" data/acme2certifier/settings.py + sudo sed -i "s/USE_I18N = True/USE_I18N = False/g" data/acme2certifier/settings.py + + - name: "[ PREPARE ] create lego folder" + run: | + mkdir lego + + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + + - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + run: | + mkdir -p data/volume/acme_ca + sudo cp test/ca/certsrv_ca_certs.pem data/volume/acme_ca/ca_certs.pem + sudo touch data/volume/acme_srv.cfg + sudo chmod 777 data/volume/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/volume/acme_srv.cfg + sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> data/volume/acme_srv.cfg + sudo echo "api_host: $NCM_API_HOST" >> data/volume/acme_srv.cfg + sudo echo "api_user: $NCM_API_USER" >> data/volume/acme_srv.cfg + sudo echo "api_password: $NCM_API_PASSWORD" >> data/volume/acme_srv.cfg + sudo echo "ca_name: $NCM_CA_NAME" >> data/volume/acme_srv.cfg + sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> data/volume/acme_srv.cfg + sudo echo "profile_id: 101" >> data/volume/acme_srv.cfg + env: + NCM_API_HOST: ${{ secrets.NCM_API_HOST }} + NCM_API_USER: ${{ secrets.NCM_API_USER }} + NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} + NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} + NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} + + - name: "[ PREPARE ] Almalinux instance" + run: | + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + docker run -d -id --privileged --network acme -p 22280:80 --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd + + - name: "[ RUN ] Execute install scipt" + run: | + docker exec acme-srv sh /tmp/acme2certifier/django_tester.sh + + - name: "Test http://acme-srv/directory is accessible" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "Enroll HTTP-01 single domain and ip address " + run: | + docker run -i -p 80:80 -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme -d $RUNNER_IP --http run + sudo chmod 777 lego/certificates/lego.acme.issuer.crt + sudo cp lego/certificates/lego.acme.issuer.crt lego.acme.issuer.crt + sudo awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < lego.acme.issuer.crt + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt --text --noout | grep "IP Address" + env: + RUNNER_IP: ${{ env.RUNNER_IP }} + + - name: "[ * ] collecting test logs" + if: ${{ failure() }} + run: | + mkdir -p ${{ github.workspace }}/artifact/upload + docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier + docker exec acme-srv tar cvfz /tmp/acme2certifier/nginx.tgz /etc/nginx + sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf + docker exec acme-srv rpm -qa > ${{ github.workspace }}/artifact/data/packages.txt + docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log lego + + - name: "[ * ] uploading artificates" + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: ip_django_rpm-rh${{ matrix.rhversion }}.tar.gz + path: ${{ github.workspace }}/artifact/upload/ + + + diff --git a/.github/workflows/ipv6-test.yml b/.github/workflows/ipv6-test.yml index beb80582..6ee37282 100644 --- a/.github/workflows/ipv6-test.yml +++ b/.github/workflows/ipv6-test.yml @@ -301,3 +301,282 @@ jobs: with: name: ipv6_nginx_django.tar.gz path: ${{ github.workspace }}/artifact/upload/ + + rpm_wsgi_ipv6: + name: "rpm_wsgi_ipv6" + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] + steps: + - name: "checkout GIT" + uses: actions/checkout@v4 + + - name: Retrieve Version from version.py + run: | + echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV + - run: echo "Latest tag is ${{ env.TAG_NAME }}" + + - name: update version number in spec file + run: | + # sudo sed -i "s/Source0:.*/Source0: %{name}-%{version}.tar.gz/g" examples/install_scripts/rpm/acme2certifier.spec + sudo sed -i "s/__version__/${{ env.TAG_NAME }}/g" examples/install_scripts/rpm/acme2certifier.spec + cat examples/install_scripts/rpm/acme2certifier.spec + + - name: build RPM package + id: rpm + uses: grindsa/rpmbuild@alma9 + with: + spec_file: "examples/install_scripts/rpm/acme2certifier.spec" + + - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" + + - name: "[ PREPARE ] setup environment for alma installation" + run: | + docker network create acme --ipv6 --subnet "fdbb:6445:65b4:0a60::/64" + sudo mkdir -p data + sudo chmod -R 777 data + sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data + sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data + + - name: "[ PREPARE ] create lego and certbot folder" + run: | + mkdir lego + mkdir certbot + + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + + - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + run: | + mkdir -p data/acme_ca + sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem + sudo touch data/acme_srv.cfg + sudo chmod 777 data/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/acme_srv.cfg + sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> data/acme_srv.cfg + sudo echo "api_host: $NCM_API_HOST" >> data/acme_srv.cfg + sudo echo "api_user: $NCM_API_USER" >> data/acme_srv.cfg + sudo echo "api_password: $NCM_API_PASSWORD" >> data/acme_srv.cfg + sudo echo "ca_name: $NCM_CA_NAME" >> data/acme_srv.cfg + sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> data/acme_srv.cfg + sudo echo "profile_id: 101" >> data/acme_srv.cfg + sudo echo -e "\n\n[Renewalinfo]" >> data/acme_srv.cfg + sudo echo "renewal_force: True" >> data/acme_srv.cfg + + env: + NCM_API_HOST: ${{ secrets.NCM_API_HOST }} + NCM_API_USER: ${{ secrets.NCM_API_USER }} + NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} + NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} + NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} + + - name: "[ PREPARE ] Almalinux instance" + run: | + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd + + - name: "[ RUN ] Execute install scipt" + run: | + docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh + + - name: "[ PREPARE ] prepare acme.sh container" + run: | + docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + + - name: "[ ENROLL ] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + + - name: "[ ENROL] lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --cert.timeout 180 --http run + + - name: "[ REGISTER ] certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email + + - name: "[ ENROLL ] certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot + + - name: "[ * ] collecting test logs" + if: ${{ failure() }} + run: | + mkdir -p ${{ github.workspace }}/artifact/upload + docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier + sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf + docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log + + - name: "[ * ] uploading artificates" + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: rpm_wsgi_ipv6-rh${{ matrix.rhversion }}.tar.gz + path: ${{ github.workspace }}/artifact/upload/ + + + rpm_django_ipv6: + name: "rpm_django_ipv6" + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] + steps: + - name: "checkout GIT" + uses: actions/checkout@v4 + + - name: "[ PREPARE ] get runner ip" + run: | + echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV + echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV + - run: echo "runner IP is ${{ env.RUNNER_IP }}" + + - name: Retrieve Version from version.py + run: | + echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV + - run: echo "Latest tag is ${{ env.TAG_NAME }}" + + - name: update version number in spec file and path in nginx ssl config + run: | + sudo sed -i "s/__version__/${{ env.TAG_NAME }}/g" examples/install_scripts/rpm/acme2certifier.spec + sudo sed -i "s/\/var\/www\/acme2certifier\/volume/\/etc\/nginx/g" examples/nginx/nginx_acme_srv_ssl.conf + git config --global user.email "grindelsack@gmail.com" + git config --global user.name "rpm update" + git add examples/nginx + git commit -a -m "rpm update" + + - name: build RPM package + id: rpm + uses: grindsa/rpmbuild@alma9 + with: + spec_file: "examples/install_scripts/rpm/acme2certifier.spec" + + - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" + + - name: "[ PREPARE ] setup environment for alma installation" + run: | + docker network create acme --ipv6 --subnet "fdbb:6445:65b4:0a60::/64" + sudo mkdir -p data/volume + sudo mkdir -p data/acme2certifier + sudo mkdir -p data/nginx + sudo chmod -R 777 data + sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data + sudo cp examples/Docker/almalinux-systemd/django_tester.sh data + sudo cp .github/acme2certifier_cert.pem data/nginx/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem data/nginx/acme2certifier_key.pem + sudo cp .github/django_settings.py data/acme2certifier/settings.py + sudo sed -i "s/\/var\/www\//\/opt\//g" data/acme2certifier/settings.py + sudo sed -i "s/USE_I18N = True/USE_I18N = False/g" data/acme2certifier/settings.py + + - name: "[ PREPARE ] create lego folder" + run: | + mkdir lego + + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + + - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + run: | + mkdir -p data/volume/acme_ca + sudo cp test/ca/certsrv_ca_certs.pem data/volume/acme_ca/ca_certs.pem + sudo touch data/volume/acme_srv.cfg + sudo chmod 777 data/volume/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/volume/acme_srv.cfg + sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> data/volume/acme_srv.cfg + sudo echo "api_host: $NCM_API_HOST" >> data/volume/acme_srv.cfg + sudo echo "api_user: $NCM_API_USER" >> data/volume/acme_srv.cfg + sudo echo "api_password: $NCM_API_PASSWORD" >> data/volume/acme_srv.cfg + sudo echo "ca_name: $NCM_CA_NAME" >> data/volume/acme_srv.cfg + sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> data/volume/acme_srv.cfg + sudo echo "profile_id: 101" >> data/volume/acme_srv.cfg + sudo echo -e "\n\n[Renewalinfo]" >> data/volume/acme_srv.cfg + sudo echo "renewal_force: True" >> data/volume/acme_srv.cfg + env: + NCM_API_HOST: ${{ secrets.NCM_API_HOST }} + NCM_API_USER: ${{ secrets.NCM_API_USER }} + NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} + NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} + NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} + + - name: "[ PREPARE ] Almalinux instance" + run: | + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + docker run -d -id --privileged --network acme -p 22280:80 --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd + + - name: "[ RUN ] Execute install scipt" + run: | + docker exec acme-srv sh /tmp/acme2certifier/django_tester.sh + + - name: "Test http://acme-srv/directory is accessible" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + + - name: "[ PREPARE ] prepare acme.sh container" + run: | + docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + + - name: "[ ENROLL ] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + + - name: "[ ENROL] lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --cert.timeout 180 --http run + + - name: "[ REGISTER ] certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email + + - name: "[ ENROLL ] certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot + + - name: "[ * ] collecting test logs" + if: ${{ failure() }} + run: | + mkdir -p ${{ github.workspace }}/artifact/upload + docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier + docker exec acme-srv tar cvfz /tmp/acme2certifier/nginx.tgz /etc/nginx + sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf + docker exec acme-srv rpm -qa > ${{ github.workspace }}/artifact/data/packages.txt + docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log lego + + - name: "[ * ] uploading artificates" + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: rpm_django_ipv6-rh${{ matrix.rhversion }}.tar.gz + path: ${{ github.workspace }}/artifact/upload/ diff --git a/.github/workflows/proxy-test.yml b/.github/workflows/proxy-test.yml index 8b1482f4..a4772dd6 100644 --- a/.github/workflows/proxy-test.yml +++ b/.github/workflows/proxy-test.yml @@ -189,6 +189,10 @@ jobs: proxy_tests_rpm: name: "proxy_tests_rpm" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] steps: - name: "checkout GIT" @@ -225,7 +229,7 @@ jobs: - name: "Retrieve rpms from SBOM repo" run: | git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom - cp /tmp/sbom/rpm-repo/RPMs/*ntlm*.rpm data + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data env: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} @@ -268,8 +272,10 @@ jobs: - name: "[ PREPARE ] Almalinux instance" run: | - cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache - docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + docker run -d -id --privileged --network acme -p 22280:80 --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - name: "[ RUN ] Execute install scipt" run: | @@ -474,5 +480,5 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: proxy-rpm.tar.gz + name: proxy-rpm-rh${{ matrix.rhversion }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ \ No newline at end of file diff --git a/.github/workflows/tnauth-test.yml b/.github/workflows/tnauth-test.yml index 41db3dec..56ca4905 100644 --- a/.github/workflows/tnauth-test.yml +++ b/.github/workflows/tnauth-test.yml @@ -86,6 +86,10 @@ jobs: tnauth_rpm_tests: name: "tnauth_rpm_tests" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -117,6 +121,14 @@ jobs: sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + - name: "[ PREPARE ] setup a2c with certifier_ca_handler" run: | mkdir -p data/acme_ca @@ -141,7 +153,9 @@ jobs: - name: "[ PREPARE ] Almalinux instance" run: | - cat examples/Docker/almalinux-systemd/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme -p 22280:80 --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - name: "[ RUN ] Execute install scipt" @@ -180,5 +194,5 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: tnauth-rpm.tar.gz + name: tnauth-rpm-rh${{ matrix.rhversion }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ diff --git a/.github/workflows/wsgi_handler-test.yml b/.github/workflows/wsgi_handler-test.yml index d0addc5b..fcfb995e 100644 --- a/.github/workflows/wsgi_handler-test.yml +++ b/.github/workflows/wsgi_handler-test.yml @@ -3,7 +3,7 @@ name: WSGI handler tests on: push: pull_request: - branches: [ devel, db_file_customization ] + branches: [ devel] schedule: # * is a special character in YAML so you have to quote this string - cron: '0 2 * * 6' @@ -148,3 +148,132 @@ jobs: with: name: nginx_cust_db.tar.gz path: ${{ github.workspace }}/artifact/upload/ + + rpm_cust_db_file: + name: "rpm_cust_db_file" + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] + steps: + - name: "checkout GIT" + uses: actions/checkout@v4 + + - name: Retrieve Version from version.py + run: | + echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV + - run: echo "Latest tag is ${{ env.TAG_NAME }}" + + - name: update version number in spec file + run: | + # sudo sed -i "s/Source0:.*/Source0: %{name}-%{version}.tar.gz/g" examples/install_scripts/rpm/acme2certifier.spec + sudo sed -i "s/__version__/${{ env.TAG_NAME }}/g" examples/install_scripts/rpm/acme2certifier.spec + cat examples/install_scripts/rpm/acme2certifier.spec + + - name: build RPM package + id: rpm + uses: grindsa/rpmbuild@alma9 + with: + spec_file: "examples/install_scripts/rpm/acme2certifier.spec" + + - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" + + - name: "[ PREPARE ] setup environment for alma installation" + run: | + docker network create acme + sudo mkdir -p data + sudo chmod -R 777 data + sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data + sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data + + - name: "[ PREPARE ] create letsencrypt and lego folder" + run: | + mkdir certbot + mkdir lego + + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + + - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + run: | + sudo mkdir -p data + sudo touch data/acme_srv.cfg + sudo chmod 777 data/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/acme_srv.cfg + sudo echo "handler_file: /opt/acme2certifier/examples/ca_handler/certifier_ca_handler.py" >> data/acme_srv.cfg + sudo echo "api_host: $NCM_API_HOST" >> data/acme_srv.cfg + sudo echo "api_user: $NCM_API_USER" >> data/acme_srv.cfg + sudo echo "api_password: $NCM_API_PASSWORD" >> data/acme_srv.cfg + sudo echo "ca_name: $NCM_CA_NAME" >> data/acme_srv.cfg + sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> data/acme_srv.cfg + sudo echo "[DBhandler]" >> data/acme_srv.cfg + sudo echo "dbfile: /opt/acme2certifier/volume/a2c.db" >> data/acme_srv.cfg + sudo echo "[Directory]" >> data/acme_srv.cfg + sudo echo "url_prefix: /foo" >> data/acme_srv.cfg + sleep 5 + env: + NCM_API_HOST: ${{ secrets.NCM_API_HOST }} + NCM_API_USER: ${{ secrets.NCM_API_USER }} + NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} + NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} + NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} + + - name: "[ PREPARE ] Almalinux instance" + run: | + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd + + - name: "[ RUN ] Execute install scipt" + run: | + docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh + + - name: "Sleep for 5s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 5s + + - name: "Test http://acme-srv/directory is accessible" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "[ PREPARE ] prepare acme.sh container" + run: | + docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + + - name: "[ ENROLL ] acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + + - name: "[ ENROLL ] lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + + - name: "[ * ] collecting test logs" + if: ${{ failure() }} + run: | + mkdir -p ${{ github.workspace }}/artifact/upload + docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier + sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf + docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh + + - name: "[ * ] uploading artificates" + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: rpm_cust_db_file-rh${{ matrix.rhversion }}.tar.gz + path: ${{ github.workspace }}/artifact/upload/ From 91f9cf8c93bb420d1b3d3d45bd67e920d99c52ee Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 10 Mar 2024 17:02:37 +0100 Subject: [PATCH 101/460] [wf] arm64 tests --- .github/workflows/arm64_tests.yml | 296 ++++++++++++++++++++++++++++++ 1 file changed, 296 insertions(+) create mode 100644 .github/workflows/arm64_tests.yml diff --git a/.github/workflows/arm64_tests.yml b/.github/workflows/arm64_tests.yml new file mode 100644 index 00000000..828aeba1 --- /dev/null +++ b/.github/workflows/arm64_tests.yml @@ -0,0 +1,296 @@ +name: arm64_tests +on: + push: + branches: + - "devel" + schedule: + # * is a special character in YAML so you have to quote this string + - cron: '0 4 * * 6' +jobs: + instance_start: + name: instance_start + runs-on: ubuntu-latest + steps: + + - name: "install awccli" + run: | + sudo apt-get update + pip3 install awscli --upgrade --user + pip3 install boto3 --upgrade --user + export PATH=$PATH:$HOME/.local/bin + + - name: "configure awccli" + run: | + aws --version + aws configure set aws_access_key_id ${{ secrets.AWS_ACCESS_KEY_ID }} + aws configure set aws_secret_access_key ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws configure set default.region ${{ secrets.AWS_REGION }} + + - name: "check instance status" + run: | + wget https://raw.githubusercontent.com/grindsa/aws_ec2_mgr/main/aws_ec_mgr.py + chmod a+rx ./aws_ec_mgr.py + python3 ./aws_ec_mgr.py -a state -r ${{ secrets.AWS_REGION }} -i ${{ secrets.AWS_INSTANCE_ID }} | grep -i "stopped" + + - name: "start instance" + run: | + python3 ./aws_ec_mgr.py -a start -r ${{ secrets.AWS_REGION }} -i ${{ secrets.AWS_INSTANCE_ID }} + + - name: "[ WAIT ] Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "check instance status" + run: | + python3 ./aws_ec_mgr.py -a state -r ${{ secrets.AWS_REGION }} -i ${{ secrets.AWS_INSTANCE_ID }} | grep -i "running" + + build_test: + name: build_test + runs-on: ubuntu-latest + needs: instance_start + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] + steps: + + - name: "checkout GIT" + uses: actions/checkout@v4 + + - name: "Retrieve Version from version.py" + run: | + echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV + echo UUID=$(uuidgen) >> $GITHUB_ENV + + - run: echo "Repo is at version ${{ steps.acme2certifier_ver.outputs.tag }}" + - run: echo "UUID ${{ env.UUID }}" + + - name: "Prepare ssh environment in ramdisk" + run: | + sudo mkdir -p /tmp/rd + sudo mount -t tmpfs -o size=5M none /tmp/rd + sudo echo "$SSH_KEY" > /tmp/rd/ak.tmp + sudo chmod 600 /tmp/rd/ak.tmp + sudo echo "$KNOWN_HOSTS" > /tmp/rd/known_hosts + env: + SSH_KEY: ${{ secrets.AWS_SSH_KEY }} + KNOWN_HOSTS: ${{ secrets.AWS_SSH_KNOWN_HOSTS }} + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + with: + platforms: 'arm64' + + - uses: docker/setup-buildx-action@v3 + with: + version: latest + buildkitd-flags: --debug + + - name: Build + uses: docker/build-push-action@v5 + with: + load: true + tags: grindsa/acme2certifier:${{ matrix.websrv }}-${{ matrix.dbhandler }}-${{ env.UUID }} + file: examples/Docker/${{ matrix.websrv }}/${{ matrix.dbhandler }}/Dockerfile + platforms: linux/arm64 + + - name: "Check if image is built" + run: | + docker image save -o /tmp/a2c-image-$WEB_SRV-$DB_HANDLER.tar grindsa/acme2certifier:$WEB_SRV-$DB_HANDLER-$UUID + ls -la /tmp/a2c-image-$WEB_SRV-$DB_HANDLER.tar + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} + UUID: ${{ env.UUID }} + + - name: "Compress image" + run: | + gzip /tmp/a2c-image-$WEB_SRV-$DB_HANDLER.tar + ls -la /tmp/a2c-image-$WEB_SRV-$DB_HANDLER.tar.gz + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} + + - name: "Create working directory on remote host" + run: sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts mkdir -p /tmp/a2c/$UUID + env: + SSH_USER: ${{ secrets.AWS_SSH_USER }} + SSH_HOST: ${{ secrets.AWS_SSH_HOST }} + UUID: ${{ env.UUID }} + + - name: "Copy image to remote host" + run: sudo scp -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts /tmp/a2c-image-$WEB_SRV-$DB_HANDLER.tar.gz $SSH_USER@$SSH_HOST:/tmp/a2c/$UUID/ + env: + SSH_USER: ${{ secrets.AWS_SSH_USER }} + SSH_HOST: ${{ secrets.AWS_SSH_HOST }} + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} + UUID: ${{ env.UUID }} + + - name: "Unpack image on remote host" + run: sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts gunzip /tmp/a2c/$UUID/a2c-image-$WEB_SRV-$DB_HANDLER.tar.gz + env: + SSH_USER: ${{ secrets.AWS_SSH_USER }} + SSH_HOST: ${{ secrets.AWS_SSH_HOST }} + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} + UUID: ${{ env.UUID }} + + - name: "Load image on remote host" + run: sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "docker load < /tmp/a2c/$UUID/a2c-image-$WEB_SRV-$DB_HANDLER.tar" + env: + SSH_USER: ${{ secrets.AWS_SSH_USER }} + SSH_HOST: ${{ secrets.AWS_SSH_HOST }} + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} + UUID: ${{ env.UUID }} + + - name: "Prepare and data package" + run: | + sudo mkdir -p /tmp/data/acme_ca/certs + sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem /tmp/data/acme_ca/ + sudo cp .github/openssl_ca_handler.py_acme_srv_choosen_handler.cfg /tmp/data/acme_srv.cfg + sudo cp .github/acme2certifier.pem /tmp/data/acme2certifier.pem + sudo cp .github/django_settings.py /tmp/data/settings.py + sudo cp .github/acme2certifier_cert.pem /tmp/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem /tmp/data/acme2certifier_key.pem + + - name: "Copy data package to remote host" + run: sudo scp -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts -r /tmp/data $SSH_USER@$SSH_HOST:/tmp/a2c/$UUID/ + env: + SSH_USER: ${{ secrets.AWS_SSH_USER }} + SSH_HOST: ${{ secrets.AWS_SSH_HOST }} + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} + UUID: ${{ env.UUID }} + + - run: echo "Image name - grindsa/acme2certifier:$WEB_SRV-$DB_HANDLER-$UUID" + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} + UUID: ${{ env.UUID }} + + - name: "Start container on remote host" + run: | + sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "docker network create $UUID" + sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "docker run -d --rm -id --platform linux/arm64 --network $UUID --name=acme-srv-$UUID -v /tmp/a2c/$UUID/data:/var/www/acme2certifier/volume/ grindsa/acme2certifier:$WEB_SRV-$DB_HANDLER-$UUID" + env: + SSH_USER: ${{ secrets.AWS_SSH_USER }} + SSH_HOST: ${{ secrets.AWS_SSH_HOST }} + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} + UUID: ${{ env.UUID }} + + - name: "Sleep for 5s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 5s + + - name: "Test http://acme-srv/directory internally" + run: sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "docker run -i --rm --network $UUID curlimages/curl -f http://acme-srv-$UUID/directory" + env: + SSH_USER: ${{ secrets.AWS_SSH_USER }} + SSH_HOST: ${{ secrets.AWS_SSH_HOST }} + UUID: ${{ env.UUID }} + + - name: "Test if https://acme-srv/directory internally" + run: sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "docker run -i --rm --network $UUID curlimages/curl --insecure -f https://acme-srv-$UUID/directory" + env: + SSH_USER: ${{ secrets.AWS_SSH_USER }} + SSH_HOST: ${{ secrets.AWS_SSH_HOST }} + UUID: ${{ env.UUID }} + + - name: "acme.sh enroll" + run: | + sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "mkdir -p /tmp/a2c/$UUID/acme-sh" + sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "docker run --rm -id -v /tmp/a2c/$UUID/acme-sh:/acme.sh --network $UUID --name=acme-sh-$UUID neilpang/acme.sh:latest daemon" + sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "docker exec -i acme-sh-$UUID acme.sh --server http://acme-srv-$UUID --accountemail 'acme-sh@example.com' --issue -d acme-sh-$UUID --standalone --debug 3 --output-insecure --force" + env: + SSH_USER: ${{ secrets.AWS_SSH_USER }} + SSH_HOST: ${{ secrets.AWS_SSH_HOST }} + UUID: ${{ env.UUID }} + + - name: "acme.sh revoke" + run: | + sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "docker exec -i acme-sh-$UUID acme.sh --server http://acme-srv-$UUID --revoke -d acme-sh-$UUID --standalone --debug 3 --output-insecure" + env: + SSH_USER: ${{ secrets.AWS_SSH_USER }} + SSH_HOST: ${{ secrets.AWS_SSH_HOST }} + UUID: ${{ env.UUID }} + + - name: "Certbot enroll" + run: | + sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "mkdir -p /tmp/a2c/$UUID/certbot" + sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "docker run -i --rm --name certbot-$UUID --network $UUID -v /tmp/a2c/$UUID/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv-$UUID --no-eff-email" + sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "docker run -i --rm --name certbot-$UUID --network $UUID -v /tmp/a2c/$UUID/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv-$UUID --standalone --preferred-challenges http -d certbot-$UUID --cert-name certbot-$UUID" + env: + SSH_USER: ${{ secrets.AWS_SSH_USER }} + SSH_HOST: ${{ secrets.AWS_SSH_HOST }} + UUID: ${{ env.UUID }} + + - name: "Certbot revoke" + run: | + sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "docker run -i --rm --name certbot-$UUID --network $UUID -v /tmp/a2c/$UUID/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv-$UUID -d certbot-$UUID --cert-name certbot-$UUID" + env: + SSH_USER: ${{ secrets.AWS_SSH_USER }} + SSH_HOST: ${{ secrets.AWS_SSH_HOST }} + UUID: ${{ env.UUID }} + + - name: "Lego enroll" + run: | + sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "mkdir -p /tmp/a2c/$UUID/lego" + sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "docker run -i -v /tmp/a2c/$UUID/lego:/.lego/ --rm --name lego-$UUID --network $UUID goacme/lego -s http://acme-srv-$UUID/directory -a --email lego@example.com -d lego-$UUID --http run" + env: + SSH_USER: ${{ secrets.AWS_SSH_USER }} + SSH_HOST: ${{ secrets.AWS_SSH_HOST }} + UUID: ${{ env.UUID }} + + - name: "Lego revoke" + run: | + sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "docker run -i -v /tmp/a2c/$UUID/lego:/.lego/ --rm --name lego-$UUID --network $UUID goacme/lego -s http://acme-srv-$UUID -a --email "lego@example.com" -d lego-$UUID revoke" + env: + SSH_USER: ${{ secrets.AWS_SSH_USER }} + SSH_HOST: ${{ secrets.AWS_SSH_HOST }} + UUID: ${{ env.UUID }} + + - name: "Cleanup on remote host" + run: | + sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "docker stop acme-sh-$UUID" + sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "docker stop acme-srv-$UUID" + sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "docker network rm $UUID" + sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "docker image rm grindsa/acme2certifier:$WEB_SRV-$DB_HANDLER-$UUID" + sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "sudo rm -rf /tmp/a2c/$UUID" + env: + SSH_USER: ${{ secrets.AWS_SSH_USER }} + SSH_HOST: ${{ secrets.AWS_SSH_HOST }} + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} + UUID: ${{ env.UUID }} + + instance_stop: + name: instance_stop + runs-on: ubuntu-latest + needs: build_test + steps: + - name: "install awccli" + run: | + sudo apt-get update + pip3 install awscli --upgrade --user + pip3 install boto3 --upgrade --user + export PATH=$PATH:$HOME/.local/bin + + - name: "configure awccli" + run: | + aws --version + aws configure set aws_access_key_id ${{ secrets.AWS_ACCESS_KEY_ID }} + aws configure set aws_secret_access_key ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws configure set default.region ${{ secrets.AWS_REGION }} + + - name: "stop instance" + run: | + wget https://raw.githubusercontent.com/grindsa/aws_ec2_mgr/main/aws_ec_mgr.py + chmod a+rx ./aws_ec_mgr.py + python3 ./aws_ec_mgr.py -a stop -r ${{ secrets.AWS_REGION }} -i ${{ secrets.AWS_INSTANCE_ID }} + python3 ./aws_ec_mgr.py -a state -r ${{ secrets.AWS_REGION }} -i ${{ secrets.AWS_INSTANCE_ID }} \ No newline at end of file From 7046dfc9d8db75d89693bac436d06e50ae273495 Mon Sep 17 00:00:00 2001 From: grindsa Date: Tue, 12 Mar 2024 13:31:12 +0100 Subject: [PATCH 102/460] [wf] removed schedule in arm64_test workflow --- .github/workflows/arm64_tests.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/arm64_tests.yml b/.github/workflows/arm64_tests.yml index 828aeba1..76da5362 100644 --- a/.github/workflows/arm64_tests.yml +++ b/.github/workflows/arm64_tests.yml @@ -3,9 +3,6 @@ on: push: branches: - "devel" - schedule: - # * is a special character in YAML so you have to quote this string - - cron: '0 4 * * 6' jobs: instance_start: name: instance_start From 7ed0a74392f94080426b4a8d5bbfc31a15d2f38f Mon Sep 17 00:00:00 2001 From: grindsa Date: Tue, 12 Mar 2024 14:20:19 +0100 Subject: [PATCH 103/460] [wf] arm64 image creation --- .../workflows/push_images_to_dockerhub.yml | 542 +++++++++++------- 1 file changed, 345 insertions(+), 197 deletions(-) diff --git a/.github/workflows/push_images_to_dockerhub.yml b/.github/workflows/push_images_to_dockerhub.yml index fcd6965a..bd626b95 100644 --- a/.github/workflows/push_images_to_dockerhub.yml +++ b/.github/workflows/push_images_to_dockerhub.yml @@ -8,21 +8,53 @@ on: - cron: '0 4 * * 6' jobs: - #update_docker_hub_description: - # runs-on: ubuntu-latest - # steps: - # - uses: actions/checkout@v4 - # - name: Docker Hub Description - # uses: peter-evans/dockerhub-description@v2 - # env: - # DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USER }} - # DOCKERHUB_PASSWORD: ${{ secrets.DOCKERHUB_PASSWORD }} - # DOCKERHUB_REPOSITORY: grindsa/acme2certifier + instance_start: + name: instance_start + runs-on: ubuntu-latest + steps: + - name: "install awccli" + run: | + sudo apt-get update + pip3 install awscli --upgrade --user + pip3 install boto3 --upgrade --user + export PATH=$PATH:$HOME/.local/bin + + - name: "configure awccli" + run: | + aws --version + aws configure set aws_access_key_id ${{ secrets.AWS_ACCESS_KEY_ID }} + aws configure set aws_secret_access_key ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws configure set default.region ${{ secrets.AWS_REGION }} + + - name: "check instance status" + run: | + wget https://raw.githubusercontent.com/grindsa/aws_ec2_mgr/main/aws_ec_mgr.py + chmod a+rx ./aws_ec_mgr.py + python3 ./aws_ec_mgr.py -a state -r ${{ secrets.AWS_REGION }} -i ${{ secrets.AWS_INSTANCE_ID }} | grep -i "stopped" + + - name: "start instance" + run: | + python3 ./aws_ec_mgr.py -a start -r ${{ secrets.AWS_REGION }} -i ${{ secrets.AWS_INSTANCE_ID }} + + - name: "[ WAIT ] Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "check instance status" + run: | + python3 ./aws_ec_mgr.py -a state -r ${{ secrets.AWS_REGION }} -i ${{ secrets.AWS_INSTANCE_ID }} | grep -i "running" build_and_upload_images_to_hub: name: Push images to dockerhub and github runs-on: ubuntu-latest + needs: instance_start + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] steps: - name: "Get current version" uses: oprypin/find-latest-tag@v1 @@ -43,277 +75,393 @@ jobs: - run: echo "APP tag is ${{ env.APP_NAME }}" - run: echo "Latest tag is ${{ env.TAG_NAME }}" - - name: "Create images" - run: | - cat examples/Docker/apache2/wsgi/Dockerfile | docker build -t grindsa/acme2certifier:apache2-wsgi -t grindsa/acme2certifier:${{ env.TAG_NAME }}-apache2-wsgi -t ghcr.io/grindsa/acme2certifier:apache2-wsgi -t ghcr.io/grindsa/acme2certifier:${{ env.TAG_NAME }}-apache2-wsgi -f - . --no-cache - cat examples/Docker/apache2/django/Dockerfile | docker build -t grindsa/acme2certifier:apache2-django -t grindsa/acme2certifier:${{ env.TAG_NAME }}-apache2-django -t ghcr.io/grindsa/acme2certifier:apache2-django -t ghcr.io/grindsa/acme2certifier:${{ env.TAG_NAME }}-apache2-django -f - . --no-cache - cat examples/Docker/nginx/wsgi/Dockerfile | docker build -t grindsa/acme2certifier:nginx-wsgi -t grindsa/acme2certifier:${{ env.TAG_NAME }}-nginx-wsgi -t ghcr.io/grindsa/acme2certifier:nginx-wsgi -t ghcr.io/grindsa/acme2certifier:${{ env.TAG_NAME }}-nginx-wsgi -f - . --no-cache - cat examples/Docker/nginx/django/Dockerfile | docker build -t grindsa/acme2certifier:nginx-django -t grindsa/acme2certifier:${{ env.TAG_NAME }}-nginx-django -t ghcr.io/grindsa/acme2certifier:nginx-django -t ghcr.io/grindsa/acme2certifier:${{ env.TAG_NAME }}-nginx-django -f - . --no-cache - - - name: "upload images to hub.docker.com" - run: | - docker login -u ${{ secrets.DOCKERHUB_USER }} -p ${{ secrets.DOCKERHUB_TOKEN }} - docker push -a grindsa/acme2certifier - - - name: "upload images to ghcr.io" - run: | - docker login ghcr.io -u ${{ secrets.GHCR_USER }} -p ${{ secrets.GHCR_TOKEN }} - docker push -a ghcr.io/grindsa/acme2certifier + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + with: + platforms: all - - name: "Install syft" - run: | - sudo curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin + - uses: docker/setup-buildx-action@v3 + with: + version: latest + buildkitd-flags: --debug - - name: "Retrieve SBOM repo" - run: | - git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom - env: - GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} - GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USER }} + password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: "Generate SBOMs for a2c images " - run: | - mkdir -p /tmp/sbom/sbom/acme2certifier - syft grindsa/acme2certifier:apache2-wsgi > /tmp/sbom/sbom/acme2certifier/acme2certifier-apache2-wsgi_sbom.txt - syft grindsa/acme2certifier:apache2-wsgi -o json > /tmp/sbom/sbom/acme2certifier/acme2certifier_apache2-wsgi_sbom.json - syft grindsa/acme2certifier:apache2-django > /tmp/sbom/sbom/acme2certifier/acme2certifier-apache2-django_sbom.txt - syft grindsa/acme2certifier:apache2-django -o json > /tmp/sbom/sbom/acme2certifier/acme2certifier_apache2-django_sbom.json - syft grindsa/acme2certifier:nginx-wsgi > /tmp/sbom/sbom/acme2certifier/acme2certifier-nginx-wsgi_sbom.txt - syft grindsa/acme2certifier:nginx-wsgi -o json > /tmp/sbom/sbom/acme2certifier/acme2certifier_nginx-wsgi_sbom.json - syft grindsa/acme2certifier:nginx-django > /tmp/sbom/sbom/acme2certifier/acme2certifier-nginx-django_sbom.txt - syft grindsa/acme2certifier:nginx-django -o json > /tmp/sbom/sbom/acme2certifier/acme2certifier_nginx-django_sbom.json + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ secrets.GHCR_USER }} + password: ${{ secrets.GHCR_TOKEN }} - - name: "Upload Changes" - run: | - cd /tmp/sbom - git config --global user.email "grindelsack@gmail.com" - git config --global user.name "SBOM Generator" - git add sbom/acme2certifier/ - git commit -a -m "SBOM update" - git push + - name: Build + uses: docker/build-push-action@v5 + with: + push: true + tags: grindsa/acme2certifier:${{ matrix.websrv }}-${{ matrix.dbhandler }}, grindsa/acme2certifier:${{ env.TAG_NAME }}-${{ matrix.websrv }}-${{ matrix.dbhandler }} + file: examples/Docker/${{ matrix.websrv }}/${{ matrix.dbhandler }}/Dockerfile + platforms: linux/arm64, linux/amd64 - - name: "delete images from local repository" + - name: Push image to GHCR run: | - docker rmi $(docker images grindsa/acme2certifier -q) --no-prune --force + docker buildx imagetools create \ + --tag ghcr.io/grindsa/acme2certifier:${{ matrix.websrv }}-${{ matrix.dbhandler }} \ + --tag ghcr.io/grindsa/acme2certifier:${{ env.TAG_NAME }}-${{ matrix.websrv }}-${{ matrix.dbhandler }} \ + grindsa/acme2certifier:${{ env.TAG_NAME }}-${{ matrix.websrv }}-${{ matrix.dbhandler }} - apache2_wsgi: - name: Test acme2certifier:apache2-wsgi image - needs: [build_and_upload_images_to_hub] + amd64_pull_and_test: + name: amd64_pull_and_test runs-on: ubuntu-latest + needs: build_and_upload_images_to_hub + strategy: + fail-fast: false + matrix: + websrv: ['nginx'] + dbhandler: ['django'] + steps: + - name: "Get current version" + uses: oprypin/find-latest-tag@v1 + with: + repository: ${{ github.repository }} # The repository to scan. + releases-only: true # We know that all relevant tags have a GitHub release for them. + id: acme2certifier_ver # The step ID to refer to later. - name: Checkout code uses: actions/checkout@v4 - - name: "[ PREPARE ] setup openssl ca_handler" + - name: "Retrieve Version from version.py" + run: | + echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV + + - run: echo "Repo is at version ${{ steps.acme2certifier_ver.outputs.tag }}" + - run: echo "Latest tag is ${{ env.TAG_NAME }}" + + - name: "Prepare environment" run: | docker network create acme - sudo mkdir -p examples/Docker/data - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py + sudo mkdir -p acme-sh + sudo mkdir -p certbot + sudo mkdir -p lego + + - name: "Setup openssl ca_handler" + run: | sudo mkdir -p examples/Docker/data/acme_ca/certs sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg + sudo cp .github/openssl_ca_handler.py_acme_srv_choosen_handler.cfg examples/Docker/data/acme_srv.cfg + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USER }} + password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: "[ PREPARE ] apache2 django container" + - name: "Pull images from dockerhub and setup container" run: | - docker run -d -p 80:80 --rm -id --network acme --name=acme-srv -v "$(pwd)/examples/Docker/data":/var/www/acme2certifier/volume/ grindsa/acme2certifier:apache2-wsgi + docker run -d -p 80:80 --rm -id --network acme --name=acme-srv -v "$(pwd)/examples/Docker/data":/var/www/acme2certifier/volume/ grindsa/acme2certifier:$TAG_NAME-$WEB_SRV-$DB_HANDLER + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} + TAG_NAME: ${{ env.TAG_NAME }} - - name: "[ PREPARE ] prepare acme.sh container" + - name: "[ WAIT ] Sleep for 5s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 5s + + - name: "Test if http://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "Prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ ENROLL ] via openssl ca_handler" + - name: "Enroll via acme.sh" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer + ls -la *.pem + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ DEACTIVATE ] acme.sh" + - name: "Revoke via acme.sh" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --deactivate-account --debug 2 --output-insecure + docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "[ * ] collecting test data" - if: ${{ failure() }} + - name: "Register certbot" run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ - cd examples/Docker - docker logs acme-srv > ${{ github.workspace }}/artifact/docker.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker.log data acme-sh + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ * ] uploading artifacts" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: apache_wsgi.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - test_apache2_django: - name: Test acme2certifier:apache2-django image - needs: [build_and_upload_images_to_hub] - runs-on: ubuntu-latest - steps: + - name: "Enroll certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem - - name: Checkout code - uses: actions/checkout@v4 + - name: "Revoke via certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - - name: "[ PREPARE ] setup openssl ca_handler and django config" + - name: "Enroll lego" run: | - docker network create acme - sudo mkdir -p examples/Docker/data - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg - sudo cp .github/django_settings.py examples/Docker/data/settings.py + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - - name: "[ PREPARE ] apache2 wsgi container" + - name: "Revoke via lego" run: | - docker run -d -p 80:80 --rm -id --network acme --name=acme-srv -v "$(pwd)/examples/Docker/data":/var/www/acme2certifier/volume/ grindsa/acme2certifier:apache2-django + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke - - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 5s + - name: "Install syft" + run: | + sudo curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin - - name: "[ PREPARE ] django update" + - name: "Retrieve SBOM repo" run: | - docker exec acme-srv python3 /var/www/acme2certifier/tools/django_update.py - sudo chmod a+w examples/Docker/data/db.sqlite3 + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} - - name: "[ PREPARE ] prepare acme.sh container" + - name: "Generate SBOMs for acme2certifier-${{ matrix.websrv }}-${{ matrix.dbhandler }}" run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + mkdir -p /tmp/sbom/sbom/acme2certifier + syft grindsa/acme2certifier:${{ matrix.websrv }}-${{ matrix.dbhandler }} > /tmp/sbom/sbom/acme2certifier/acme2certifier-${{ matrix.websrv }}-${{ matrix.dbhandler }}_sbom.txt + syft grindsa/acme2certifier:${{ matrix.websrv }}-${{ matrix.dbhandler }} -o json > /tmp/sbom/sbom/acme2certifier/acme2certifier-${{ matrix.websrv }}-${{ matrix.dbhandler }}_sbom.json + ls -la /tmp/sbom/sbom/acme2certifier - - name: "[ ENROLL ] via openssl ca_handler" + - name: "Upload Changes" + continue-on-error: true run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + cd /tmp/sbom + git config --global user.email "grindelsack@gmail.com" + git config --global user.name "SBOM Generator" + git add sbom/acme2certifier/ + git commit -a -m "SBOM update" + git push - - name: "[ DEACTIVATE ] acme.sh" + - name: "Delete images from local repository" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --deactivate-account --debug 2 --output-insecure + docker stop acme-srv + docker rmi $(docker images grindsa/acme2certifier -q) --no-prune --force - name: "[ * ] collecting test data" if: ${{ failure() }} run: | mkdir -p ${{ github.workspace }}/artifact/upload sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + # sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ cd examples/Docker - docker logs acme-srv > ${{ github.workspace }}/artifact/docker.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker.log data acme-sh + docker logs acme-srv > ${{ github.workspace }}/artifact/acme-srv.log 2>&1 + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz acme-srv.log data # acme-sh - name: "[ * ] uploading artifacts" uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: apache_django.tar.gz + name: amd64_pull_and_test-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ - nginx_wsgi: - name: Test acme2certifier:nginx-wsgi image - needs: [build_and_upload_images_to_hub] + arm64_pull_and_test: + name: arm64_pull_and_test runs-on: ubuntu-latest + needs: build_and_upload_images_to_hub + strategy: + fail-fast: false + matrix: + websrv: ['nginx'] + dbhandler: ['django'] + steps: + - name: "Get current version" + uses: oprypin/find-latest-tag@v1 + with: + repository: ${{ github.repository }} # The repository to scan. + releases-only: true # We know that all relevant tags have a GitHub release for them. + id: acme2certifier_ver # The step ID to refer to later. - name: Checkout code uses: actions/checkout@v4 - - name: "[ PREPARE ] setup openssl ca_handler" + - name: "Retrieve Version from version.py" run: | - docker network create acme - sudo mkdir -p examples/Docker/data - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg + echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV + echo UUID=$(uuidgen) >> $GITHUB_ENV - - name: "[ PREPARE ] nginx wsgi container" - run: | - docker run -d -p 80:80 --rm -id --network acme --name=acme-srv -v "$(pwd)/examples/Docker/data":/var/www/acme2certifier/volume/ grindsa/acme2certifier:nginx-wsgi + - run: echo "Repo is at version ${{ steps.acme2certifier_ver.outputs.tag }}" + - run: echo "UUID ${{ env.UUID }}" - - name: "[ PREPARE ] prepare acme.sh container" + - name: "Prepare ssh environment in ramdisk" run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + sudo mkdir -p /tmp/rd + sudo mount -t tmpfs -o size=5M none /tmp/rd + sudo echo "$SSH_KEY" > /tmp/rd/ak.tmp + sudo chmod 600 /tmp/rd/ak.tmp + sudo echo "$KNOWN_HOSTS" > /tmp/rd/known_hosts + env: + SSH_KEY: ${{ secrets.AWS_SSH_KEY }} + KNOWN_HOSTS: ${{ secrets.AWS_SSH_KNOWN_HOSTS }} - - name: "[ ENROLL ] via openssl ca_handler" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + - name: "Create working directory on remote host" + run: sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts mkdir -p /tmp/a2c/$UUID + env: + SSH_USER: ${{ secrets.AWS_SSH_USER }} + SSH_HOST: ${{ secrets.AWS_SSH_HOST }} + UUID: ${{ env.UUID }} + + - name: "Prepare and data package" + run: | + sudo mkdir -p /tmp/data/acme_ca/certs + sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem /tmp/data/acme_ca/ + sudo cp .github/openssl_ca_handler.py_acme_srv_choosen_handler.cfg /tmp/data/acme_srv.cfg + sudo cp .github/acme2certifier.pem /tmp/data/acme2certifier.pem + sudo cp .github/django_settings.py /tmp/data/settings.py + sudo cp .github/acme2certifier_cert.pem /tmp/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem /tmp/data/acme2certifier_key.pem + + - name: "Copy data package to remote host" + run: sudo scp -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts -r /tmp/data $SSH_USER@$SSH_HOST:/tmp/a2c/$UUID/ + env: + SSH_USER: ${{ secrets.AWS_SSH_USER }} + SSH_HOST: ${{ secrets.AWS_SSH_HOST }} + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} + UUID: ${{ env.UUID }} - - name: "[ DEACTIVATE ] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --deactivate-account --debug 2 --output-insecure + - run: echo "Image name - grindsa/acme2certifier:$TAG_NAME-$WEB_SRV-$DB_HANDLER" + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} + TAG_NAME: ${{ env.TAG_NAME }} - - name: "[ * ] collecting test data" - if: ${{ failure() }} + - name: "Pull images from dockerhub and setup container" run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ - cd examples/Docker - docker logs acme-srv > ${{ github.workspace }}/artifact/docker.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker.log data acme-sh - - - name: "[ * ] uploading artifacts" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} + sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "docker network create $UUID" + sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "docker run -d --rm -id --network $UUID --name=acme-srv-$UUID -v "/tmp/a2c/$UUID/data":/var/www/acme2certifier/volume/ grindsa/acme2certifier:$TAG_NAME-$WEB_SRV-$DB_HANDLER" + env: + SSH_USER: ${{ secrets.AWS_SSH_USER }} + SSH_HOST: ${{ secrets.AWS_SSH_HOST }} + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} + TAG_NAME: ${{ env.TAG_NAME }} + UUID: ${{ env.UUID }} + + - name: "Sleep for 5s" + uses: juliangruber/sleep-action@v2.0.3 with: - name: nginx_wsgi.tar.gz - path: ${{ github.workspace }}/artifact/upload/ + time: 5s - test_nginx_django: - name: Test acme2certifier:nginx-django image - needs: [build_and_upload_images_to_hub] - runs-on: ubuntu-latest - steps: + - name: "Test http://acme-srv/directory internally" + run: sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "docker run -i --rm --network $UUID curlimages/curl -f http://acme-srv-$UUID/directory" + env: + SSH_USER: ${{ secrets.AWS_SSH_USER }} + SSH_HOST: ${{ secrets.AWS_SSH_HOST }} + UUID: ${{ env.UUID }} - - name: Checkout code - uses: actions/checkout@v4 + - name: "Test if https://acme-srv/directory internally" + run: sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "docker run -i --rm --network $UUID curlimages/curl --insecure -f https://acme-srv-$UUID/directory" + env: + SSH_USER: ${{ secrets.AWS_SSH_USER }} + SSH_HOST: ${{ secrets.AWS_SSH_HOST }} + UUID: ${{ env.UUID }} - - name: "[ PREPARE ] setup openssl ca_handler and django config" + - name: "acme.sh enroll" run: | - docker network create acme - sudo mkdir -p examples/Docker/data - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg - sudo cp .github/django_settings.py examples/Docker/data/settings.py + sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "mkdir -p /tmp/a2c/$UUID/acme-sh" + sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "docker run --rm -id -v /tmp/a2c/$UUID/acme-sh:/acme.sh --network $UUID --name=acme-sh-$UUID neilpang/acme.sh:latest daemon" + sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "docker exec -i acme-sh-$UUID acme.sh --server http://acme-srv-$UUID --accountemail 'acme-sh@example.com' --issue -d acme-sh-$UUID --standalone --debug 3 --output-insecure --force" + env: + SSH_USER: ${{ secrets.AWS_SSH_USER }} + SSH_HOST: ${{ secrets.AWS_SSH_HOST }} + UUID: ${{ env.UUID }} - - name: "[ PREPARE ] nginx django container" + - name: "acme.sh revoke" run: | - docker run -d -p 80:80 --rm -id --network acme --name=acme-srv -v "$(pwd)/examples/Docker/data":/var/www/acme2certifier/volume/ grindsa/acme2certifier:nginx-django - # docker exec acme-srv python3 /var/www/acme2certifier/tools/django_update.py - # sudo chmod a+w examples/Docker/data/db.sqlite3 + sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "docker exec -i acme-sh-$UUID acme.sh --server http://acme-srv-$UUID --revoke -d acme-sh-$UUID --standalone --debug 3 --output-insecure" + env: + SSH_USER: ${{ secrets.AWS_SSH_USER }} + SSH_HOST: ${{ secrets.AWS_SSH_HOST }} + UUID: ${{ env.UUID }} - - name: "[ PREPARE ] prepare acme.sh container" + - name: "Certbot enroll" run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "mkdir -p /tmp/a2c/$UUID/certbot" + sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "docker run -i --rm --name certbot-$UUID --network $UUID -v /tmp/a2c/$UUID/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv-$UUID --no-eff-email" + sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "docker run -i --rm --name certbot-$UUID --network $UUID -v /tmp/a2c/$UUID/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv-$UUID --standalone --preferred-challenges http -d certbot-$UUID --cert-name certbot-$UUID" + env: + SSH_USER: ${{ secrets.AWS_SSH_USER }} + SSH_HOST: ${{ secrets.AWS_SSH_HOST }} + UUID: ${{ env.UUID }} - - name: "[ ENROLL ] via openssl ca_handler" + - name: "Certbot revoke" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "docker run -i --rm --name certbot-$UUID --network $UUID -v /tmp/a2c/$UUID/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv-$UUID -d certbot-$UUID --cert-name certbot-$UUID" + env: + SSH_USER: ${{ secrets.AWS_SSH_USER }} + SSH_HOST: ${{ secrets.AWS_SSH_HOST }} + UUID: ${{ env.UUID }} - - name: "[ DEACTIVATE ] acme.sh" + - name: "Lego enroll" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --deactivate-account --debug 2 --output-insecure + sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "mkdir -p /tmp/a2c/$UUID/lego" + sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "docker run -i -v /tmp/a2c/$UUID/lego:/.lego/ --rm --name lego-$UUID --network $UUID goacme/lego -s http://acme-srv-$UUID/directory -a --email lego@example.com -d lego-$UUID --http run" + env: + SSH_USER: ${{ secrets.AWS_SSH_USER }} + SSH_HOST: ${{ secrets.AWS_SSH_HOST }} + UUID: ${{ env.UUID }} - - name: "[ * ] collecting test data" - if: ${{ failure() }} + - name: "Lego revoke" run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ - cd examples/Docker - docker logs acme-srv > ${{ github.workspace }}/artifact/docker.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker.log data acme-sh + sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "docker run -i -v /tmp/a2c/$UUID/lego:/.lego/ --rm --name lego-$UUID --network $UUID goacme/lego -s http://acme-srv-$UUID -a --email "lego@example.com" -d lego-$UUID revoke" + env: + SSH_USER: ${{ secrets.AWS_SSH_USER }} + SSH_HOST: ${{ secrets.AWS_SSH_HOST }} + UUID: ${{ env.UUID }} - - name: "[ * ] uploading artifacts" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: nginx_django.tar.gz - path: ${{ github.workspace }}/artifact/upload/ + - name: "Cleanup on remote host" + run: | + sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "docker stop acme-sh-$UUID" + sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "docker stop acme-srv-$UUID" + sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "docker network rm $UUID" + sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "docker image rm grindsa/acme2certifier:$TAG_NAME-$WEB_SRV-$DB_HANDLER" + sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -o UserKnownHostsFile=/tmp/rd/known_hosts "sudo rm -rf /tmp/a2c/$UUID" + env: + SSH_USER: ${{ secrets.AWS_SSH_USER }} + SSH_HOST: ${{ secrets.AWS_SSH_HOST }} + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} + UUID: ${{ env.UUID }} + + instance_stop: + name: instance_stop + runs-on: ubuntu-latest + needs: arm64_pull_and_test + steps: + - name: "install awccli" + run: | + sudo apt-get update + pip3 install awscli --upgrade --user + pip3 install boto3 --upgrade --user + export PATH=$PATH:$HOME/.local/bin + + - name: "configure awccli" + run: | + aws --version + aws configure set aws_access_key_id ${{ secrets.AWS_ACCESS_KEY_ID }} + aws configure set aws_secret_access_key ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws configure set default.region ${{ secrets.AWS_REGION }} + + - name: "stop instance" + run: | + wget https://raw.githubusercontent.com/grindsa/aws_ec2_mgr/main/aws_ec_mgr.py + chmod a+rx ./aws_ec_mgr.py + python3 ./aws_ec_mgr.py -a stop -r ${{ secrets.AWS_REGION }} -i ${{ secrets.AWS_INSTANCE_ID }} + python3 ./aws_ec_mgr.py -a state -r ${{ secrets.AWS_REGION }} -i ${{ secrets.AWS_INSTANCE_ID }} \ No newline at end of file From 71b38c3e39cb6815158cae1fd481f69d52989d14 Mon Sep 17 00:00:00 2001 From: grindsa Date: Tue, 12 Mar 2024 14:21:34 +0100 Subject: [PATCH 104/460] [wf] matrix adaption --- .github/workflows/push_images_to_dockerhub.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/push_images_to_dockerhub.yml b/.github/workflows/push_images_to_dockerhub.yml index bd626b95..b8dbf0ac 100644 --- a/.github/workflows/push_images_to_dockerhub.yml +++ b/.github/workflows/push_images_to_dockerhub.yml @@ -120,8 +120,8 @@ jobs: strategy: fail-fast: false matrix: - websrv: ['nginx'] - dbhandler: ['django'] + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] steps: - name: "Get current version" @@ -277,8 +277,8 @@ jobs: strategy: fail-fast: false matrix: - websrv: ['nginx'] - dbhandler: ['django'] + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] steps: - name: "Get current version" From da5a83a611b9552676342e09a13c5f237ca1e760 Mon Sep 17 00:00:00 2001 From: grindsa Date: Tue, 12 Mar 2024 15:17:29 +0100 Subject: [PATCH 105/460] [wf] ari workflow improvement --- .github/workflows/ari-test.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ari-test.yml b/.github/workflows/ari-test.yml index 9cb3d3ce..4a9dbe10 100644 --- a/.github/workflows/ari-test.yml +++ b/.github/workflows/ari-test.yml @@ -53,8 +53,8 @@ jobs: - name: "[ RENEW ] HTTP-01 single domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep 2> ari.txt - grep "renewalInfo endpoint indicates that renewal is needed" ari.txt cat ari.txt + grep "renewalInfo endpoint indicates that renewal is needed" ari.txt sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - name: "[ * ] collecting test logs" @@ -124,8 +124,8 @@ jobs: - name: "[ RENEW ] HTTP-01 single domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep 2> ari.txt - grep "renewalInfo endpoint indicates that renewal is needed" ari.txt cat ari.txt + grep "renewalInfo endpoint indicates that renewal is needed" ari.txt sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - name: "[ * ] collecting test logs" @@ -194,8 +194,8 @@ jobs: - name: "[ RENEW ] HTTP-01 single domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep 2> ari.txt - grep "renewalInfo endpoint indicates that renewal is needed" ari.txt cat ari.txt + grep "renewalInfo endpoint indicates that renewal is needed" ari.txt sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - name: "[ * ] collecting test logs" @@ -266,8 +266,8 @@ jobs: - name: "[ RENEW ] HTTP-01 single domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep 2> ari.txt - grep "renewalInfo endpoint indicates that renewal is needed" ari.txt cat ari.txt + grep "renewalInfo endpoint indicates that renewal is needed" ari.txt sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - name: "[ * ] collecting test logs" @@ -365,8 +365,8 @@ jobs: - name: "[ RENEW ] HTTP-01 single domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep 2> ari.txt - grep "renewalInfo endpoint indicates that renewal is needed" ari.txt cat ari.txt + grep "renewalInfo endpoint indicates that renewal is needed" ari.txt sudo openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - name: "[ * ] collecting test logs" @@ -484,8 +484,8 @@ jobs: - name: "[ RENEW ] HTTP-01 single domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep 2> ari.txt - grep "renewalInfo endpoint indicates that renewal is needed" ari.txt cat ari.txt + grep "renewalInfo endpoint indicates that renewal is needed" ari.txt sudo openssl verify -CAfile data/volume/acme_ca/root-ca-cert.pem -untrusted data/volume/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - name: "[ * ] collecting test logs" From f38de29080a705e676f1fa40c83e480db8ba77cf Mon Sep 17 00:00:00 2001 From: grindsa Date: Tue, 12 Mar 2024 15:55:50 +0100 Subject: [PATCH 106/460] [wf] timer improvements --- .github/workflows/ari-test.yml | 17 +++++++++++------ .github/workflows/test_headerinfo.yml | 22 +++++----------------- 2 files changed, 16 insertions(+), 23 deletions(-) diff --git a/.github/workflows/ari-test.yml b/.github/workflows/ari-test.yml index 4a9dbe10..461fd6ee 100644 --- a/.github/workflows/ari-test.yml +++ b/.github/workflows/ari-test.yml @@ -25,6 +25,11 @@ jobs: docker-compose up -d docker-compose logs + - name: "[ WAIT ] Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory @@ -53,8 +58,8 @@ jobs: - name: "[ RENEW ] HTTP-01 single domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep 2> ari.txt - cat ari.txt grep "renewalInfo endpoint indicates that renewal is needed" ari.txt + cat ari.txt sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - name: "[ * ] collecting test logs" @@ -124,8 +129,8 @@ jobs: - name: "[ RENEW ] HTTP-01 single domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep 2> ari.txt - cat ari.txt grep "renewalInfo endpoint indicates that renewal is needed" ari.txt + cat ari.txt sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - name: "[ * ] collecting test logs" @@ -194,8 +199,8 @@ jobs: - name: "[ RENEW ] HTTP-01 single domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep 2> ari.txt - cat ari.txt grep "renewalInfo endpoint indicates that renewal is needed" ari.txt + cat ari.txt sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - name: "[ * ] collecting test logs" @@ -266,8 +271,8 @@ jobs: - name: "[ RENEW ] HTTP-01 single domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep 2> ari.txt - cat ari.txt grep "renewalInfo endpoint indicates that renewal is needed" ari.txt + cat ari.txt sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - name: "[ * ] collecting test logs" @@ -365,8 +370,8 @@ jobs: - name: "[ RENEW ] HTTP-01 single domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep 2> ari.txt - cat ari.txt grep "renewalInfo endpoint indicates that renewal is needed" ari.txt + cat ari.txt sudo openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - name: "[ * ] collecting test logs" @@ -484,8 +489,8 @@ jobs: - name: "[ RENEW ] HTTP-01 single domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep 2> ari.txt - cat ari.txt grep "renewalInfo endpoint indicates that renewal is needed" ari.txt + cat ari.txt sudo openssl verify -CAfile data/volume/acme_ca/root-ca-cert.pem -untrusted data/volume/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - name: "[ * ] collecting test logs" diff --git a/.github/workflows/test_headerinfo.yml b/.github/workflows/test_headerinfo.yml index 04d1725a..6c23e6a1 100644 --- a/.github/workflows/test_headerinfo.yml +++ b/.github/workflows/test_headerinfo.yml @@ -28,9 +28,6 @@ jobs: run: | mkdir lego - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "setup a2c with xca_ca_handler" run: | sudo mkdir -p examples/Docker/data/xca @@ -57,6 +54,11 @@ jobs: XCA_TEMPLATE: ${{ secrets.XCA_TEMPLATE }} XCA_DB_NAME: ${{ secrets.XCA_DB_NAME }} + - name: "[ WAIT ] Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + - name: "Test http://acme-srv/directory is accessable again" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory @@ -112,9 +114,6 @@ jobs: run: | mkdir lego - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "setup a2c with xca_ca_handler" run: | sudo mkdir -p examples/Docker/data/xca @@ -202,9 +201,6 @@ jobs: run: | mkdir lego - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "setup a2c with xca_ca_handler" run: | sudo mkdir -p examples/Docker/data/xca @@ -288,18 +284,10 @@ jobs: docker-compose up -d docker-compose logs - - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s - - name: "create letsencrypt and lego folder" run: | mkdir lego - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "setup a2c with xca_ca_handler" run: | sudo mkdir -p examples/Docker/data/xca From 1e394f6eccaafb86d1707019f8058c39426bbeed Mon Sep 17 00:00:00 2001 From: grindsa Date: Wed, 13 Mar 2024 07:40:57 +0100 Subject: [PATCH 107/460] [fix] leading zero in serial during renewal_info handling --- acme_srv/renewalinfo.py | 3 ++ test/test_renewalinfo.py | 100 +++++++++++++++++++++------------------ 2 files changed, 58 insertions(+), 45 deletions(-) diff --git a/acme_srv/renewalinfo.py b/acme_srv/renewalinfo.py index f93d76ad..d420f3eb 100644 --- a/acme_srv/renewalinfo.py +++ b/acme_srv/renewalinfo.py @@ -110,6 +110,9 @@ def _draft02_lookup(self, serial: str, aki: str) -> Dict[str, str]: cert_dic = {} try: cert_list = self.dbstore.certificates_search('serial', serial, operant='is', vlist=['id', 'name', 'cert', 'cert_raw', 'expire_uts', 'issue_uts', 'aki', 'created_at']) + if not cert_list and serial.startswith('0'): + # cover cornercase where serial is padded with leading zeros + cert_list = self.dbstore.certificates_search('serial', serial.lstrip('0'), operant='is', vlist=['id', 'name', 'cert', 'cert_raw', 'expire_uts', 'issue_uts', 'aki', 'created_at']) for cert in cert_list: if cert['aki'] == aki: cert_dic = cert diff --git a/test/test_renewalinfo.py b/test/test_renewalinfo.py index 7828ea0d..814883f1 100644 --- a/test/test_renewalinfo.py +++ b/test/test_renewalinfo.py @@ -214,20 +214,20 @@ def test_016_get(self, mock_update, mock_renstr_get, mock_renget): self.assertIn('ERROR:test_a2c:Renewalinfo.get() - error: renewalinfo_get', lcm.output) @patch('acme_srv.message.Message.check') - def test_016_update(self, mock_mcheck): + def test_017_update(self, mock_mcheck): """ test update() """ mock_mcheck.return_value = (400, 'message', 'detail', 'protected', 'payload', 'account_name') self.assertEqual({'code': 400}, self.renewalinfo.update('content')) @patch('acme_srv.message.Message.check') - def test_017_update(self, mock_mcheck): + def test_018_update(self, mock_mcheck): """ test update() """ mock_mcheck.return_value = (200, 'message', 'detail', 'protected', {'certid': 'certid'}, 'account_name') self.assertEqual({'code': 400}, self.renewalinfo.update('content')) @patch('acme_srv.renewalinfo.Renewalinfo._cert_dic_lookup') @patch('acme_srv.message.Message.check') - def test_018_update(self, mock_mcheck, mock_lookup): + def test_019_update(self, mock_mcheck, mock_lookup): """ test update() """ mock_mcheck.return_value = (200, 'message', 'detail', 'protected', {'certid': 'certid', 'replaced': True}, 'account_name') mock_lookup.return_value = None @@ -235,7 +235,7 @@ def test_018_update(self, mock_mcheck, mock_lookup): @patch('acme_srv.renewalinfo.Renewalinfo._cert_dic_lookup') @patch('acme_srv.message.Message.check') - def test_019_update(self, mock_mcheck, mock_lookup): + def test_020_update(self, mock_mcheck, mock_lookup): """ test update() """ mock_mcheck.return_value = (200, 'message', 'detail', 'protected', {'certid': 'certid', 'replaced': False}, 'account_name') mock_lookup.return_value = {'foo': 'bar'} @@ -243,7 +243,7 @@ def test_019_update(self, mock_mcheck, mock_lookup): @patch('acme_srv.renewalinfo.Renewalinfo._cert_dic_lookup') @patch('acme_srv.message.Message.check') - def test_020_update(self, mock_mcheck, mock_lookup): + def test_021_update(self, mock_mcheck, mock_lookup): """ test update() """ mock_mcheck.return_value = (200, 'message', 'detail', 'protected', {'certid': 'certid', 'replaced': True}, 'account_name') mock_lookup.return_value = {'foo': 'bar'} @@ -252,28 +252,28 @@ def test_020_update(self, mock_mcheck, mock_lookup): @patch('acme_srv.renewalinfo.Renewalinfo._cert_dic_lookup') @patch('acme_srv.message.Message.check') - def test_021_update(self, mock_mcheck, mock_lookup): + def test_022_update(self, mock_mcheck, mock_lookup): """ test update() """ mock_mcheck.return_value = (200, 'message', 'detail', 'protected', {'certid': 'certid', 'replaced': True}, 'account_name') mock_lookup.return_value = {'foo': 'bar'} self.renewalinfo.dbstore.certificate_add.return_value = 1 self.assertEqual({'code': 200}, self.renewalinfo.update('content')) - def test_022_renewalinfo_string_get(self): + def test_023_renewalinfo_string_get(self): """ test update() """ self.renewalinfo.server_name = 'http://server.name' self.renewalinfo.path_dic = {'renewalinfo': '/renewalinfo'} input_string = 'http://server.name/renewalinfo/foo' self.assertEqual('foo', self.renewalinfo._renewalinfo_string_get(input_string)) - def test_023_renewalinfo_string_get(self): + def test_024_renewalinfo_string_get(self): """ test update() """ self.renewalinfo.server_name = 'http://server.name' self.renewalinfo.path_dic = {'renewalinfo': '/renewalinfo'} input_string = 'http://server.name/renewalinfofoo' self.assertEqual('foo', self.renewalinfo._renewalinfo_string_get(input_string)) - def test_024_renewalinfo_string_get(self): + def test_025_renewalinfo_string_get(self): """ test update() """ self.renewalinfo.server_name = 'http://server.name' self.renewalinfo.path_dic = {'renewalinfo': '/renewalinfo/'} @@ -284,7 +284,7 @@ def test_024_renewalinfo_string_get(self): @patch('acme_srv.renewalinfo.Renewalinfo._draft01_lookup') @patch('acme_srv.renewalinfo.certid_hex_get') @patch('acme_srv.renewalinfo.Renewalinfo._serial_aki_get') - def test_025_cert_dic_lookup(self, mock_aki, mock_certid, mock_draft01, mock_draft02): + def test_026_cert_dic_lookup(self, mock_aki, mock_certid, mock_draft01, mock_draft02): """ test _cert_dic_lookup() """ mock_aki.return_value = ('serail', 'aki') mock_draft01.return_value = {'foo': 'draft01'} @@ -299,7 +299,7 @@ def test_025_cert_dic_lookup(self, mock_aki, mock_certid, mock_draft01, mock_dra @patch('acme_srv.renewalinfo.Renewalinfo._draft01_lookup') @patch('acme_srv.renewalinfo.certid_hex_get') @patch('acme_srv.renewalinfo.Renewalinfo._serial_aki_get') - def test_026_cert_dic_lookup(self, mock_aki, mock_certid, mock_draft01, mock_draft02): + def test_027_cert_dic_lookup(self, mock_aki, mock_certid, mock_draft01, mock_draft02): """ test _cert_dic_lookup() """ mock_aki.return_value = ('serail', 'aki') mock_certid.return_value = ('mda', 'certid') @@ -311,31 +311,14 @@ def test_026_cert_dic_lookup(self, mock_aki, mock_certid, mock_draft01, mock_dra self.assertTrue(mock_draft01.called) self.assertFalse(mock_draft02.called) - def test_027_draft01_lookup(self): + def test_028_draft01_lookup(self): """ test _draft01_lookup() """ self.renewalinfo.dbstore.certificate_lookup.return_value = {'foo': 'bar'} self.assertEqual({'foo': 'bar'}, self.renewalinfo._draft01_lookup('certid_hex')) - def test_028_draft01_lookup(self): - """ test _draft01_lookup() """ - self.renewalinfo.dbstore.certificate_lookup.side_effect = Exception('cert_lookup') - with self.assertLogs('test_a2c', level='INFO') as lcm: - self.assertFalse(self.renewalinfo._draft01_lookup('certid_hex')) - self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Renewalinfo._draft01_lookup(): cert_lookup', lcm.output) - - def test_029_draft02_lookup(self): - """ test _draft02_lookup() """ - self.renewalinfo.dbstore.certificates_search.return_value = [{'foo': 'bar01', 'aki': 'aki01'}, {'foo': 'bar02', 'aki': 'aki02'}] - self.assertEqual({'aki': 'aki01', 'foo': 'bar01'}, self.renewalinfo._draft02_lookup('serial', 'aki01')) - - def test_030_draft02_lookup(self): - """ test _draft02_lookup() """ - self.renewalinfo.dbstore.certificates_search.return_value = [{'foo': 'bar01', 'aki': 'aki01'}, {'foo': 'bar02', 'aki': 'aki02'}] - self.assertEqual({'aki': 'aki02', 'foo': 'bar02'}, self.renewalinfo._draft02_lookup('serial', 'aki02')) - @patch('acme_srv.renewalinfo.cert_aki_get') @patch('acme_srv.renewalinfo.cert_serial_get') - def test_031_cert_table_update(self, mock_serial, mock_aki): + def test_029_cert_table_update(self, mock_serial, mock_aki): """ test _cert_table_update() """ self.renewalinfo.dbstore.certificates_search.return_value = [{'foo': 'bar', 'cert_raw': 'cert_raw', 'name': 'name', 'cert': 'cert'}] self.assertFalse(self.renewalinfo._cert_table_update()) @@ -344,7 +327,7 @@ def test_031_cert_table_update(self, mock_serial, mock_aki): @patch('acme_srv.renewalinfo.cert_aki_get') @patch('acme_srv.renewalinfo.cert_serial_get') - def test_032_cert_table_update(self, mock_serial, mock_aki): + def test_030_cert_table_update(self, mock_serial, mock_aki): """ test _cert_table_update() """ self.renewalinfo.dbstore.certificates_search.return_value = [{'foo': 'bar', 'cert_raw': None, 'name': 'name', 'cert': 'cert'}] self.assertFalse(self.renewalinfo._cert_table_update()) @@ -353,21 +336,48 @@ def test_032_cert_table_update(self, mock_serial, mock_aki): @patch('acme_srv.renewalinfo.cert_aki_get') @patch('acme_srv.renewalinfo.cert_serial_get') - def test_033_cert_table_update(self, mock_serial, mock_aki): + def test_031_cert_table_update(self, mock_serial, mock_aki): """ test _cert_table_update() """ self.renewalinfo.dbstore.certificates_search.return_value = [{'foo': 'bar', 'name': 'name', 'cert': 'cert'}] self.assertFalse(self.renewalinfo._cert_table_update()) self.assertFalse(mock_serial.called) self.assertFalse(mock_aki.called) - def test_034_draft02_lookup(self): + def test_032_draft02_lookup(self): """ test _draft02_lookup() """ self.renewalinfo.dbstore.certificates_search.return_value = [{'foo': 'bar01', 'aki': 'aki01'}, {'foo': 'bar02', 'aki': 'aki02'}] self.assertFalse(self.renewalinfo._draft02_lookup('serial', 'aki03')) + def test_033_draft01_lookup(self): + """ test _draft01_lookup() """ + self.renewalinfo.dbstore.certificate_lookup.side_effect = Exception('cert_lookup') + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.renewalinfo._draft01_lookup('certid_hex')) + self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Renewalinfo._draft01_lookup(): cert_lookup', lcm.output) + + def test_034_draft02_lookup(self): + """ test _draft02_lookup() """ + self.renewalinfo.dbstore.certificates_search.return_value = [{'foo': 'bar01', 'aki': 'aki01'}, {'foo': 'bar02', 'aki': 'aki02'}] + self.assertEqual({'aki': 'aki01', 'foo': 'bar01'}, self.renewalinfo._draft02_lookup('serial', 'aki01')) + + def test_035_draft02_lookup(self): + """ test _draft02_lookup() """ + self.renewalinfo.dbstore.certificates_search.return_value = [{'foo': 'bar01', 'aki': 'aki01'}, {'foo': 'bar02', 'aki': 'aki02'}] + self.assertEqual({'aki': 'aki02', 'foo': 'bar02'}, self.renewalinfo._draft02_lookup('serial', 'aki02')) + + def test_036_draft02_lookup(self): + """ test _draft02_lookup() failed with leading zero """ + self.renewalinfo.dbstore.certificates_search.side_effect = [[], [{'foo': 'bar01', 'aki': 'aki01'}, {'foo': 'bar02', 'aki': 'aki02'}]] + self.assertEqual({'aki': 'aki02', 'foo': 'bar02'}, self.renewalinfo._draft02_lookup('00serial', 'aki02')) + + def test_037_draft02_lookup(self): + """ test _draft02_lookup() without leading zero""" + self.renewalinfo.dbstore.certificates_search.side_effect = [[], [{'foo': 'bar01', 'aki': 'aki01'}, {'foo': 'bar02', 'aki': 'aki02'}]] + self.assertFalse(self.renewalinfo._draft02_lookup('serial', 'aki02')) + @patch('acme_srv.renewalinfo.cert_aki_get') @patch('acme_srv.renewalinfo.cert_serial_get') - def test_035_cert_table_update(self, mock_serial, mock_aki): + def test_038_cert_table_update(self, mock_serial, mock_aki): """ test _cert_table_update() """ self.renewalinfo.dbstore.certificates_search.side_effect = Exception('certificates_search') with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -376,14 +386,14 @@ def test_035_cert_table_update(self, mock_serial, mock_aki): self.assertFalse(mock_serial.called) self.assertFalse(mock_aki.called) - def test_036_draft02_lookup(self): + def test_039_draft02_lookup(self): """ test _draft02_lookup() """ self.renewalinfo.dbstore.certificates_search.return_value = [{'foo': 'bar01', }, {'foo': 'bar02', 'aki': 'aki02'}] with self.assertLogs('test_a2c', level='INFO') as lcm: self.assertFalse(self.renewalinfo._draft02_lookup('serial', 'aki03')) self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Renewalinfo._draft02_lookup(): certificates_search', lcm.output) - def test_037_draft02_lookup(self): + def test_040_draft02_lookup(self): """ test _draft02_lookup() """ self.renewalinfo.dbstore.certificates_search.side_effect = Exception('certificates_search') with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -392,7 +402,7 @@ def test_037_draft02_lookup(self): @patch('acme_srv.renewalinfo.b64_url_recode') @patch('acme_srv.renewalinfo.b64_decode') - def test_038_serial_aki_get(self, mock_dec, mock_rec): + def test_041_serial_aki_get(self, mock_dec, mock_rec): """ test _serial_aki_get() """ mock_dec.side_effect = [b'aki', b'serial'] mock_rec.side_effect = ['foo1', 'foo2'] @@ -402,7 +412,7 @@ def test_038_serial_aki_get(self, mock_dec, mock_rec): @patch('acme_srv.renewalinfo.b64_url_recode') @patch('acme_srv.renewalinfo.b64_decode') - def test_039_serial_aki_get(self, mock_dec, mock_rec): + def test_042_serial_aki_get(self, mock_dec, mock_rec): """ test _serial_aki_get() """ mock_dec.side_effect = [b'aki', b'serial'] mock_rec.side_effect = ['foo1', 'foo2'] @@ -412,7 +422,7 @@ def test_039_serial_aki_get(self, mock_dec, mock_rec): @patch('acme_srv.renewalinfo.b64_url_recode') @patch('acme_srv.renewalinfo.b64_decode') - def test_040_serial_aki_get(self, mock_dec, mock_rec): + def test_043_serial_aki_get(self, mock_dec, mock_rec): """ test _serial_aki_get() """ mock_dec.side_effect = [b'aki', b'serial'] mock_rec.side_effect = ['foo1', 'foo2'] @@ -420,27 +430,27 @@ def test_040_serial_aki_get(self, mock_dec, mock_rec): self.assertFalse(mock_dec.called) self.assertFalse(mock_rec.called) - def test_041_renewalinfo_generate(self): + def test_044_renewalinfo_generate(self): """ test _renewalinfo_generate() """ self.assertFalse(self.renewalinfo._renewalinfo_generate({})) - def test_042_renewalinfo_generate(self): + def test_045_renewalinfo_generate(self): """ test _renewalinfo_generate() """ cert_dic = {'foo': 'bar'} self.assertFalse(self.renewalinfo._renewalinfo_generate(cert_dic)) - def test_043_renewalinfo_generate(self): + def test_046_renewalinfo_generate(self): """ test _renewalinfo_generate() """ cert_dic = {'expire_uts': 0} self.assertFalse(self.renewalinfo._renewalinfo_generate(cert_dic)) - def test_044_renewalinfo_generate(self): + def test_047_renewalinfo_generate(self): """ test _renewalinfo_generate() """ cert_dic = {'expire_uts': 1000, 'issue_uts': 100} self.assertEqual({'suggestedWindow': {'start': '1970-01-01T00:14:25Z', 'end': '1970-01-01T00:16:40Z'}}, self.renewalinfo._renewalinfo_generate(cert_dic)) @patch('acme_srv.renewalinfo.uts_now') - def test_045_renewalinfo_generate(self, mock_uts): + def test_048_renewalinfo_generate(self, mock_uts): """ test _renewalinfo_generate() """ mock_uts.return_value = 100 cert_dic = {'expire_uts': 1000} @@ -448,7 +458,7 @@ def test_045_renewalinfo_generate(self, mock_uts): self.assertTrue(mock_uts.called) @patch('acme_srv.renewalinfo.uts_now') - def test_046_renewalinfo_generate(self, mock_uts): + def test_049_renewalinfo_generate(self, mock_uts): """ test _renewalinfo_generate() """ mock_uts.return_value = 86400000 cert_dic = {'expire_uts': 1000, 'issue_uts': 200} From bd22005b4bdf464b87e766f7c51ae66b1f69e5c2 Mon Sep 17 00:00:00 2001 From: grindsa Date: Wed, 13 Mar 2024 14:13:45 +0100 Subject: [PATCH 108/460] [fix] leading Zero in serialnumber --- acme_srv/renewalinfo.py | 18 +++++-- test/test_renewalinfo.py | 113 +++++++++++++++++++++++---------------- 2 files changed, 82 insertions(+), 49 deletions(-) diff --git a/acme_srv/renewalinfo.py b/acme_srv/renewalinfo.py index f1f1e8f2..d420f3eb 100644 --- a/acme_srv/renewalinfo.py +++ b/acme_srv/renewalinfo.py @@ -110,6 +110,9 @@ def _draft02_lookup(self, serial: str, aki: str) -> Dict[str, str]: cert_dic = {} try: cert_list = self.dbstore.certificates_search('serial', serial, operant='is', vlist=['id', 'name', 'cert', 'cert_raw', 'expire_uts', 'issue_uts', 'aki', 'created_at']) + if not cert_list and serial.startswith('0'): + # cover cornercase where serial is padded with leading zeros + cert_list = self.dbstore.certificates_search('serial', serial.lstrip('0'), operant='is', vlist=['id', 'name', 'cert', 'cert_raw', 'expire_uts', 'issue_uts', 'aki', 'created_at']) for cert in cert_list: if cert['aki'] == aki: cert_dic = cert @@ -206,17 +209,24 @@ def get(self, url: str) -> Dict[str, str]: renewalinfo_string = self._renewalinfo_string_get(url) # get renewal information - rewalinfo_dic = self._renewalinfo_get(renewalinfo_string) + try: + rewalinfo_dic = self._renewalinfo_get(renewalinfo_string) + if rewalinfo_dic: + rc_code = 200 + else: + rc_code = 404 + except Exception as err_: + self.logger.error('Renewalinfo.get() - error: %s', err_) + rewalinfo_dic = {} + rc_code = 400 - response_dic = {} + response_dic = {'code': rc_code} if rewalinfo_dic: - response_dic['code'] = 200 # filter certificate and decode it response_dic['data'] = rewalinfo_dic # order status is processing - ratelimiting response_dic['header'] = {'Retry-After': f'{self.retry_after_timeout}'.format()} else: - response_dic['code'] = 404 response_dic['data'] = self.err_msg_dic['malformed'] return response_dic diff --git a/test/test_renewalinfo.py b/test/test_renewalinfo.py index 5074e1e4..814883f1 100644 --- a/test/test_renewalinfo.py +++ b/test/test_renewalinfo.py @@ -200,21 +200,34 @@ def test_015_get(self, mock_update, mock_renstr_get, mock_renget): self.assertTrue(mock_update.called) self.assertTrue(mock_renstr_get.called) + @patch('acme_srv.renewalinfo.Renewalinfo._renewalinfo_get') + @patch('acme_srv.renewalinfo.Renewalinfo._renewalinfo_string_get') + @patch('acme_srv.renewalinfo.Renewalinfo._cert_table_update') + def test_016_get(self, mock_update, mock_renstr_get, mock_renget): + """ test get() """ + mock_renget.side_effect = Exception('renewalinfo_get') + self.renewalinfo.dbstore.hkparameter_get.return_value = None + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertEqual({'code': 400, 'data': 'urn:ietf:params:acme:error:malformed'}, self. renewalinfo.get('url')) + self.assertTrue(mock_update.called) + self.assertTrue(mock_renstr_get.called) + self.assertIn('ERROR:test_a2c:Renewalinfo.get() - error: renewalinfo_get', lcm.output) + @patch('acme_srv.message.Message.check') - def test_016_update(self, mock_mcheck): + def test_017_update(self, mock_mcheck): """ test update() """ mock_mcheck.return_value = (400, 'message', 'detail', 'protected', 'payload', 'account_name') self.assertEqual({'code': 400}, self.renewalinfo.update('content')) @patch('acme_srv.message.Message.check') - def test_017_update(self, mock_mcheck): + def test_018_update(self, mock_mcheck): """ test update() """ mock_mcheck.return_value = (200, 'message', 'detail', 'protected', {'certid': 'certid'}, 'account_name') self.assertEqual({'code': 400}, self.renewalinfo.update('content')) @patch('acme_srv.renewalinfo.Renewalinfo._cert_dic_lookup') @patch('acme_srv.message.Message.check') - def test_018_update(self, mock_mcheck, mock_lookup): + def test_019_update(self, mock_mcheck, mock_lookup): """ test update() """ mock_mcheck.return_value = (200, 'message', 'detail', 'protected', {'certid': 'certid', 'replaced': True}, 'account_name') mock_lookup.return_value = None @@ -222,7 +235,7 @@ def test_018_update(self, mock_mcheck, mock_lookup): @patch('acme_srv.renewalinfo.Renewalinfo._cert_dic_lookup') @patch('acme_srv.message.Message.check') - def test_019_update(self, mock_mcheck, mock_lookup): + def test_020_update(self, mock_mcheck, mock_lookup): """ test update() """ mock_mcheck.return_value = (200, 'message', 'detail', 'protected', {'certid': 'certid', 'replaced': False}, 'account_name') mock_lookup.return_value = {'foo': 'bar'} @@ -230,7 +243,7 @@ def test_019_update(self, mock_mcheck, mock_lookup): @patch('acme_srv.renewalinfo.Renewalinfo._cert_dic_lookup') @patch('acme_srv.message.Message.check') - def test_020_update(self, mock_mcheck, mock_lookup): + def test_021_update(self, mock_mcheck, mock_lookup): """ test update() """ mock_mcheck.return_value = (200, 'message', 'detail', 'protected', {'certid': 'certid', 'replaced': True}, 'account_name') mock_lookup.return_value = {'foo': 'bar'} @@ -239,28 +252,28 @@ def test_020_update(self, mock_mcheck, mock_lookup): @patch('acme_srv.renewalinfo.Renewalinfo._cert_dic_lookup') @patch('acme_srv.message.Message.check') - def test_021_update(self, mock_mcheck, mock_lookup): + def test_022_update(self, mock_mcheck, mock_lookup): """ test update() """ mock_mcheck.return_value = (200, 'message', 'detail', 'protected', {'certid': 'certid', 'replaced': True}, 'account_name') mock_lookup.return_value = {'foo': 'bar'} self.renewalinfo.dbstore.certificate_add.return_value = 1 self.assertEqual({'code': 200}, self.renewalinfo.update('content')) - def test_022_renewalinfo_string_get(self): + def test_023_renewalinfo_string_get(self): """ test update() """ self.renewalinfo.server_name = 'http://server.name' self.renewalinfo.path_dic = {'renewalinfo': '/renewalinfo'} input_string = 'http://server.name/renewalinfo/foo' self.assertEqual('foo', self.renewalinfo._renewalinfo_string_get(input_string)) - def test_023_renewalinfo_string_get(self): + def test_024_renewalinfo_string_get(self): """ test update() """ self.renewalinfo.server_name = 'http://server.name' self.renewalinfo.path_dic = {'renewalinfo': '/renewalinfo'} input_string = 'http://server.name/renewalinfofoo' self.assertEqual('foo', self.renewalinfo._renewalinfo_string_get(input_string)) - def test_024_renewalinfo_string_get(self): + def test_025_renewalinfo_string_get(self): """ test update() """ self.renewalinfo.server_name = 'http://server.name' self.renewalinfo.path_dic = {'renewalinfo': '/renewalinfo/'} @@ -271,7 +284,7 @@ def test_024_renewalinfo_string_get(self): @patch('acme_srv.renewalinfo.Renewalinfo._draft01_lookup') @patch('acme_srv.renewalinfo.certid_hex_get') @patch('acme_srv.renewalinfo.Renewalinfo._serial_aki_get') - def test_025_cert_dic_lookup(self, mock_aki, mock_certid, mock_draft01, mock_draft02): + def test_026_cert_dic_lookup(self, mock_aki, mock_certid, mock_draft01, mock_draft02): """ test _cert_dic_lookup() """ mock_aki.return_value = ('serail', 'aki') mock_draft01.return_value = {'foo': 'draft01'} @@ -286,7 +299,7 @@ def test_025_cert_dic_lookup(self, mock_aki, mock_certid, mock_draft01, mock_dra @patch('acme_srv.renewalinfo.Renewalinfo._draft01_lookup') @patch('acme_srv.renewalinfo.certid_hex_get') @patch('acme_srv.renewalinfo.Renewalinfo._serial_aki_get') - def test_026_cert_dic_lookup(self, mock_aki, mock_certid, mock_draft01, mock_draft02): + def test_027_cert_dic_lookup(self, mock_aki, mock_certid, mock_draft01, mock_draft02): """ test _cert_dic_lookup() """ mock_aki.return_value = ('serail', 'aki') mock_certid.return_value = ('mda', 'certid') @@ -298,31 +311,14 @@ def test_026_cert_dic_lookup(self, mock_aki, mock_certid, mock_draft01, mock_dra self.assertTrue(mock_draft01.called) self.assertFalse(mock_draft02.called) - def test_027_draft01_lookup(self): + def test_028_draft01_lookup(self): """ test _draft01_lookup() """ self.renewalinfo.dbstore.certificate_lookup.return_value = {'foo': 'bar'} self.assertEqual({'foo': 'bar'}, self.renewalinfo._draft01_lookup('certid_hex')) - def test_028_draft01_lookup(self): - """ test _draft01_lookup() """ - self.renewalinfo.dbstore.certificate_lookup.side_effect = Exception('cert_lookup') - with self.assertLogs('test_a2c', level='INFO') as lcm: - self.assertFalse(self.renewalinfo._draft01_lookup('certid_hex')) - self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Renewalinfo._draft01_lookup(): cert_lookup', lcm.output) - - def test_029_draft02_lookup(self): - """ test _draft02_lookup() """ - self.renewalinfo.dbstore.certificates_search.return_value = [{'foo': 'bar01', 'aki': 'aki01'}, {'foo': 'bar02', 'aki': 'aki02'}] - self.assertEqual({'aki': 'aki01', 'foo': 'bar01'}, self.renewalinfo._draft02_lookup('serial', 'aki01')) - - def test_030_draft02_lookup(self): - """ test _draft02_lookup() """ - self.renewalinfo.dbstore.certificates_search.return_value = [{'foo': 'bar01', 'aki': 'aki01'}, {'foo': 'bar02', 'aki': 'aki02'}] - self.assertEqual({'aki': 'aki02', 'foo': 'bar02'}, self.renewalinfo._draft02_lookup('serial', 'aki02')) - @patch('acme_srv.renewalinfo.cert_aki_get') @patch('acme_srv.renewalinfo.cert_serial_get') - def test_031_cert_table_update(self, mock_serial, mock_aki): + def test_029_cert_table_update(self, mock_serial, mock_aki): """ test _cert_table_update() """ self.renewalinfo.dbstore.certificates_search.return_value = [{'foo': 'bar', 'cert_raw': 'cert_raw', 'name': 'name', 'cert': 'cert'}] self.assertFalse(self.renewalinfo._cert_table_update()) @@ -331,7 +327,7 @@ def test_031_cert_table_update(self, mock_serial, mock_aki): @patch('acme_srv.renewalinfo.cert_aki_get') @patch('acme_srv.renewalinfo.cert_serial_get') - def test_032_cert_table_update(self, mock_serial, mock_aki): + def test_030_cert_table_update(self, mock_serial, mock_aki): """ test _cert_table_update() """ self.renewalinfo.dbstore.certificates_search.return_value = [{'foo': 'bar', 'cert_raw': None, 'name': 'name', 'cert': 'cert'}] self.assertFalse(self.renewalinfo._cert_table_update()) @@ -340,21 +336,48 @@ def test_032_cert_table_update(self, mock_serial, mock_aki): @patch('acme_srv.renewalinfo.cert_aki_get') @patch('acme_srv.renewalinfo.cert_serial_get') - def test_033_cert_table_update(self, mock_serial, mock_aki): + def test_031_cert_table_update(self, mock_serial, mock_aki): """ test _cert_table_update() """ self.renewalinfo.dbstore.certificates_search.return_value = [{'foo': 'bar', 'name': 'name', 'cert': 'cert'}] self.assertFalse(self.renewalinfo._cert_table_update()) self.assertFalse(mock_serial.called) self.assertFalse(mock_aki.called) - def test_034_draft02_lookup(self): + def test_032_draft02_lookup(self): """ test _draft02_lookup() """ self.renewalinfo.dbstore.certificates_search.return_value = [{'foo': 'bar01', 'aki': 'aki01'}, {'foo': 'bar02', 'aki': 'aki02'}] self.assertFalse(self.renewalinfo._draft02_lookup('serial', 'aki03')) + def test_033_draft01_lookup(self): + """ test _draft01_lookup() """ + self.renewalinfo.dbstore.certificate_lookup.side_effect = Exception('cert_lookup') + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.renewalinfo._draft01_lookup('certid_hex')) + self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Renewalinfo._draft01_lookup(): cert_lookup', lcm.output) + + def test_034_draft02_lookup(self): + """ test _draft02_lookup() """ + self.renewalinfo.dbstore.certificates_search.return_value = [{'foo': 'bar01', 'aki': 'aki01'}, {'foo': 'bar02', 'aki': 'aki02'}] + self.assertEqual({'aki': 'aki01', 'foo': 'bar01'}, self.renewalinfo._draft02_lookup('serial', 'aki01')) + + def test_035_draft02_lookup(self): + """ test _draft02_lookup() """ + self.renewalinfo.dbstore.certificates_search.return_value = [{'foo': 'bar01', 'aki': 'aki01'}, {'foo': 'bar02', 'aki': 'aki02'}] + self.assertEqual({'aki': 'aki02', 'foo': 'bar02'}, self.renewalinfo._draft02_lookup('serial', 'aki02')) + + def test_036_draft02_lookup(self): + """ test _draft02_lookup() failed with leading zero """ + self.renewalinfo.dbstore.certificates_search.side_effect = [[], [{'foo': 'bar01', 'aki': 'aki01'}, {'foo': 'bar02', 'aki': 'aki02'}]] + self.assertEqual({'aki': 'aki02', 'foo': 'bar02'}, self.renewalinfo._draft02_lookup('00serial', 'aki02')) + + def test_037_draft02_lookup(self): + """ test _draft02_lookup() without leading zero""" + self.renewalinfo.dbstore.certificates_search.side_effect = [[], [{'foo': 'bar01', 'aki': 'aki01'}, {'foo': 'bar02', 'aki': 'aki02'}]] + self.assertFalse(self.renewalinfo._draft02_lookup('serial', 'aki02')) + @patch('acme_srv.renewalinfo.cert_aki_get') @patch('acme_srv.renewalinfo.cert_serial_get') - def test_035_cert_table_update(self, mock_serial, mock_aki): + def test_038_cert_table_update(self, mock_serial, mock_aki): """ test _cert_table_update() """ self.renewalinfo.dbstore.certificates_search.side_effect = Exception('certificates_search') with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -363,14 +386,14 @@ def test_035_cert_table_update(self, mock_serial, mock_aki): self.assertFalse(mock_serial.called) self.assertFalse(mock_aki.called) - def test_036_draft02_lookup(self): + def test_039_draft02_lookup(self): """ test _draft02_lookup() """ self.renewalinfo.dbstore.certificates_search.return_value = [{'foo': 'bar01', }, {'foo': 'bar02', 'aki': 'aki02'}] with self.assertLogs('test_a2c', level='INFO') as lcm: self.assertFalse(self.renewalinfo._draft02_lookup('serial', 'aki03')) self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Renewalinfo._draft02_lookup(): certificates_search', lcm.output) - def test_037_draft02_lookup(self): + def test_040_draft02_lookup(self): """ test _draft02_lookup() """ self.renewalinfo.dbstore.certificates_search.side_effect = Exception('certificates_search') with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -379,7 +402,7 @@ def test_037_draft02_lookup(self): @patch('acme_srv.renewalinfo.b64_url_recode') @patch('acme_srv.renewalinfo.b64_decode') - def test_038_serial_aki_get(self, mock_dec, mock_rec): + def test_041_serial_aki_get(self, mock_dec, mock_rec): """ test _serial_aki_get() """ mock_dec.side_effect = [b'aki', b'serial'] mock_rec.side_effect = ['foo1', 'foo2'] @@ -389,7 +412,7 @@ def test_038_serial_aki_get(self, mock_dec, mock_rec): @patch('acme_srv.renewalinfo.b64_url_recode') @patch('acme_srv.renewalinfo.b64_decode') - def test_039_serial_aki_get(self, mock_dec, mock_rec): + def test_042_serial_aki_get(self, mock_dec, mock_rec): """ test _serial_aki_get() """ mock_dec.side_effect = [b'aki', b'serial'] mock_rec.side_effect = ['foo1', 'foo2'] @@ -399,7 +422,7 @@ def test_039_serial_aki_get(self, mock_dec, mock_rec): @patch('acme_srv.renewalinfo.b64_url_recode') @patch('acme_srv.renewalinfo.b64_decode') - def test_040_serial_aki_get(self, mock_dec, mock_rec): + def test_043_serial_aki_get(self, mock_dec, mock_rec): """ test _serial_aki_get() """ mock_dec.side_effect = [b'aki', b'serial'] mock_rec.side_effect = ['foo1', 'foo2'] @@ -407,27 +430,27 @@ def test_040_serial_aki_get(self, mock_dec, mock_rec): self.assertFalse(mock_dec.called) self.assertFalse(mock_rec.called) - def test_041_renewalinfo_generate(self): + def test_044_renewalinfo_generate(self): """ test _renewalinfo_generate() """ self.assertFalse(self.renewalinfo._renewalinfo_generate({})) - def test_042_renewalinfo_generate(self): + def test_045_renewalinfo_generate(self): """ test _renewalinfo_generate() """ cert_dic = {'foo': 'bar'} self.assertFalse(self.renewalinfo._renewalinfo_generate(cert_dic)) - def test_043_renewalinfo_generate(self): + def test_046_renewalinfo_generate(self): """ test _renewalinfo_generate() """ cert_dic = {'expire_uts': 0} self.assertFalse(self.renewalinfo._renewalinfo_generate(cert_dic)) - def test_044_renewalinfo_generate(self): + def test_047_renewalinfo_generate(self): """ test _renewalinfo_generate() """ cert_dic = {'expire_uts': 1000, 'issue_uts': 100} self.assertEqual({'suggestedWindow': {'start': '1970-01-01T00:14:25Z', 'end': '1970-01-01T00:16:40Z'}}, self.renewalinfo._renewalinfo_generate(cert_dic)) @patch('acme_srv.renewalinfo.uts_now') - def test_045_renewalinfo_generate(self, mock_uts): + def test_048_renewalinfo_generate(self, mock_uts): """ test _renewalinfo_generate() """ mock_uts.return_value = 100 cert_dic = {'expire_uts': 1000} @@ -435,7 +458,7 @@ def test_045_renewalinfo_generate(self, mock_uts): self.assertTrue(mock_uts.called) @patch('acme_srv.renewalinfo.uts_now') - def test_046_renewalinfo_generate(self, mock_uts): + def test_049_renewalinfo_generate(self, mock_uts): """ test _renewalinfo_generate() """ mock_uts.return_value = 86400000 cert_dic = {'expire_uts': 1000, 'issue_uts': 200} From ba943e46c5666a320e148f2f8b1e3fbab8cc3947 Mon Sep 17 00:00:00 2001 From: grindsa Date: Fri, 15 Mar 2024 14:52:02 +0100 Subject: [PATCH 109/460] [wf] refactoring workflows --- .../workflows/acme_sh-application-test.yml | 372 +----- .github/workflows/alpn-test.yml | 55 +- .github/workflows/ari-test.yml | 249 +--- .github/workflows/ca_handler_tests_acme.yml | 101 +- .github/workflows/ca_handler_tests_asa.yml | 49 +- .../workflows/ca_handler_tests_certifier.yml | 260 ++-- .github/workflows/ca_handler_tests_cmp.yml | 174 +-- .github/workflows/ca_handler_tests_ejbca.yml | 48 +- .github/workflows/ca_handler_tests_est.yml | 157 +-- .github/workflows/ca_handler_tests_msca.yml | 842 ++++--------- .github/workflows/ca_handler_tests_nclm.yml | 69 +- .../workflows/ca_handler_tests_openssl.yml | 280 ++--- .../workflows/ca_handler_tests_openxpki.yml | 119 +- .github/workflows/ca_handler_tests_xca.yml | 130 +- .github/workflows/caddy-application-test.yml | 264 +--- .../workflows/certbot-application-test.yml | 293 +---- .../certmanager-application-test.yml | 585 ++------- .github/workflows/dns-test.yml | 52 +- .github/workflows/enrollment-timeout.yml | 160 +-- .github/workflows/hooks-test.yml | 1093 +++-------------- .github/workflows/ip-address-tests.yml | 240 +--- .github/workflows/ipv6-test.yml | 195 +-- .github/workflows/lego-application-test.yml | 297 +---- .github/workflows/proxy-test.yml | 170 ++- .github/workflows/test_headerinfo.yml | 301 +---- .github/workflows/tnauth-test.yml | 43 +- .../workflows/traffic-application-test.yml | 34 +- 27 files changed, 1599 insertions(+), 5033 deletions(-) diff --git a/.github/workflows/acme_sh-application-test.yml b/.github/workflows/acme_sh-application-test.yml index 917556e3..4a613543 100644 --- a/.github/workflows/acme_sh-application-test.yml +++ b/.github/workflows/acme_sh-application-test.yml @@ -9,371 +9,51 @@ on: - cron: '0 2 * * 6' jobs: - acme_sh_apache2_wsgi: - name: "acme_sh_apache2_wsgi" + acme_container_tests: + name: "acme_container_tests" runs-on: ubuntu-latest strategy: fail-fast: false matrix: accountkeylength: [2048, ec-256, ec-521] - keylength: [2048, 4096, ec-521] + keylength: [2048, ec-521] + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" - working-directory: examples/Docker/ - run: | - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup openssl ca_handler" - run: | - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - docker-compose restart - docker-compose logs - - - name: "[ PREPARE ] prepare acme.sh container" - run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - - name: "[ ENROLL ] HTTP-01 single domain acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength ${{ matrix.keylength }} --accountkeylength ${{ matrix.accountkeylength }} --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="_ecc" - fi - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer - - - name: "[ RENEW ] HTTP-01 single domain acme.sh" + - name: "create folders" run: | - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="--ecc" - fi - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength ${{ matrix.keylength }} --renew --force ${ECC} -d acme-sh.acme --standalone --debug 3 --output-insecure - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="_ecc" - fi - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer + mkdir acme-sh - - name: "[ REVOKE ] HTTP-01 single domain acme.sh" - run: | - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="--ecc" - fi - docker exec -i acme-sh acme.sh --server http://acme-srv --revoke ${ECC} -d acme-sh.acme --standalone --debug 2 --output-insecure - - - name: "[ ENROLL ] HTTP-01 2x domain acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength ${{ matrix.keylength }} --issue -d acme-sh.acme -d acme-sh. --standalone --debug 3 --output-insecure - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="_ecc" - fi - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer - - - name: "[ RENEW ] HTTP-01 2x domain acme.sh" - run: | - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="--ecc" - fi - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength ${{ matrix.keylength }} --renew --force ${ECC} -d acme-sh.acme -d acme-sh. --standalone --debug 3 --output-insecure - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="_ecc" - fi - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer - - - name: "[ REVOKE ] HTTP-01 2x domain acme.sh" - run: | - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="--ecc" - fi - docker exec -i acme-sh acme.sh --server http://acme-srv --revoke ${ECC} -d acme-sh.acme -d acme-sh. --standalone --debug 3 --output-insecure - - - name: "[ DEACTIVATE ] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --deactivate-account --debug 2 --output-insecure - - - name: "[ * ] collecting test data" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh - - - name: "[ * ] uploading artifacts" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: acme_sh_apache2_wsgi-${{ matrix.accountkeylength }}_key-${{ matrix.keylength }}.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - acme_sh_apache2_django: - name: "acme_sh_apache2_django" - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - accountkeylength: [2048, ec-256, ec-521] - keylength: [2048, 4096, ec-521] - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (apache2_django)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | - sed -i "s/wsgi/django/g" .env sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker network create acme docker-compose up -d docker-compose logs + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup openssl ca_handler and django config" + - name: "setup openssl ca_handler" run: | - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py sudo mkdir -p examples/Docker/data/acme_ca/certs sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem sudo cp .github/django_settings.py examples/Docker/data/settings.py + sudo cp .github/openssl_ca_handler.py_acme_srv_choosen_handler.cfg examples/Docker/data/acme_srv.cfg cd examples/Docker/ docker-compose restart docker-compose logs - - name: "[ PREPARE ] prepare acme.sh container" - run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - - name: "[ ENROLL ] HTTP-01 single domain acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength ${{ matrix.keylength }} --accountkeylength ${{ matrix.accountkeylength }} --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="_ecc" - fi - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer - - - name: "[ RENEW ] HTTP-01 single domain acme.sh" - run: | - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="--ecc" - fi - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength ${{ matrix.keylength }} --renew --force ${ECC} -d acme-sh.acme --standalone --debug 3 --output-insecure - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="_ecc" - fi - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer - - - name: "[ REVOKE ] HTTP-01 single domain acme.sh" - run: | - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="--ecc" - fi - docker exec -i acme-sh acme.sh --server http://acme-srv --revoke ${ECC} -d acme-sh.acme --standalone --debug 2 --output-insecure - - - name: "[ ENROLL ] HTTP-01 2x domain acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength ${{ matrix.keylength }} --issue -d acme-sh.acme -d acme-sh. --standalone --debug 3 --output-insecure - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="_ecc" - fi - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer - - - name: "[ RENEW ] HTTP-01 2x domain acme.sh" - run: | - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="--ecc" - fi - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength ${{ matrix.keylength }} --renew --force ${ECC} -d acme-sh.acme -d acme-sh. --standalone --debug 3 --output-insecure - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="_ecc" - fi - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer - - - name: "[ REVOKE ] HTTP-01 2x domain acme.sh" - run: | - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="--ecc" - fi - docker exec -i acme-sh acme.sh --server http://acme-srv --revoke ${ECC} -d acme-sh.acme -d acme-sh. --standalone --debug 3 --output-insecure - - - name: "[ DEACTIVATE ] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --deactivate-account --debug 2 --output-insecure - - - name: "[ * ] collecting test data" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh - - - name: "[ * ] uploading artifacts" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: acme_sh_apache2_django-${{ matrix.accountkeylength }}_key-${{ matrix.keylength }}.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - acme_sh_nginx_wsgi: - name: "acme_sh_nginx_wsgi" - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - accountkeylength: [2048, ec-256, ec-521] - keylength: [2048, 4096, ec-521] - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (nginx_django)" - working-directory: examples/Docker/ - run: | - sed -i "s/apache2/nginx/g" .env - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup openssl ca_handler" - run: | - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - docker-compose restart - docker-compose logs - - - name: "[ PREPARE ] prepare acme.sh container" - run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - - name: "[ ENROLL ] HTTP-01 single domain acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength ${{ matrix.keylength }} --accountkeylength ${{ matrix.accountkeylength }} --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="_ecc" - fi - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer - - - name: "[ RENEW ] HTTP-01 single domain acme.sh" - run: | - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="--ecc" - fi - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength ${{ matrix.keylength }} --renew --force ${ECC} -d acme-sh.acme --standalone --debug 3 --output-insecure - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="_ecc" - fi - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer - - - name: "[ REVOKE ] HTTP-01 single domain acme.sh" - run: | - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="--ecc" - fi - docker exec -i acme-sh acme.sh --server http://acme-srv --revoke ${ECC} -d acme-sh.acme --standalone --debug 2 --output-insecure - - - name: "[ ENROLL ] HTTP-01 2x domain acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength ${{ matrix.keylength }} --issue -d acme-sh.acme -d acme-sh. --standalone --debug 3 --output-insecure - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="_ecc" - fi - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer - - - name: "[ RENEW ] HTTP-01 2x domain acme.sh" - run: | - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="--ecc" - fi - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength ${{ matrix.keylength }} --renew --force ${ECC} -d acme-sh.acme -d acme-sh. --standalone --debug 3 --output-insecure - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="_ecc" - fi - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer - - - name: "[ REVOKE ] HTTP-01 2x domain acme.sh" - run: | - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="--ecc" - fi - docker exec -i acme-sh acme.sh --server http://acme-srv --revoke ${ECC} -d acme-sh.acme -d acme-sh. --standalone --debug 3 --output-insecure - - - name: "[ DEACTIVATE ] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --deactivate-account --debug 2 --output-insecure - - - name: "[ * ] collecting test data" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh - - - name: "[ * ] uploading artifacts" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: acme_sh_nginx_wsgi-${{ matrix.accountkeylength }}_key-${{ matrix.keylength }}.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - acme_sh_nginx_django: - name: "acme_sh_nginx_django" - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - accountkeylength: [2048, ec-256, ec-521] - keylength: [2048, 4096, ec-521] - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (nginx_django)" - working-directory: examples/Docker/ - run: | - sed -i "s/wsgi/django/g" .env - sed -i "s/apache2/nginx/g" .env - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - name: "[ WAIT ] Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: @@ -382,16 +62,8 @@ jobs: - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] setup openssl ca_handler and django config" - run: | - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg - sudo cp .github/django_settings.py examples/Docker/data/settings.py - cd examples/Docker/ - docker-compose restart - docker-compose logs + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - name: "[ PREPARE ] prepare acme.sh container" run: | @@ -467,5 +139,5 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: acme_sh_nginx_django-${{ matrix.accountkeylength }}_key-${{ matrix.keylength }}.tar.gz + name: acme_container_tests${{ matrix.websrv }}-${{ matrix.dbhandler }}-${{ matrix.accountkeylength }}_key-${{ matrix.keylength }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ diff --git a/.github/workflows/alpn-test.yml b/.github/workflows/alpn-test.yml index e8c79ec0..2116a5fc 100644 --- a/.github/workflows/alpn-test.yml +++ b/.github/workflows/alpn-test.yml @@ -9,50 +9,75 @@ on: - cron: '0 2 * * 6' jobs: - alpn_apache2_wsgi: - name: "alpn_apache2_wsgi" + alpn_container_tests: + name: "alpn__container_tests" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + - name: "create folders" + run: | + mkdir lego + mkdir acme-sh + mkdir certbot + + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker network create acme docker-compose up -d docker-compose logs + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup openssl ca_handler" + - name: "setup openssl ca_handler" run: | - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py sudo mkdir -p examples/Docker/data/acme_ca/certs sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py + sudo cp .github/openssl_ca_handler.py_acme_srv_choosen_handler.cfg examples/Docker/data/acme_srv.cfg + sudo chmod 777 examples/Docker/data/acme_srv.cfg sudo chmod 777 examples/Docker/data/acme_srv.cfg cd examples/Docker/ docker-compose restart docker-compose logs - - name: "Test http://acme-srv/directory is accessable again" + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "Prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ ENROLL ] acme.sh" + - name: "Enroll acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ ENROLL ] lego" + - name: "Enroll lego" run: | - mkdir lego docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --tls run sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt @@ -69,7 +94,7 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: alpn.tar.gz + name: alpn_containercontainer-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ alpn_apache2_wsgi_rpm: diff --git a/.github/workflows/ari-test.yml b/.github/workflows/ari-test.yml index 9cb3d3ce..8b4a29b9 100644 --- a/.github/workflows/ari-test.yml +++ b/.github/workflows/ari-test.yml @@ -10,171 +10,47 @@ on: jobs: - ari_apache2_wsgi: - name: "ari_apache2_wsgi" + ari_container_tests: + name: "ari_container_tests" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" - working-directory: examples/Docker/ - run: | - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup openssl ca_handler" - run: | - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo echo -e "\n\n[Renewalinfo]" >> examples/Docker/data/acme_srv.cfg - sudo echo "renewal_force: True" >> examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - docker-compose restart - docker-compose logs - - - name: "create lego folder" + - name: "create folders" run: | mkdir lego + mkdir acme-sh + mkdir certbot - - name: "[ ENROLL ] HTTP-01 single domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - - name: "[ RENEW ] HTTP-01 single domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep 2> ari.txt - grep "renewalInfo endpoint indicates that renewal is needed" ari.txt - cat ari.txt - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: ari_apache2_wsgi.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - ari_apache2_django: - name: "ari_apache2_django" - runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (apache2_django)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | - sed -i "s/wsgi/django/g" .env sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker network create acme docker-compose up -d docker-compose logs + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup openssl ca_handler and django config" + - name: "Setup openssl ca_handler" run: | - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py sudo mkdir -p examples/Docker/data/acme_ca/certs sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo echo -e "\n\n[Renewalinfo]" >> examples/Docker/data/acme_srv.cfg - sudo echo "renewal_force: True" >> examples/Docker/data/acme_srv.cfg + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem sudo cp .github/django_settings.py examples/Docker/data/settings.py - cd examples/Docker/ - docker-compose restart - docker-compose logs - - - name: "create lego folder" - run: | - mkdir lego - - - name: "[ ENROLL ] HTTP-01 single domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - - name: "[ RENEW ] HTTP-01 single domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep 2> ari.txt - grep "renewalInfo endpoint indicates that renewal is needed" ari.txt - cat ari.txt - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: ari_apache2_django.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - ari_nginx_wsgi: - name: "ari_nginx_wsgi" - runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (nginx_django)" - working-directory: examples/Docker/ - run: | - sed -i "s/apache2/nginx/g" .env - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup openssl ca_handler" - run: | - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg + sudo cp .github/openssl_ca_handler.py_acme_srv_choosen_handler.cfg examples/Docker/data/acme_srv.cfg sudo chmod 777 examples/Docker/data/acme_srv.cfg sudo echo -e "\n\n[Renewalinfo]" >> examples/Docker/data/acme_srv.cfg sudo echo "renewal_force: True" >> examples/Docker/data/acme_srv.cfg @@ -182,57 +58,7 @@ jobs: docker-compose restart docker-compose logs - - name: "create lego folder" - run: | - mkdir lego - - - name: "[ ENROLL ] HTTP-01 single domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - - name: "[ RENEW ] HTTP-01 single domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep 2> ari.txt - grep "renewalInfo endpoint indicates that renewal is needed" ari.txt - cat ari.txt - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: ari_nginx_wsgi.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - ari_nginx_django: - name: "lego_nginx_django" - runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (nginx_django)" - working-directory: examples/Docker/ - run: | - sed -i "s/wsgi/django/g" .env - sed -i "s/apache2/nginx/g" .env - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "[ WAIT ] Sleep for 10s" + - name: "Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -240,30 +66,15 @@ jobs: - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] setup openssl ca_handler and django config" - run: | - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo echo -e "\n\n[Renewalinfo]" >> examples/Docker/data/acme_srv.cfg - sudo echo "renewal_force: True" >> examples/Docker/data/acme_srv.cfg - sudo cp .github/django_settings.py examples/Docker/data/settings.py - cd examples/Docker/ - docker-compose restart - docker-compose logs - - - name: "create lego folder" - run: | - mkdir lego + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - name: "[ ENROLL ] HTTP-01 single domain lego" + - name: "enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - name: "[ RENEW ] HTTP-01 single domain lego" + - name: "renew lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep 2> ari.txt grep "renewalInfo endpoint indicates that renewal is needed" ari.txt @@ -284,7 +95,7 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: ari_nginx_django.tar.gz + name: ari_container-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ ari_wsgi_rpm: @@ -375,12 +186,14 @@ jobs: mkdir -p ${{ github.workspace }}/artifact/upload docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + sudo cp -rp certbot/ ${{ github.workspace }}/artifact/certbot/ sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ sudo rm ${{ github.workspace }}/artifact/data/*.rpm docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log lego + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh certbot lego - name: "[ * ] uploading artificates" uses: actions/upload-artifact@v4 diff --git a/.github/workflows/ca_handler_tests_acme.yml b/.github/workflows/ca_handler_tests_acme.yml index da92b7b4..05db35a2 100644 --- a/.github/workflows/ca_handler_tests_acme.yml +++ b/.github/workflows/ca_handler_tests_acme.yml @@ -9,21 +9,39 @@ on: jobs: acme_ca_handler_test: - name: "ACME CAhandler Tests - Docker" + name: "acme_ca_handler_test" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] + steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + - name: "create folders" + run: | + mkdir lego + mkdir acme-sh + mkdir certbot + + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker network create acme docker-compose up -d docker-compose logs + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - - name: "[ PREPARE ] setup le-sim" + - name: "Setup le-sim" run: | sudo mkdir -p examples/Docker/data-le sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data-le/ca_handler.py @@ -41,20 +59,23 @@ jobs: - name: "Test http://acme-le-sim/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-le-sim/directory - - name: "[ PREPARE ] prepare acme.sh container" + - name: "Prepare acme.sh container" run: | - sudo mkdir acme-sh docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ TEST ] enroll from le-sim" + - name: "Enroll from le-sim" run: | docker exec -i acme-sh acme.sh --server http://acme-le-sim --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force openssl verify -CAfile acme-sh/acme-sh.acme_ecc/ca.cer acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ PREPARE ] setup acme_ca_handler" + - name: "Setup acme ca_handler" run: | sudo mkdir -p examples/Docker/data/acme sudo chmod -R 777 examples/Docker/data/acme + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg sudo chmod 777 examples/Docker/data/acme_srv.cfg sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg @@ -63,8 +84,22 @@ jobs: sudo echo "acme_url: http://acme-le-sim" >> examples/Docker/data/acme_srv.cfg sudo echo "acme_account_email: grindsa@foo.bar" >> examples/Docker/data/acme_srv.cfg sudo sed -i "s/challenge_validation_disable: False/challenge_validation_disable: True/g" examples/Docker/data/acme_srv.cfg + cd examples/Docker/ + docker-compose restart + docker-compose logs + + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Test http://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - name: "[ ENROLL ] via acme_ca_handler" + - name: "Enroll via acme_ca_handler" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-srv.acme --standalone --debug 3 --output-insecure --force & sleep 30 @@ -85,25 +120,36 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: acme_ca_handler.tar.gz + name: acme_ca_handler_container-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ acme_ca_handler_sectigo_test: name: "ACME CAhandler sectigo Tests - Docker" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker network create acme docker-compose up -d docker-compose logs + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - - name: "[ PREPARE ] setup le-sim" + - name: "Setup le-sim" run: | sudo mkdir -p examples/Docker/data-le sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data-le/ca_handler.py @@ -122,20 +168,24 @@ jobs: - name: "Test http://acme-le-sim/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-le-sim/directory - - name: "[ PREPARE ] prepare acme.sh container" + - name: "Prepare acme.sh container" run: | sudo mkdir acme-sh docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ TEST ] enroll from le-sim" + - name: "Enroll from le-sim" run: | docker exec -i acme-sh acme.sh --server http://acme-le-sim --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force openssl verify -CAfile acme-sh/acme-sh.acme_ecc/ca.cer acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ PREPARE ] setup acme_ca_handler" + - name: "Setup openssl ca_handler" run: | - sudo mkdir -p examples/Docker/data/acme - sudo chmod -R 777 examples/Docker/data/acme + sudo mkdir -p examples/Docker/data/acme_ca/certs + sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg sudo chmod 777 examples/Docker/data/acme_srv.cfg sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg @@ -144,8 +194,23 @@ jobs: sudo echo "acme_url: http://acme-le-sim" >> examples/Docker/data/acme_srv.cfg sudo echo "acme_account_email: grindsa@foo.bar" >> examples/Docker/data/acme_srv.cfg sudo sed -i "s/challenge_validation_disable: False/challenge_validation_disable: True/g" examples/Docker/data/acme_srv.cfg + cd examples/Docker/ + docker-compose restart + docker-compose logs + + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Test http://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + - - name: "[ ENROLL ] via acme_ca_handler" + - name: "Enroll via acme_ca_handler" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-srv.acme --standalone --debug 3 --output-insecure --force & sleep 30 @@ -166,7 +231,7 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: acme_ca_handler_sectigo.tar.gz + name: acme_ca_handler_sectigo_container-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ rpm_acme_ca_handler_test: diff --git a/.github/workflows/ca_handler_tests_asa.yml b/.github/workflows/ca_handler_tests_asa.yml index 3541fb07..fd58159d 100644 --- a/.github/workflows/ca_handler_tests_asa.yml +++ b/.github/workflows/ca_handler_tests_asa.yml @@ -12,32 +12,44 @@ jobs: asa_handler_tests: name: "asa_handler_tests" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + - name: "create folders" + run: | + mkdir lego + mkdir acme-sh + mkdir certbot + + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker network create acme docker-compose up -d docker-compose logs - - - name: "[ PREPARE ] create letsencrypt and lego folder" - run: | - mkdir certbot - mkdir lego - mkdir acme-sh - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - name: "[ PREPARE ] setup a2c with asa_ca_handler" run: | - sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem - sudo touch examples/Docker/data/acme_srv.cfg + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py + sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg sudo chmod 777 examples/Docker/data/acme_srv.cfg + sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg sudo echo "handler_file: examples/ca_handler/asa_ca_handler.py" >> examples/Docker/data/acme_srv.cfg sudo echo "api_host: $ASA_API_HOST" >> examples/Docker/data/acme_srv.cfg @@ -60,9 +72,17 @@ jobs: ASA_CA_BUNDLE: ${{ secrets.ASA_CA_BUNDLE }} ASA_PROFILE1: ${{ secrets.ASA_PROFILE1 }} - - name: "Test http://acme-srv/directory is accessable again" + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + - name: "[ PREPARE ] prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon @@ -160,7 +180,6 @@ jobs: docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot --force-renewal --key-type rsa --rsa-key-size 2048 sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem sudo openssl x509 -in certbot/live/certbot/cert.pem -ext keyUsage -noout | grep "Key Encipherment, Data Encipherment" - # sudo openssl x509 -in certbot/live/certbot/cert.pem -text -noout - name: "revoke HTTP-01 single domain certbot" run: | @@ -193,7 +212,7 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: asa_wsgi.tar.gz + name: asa-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ asa_handler_tests_rpm: diff --git a/.github/workflows/ca_handler_tests_certifier.yml b/.github/workflows/ca_handler_tests_certifier.yml index f1c13fd2..f5e47000 100644 --- a/.github/workflows/ca_handler_tests_certifier.yml +++ b/.github/workflows/ca_handler_tests_certifier.yml @@ -12,31 +12,44 @@ jobs: certifier_handler_tests: name: "certifier_handler_tests" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + - name: "create folders" + run: | + mkdir lego + mkdir acme-sh + mkdir certbot + + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker network create acme docker-compose up -d docker-compose logs + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - - name: "[ PREPARE ] create letsencrypt and lego folder" - run: | - mkdir certbot - mkdir lego - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "Setup a2c with certifier_ca_handler" run: | - sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem - sudo touch examples/Docker/data/acme_srv.cfg + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py + sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg sudo chmod 777 examples/Docker/data/acme_srv.cfg + sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> examples/Docker/data/acme_srv.cfg sudo echo "api_host: $NCM_API_HOST" >> examples/Docker/data/acme_srv.cfg @@ -54,89 +67,54 @@ jobs: NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "Test http://acme-srv/directory is accessable again" + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "Prepare acme.sh container" run: | - sudo mkdir acme-sh docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ ENROLL ] acme.sh" + - name: "Enroll acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "revoke via acme.sh" + - name: "Revoke via acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "[ REGISTER ] certbot" + - name: "Register certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ ENROLL ] HTTP-01 single domain certbot" + - name: "Enroll HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem - - name: "revoke HTTP-01 single domain certbot" + - name: "Revoke HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - - name: "[ ENROLL ] lego" + - name: "Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - - name: "revoke HTTP-01 single domain lego" + - name: "Revoke HTTP-01 single domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ - sudo cp -rp certbot/ ${{ github.workspace }}/artifact/certbot/ - sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh certbot lego - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: ncm.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - certifier_p101_handler_tests: - name: "certifier_p101_handler_tests" - runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" - working-directory: examples/Docker/ - run: | - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "[ PREPARE ] create letsencrypt and lego folder" - run: | - mkdir certbot - mkdir lego - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "Setup a2c with certifier_ca_handler with profile 101" run: | sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem sudo touch examples/Docker/data/acme_srv.cfg @@ -158,92 +136,55 @@ jobs: NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} + PROFILE: ${{ secrets.PROFILE }} + + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s - - name: "Test http://acme-srv/directory is accessable again" + - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" - run: | - sudo mkdir acme-sh - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - name: "[ ENROLL ] acme.sh" + - name: "Enroll acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "revoke via acme.sh" + - name: "Revoke via acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "[ REGISTER ] certbot" + - name: "Register certbot" run: | + sudo rm -rf certbot/* docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ ENROLL ] HTTP-01 single domain certbot" + - name: "Enroll HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem sudo openssl x509 -in certbot/live/certbot/cert.pem -ext extendedKeyUsage -noout | grep -i "TLS Web Client" - - name: "revoke HTTP-01 single domain certbot" + - name: "Revoke HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - - name: "[ ENROLL ] lego" + - name: "Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Client" - - name: "revoke HTTP-01 single domain lego" + - name: "Revoke HTTP-01 single domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ - sudo cp -rp certbot/ ${{ github.workspace }}/artifact/certbot/ - sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh certbot lego - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: certifier_p101_handler_tests.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - certifier_p102_handler_tests: - name: "certifier_p102_handler_tests" - runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" - working-directory: examples/Docker/ - run: | - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "[ PREPARE ] create letsencrypt and lego folder" - run: | - mkdir certbot - mkdir lego - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "Setup a2c with certifier_ca_handler with Profile 102" run: | sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem sudo touch examples/Docker/data/acme_srv.cfg @@ -266,45 +207,49 @@ jobs: NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "Test http://acme-srv/directory is accessable again" + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" - run: | - sudo mkdir acme-sh - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - name: "[ ENROLL ] acme.sh" + - name: "Enroll acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "revoke via acme.sh" + - name: "Revoke via acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "[ REGISTER ] certbot" + - name: "Register certbot" run: | + sudo rm -rf certbot/* docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ ENROLL ] HTTP-01 single domain certbot" + - name: "Enroll HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem sudo openssl x509 -in certbot/live/certbot/cert.pem -ext extendedKeyUsage -noout | grep -i "TLS Web Server" - - name: "revoke HTTP-01 single domain certbot" + - name: "Revoke HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - - name: "[ ENROLL ] lego" + - name: "Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Server" - - name: "revoke HTTP-01 single domain lego" + - name: "Revoke HTTP-01 single domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke @@ -324,7 +269,7 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: certifier_p102_handler_tests.tar.gz + name: ncm-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ certifier_handler_tests_rpm: @@ -473,34 +418,45 @@ jobs: name: certifier_ca_handler_rpm-rh${{ matrix.rhversion }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ - certifier_handler_headerinfo_tests: name: "certifier_handler_headerinfo_tests" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker network create acme docker-compose up -d docker-compose logs + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - name: "[ PREPARE ] create lego folder" run: | mkdir lego - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" run: | - sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem - sudo touch examples/Docker/data/acme_srv.cfg + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py + sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg sudo chmod 777 examples/Docker/data/acme_srv.cfg + sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> examples/Docker/data/acme_srv.cfg sudo echo "api_host: $NCM_API_HOST" >> examples/Docker/data/acme_srv.cfg @@ -519,38 +475,46 @@ jobs: NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "Test http://acme-srv/directory is accessable again" + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "Prepare acme.sh container" run: | sudo mkdir acme-sh docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ REGISTER] acme.sh" + - name: "Register acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 - - name: "[ ENROLL] acme.sh with profileID 101" + - name: "Enroll acme.sh with profileID 101" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --useragent profileID=101 --debug 3 --output-insecure awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Client" - - name: "[ ENROLL ] lego with profileID 101" + - name: "Enroll lego with profileID 101" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent profileID=101 -d lego.acme --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Client" - - name: "[ ENROLL] acme.sh with profileID 102" + - name: "Enroll acme.sh with profileID 102" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --renew --force -d acme-sh.acme --standalone --useragent profileID=102 --debug 3 --output-insecure openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Server" - - name: "[ ENROLL ] lego with profileID 102" + - name: "Enroll lego with profileID 102" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent profileID=102 -d lego.acme --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt @@ -570,5 +534,5 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: certifier_handler_headerinfo_tests.tar.gz + name: certifier_handler_headerinfo-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ \ No newline at end of file diff --git a/.github/workflows/ca_handler_tests_cmp.yml b/.github/workflows/ca_handler_tests_cmp.yml index 1e48e41d..d3867bb3 100644 --- a/.github/workflows/ca_handler_tests_cmp.yml +++ b/.github/workflows/ca_handler_tests_cmp.yml @@ -9,42 +9,51 @@ on: - cron: '0 2 * * 6' jobs: - cmp_handler_tests_keycert: - name: "cmp_handler_tests_keycert" + cmp_handler_tests: + name: "cmp_handler_tests" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] steps: - name: "checkout GIT" uses: actions/checkout@v4 - #- name: "[ PREPARE ] patch docker file to ubuntu 22.04" - # run: | - # sudo sed -i "s/FROM ubuntu:20.04/FROM ubuntu:22.04/g" examples/Docker/apache2/wsgi/Dockerfile + - name: "create folders" + run: | + mkdir lego + mkdir acme-sh + mkdir certbot - - name: "[ PREPARE ] get runner ip" + - name: "Get runner ip" run: | echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV - run: echo "runner IP is ${{ env.RUNNER_IP }}" - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker network create acme docker-compose up -d docker-compose logs + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - - name: "[ PREPARE ] create letsencrypt and lego folder" - run: | - mkdir certbot - mkdir lego - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup a2c with cmp_ca_handler" + - name: "Setup a2c with cmp_ca_handler with key-cert authentication" run: | + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py sudo touch examples/Docker/data/ca_bundle.pem sudo touch examples/Docker/data/ra_cert.pem sudo touch examples/Docker/data/ra_key.pem @@ -75,15 +84,22 @@ jobs: CMP_RA_CERT: ${{ secrets.CMP_RA_CERT }} CMP_TRUSTED: ${{ secrets.CMP_TRUSTED }} - - name: "Test http://acme-srv/directory is accessable again" + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "Prepare acme.sh container" run: | - sudo mkdir acme-sh docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ PREPARE ] ssh environment on ramdisk" + - name: "Create ssh environment on ramdisk" run: | sudo mkdir -p /tmp/rd sudo mount -t tmpfs -o size=5M none /tmp/rd @@ -94,7 +110,7 @@ jobs: SSH_KEY: ${{ secrets.WCCE_SSH_ACCESS_KEY }} KNOWN_HOSTS: ${{ secrets.WCCE_SSH_KNOWN_HOSTS }} - - name: "[ PREPARE ] establish SSH connection" + - name: "Establish SSH connection" run: sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -p $SSH_PORT -o UserKnownHostsFile=/tmp/rd/known_hosts -L 8086:$CMP_HOST:8086 -g ping -c 180 $CMP_HOST & env: SSH_USER: ${{ secrets.CMP_SSH_USER }} @@ -102,72 +118,23 @@ jobs: SSH_PORT: ${{ secrets.CMP_SSH_PORT }} CMP_HOST: ${{ secrets.CMP_HOST }} - - name: "[ PREPARE ] Sleep for 5s" + - name: " Sleep for 5s" uses: juliangruber/sleep-action@v2.0.3 with: time: 5s - - name: "[ ENROLL ] acme.sh" + - name: "Enroll acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ - sudo cp -rp certbot/ ${{ github.workspace }}/artifact/certbot/ - sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh certbot lego - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: cmpkeycert.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - cmp_handler_tests_refpsk: - name: "cmp_handler_tests_refpsk" - runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] patch docker file to ubuntu 22.04" - run: | - sudo sed -i "s/FROM ubuntu:20.04/FROM ubuntu:22.04/g" examples/Docker/apache2/wsgi/Dockerfile - - - name: "[ PREPARE ] get runner ip" - run: | - echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV - echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV - - - run: echo "runner IP is ${{ env.RUNNER_IP }}" - - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" - working-directory: examples/Docker/ - run: | - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "[ PREPARE ] create letsencrypt and lego folder" - run: | - mkdir certbot - mkdir lego - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup a2c with cmp_ca_handler" + - name: "[ PREPARE ] setup a2c with cmp_ca_handler with PSK refnum authentication" run: | + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py sudo touch examples/Docker/data/ca_bundle.pem sudo touch examples/Docker/data/ra_cert.pem sudo chmod 777 examples/Docker/data/*.pem @@ -198,39 +165,18 @@ jobs: CMP_REF: ${{ secrets.CMP_REF }} CMP_SECRET: ${{ secrets.CMP_SECRET }} - - name: "Test http://acme-srv/directory is accessable again" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] prepare acme.sh container" - run: | - sudo mkdir acme-sh - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - - name: "[ PREPARE ] ssh environment on ramdisk" - run: | - sudo mkdir -p /tmp/rd - sudo mount -t tmpfs -o size=5M none /tmp/rd - sudo echo "$SSH_KEY" > /tmp/rd/ak.tmp - sudo chmod 600 /tmp/rd/ak.tmp - sudo echo "$KNOWN_HOSTS" > /tmp/rd/known_hosts - env: - SSH_KEY: ${{ secrets.WCCE_SSH_ACCESS_KEY }} - KNOWN_HOSTS: ${{ secrets.WCCE_SSH_KNOWN_HOSTS }} - - - name: "[ PREPARE ] establish SSH connection" - run: sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -p $SSH_PORT -o UserKnownHostsFile=/tmp/rd/known_hosts -L 8086:$CMP_HOST:8086 -g ping -c 180 $CMP_HOST & - env: - SSH_USER: ${{ secrets.CMP_SSH_USER }} - SSH_HOST: ${{ secrets.CMP_SSH_HOST }} - SSH_PORT: ${{ secrets.CMP_SSH_PORT }} - CMP_HOST: ${{ secrets.CMP_HOST }} - - - name: "[ PREPARE ] Sleep for 5s" + - name: "Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: - time: 5s + time: 10s + + - name: "Test http://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - name: "[ ENROLL ] acme.sh" + - name: "Enroll acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer @@ -252,11 +198,11 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: cmprefpsk.tar.gz + name: cmp_handler_tests-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz.tar.gz path: ${{ github.workspace }}/artifact/upload/ - cmp_handler_tests_keycert_cmp: - name: "cmp_handler_tests_keycert_cmp" + rpm_cmp_handler_tests_keycert: + name: "rpm_cmp_handler_tests_keycert" runs-on: ubuntu-latest steps: - name: "checkout GIT" @@ -402,11 +348,11 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: cmpkeycert.tar_rpm.gz + name: rpm_cmp_handler_tests_keycert.tar.gz path: ${{ github.workspace }}/artifact/upload/ - cmp_handler_tests_refpsk_cmp: - name: "cmp_handler_tests_refpsk_cmp" + rpm_cmp_handler_tests_refpsk: + name: "rpm_cmp_handler_tests_refpsk" runs-on: ubuntu-latest steps: - name: "checkout GIT" @@ -552,5 +498,5 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: cmprefpsk.tar_rpm.gz + name: rpm_cmp_handler_tests_refpsk.tar_rpm.gz path: ${{ github.workspace }}/artifact/upload/ \ No newline at end of file diff --git a/.github/workflows/ca_handler_tests_ejbca.yml b/.github/workflows/ca_handler_tests_ejbca.yml index 784e7180..616d7ea7 100644 --- a/.github/workflows/ca_handler_tests_ejbca.yml +++ b/.github/workflows/ca_handler_tests_ejbca.yml @@ -12,11 +12,23 @@ jobs: ejb_ca_tests: name: "ejbca_hander_handler_tests docker image" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] + steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] get runner ip" + - name: "create folders" + run: | + mkdir lego + mkdir acme-sh + mkdir certbot + + - name: "Get runner ip" run: | echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV @@ -32,12 +44,6 @@ jobs: env: EJBCA_IP: ${{ env.RUNNER_IP }} - - name: "[ PREPARE ] create acme-sh, letsencrypt and lego folders" - run: | - mkdir certbot - mkdir lego - mkdir acme-sh - - name: "Instanciate ejbca server" run: | docker run -id --rm -p 80:8080 -p 443:8443 -e TLS_SETUP_ENABLED=true -v $(pwd)/examples/ejbca:/tmp/data -v $(pwd)/examples/Docker/data:/tmp/store --name "ejbca" -h ejbca keyfactor/ejbca-ce @@ -97,17 +103,25 @@ jobs: env: SAEC: ${{ env.SAEC }} - - name: "Build docker-compose (apache2_wsgi)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | + sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker-compose up -d docker-compose logs - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - name: "setup a2c with ejbca_ca_handler" run: | + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py sudo touch examples/Docker/data/acme_srv.cfg sudo chmod 777 examples/Docker/data/acme_srv.cfg sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg @@ -127,9 +141,17 @@ jobs: env: SAEC: ${{ env.SAEC }} - - name: "Test http://acme-srv/directory is accessable again" + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + - name: "prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon @@ -183,7 +205,7 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: ejbca.tar.gz + name: ejbca-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz.tar.gz path: ${{ github.workspace }}/artifact/upload/ ejbca_ca_handler_tests_rpm: diff --git a/.github/workflows/ca_handler_tests_est.yml b/.github/workflows/ca_handler_tests_est.yml index a165a049..338f4210 100644 --- a/.github/workflows/ca_handler_tests_est.yml +++ b/.github/workflows/ca_handler_tests_est.yml @@ -1,4 +1,5 @@ name: CA handler tests - EST handler +# Clientauth tests are not working on testrfc7030 and are done insed openxpi wf on: push: @@ -12,31 +13,42 @@ jobs: est_handler_tests: name: "est_handler_tests" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] + steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] create network" + - name: "create folders" run: | - docker network create acme + mkdir lego + mkdir acme-sh + mkdir certbot - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env + docker network create acme docker-compose up -d docker-compose logs - - - name: "[ PREPARE ] create letsencrypt and lego folder" - run: | - mkdir acme-sh - mkdir lego - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - name: "[ PREPARE ] setup esthandler using http-basic-auth" run: | + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py sudo mkdir -p examples/Docker/data/est sudo chmod -R 777 examples/Docker/data/est sudo touch $HOME/.rnd @@ -60,70 +72,29 @@ jobs: docker-compose restart docker-compose logs - - name: "[ PREPARE ] prepare acme.sh container" + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Test http://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "Prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ ENROLL ] via EST using http-basic-auth" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force - # openssl verify -CAfile examples/Docker/data/est/ca_bundle.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + # - name: "Enroll acme-sh" + # run: | + # docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force - - name: "[ ENROLL ] lego" + - name: "Enroll lego" run: | docker run -i -v $PWD/lego/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - # Clientauth tests are not working on testrfc7030 and are done insed openxpi wf - #- name: "[ PREPARE ] delete lego and acme.sh" - # run: | - # sudo rm -rf lego/* - # sudo rm -rf acme-sh/* - - #- name: "[ PREPARE ] setup using tls-client-auth" - # run: | - # sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg - # sudo echo "handler_file: examples/ca_handler/est_ca_handler.py" >> examples/Docker/data/acme_srv.cfg - # sudo echo "est_host: https://testrfc7030.com:9443" >> examples/Docker/data/acme_srv.cfg - # sudo echo "est_client_key: volume/est/est_client_key.pem" >> examples/Docker/data/acme_srv.cfg - # sudo echo "est_client_cert: volume/est/est_client_cert.pem" >> examples/Docker/data/acme_srv.cfg - # sudo echo "ca_bundle: volume/est/ca_bundle.pem" >> examples/Docker/data/acme_srv.cfg - # cd examples/Docker/ - # docker-compose restart - # docker-compose logs - - #- name: "[ ENROLL ] via est using tls-client-auth" - # run: | - # docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force - - #- name: "[ ENROLL ] lego" - # run: | - # docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - - #- name: "[ PREPARE ] delete lego and acme.sh" - # run: | - # sudo rm -rf lego/* - # sudo rm -rf acme-sh/* - - #- name: "[ PREPARE ] setup using tls-client-auth via pkcs12" - # run: | - # sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg - # sudo echo "handler_file: examples/ca_handler/est_ca_handler.py" >> examples/Docker/data/acme_srv.cfg - # sudo echo "est_host: https://testrfc7030.com:9443" >> examples/Docker/data/acme_srv.cfg - # sudo echo "est_client_cert: volume/est/est_client_cert.p12" >> examples/Docker/data/acme_srv.cfg - # sudo echo "cert_passphrase: Test1234" >> examples/Docker/data/acme_srv.cfg - # sudo echo "ca_bundle: volume/est/ca_bundle.pem" >> examples/Docker/data/acme_srv.cfg - # cd examples/Docker/ - # docker-compose restart - # docker-compose logs - - #- name: "[ ENROLL ] via est using tls-client-auth" - # run: | - # docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force - - #- name: "[ ENROLL ] lego" - # run: | - # docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | @@ -137,7 +108,7 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: est.tar.gz + name: est-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz.tar.gz path: ${{ github.workspace }}/artifact/upload/ est_handler_tests_rpm: @@ -248,54 +219,6 @@ jobs: sudo rm -rf lego/* sudo rm -rf acme-sh/* - # Clientauth tests are not working on testrfc7030 and are done insed openxpi wf - #- name: "[ PREPARE ] setup using tls-client-auth" - # run: | - # sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/acme_srv.cfg - # sudo echo "handler_file: /opt/acme2certifier/examples/ca_handler/est_ca_handler.py" >> data/acme_srv.cfg - # sudo echo "est_host: https://testrfc7030.com:9443" >> data/acme_srv.cfg - # sudo echo "est_client_key: volume/acme_ca/est_client_key.pem" >> data/acme_srv.cfg - # sudo echo "est_client_cert: volume/acme_ca/est_client_cert.pem" >> data/acme_srv.cfg - # sudo echo "ca_bundle: volume/acme_ca/ca_bundle.pem" >> data/acme_srv.cfg - - #- name: "[ PREPARE ] reconfigure est ca-handler " - # run: | - # docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart - - #- name: "[ ENROLL ] via est using tls-client-auth" - # run: | - # docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force - - #- name: "[ ENROLL ] lego" - # run: | - # docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - - #- name: "[ PREPARE ] delete lego and acme.sh" - # run: | - # sudo rm -rf lego/* - # sudo rm -rf acme-sh/* - - #- name: "[ PREPARE ] setup using tls-client-auth" - # run: | - # sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/acme_srv.cfg - # sudo echo "handler_file: /opt/acme2certifier/examples/ca_handler/est_ca_handler.py" >> data/acme_srv.cfg - # sudo echo "est_host: https://testrfc7030.com:9443" >> data/acme_srv.cfg - # sudo echo "est_client_cert: volume/acme_ca/est_client_cert.p12" >> data/acme_srv.cfg - # sudo echo "cert_passphrase: Test1234" >> data/acme_srv.cfg - # sudo echo "ca_bundle: False" >> data/acme_srv.cfg - - #- name: "[ PREPARE ] reconfigure est ca-handler " - # run: | - # docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart - - #- name: "[ ENROLL ] via est using tls-client-auth" - # run: | - # docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force - - #- name: "[ ENROLL ] lego" - # run: | - # docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | diff --git a/.github/workflows/ca_handler_tests_msca.yml b/.github/workflows/ca_handler_tests_msca.yml index eac4195f..d393d7fb 100644 --- a/.github/workflows/ca_handler_tests_msca.yml +++ b/.github/workflows/ca_handler_tests_msca.yml @@ -9,147 +9,29 @@ on: - cron: '0 2 * * 6' jobs: - wcce_handler_ntlm_tests: - name: "wcce_handler_ntlm_tests" + msca_handler_tests: + name: "msca_handler_tests" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] get runner ip" - run: | - echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV - echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV - - - run: echo "runner IP is ${{ env.RUNNER_IP }}" - - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" - working-directory: examples/Docker/ - run: | - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "[ PREPARE ] create letsencrypt and lego folder" + - name: "create folders" run: | - mkdir certbot mkdir lego - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup a2c with ms_wcce_ca_handler" - run: | - sudo touch examples/Docker/data/ca_certs.pem - sudo chmod 777 examples/Docker/data/ca_certs.pem - sudo echo "$WCCE_CA_BUNDLE" > examples/Docker/data/ca_certs.pem - sudo touch examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg - sudo echo "handler_file: /var/www/acme2certifier/examples/ca_handler/mswcce_ca_handler.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "host: $RUNNER_IP" >> examples/Docker/data/acme_srv.cfg - sudo echo "user: $WCCE_USER" >> examples/Docker/data/acme_srv.cfg - sudo echo "password: $WCCE_PASSWORD" >> examples/Docker/data/acme_srv.cfg - sudo echo "template: $WCCE_TEMPLATE" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_name: $WCCE_CA_NAME" >> examples/Docker/data/acme_srv.cfg - sudo echo "target_domain: $WCCE_ADS_DOMAIN" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_bundle: volume/ca_certs.pem" >> examples/Docker/data/acme_srv.cfg - sudo echo "bump: $WCCE_HOST" >> examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - docker-compose restart - docker-compose logs - env: - RUNNER_IP: ${{ env.RUNNER_IP }} - WCCE_USER: ${{ secrets.WCCE_USER }} - WCCE_PASSWORD: ${{ secrets.WCCE_PASSWORD }} - WCCE_TEMPLATE: ${{ secrets.WCCE_TEMPLATE }} - WCCE_CA_NAME: ${{ secrets.WCCE_CA_NAME }} - WCCE_ADS_DOMAIN: ${{ secrets.WCCE_ADS_DOMAIN }} - WCCE_CA_BUNDLE: ${{ secrets.WCCE_CA_BUNDLE }} - WCCE_HOST: ${{ secrets.WCCE_HOST }} - - - name: "Test http://acme-srv/directory is accessable again" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] prepare acme.sh container" - run: | - sudo mkdir acme-sh - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - - name: "[ PREPARE ] ssh environment on ramdisk " - run: | - sudo mkdir -p /tmp/rd - sudo mount -t tmpfs -o size=5M none /tmp/rd - sudo echo "$SSH_KEY" > /tmp/rd/ak.tmp - sudo chmod 600 /tmp/rd/ak.tmp - sudo echo "$KNOWN_HOSTS" > /tmp/rd/known_hosts - env: - SSH_KEY: ${{ secrets.WCCE_SSH_ACCESS_KEY }} - KNOWN_HOSTS: ${{ secrets.WCCE_SSH_KNOWN_HOSTS }} - - - name: "[ PREPARE ] establish SSH connection" - run: sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -p $SSH_PORT -o UserKnownHostsFile=/tmp/rd/known_hosts -L 445:$WCCE_HOST:445 -g ping -c 75 $WCCE_HOST & - env: - SSH_USER: ${{ secrets.WCCE_SSH_USER }} - SSH_HOST: ${{ secrets.WCCE_SSH_HOST }} - SSH_PORT: ${{ secrets.WCCE_SSH_PORT }} - WCCE_HOST: ${{ secrets.WCCE_HOST }} - - - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 5s - - - name: "[ ENROLL ] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force - openssl verify -CAfile examples/Docker/data/ca_certs.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - - name: "[ REGISTER] certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - - name: "[ ENROLL ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - sudo openssl verify -CAfile examples/Docker/data/ca_certs.pem certbot/live/certbot/cert.pem - - - name: "[ ENROLL ] lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - sudo openssl verify -CAfile examples/Docker/data/ca_certs.pem lego/certificates/lego.acme.crt - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ - sudo cp -rp certbot/ ${{ github.workspace }}/artifact/certbot/ - sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh certbot lego - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: wcce_ntlm.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - wcce_handler_krb_tests: - name: "wcce_handler_krb_tests" - runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 + mkdir acme-sh + mkdir certbot - name: "[ PREPARE ] get runner ip" run: | echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV + - run: echo "runner IP is ${{ env.RUNNER_IP }}" - name: "Install dnsmasq" @@ -164,6 +46,7 @@ jobs: sudo sed -i "s/RUNNER_IP/$RUNNER_IP/g" dnsmasq/dnsmasq.conf sudo echo "address=/$WCCE_FQDN/$RUNNER_IP" >> dnsmasq/dnsmasq.conf sudo echo "address=/$WCCE_ADS_DOMAIN/$RUNNER_IP" >> dnsmasq/dnsmasq.conf + sudo echo "address=/$WES_HOST/$RUNNER_IP" >> dnsmasq/dnsmasq.conf cat dnsmasq/dnsmasq.conf sudo cp dnsmasq/dnsmasq.conf /etc/ sudo systemctl enable dnsmasq @@ -172,33 +55,38 @@ jobs: RUNNER_IP: ${{ env.RUNNER_IP }} WCCE_ADS_DOMAIN: ${{ secrets.WCCE_ADS_DOMAIN }} WCCE_FQDN: ${{ secrets.WCCE_FQDN }} + WES_HOST: ${{ secrets.WES_HOST }} - name: "[ PREPARE ] test dns resulution" run: | host $WCCE_ADS_DOMAIN 127.0.0.1 host $WCCE_FQDN 127.0.0.1 + host $WES_HOST 127.0.0.1 env: WCCE_ADS_DOMAIN: ${{ secrets.WCCE_ADS_DOMAIN }} WCCE_FQDN: ${{ secrets.WCCE_FQDN }} + WES_HOST: ${{ secrets.WES_HOST }} - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | - docker network create acme sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env + docker network create acme docker-compose up -d docker-compose logs + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - - name: "[ PREPARE ] create letsencrypt and lego folder" - run: | - mkdir certbot - mkdir lego - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup a2c with ms_wcce_ca_handler" + - name: "Setup a2c with ms_wcce_ca_handler (ntlm)" run: | + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py sudo touch examples/Docker/data/ca_certs.pem sudo chmod 777 examples/Docker/data/ca_certs.pem sudo echo "$WCCE_CA_BUNDLE" > examples/Docker/data/ca_certs.pem @@ -206,38 +94,38 @@ jobs: sudo chmod 777 examples/Docker/data/acme_srv.cfg sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg sudo echo "handler_file: /var/www/acme2certifier/examples/ca_handler/mswcce_ca_handler.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "host: $WCCE_FQDN" >> examples/Docker/data/acme_srv.cfg + sudo echo "host: $RUNNER_IP" >> examples/Docker/data/acme_srv.cfg sudo echo "user: $WCCE_USER" >> examples/Docker/data/acme_srv.cfg sudo echo "password: $WCCE_PASSWORD" >> examples/Docker/data/acme_srv.cfg sudo echo "template: $WCCE_TEMPLATE" >> examples/Docker/data/acme_srv.cfg sudo echo "ca_name: $WCCE_CA_NAME" >> examples/Docker/data/acme_srv.cfg sudo echo "target_domain: $WCCE_ADS_DOMAIN" >> examples/Docker/data/acme_srv.cfg - sudo echo "domain_controller: $RUNNER_IP" >> examples/Docker/data/acme_srv.cfg sudo echo "ca_bundle: volume/ca_certs.pem" >> examples/Docker/data/acme_srv.cfg - sudo echo "use_kerberos: True" >> examples/Docker/data/acme_srv.cfg cd examples/Docker/ docker-compose restart docker-compose logs env: RUNNER_IP: ${{ env.RUNNER_IP }} - DNSMASQ_IP: ${{ env.DNSMASQ_IP }} WCCE_USER: ${{ secrets.WCCE_USER }} WCCE_PASSWORD: ${{ secrets.WCCE_PASSWORD }} WCCE_TEMPLATE: ${{ secrets.WCCE_TEMPLATE }} WCCE_CA_NAME: ${{ secrets.WCCE_CA_NAME }} WCCE_ADS_DOMAIN: ${{ secrets.WCCE_ADS_DOMAIN }} WCCE_CA_BUNDLE: ${{ secrets.WCCE_CA_BUNDLE }} - WCCE_FQDN: ${{ secrets.WCCE_FQDN }} + WCCE_HOST: ${{ secrets.WCCE_HOST }} - - name: "Test http://acme-srv/directory is accessable again" + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" - run: | - sudo mkdir acme-sh - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - name: "[ PREPARE ] ssh environment on ramdisk " + - name: "Prepare ssh environment on ramdisk " run: | sudo mkdir -p /tmp/rd sudo mount -t tmpfs -o size=5M none /tmp/rd @@ -248,384 +136,189 @@ jobs: SSH_KEY: ${{ secrets.WCCE_SSH_ACCESS_KEY }} KNOWN_HOSTS: ${{ secrets.WCCE_SSH_KNOWN_HOSTS }} - - name: "[ PREPARE ] establish SSH connection" - run: sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -p $SSH_PORT -o UserKnownHostsFile=/tmp/rd/known_hosts -L 445:$WCCE_HOST:445 -L 88:$WCCE_HOST:88 -g ping -c 75 $WCCE_HOST & + - name: "Establish SSH connection" + run: sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -p $SSH_PORT -o UserKnownHostsFile=/tmp/rd/known_hosts -L 445:$WCCE_HOST:445 -L 88:$WCCE_HOST:88 -L 443:$WES_IP:443 -g ping -c 300 $WCCE_HOST & env: SSH_USER: ${{ secrets.WCCE_SSH_USER }} SSH_HOST: ${{ secrets.WCCE_SSH_HOST }} SSH_PORT: ${{ secrets.WCCE_SSH_PORT }} WCCE_HOST: ${{ secrets.WCCE_HOST }} + WES_IP: ${{ secrets.WES_IP }} - - name: "[ PREPARE ] Sleep for 5s" + - name: "Sleep for 5s" uses: juliangruber/sleep-action@v2.0.3 with: time: 5s - - name: "[ ENROLL ] acme.sh" + - name: "Prepare acme.sh container" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force - openssl verify -CAfile examples/Docker/data/ca_certs.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "check for kerberos connection" - working-directory: examples/Docker/ + - name: "Enroll acme.sh" run: | - docker-compose logs | grep -i "Trying to connect" + docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force + openssl verify -CAfile examples/Docker/data/ca_certs.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ REGISTER] certbot" + - name: "Register certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ ENROLL ] HTTP-01 single domain certbot" + - name: "Enroll certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile examples/Docker/data/ca_certs.pem certbot/live/certbot/cert.pem - - name: "[ ENROLL ] lego" + - name: "Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run sudo openssl verify -CAfile examples/Docker/data/ca_certs.pem lego/certificates/lego.acme.crt - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ - sudo cp -rp certbot/ ${{ github.workspace }}/artifact/certbot/ - sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ - sudo cp -rp dnsmasq/ ${{ github.workspace }}/artifact/dnsmasq/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh certbot lego dnsmasq - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: wcce_krb.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - wes_handler_tests: - name: "wes_handler_tests" - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - authscheme: ['ntlm'] - - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] get runner ip" - run: | - echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV - echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV - - - run: echo "runner IP is ${{ env.RUNNER_IP }}" - - - name: "Install dnsmasq" - run: | - sudo apt-get update - sudo apt-get install -y dnsmasq - sudo systemctl disable systemd-resolved - sudo systemctl stop systemd-resolved - sudo mkdir -p dnsmasq - sudo cp .github/dnsmasq.conf dnsmasq/ - sudo chmod -R 777 dnsmasq/dnsmasq.conf - sudo sed -i "s/RUNNER_IP/$RUNNER_IP/g" dnsmasq/dnsmasq.conf - sudo echo "address=/$WES_HOST/$RUNNER_IP" >> dnsmasq/dnsmasq.conf - cat dnsmasq/dnsmasq.conf - sudo cp dnsmasq/dnsmasq.conf /etc/ - sudo systemctl enable dnsmasq - sudo systemctl start dnsmasq - env: - RUNNER_IP: ${{ env.RUNNER_IP }} - WES_HOST: ${{ secrets.WES_HOST }} - - - name: "[ PREPARE ] test dns resulution" + - name: "Setup a2c with ms_wcce_ca_handler (Kerboros)" run: | - host $WES_HOST 127.0.0.1 - env: - WES_HOST: ${{ secrets.WES_HOST }} - - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" - working-directory: examples/Docker/ - run: | - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "[ PREPARE ] create letsencrypt and lego folder" - run: | - mkdir certbot - mkdir lego - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup a2c with mscertsrv_ca_handler" - run: | - sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem + sudo touch examples/Docker/data/ca_certs.pem + sudo chmod 777 examples/Docker/data/ca_certs.pem + sudo echo "$WCCE_CA_BUNDLE" > examples/Docker/data/ca_certs.pem sudo touch examples/Docker/data/acme_srv.cfg sudo chmod 777 examples/Docker/data/acme_srv.cfg sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg - sudo echo "handler_file: examples/ca_handler/mscertsrv_ca_handler.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "host: $WES_HOST" >> examples/Docker/data/acme_srv.cfg - sudo echo "user: $WES_USER" >> examples/Docker/data/acme_srv.cfg - sudo echo "password: $WES_PASSWORD" >> examples/Docker/data/acme_srv.cfg - sudo echo "auth_method: $WES_AUTHMETHOD" >> examples/Docker/data/acme_srv.cfg - sudo echo "template: $WES_TEMPLATE" >> examples/Docker/data/acme_srv.cfg + sudo echo "handler_file: /var/www/acme2certifier/examples/ca_handler/mswcce_ca_handler.py" >> examples/Docker/data/acme_srv.cfg + sudo echo "host: $WCCE_FQDN" >> examples/Docker/data/acme_srv.cfg + sudo echo "user: $WCCE_USER" >> examples/Docker/data/acme_srv.cfg + sudo echo "password: $WCCE_PASSWORD" >> examples/Docker/data/acme_srv.cfg + sudo echo "template: $WCCE_TEMPLATE" >> examples/Docker/data/acme_srv.cfg + sudo echo "ca_name: $WCCE_CA_NAME" >> examples/Docker/data/acme_srv.cfg + sudo echo "target_domain: $WCCE_ADS_DOMAIN" >> examples/Docker/data/acme_srv.cfg + sudo echo "domain_controller: $RUNNER_IP" >> examples/Docker/data/acme_srv.cfg sudo echo "ca_bundle: volume/ca_certs.pem" >> examples/Docker/data/acme_srv.cfg + sudo echo "use_kerberos: True" >> examples/Docker/data/acme_srv.cfg cd examples/Docker/ docker-compose restart docker-compose logs - env: - WES_HOST: ${{ secrets.WES_HOST }} - WES_USER: ${{ secrets.WES_USER }} - WES_PASSWORD: ${{ secrets.WES_PASSWORD }} - WES_AUTHMETHOD: ${{ matrix.authscheme }} - WES_TEMPLATE: ${{ secrets.WES_TEMPLATE }} - - - name: "Test http://acme-srv/directory is accessable again" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] ssh environment on ramdisk" - run: | - sudo mkdir -p /tmp/rd - sudo mount -t tmpfs -o size=5M none /tmp/rd - sudo echo "$SSH_KEY" > /tmp/rd/ak.tmp - sudo chmod 600 /tmp/rd/ak.tmp - sudo echo "$KNOWN_HOSTS" > /tmp/rd/known_hosts - env: - SSH_KEY: ${{ secrets.WCCE_SSH_ACCESS_KEY }} - KNOWN_HOSTS: ${{ secrets.WCCE_SSH_KNOWN_HOSTS }} - - - name: "[ PREPARE ] establish SSH connection" - run: sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -p $SSH_PORT -o UserKnownHostsFile=/tmp/rd/known_hosts -L 443:$WES_IP:443 -g ping -c 180 $WES_IP & - env: - SSH_USER: ${{ secrets.CMP_SSH_USER }} - SSH_HOST: ${{ secrets.CMP_SSH_HOST }} - SSH_PORT: ${{ secrets.CMP_SSH_PORT }} - WES_IP: ${{ secrets.WES_IP }} - - - name: "[ PREPARE ] Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 5s - - - name: "[ PREPARE ] prepare acme.sh container" - run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - - name: "[ ENROLL ] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force - openssl verify -CAfile examples/Docker/data/ca_certs.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - - name: "[ REGISTER] certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - - name: "[ ENROLL ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - sudo openssl verify -CAfile examples/Docker/data/ca_certs.pem certbot/live/certbot/cert.pem - - - name: "[ ENROLL ] lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - sudo openssl verify -CAfile examples/Docker/data/ca_certs.pem lego/certificates/lego.acme.crt - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ - sudo cp -rp certbot/ ${{ github.workspace }}/artifact/certbot/ - sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh certbot lego - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: wes_handler_tests.${{ matrix.authscheme }}.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - wcce_handler_ntlm_tests_rpm: - name: "wcce_handler_ntlm_tests_rpm" - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - rhversion: [8, 9] - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] get runner ip" - run: | - echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV - echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV - - - run: echo "runner IP is ${{ env.RUNNER_IP }}" - - - name: Retrieve Version from version.py - run: | - echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV - - - run: echo "Latest tag is ${{ env.TAG_NAME }}" - - - name: update version number in spec file - run: | - # sudo sed -i "s/Source0:.*/Source0: %{name}-%{version}.tar.gz/g" examples/install_scripts/rpm/acme2certifier.spec - sudo sed -i "s/__version__/${{ env.TAG_NAME }}/g" examples/install_scripts/rpm/acme2certifier.spec - cat examples/install_scripts/rpm/acme2certifier.spec - - - name: build RPM package - id: rpm - uses: grindsa/rpmbuild@alma9 - with: - spec_file: "examples/install_scripts/rpm/acme2certifier.spec" - - - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" - - - name: "[ PREPARE ] setup environment for alma installation" - run: | - docker network create acme - sudo mkdir -p data - sudo chmod -R 777 data - sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data - sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data - - - name: "Retrieve rpms from SBOM repo" - run: | - git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom - cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data - env: - GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} - GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} - - - name: "[ PREPARE ] prepare acme_srv.cfg with ms_wcce_ca_handler" - run: | - mkdir -p data/acme_ca - sudo touch data/acme_ca/ca_certs.pem - sudo chmod 777 data/acme_ca/ca_certs.pem - sudo echo "$WCCE_CA_BUNDLE" > data/acme_ca/ca_certs.pem - sudo touch data/acme_ca/acme_srv.cfg - sudo chmod 777 data/acme_ca/acme_srv.cfg - sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/acme_srv.cfg - sudo echo "handler_file: /opt/acme2certifier/examples/ca_handler/mswcce_ca_handler.py" >> data/acme_srv.cfg - sudo echo "host: $RUNNER_IP" >> data/acme_srv.cfg - sudo echo "user: $WCCE_USER" >> data/acme_srv.cfg - sudo echo "password: $WCCE_PASSWORD" >> data/acme_srv.cfg - sudo echo "template: $WCCE_TEMPLATE" >> data/acme_srv.cfg - sudo echo "ca_name: $WCCE_CA_NAME" >> data/acme_srv.cfg - sudo echo "target_domain: $WCCE_ADS_DOMAIN" >> data/acme_srv.cfg - sudo echo "ca_bundle: /opt/acme2certifier/volume/acme_ca/ca_certs.pem" >> data/acme_srv.cfg env: RUNNER_IP: ${{ env.RUNNER_IP }} + DNSMASQ_IP: ${{ env.DNSMASQ_IP }} WCCE_USER: ${{ secrets.WCCE_USER }} WCCE_PASSWORD: ${{ secrets.WCCE_PASSWORD }} WCCE_TEMPLATE: ${{ secrets.WCCE_TEMPLATE }} WCCE_CA_NAME: ${{ secrets.WCCE_CA_NAME }} WCCE_ADS_DOMAIN: ${{ secrets.WCCE_ADS_DOMAIN }} WCCE_CA_BUNDLE: ${{ secrets.WCCE_CA_BUNDLE }} + WCCE_FQDN: ${{ secrets.WCCE_FQDN }} - - name: "[ PREPARE ] Almalinux instance" - run: | - sudo cp examples/Docker/almalinux-systemd/Dockerfile data - sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile - cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache - docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Test http://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] create letsencrypt and lego folder" + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "Enroll acme.sh" run: | - mkdir certbot - mkdir lego - mkdir acme-sh + docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force + openssl verify -CAfile examples/Docker/data/ca_certs.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ RUN ] Execute install scipt" + - name: Check for kerberos connection" + working-directory: examples/Docker/ run: | - docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh + docker-compose logs | grep -i "Trying to connect" - - name: "Test http://acme-srv/directory is accessable " - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + - name: "Register certbot" + run: | + sudo rm -rf certbot/ + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ PREPARE ] prepare acme.sh container" + - name: "Ernoll certbot" run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot + sudo openssl verify -CAfile examples/Docker/data/ca_certs.pem certbot/live/certbot/cert.pem - - name: "[ PREPARE ] ssh environment on ramdisk " + - name: "Enroll lego" run: | - sudo mkdir -p /tmp/rd - sudo mount -t tmpfs -o size=5M none /tmp/rd - sudo echo "$SSH_KEY" > /tmp/rd/ak.tmp - sudo chmod 600 /tmp/rd/ak.tmp - sudo echo "$KNOWN_HOSTS" > /tmp/rd/known_hosts - env: - SSH_KEY: ${{ secrets.WCCE_SSH_ACCESS_KEY }} - KNOWN_HOSTS: ${{ secrets.WCCE_SSH_KNOWN_HOSTS }} + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + sudo openssl verify -CAfile examples/Docker/data/ca_certs.pem lego/certificates/lego.acme.crt - - name: "[ PREPARE ] establish SSH connection" - run: sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -p $SSH_PORT -o UserKnownHostsFile=/tmp/rd/known_hosts -L 445:$WCCE_HOST:445 -g ping -c 75 $WCCE_HOST & + - name: "Setup a2c with mscertsrv_ca_handler" + run: | + sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem + sudo touch examples/Docker/data/acme_srv.cfg + sudo chmod 777 examples/Docker/data/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg + sudo echo "handler_file: examples/ca_handler/mscertsrv_ca_handler.py" >> examples/Docker/data/acme_srv.cfg + sudo echo "host: $WES_HOST" >> examples/Docker/data/acme_srv.cfg + sudo echo "user: $WES_USER" >> examples/Docker/data/acme_srv.cfg + sudo echo "password: $WES_PASSWORD" >> examples/Docker/data/acme_srv.cfg + sudo echo "auth_method: $WES_AUTHMETHOD" >> examples/Docker/data/acme_srv.cfg + sudo echo "template: $WES_TEMPLATE" >> examples/Docker/data/acme_srv.cfg + sudo echo "ca_bundle: volume/ca_certs.pem" >> examples/Docker/data/acme_srv.cfg + sudo echo "WCCE_HOST: $WCCE_HOST" >> examples/Docker/data/acme_srv.cfg + cd examples/Docker/ + docker-compose restart + docker-compose logs env: - SSH_USER: ${{ secrets.WCCE_SSH_USER }} - SSH_HOST: ${{ secrets.WCCE_SSH_HOST }} - SSH_PORT: ${{ secrets.WCCE_SSH_PORT }} + WES_HOST: ${{ secrets.WES_HOST }} + WES_USER: ${{ secrets.WES_USER }} + WES_PASSWORD: ${{ secrets.WES_PASSWORD }} + WES_TEMPLATE: ${{ secrets.WES_TEMPLATE }} + WES_AUTHMETHOD: ${{ secrets.WES_AUTHMETHOD }} WCCE_HOST: ${{ secrets.WCCE_HOST }} - - name: "[ PREPARE ] Sleep for 5s" + - name: "Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: - time: 5s + time: 10s - - name: "[ ENROLL ] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force - openssl verify -CAfile data/acme_ca/ca_certs.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + - name: "Test http://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - name: "[ REGISTER] certbot" + #- name: "Enroll acme.sh" + # run: | + # docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force + # openssl verify -CAfile examples/Docker/data/ca_certs.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + + - name: "Register certbot" run: | + sudo rm -rf certbot/ docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ ENROLL ] HTTP-01 single domain certbot" + - name: "Enroll certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - sudo openssl verify -CAfile data/acme_ca/ca_certs.pem certbot/live/certbot/cert.pem + sudo openssl verify -CAfile examples/Docker/data/ca_certs.pem certbot/live/certbot/cert.pem - - name: "[ ENROLL ] lego" + - name: "Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - sudo openssl verify -CAfile data/acme_ca/ca_certs.pem lego/certificates/lego.acme.crt + sudo openssl verify -CAfile examples/Docker/data/ca_certs.pem lego/certificates/lego.acme.crt - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | mkdir -p ${{ github.workspace }}/artifact/upload - docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier - sudo rm -rf data/*.rpm - sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ - # docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig - # docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf - docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh + sudo cp -rp certbot/ ${{ github.workspace }}/artifact/certbot/ + sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ + sudo cp -rp dnsmasq/ ${{ github.workspace }}/artifact/dnsmasq/ + cd examples/Docker + docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh certbot lego dnsmasq - name: "[ * ] uploading artificates" uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: wcce_ntlm_rpm-rh${{ matrix.rhversion }}.tar.gz + name: msca-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ - wcce_handler_krb_tests_rpm: - name: "wcce_handler_krb_tests_rpm" + msca_handler_tests_rpm: + name: "msca_handler_tests_rpm" runs-on: ubuntu-latest strategy: fail-fast: false @@ -635,7 +328,7 @@ jobs: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] get runner ip" + - name: "Get runner ip" run: | echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV @@ -656,6 +349,7 @@ jobs: sudo sed -i "s/RUNNER_IP/$RUNNER_IP/g" dnsmasq/dnsmasq.conf sudo echo "address=/$WCCE_FQDN/$RUNNER_IP" >> dnsmasq/dnsmasq.conf sudo echo "address=/$WCCE_ADS_DOMAIN/$RUNNER_IP" >> dnsmasq/dnsmasq.conf + sudo echo "address=/$WES_HOST/$RUNNER_IP" >> dnsmasq/dnsmasq.conf cat dnsmasq/dnsmasq.conf sudo cp dnsmasq/dnsmasq.conf /etc/ sudo sed -i "s/ --local-service/ /g" /etc/init.d/dnsmasq @@ -665,14 +359,17 @@ jobs: RUNNER_IP: ${{ env.RUNNER_IP }} WCCE_ADS_DOMAIN: ${{ secrets.WCCE_ADS_DOMAIN }} WCCE_FQDN: ${{ secrets.WCCE_FQDN }} + WES_HOST: ${{ secrets.WES_HOST }} - - name: "[ PREPARE ] test dns resulution" + - name: "Test dns resulution" run: | host $WCCE_ADS_DOMAIN ${{ env.RUNNER_IP }} host $WCCE_FQDN ${{ env.RUNNER_IP }} + host $WES_HOST 127.0.0.1 env: WCCE_ADS_DOMAIN: ${{ secrets.WCCE_ADS_DOMAIN }} WCCE_FQDN: ${{ secrets.WCCE_FQDN }} + WES_HOST: ${{ secrets.WES_HOST }} - name: Retrieve Version from version.py run: | @@ -694,7 +391,7 @@ jobs: - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" - - name: "[ PREPARE ] setup environment for alma installation" + - name: "Setup environment for alma installation" run: | docker network create acme sudo mkdir -p data @@ -710,7 +407,7 @@ jobs: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} - - name: "[ PREPARE ] prepare acme_srv.cfg with ms_wcce_ca_handler" + - name: "Prepare acme_srv.cfg with ms_wcce_ca_handler" run: | mkdir -p data/acme_ca sudo touch data/acme_ca/ca_certs.pem @@ -720,15 +417,13 @@ jobs: sudo chmod 777 data/acme_ca/acme_srv.cfg sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/acme_srv.cfg sudo echo "handler_file: /opt/acme2certifier/examples/ca_handler/mswcce_ca_handler.py" >> data/acme_srv.cfg - sudo echo "host: $WCCE_FQDN" >> data/acme_srv.cfg + sudo echo "host: $RUNNER_IP" >> data/acme_srv.cfg sudo echo "user: $WCCE_USER" >> data/acme_srv.cfg sudo echo "password: $WCCE_PASSWORD" >> data/acme_srv.cfg sudo echo "template: $WCCE_TEMPLATE" >> data/acme_srv.cfg sudo echo "ca_name: $WCCE_CA_NAME" >> data/acme_srv.cfg sudo echo "target_domain: $WCCE_ADS_DOMAIN" >> data/acme_srv.cfg - sudo echo "domain_controller: $RUNNER_IP" >> data/acme_srv.cfg sudo echo "ca_bundle: /opt/acme2certifier/volume/acme_ca/ca_certs.pem" >> data/acme_srv.cfg - sudo echo "use_kerberos: True" >> data/acme_srv.cfg env: RUNNER_IP: ${{ env.RUNNER_IP }} WCCE_USER: ${{ secrets.WCCE_USER }} @@ -737,29 +432,33 @@ jobs: WCCE_CA_NAME: ${{ secrets.WCCE_CA_NAME }} WCCE_ADS_DOMAIN: ${{ secrets.WCCE_ADS_DOMAIN }} WCCE_CA_BUNDLE: ${{ secrets.WCCE_CA_BUNDLE }} - WCCE_FQDN: ${{ secrets.WCCE_FQDN }} - - name: "[ PREPARE ] Almalinux instance" + - name: "Prepare Almalinux instance" run: | sudo cp examples/Docker/almalinux-systemd/Dockerfile data sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - - name: "[ PREPARE ] create letsencrypt and lego folder" + - name: "Create letsencrypt and lego folder" run: | mkdir certbot mkdir lego mkdir acme-sh - - name: "[ RUN ] Execute install scipt" + - name: "Execute install scipt" run: | docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh + - name: "Sleep for 5s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 5s + - name: "Test http://acme-srv/directory is accessable " run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" + - name: "Prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon @@ -774,142 +473,101 @@ jobs: SSH_KEY: ${{ secrets.WCCE_SSH_ACCESS_KEY }} KNOWN_HOSTS: ${{ secrets.WCCE_SSH_KNOWN_HOSTS }} - - name: "[ PREPARE ] establish SSH connection" - run: sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -p $SSH_PORT -o UserKnownHostsFile=/tmp/rd/known_hosts -g -L 445:$WCCE_HOST:445 -g -L 88:$WCCE_HOST:88 ping -c 75 $WCCE_HOST & + - name: "Establish SSH connection" + run: sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -p $SSH_PORT -o UserKnownHostsFile=/tmp/rd/known_hosts -L 445:$WCCE_HOST:445 -L 88:$WCCE_HOST:88 -L 443:$WES_IP:443 -g ping -c 300 $WCCE_HOST & env: SSH_USER: ${{ secrets.WCCE_SSH_USER }} SSH_HOST: ${{ secrets.WCCE_SSH_HOST }} SSH_PORT: ${{ secrets.WCCE_SSH_PORT }} WCCE_HOST: ${{ secrets.WCCE_HOST }} + WES_IP: ${{ secrets.WES_IP }} - - name: "[ PREPARE ] Sleep for 5s" + - name: "Sleep for 5s" uses: juliangruber/sleep-action@v2.0.3 with: time: 5s - - name: "[ ENROLL ] acme.sh" + - name: "Enroll acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force openssl verify -CAfile data/acme_ca/ca_certs.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ REGISTER] certbot" + - name: "Register certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ ENROLL ] HTTP-01 single domain certbot" + - name: "Enroll certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile data/acme_ca/ca_certs.pem certbot/live/certbot/cert.pem - - name: "[ ENROLL ] lego" + - name: "Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run sudo openssl verify -CAfile data/acme_ca/ca_certs.pem lego/certificates/lego.acme.crt - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - sudo tail -n 200 /var/log/syslog - mkdir -p ${{ github.workspace }}/artifact/upload - docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier - sudo rm -rf data/*.rpm - sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ - # docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig - # docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf - docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: wcce_handler_krb_tests_rpm-rh${{ matrix.rhversion }}.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - wes_handler_tests_rpm: - name: "wes_handler_tests_rpm" - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - authscheme: ['ntlm'] - rhversion: [8, 9] - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] get runner ip" - run: | - echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV - echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV - - - run: echo "runner IP is ${{ env.RUNNER_IP }}" - - - name: "Install dnsmasq" + - name: "[ PREPARE ] prepare acme_srv.cfg with ms_wcce_ca_handler" run: | - sudo apt-get update - sudo apt-get install -y dnsmasq - sudo systemctl disable systemd-resolved - sudo systemctl stop systemd-resolved - sudo mkdir -p dnsmasq - sudo cp .github/dnsmasq.conf dnsmasq/ - sudo chmod -R 777 dnsmasq/dnsmasq.conf - sudo sed -i "s/RUNNER_IP/$RUNNER_IP/g" dnsmasq/dnsmasq.conf - sudo echo "address=/$WES_HOST/$RUNNER_IP" >> dnsmasq/dnsmasq.conf - cat dnsmasq/dnsmasq.conf - sudo cp dnsmasq/dnsmasq.conf /etc/ - sudo systemctl enable dnsmasq - sudo systemctl start dnsmasq + mkdir -p data/acme_ca + sudo touch data/acme_ca/ca_certs.pem + sudo chmod 777 data/acme_ca/ca_certs.pem + sudo echo "$WCCE_CA_BUNDLE" > data/acme_ca/ca_certs.pem + sudo touch data/acme_ca/acme_srv.cfg + sudo chmod 777 data/acme_ca/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/acme_srv.cfg + sudo echo "handler_file: /opt/acme2certifier/examples/ca_handler/mswcce_ca_handler.py" >> data/acme_srv.cfg + sudo echo "host: $WCCE_FQDN" >> data/acme_srv.cfg + sudo echo "user: $WCCE_USER" >> data/acme_srv.cfg + sudo echo "password: $WCCE_PASSWORD" >> data/acme_srv.cfg + sudo echo "template: $WCCE_TEMPLATE" >> data/acme_srv.cfg + sudo echo "ca_name: $WCCE_CA_NAME" >> data/acme_srv.cfg + sudo echo "target_domain: $WCCE_ADS_DOMAIN" >> data/acme_srv.cfg + sudo echo "domain_controller: $RUNNER_IP" >> data/acme_srv.cfg + sudo echo "ca_bundle: /opt/acme2certifier/volume/acme_ca/ca_certs.pem" >> data/acme_srv.cfg + sudo echo "use_kerberos: True" >> data/acme_srv.cfg env: RUNNER_IP: ${{ env.RUNNER_IP }} - WES_HOST: ${{ secrets.WES_HOST }} + WCCE_USER: ${{ secrets.WCCE_USER }} + WCCE_PASSWORD: ${{ secrets.WCCE_PASSWORD }} + WCCE_TEMPLATE: ${{ secrets.WCCE_TEMPLATE }} + WCCE_CA_NAME: ${{ secrets.WCCE_CA_NAME }} + WCCE_ADS_DOMAIN: ${{ secrets.WCCE_ADS_DOMAIN }} + WCCE_CA_BUNDLE: ${{ secrets.WCCE_CA_BUNDLE }} + WCCE_FQDN: ${{ secrets.WCCE_FQDN }} - - name: "[ PREPARE ] test dns resulution" + - name: "Reconfigure a2c " run: | - host $WES_HOST 127.0.0.1 - env: - WES_HOST: ${{ secrets.WES_HOST }} - + docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart - - name: Retrieve Version from version.py - run: | - echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV + - name: "Sleep for 5s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 5s - - run: echo "Latest tag is ${{ env.TAG_NAME }}" + - name: "Test http://acme-srv/directory is accessable " + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: update version number in spec file + - name: "Enroll acme.sh" run: | - # sudo sed -i "s/Source0:.*/Source0: %{name}-%{version}.tar.gz/g" examples/install_scripts/rpm/acme2certifier.spec - sudo sed -i "s/__version__/${{ env.TAG_NAME }}/g" examples/install_scripts/rpm/acme2certifier.spec - cat examples/install_scripts/rpm/acme2certifier.spec - - - name: build RPM package - id: rpm - uses: grindsa/rpmbuild@alma9 - with: - spec_file: "examples/install_scripts/rpm/acme2certifier.spec" + docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force + openssl verify -CAfile data/acme_ca/ca_certs.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" + - name: "Register certbot" + run: | + sudo rm -rf certbot/* + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ PREPARE ] setup environment for alma installation" + - name: "Enroll certbot" run: | - docker network create acme - sudo mkdir -p data - sudo chmod -R 777 data - sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data - # sudo cp examples/install_scripts/rpm/*.rpm data - sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot + sudo openssl verify -CAfile data/acme_ca/ca_certs.pem certbot/live/certbot/cert.pem - - name: "Retrieve rpms from SBOM repo" + - name: "Enroll lego" run: | - git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom - cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data - env: - GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} - GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + sudo openssl verify -CAfile data/acme_ca/ca_certs.pem lego/certificates/lego.acme.crt - - name: "[ PREPARE ] setup a2c with mscertsrv_ca_handler" + - name: "Setup a2c with mscertsrv_ca_handler" run: | mkdir -p data/acme_ca sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem @@ -927,72 +585,37 @@ jobs: WES_HOST: ${{ secrets.WES_HOST }} WES_USER: ${{ secrets.WES_USER }} WES_PASSWORD: ${{ secrets.WES_PASSWORD }} - WES_AUTHMETHOD: ${{ matrix.authscheme }} + WES_AUTHMETHOD: ${{ secrets.WES_AUTHMETHOD }} WES_TEMPLATE: ${{ secrets.WES_TEMPLATE }} - - name: "[ PREPARE ] Almalinux instance" - run: | - sudo cp examples/Docker/almalinux-systemd/Dockerfile data - sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile - cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache - docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - - - name: "[ PREPARE ] create letsencrypt and lego folder" - run: | - mkdir certbot - mkdir lego - mkdir acme-sh - - - name: "[ RUN ] Execute install scipt" - run: | - docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] ssh environment on ramdisk" + - name: "Reconfigure a2c " run: | - sudo mkdir -p /tmp/rd - sudo mount -t tmpfs -o size=5M none /tmp/rd - sudo echo "$SSH_KEY" > /tmp/rd/ak.tmp - sudo chmod 600 /tmp/rd/ak.tmp - sudo echo "$KNOWN_HOSTS" > /tmp/rd/known_hosts - env: - SSH_KEY: ${{ secrets.WCCE_SSH_ACCESS_KEY }} - KNOWN_HOSTS: ${{ secrets.WCCE_SSH_KNOWN_HOSTS }} + docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart - - name: "[ PREPARE ] establish SSH connection" - run: sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -p $SSH_PORT -o UserKnownHostsFile=/tmp/rd/known_hosts -L 443:$WES_IP:443 -g ping -c 180 $WES_IP & - env: - SSH_USER: ${{ secrets.CMP_SSH_USER }} - SSH_HOST: ${{ secrets.CMP_SSH_HOST }} - SSH_PORT: ${{ secrets.CMP_SSH_PORT }} - WES_IP: ${{ secrets.WES_IP }} - - - name: "[ PREPARE ] Sleep for 5s" + - name: "Sleep for 5s" uses: juliangruber/sleep-action@v2.0.3 with: time: 5s - - name: "[ PREPARE ] prepare acme.sh container" - run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + - name: "Test http://acme-srv/directory is accessable " + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ ENROLL ] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force - openssl verify -CAfile data/acme_ca/ca_certs.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + #- name: "Enroll acme.sh" + # run: | + # docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force + # openssl verify -CAfile data/acme_ca/ca_certs.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ REGISTER] certbot" + - name: "Register certbot" run: | + sudo rm -rf certbot/* docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ ENROLL ] HTTP-01 single domain certbot" + - name: "Enroll certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile data/acme_ca/ca_certs.pem certbot/live/certbot/cert.pem - - name: "[ ENROLL ] lego" + - name: "Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run sudo openssl verify -CAfile data/acme_ca/ca_certs.pem lego/certificates/lego.acme.crt @@ -1005,14 +628,15 @@ jobs: sudo rm -rf data/*.rpm sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + sudo cp -rp dnsmasq/ ${{ github.workspace }}/artifact/dnsmasq/ # docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig # docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh dnsmasq - name: "[ * ] uploading artificates" uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: wes_handler_tests_rpm-rh${{ matrix.rhversion }}.tar.gz - path: ${{ github.workspace }}/artifact/upload/ + name: msca_handler_tests_rpm-rh${{ matrix.rhversion }}.tar.gz + path: ${{ github.workspace }}/artifact/upload/ \ No newline at end of file diff --git a/.github/workflows/ca_handler_tests_nclm.yml b/.github/workflows/ca_handler_tests_nclm.yml index 5226ed94..a554e51e 100644 --- a/.github/workflows/ca_handler_tests_nclm.yml +++ b/.github/workflows/ca_handler_tests_nclm.yml @@ -12,28 +12,41 @@ jobs: nclm_handler_tests: name: "nclm_handler_tests" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + - name: "create folders" + run: | + mkdir lego + mkdir acme-sh + mkdir certbot + + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker network create acme docker-compose up -d docker-compose logs - - - name: "[ PREPARE ] create letsencrypt and lego folder" - run: | - mkdir certbot - mkdir lego - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - name: "[ PREPARE ] setup a2c with nclm_ca_handler" run: | + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem sudo touch examples/Docker/data/acme_srv.cfg sudo chmod 777 examples/Docker/data/acme_srv.cfg @@ -57,35 +70,42 @@ jobs: NCLM_CA_NAME: ${{ secrets.NCLM_CA_NAME }} NCLM_CA_ID_LIST: ${{ secrets.NCLM_CA_ID_LIST }} - - name: "Test http://acme-srv/directory is accessable again" + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "Prepare acme.sh container" run: | - sudo mkdir acme-sh docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ ENROLL ] acme.sh" + - name: "Enroll acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ REGISTER] certbot" + - name: "Register certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ ENROLL ] HTTP-01 single domain certbot" + - name: "Enroll HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem - - name: "[ ENROLL ] lego" + - name: "Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - - name: "[ PREPARE ] reconfigure nclm handler to test enrollment from MSCA" + - name: "Reconfigure nclm handler to test enrollment from MSCA" run: | sudo sed -i "s/ca_name: $NCLM_CA_NAME/ca_name: $NCLM_MSCA_NAME/g" examples/Docker/data/acme_srv.cfg sudo echo "template_name: $NCLM_MSCA_TEMPLATE_NAME" >> examples/Docker/data/acme_srv.cfg @@ -95,12 +115,23 @@ jobs: NCLM_MSCA_NAME: ${{ secrets.NCLM_MSCA_NAME }} NCLM_CA_NAME: ${{ secrets.NCLM_CA_NAME }} - - name: "[ PREPARE ] restart a2c" + - name: "Restart a2c" working-directory: examples/Docker/ run: | docker-compose restart - - name: "[ ENROLL ] lego" + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Test http://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run sudo openssl verify -CAfile lego/certificates/lego.acme.issuer.crt lego/certificates/lego.acme.crt diff --git a/.github/workflows/ca_handler_tests_openssl.yml b/.github/workflows/ca_handler_tests_openssl.yml index 624c341d..fe2961f9 100644 --- a/.github/workflows/ca_handler_tests_openssl.yml +++ b/.github/workflows/ca_handler_tests_openssl.yml @@ -9,31 +9,44 @@ on: - cron: '0 2 * * 6' jobs: - openssl_ca_handler_no_tmpl_tests: - name: "openssl_ca_handler_no_tmpl_tests" + openssl_ca_handler_tests: + name: "openssl_ca_handler_tests" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + - name: "create folders" + run: | + mkdir lego + mkdir acme-sh + mkdir certbot + + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker network create acme docker-compose up -d docker-compose logs + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - - name: "[ PREPARE ] create letsencrypt and lego folder" - run: | - mkdir certbot - mkdir lego - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup a2c with openssl_ca_handler" + - name: "Setup a2c with openssl_ca_handler - default" run: | + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py sudo mkdir -p examples/Docker/data/acme_ca/certs sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ @@ -42,15 +55,22 @@ jobs: docker-compose restart docker-compose logs - - name: "Test http://acme-srv/directory is accessable again" + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "Prepare acme.sh container" run: | - sudo mkdir acme-sh docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ ENROLL ] acme.sh" + - name: "Enroll acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer @@ -59,15 +79,15 @@ jobs: openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout | grep "Digital Signature, Key Encipherment" openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout | grep "TLS Web Server Authentication, TLS Web Client Authentication" - - name: "revoke via acme.sh" + - name: "Revoke via acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "[ REGISTER] certbot" + - name: "Register certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ ENROLL ] HTTP-01 single domain certbot" + - name: "Enroll certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem @@ -76,11 +96,11 @@ jobs: sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "Digital Signature, Key Encipherment" sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "TLS Web Server Authentication, TLS Web Client Authentication" - - name: "revoke HTTP-01 single domain certbot" + - name: "Revoke HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - - name: "[ ENROLL ] lego" + - name: "Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt @@ -89,53 +109,11 @@ jobs: sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout | grep "Digital Signature, Key Encipherment" sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout | grep "TLS Web Server Authentication, TLS Web Client Authentication" - - name: "revoke HTTP-01 single domain lego" + - name: "Revoke lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ - sudo cp -rp certbot/ ${{ github.workspace }}/artifact/certbot/ - sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh certbot lego - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: openssl_ca_handler_no_tmpl_tests.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - openssl_ca_handler_tmpl_tests: - name: "openssl_ca_handler_tmpl_tests" - runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" - working-directory: examples/Docker/ - run: | - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "[ PREPARE ] create letsencrypt and lego folder" - run: | - mkdir certbot - mkdir lego - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup a2c with openssl_ca_handler" + - name: "Setup a2c with openssl_ca_handler - with template" run: | sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py sudo mkdir -p examples/Docker/data/acme_ca/certs @@ -151,15 +129,18 @@ jobs: docker-compose restart docker-compose logs - - name: "Test http://acme-srv/directory is accessable again" + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" - run: | - sudo mkdir acme-sh - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - name: "[ ENROLL ] acme.sh" + - name: "Enroll acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force # openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer @@ -168,15 +149,16 @@ jobs: openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout | grep "TLS Web Server Authentication, OCSP Signing" - - name: "revoke via acme.sh" + - name: "Revoke via acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "[ REGISTER] certbot" + - name: "Register certbot" run: | + sudo rm -rf certbot/* docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ ENROLL ] HTTP-01 single domain certbot" + - name: "Enroll certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot # sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem @@ -185,11 +167,11 @@ jobs: sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "TLS Web Server Authentication, OCSP Signing" - - name: "revoke HTTP-01 single domain certbot" + - name: "Revoke certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - - name: "[ ENROLL ] lego" + - name: "Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run # sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt @@ -198,53 +180,11 @@ jobs: sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout | grep "TLS Web Server Authentication, OCSP Signing" - - name: "revoke HTTP-01 single domain lego" + - name: "Revoke lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ - sudo cp -rp certbot/ ${{ github.workspace }}/artifact/certbot/ - sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh certbot lego - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: openssl_ca_handler_tmpl_tests.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - openssl_ca_handler_enforce_tests: - name: "openssl_ca_handler_enforce_tests" - runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" - working-directory: examples/Docker/ - run: | - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "[ PREPARE ] create letsencrypt and lego folder" - run: | - mkdir certbot - mkdir lego - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup a2c with openssl_ca_handler" + - name: "Setup a2c with openssl_ca_handler - cn_enforce" run: | sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py sudo mkdir -p examples/Docker/data/acme_ca/certs @@ -256,68 +196,49 @@ jobs: docker-compose restart docker-compose logs - - name: "Test http://acme-srv/directory is accessable again" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ REGISTER] certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s - - name: "[ ENROLL ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem - sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout - sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "Basic Constraints: critical" - sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "Digital Signature, Key Encipherment" - sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "TLS Web Server Authentication, TLS Web Client Authentication" - sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "Subject: CN = certbot.acme" + - name: "Test http://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "revoke HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | mkdir -p ${{ github.workspace }}/artifact/upload sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ + sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ sudo cp -rp certbot/ ${{ github.workspace }}/artifact/certbot/ + sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ cd examples/Docker docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data certbot - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: openssl_ca_handler_enforce_tests.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - openssl_ca_handler_validity_adjust_tests: - name: "openssl_ca_handler_validity_adjust_tests" - runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh certbot lego - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" - working-directory: examples/Docker/ + - name: "Register certbot" run: | - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs + sudo rm -rf certbot/* + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ PREPARE ] create letsencrypt and lego folder" + - name: "Enroll certbot" run: | - mkdir certbot - mkdir lego + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot + sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem + sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout + sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "Basic Constraints: critical" + sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "Digital Signature, Key Encipherment" + sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "TLS Web Server Authentication, TLS Web Client Authentication" + sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "Subject: CN = certbot.acme" - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + - name: "Revoke certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - - name: "[ PREPARE ] setup a2c with openssl_ca_handler" + - name: "Setup a2c with openssl_ca_handler - adjust cert_validity" run: | sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py sudo mkdir -p examples/Docker/data/acme_ca/certs @@ -329,39 +250,38 @@ jobs: docker-compose restart docker-compose logs - - name: "Test http://acme-srv/directory is accessable again" + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ REGISTER] certbot" + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "Register certbot" run: | + sudo rm -rf certbot/* docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ ENROLL ] HTTP-01 single domain certbot" + - name: "Enroll certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "Not After : Jun 9 17:17:00 2030 GMT" - - name: "revoke HTTP-01 single domain certbot" + - name: "Revoke certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp certbot/ ${{ github.workspace }}/artifact/certbot/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data certbot - - name: "[ * ] uploading artificates" uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: openssl_ca_handler_validity_adjust_tests.tar.gz + name: openssl_ca_handler_tests-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz.tar.gz path: ${{ github.workspace }}/artifact/upload/ openssl_ca_handler_no_tmpl_tests_rpm: diff --git a/.github/workflows/ca_handler_tests_openxpki.yml b/.github/workflows/ca_handler_tests_openxpki.yml index 67e31a57..cc68bba5 100644 --- a/.github/workflows/ca_handler_tests_openxpki.yml +++ b/.github/workflows/ca_handler_tests_openxpki.yml @@ -12,6 +12,11 @@ jobs: ejb_ca_tests: name: "openxpki_hander_handler_tests docker image" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -107,17 +112,25 @@ jobs: env: OPENXPKI_IP: ${{ env.RUNNER_IP }} - - name: "Build docker-compose (apache2_wsgi)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | + sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker-compose up -d docker-compose logs + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "setup a2c with est_ca_handler" + - name: "Setup a2c with est_ca_handler" run: | + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py sudo touch examples/Docker/data/acme_srv.cfg sudo chmod 777 examples/Docker/data/acme_srv.cfg sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg @@ -133,31 +146,39 @@ jobs: env: OPENXPKI_IP: ${{ env.RUNNER_IP }} - - name: "Test http://acme-srv/directory is accessable again" + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "prepare acme.sh container" + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "Prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "enroll via acme.sh" + - name: "Enroll via acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "enroll lego" + - name: "Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - - name: "[ PREPARE ] delete acme-sh, letsencypt and lego folders" + - name: "Delete acme-sh, letsencypt and lego folders" run: | sudo rm -rf lego/* sudo rm -rf acme-sh/* sudo rm -rf certbot/* - - name: "setup a2c with est_ca_handler using pksc12" + - name: "Setup a2c with est_ca_handler using pksc12" run: | sudo touch examples/Docker/data/acme_srv.cfg sudo chmod 777 examples/Docker/data/acme_srv.cfg @@ -174,32 +195,40 @@ jobs: env: OPENXPKI_IP: ${{ env.RUNNER_IP }} - - name: "Test http://acme-srv/directory is accessable again" + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "prepare acme.sh container" + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "Prepare acme.sh container" run: | docker stop acme-sh docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "enroll via acme.sh" + - name: "Enroll via acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "enroll lego" + - name: "Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - - name: "[ PREPARE ] delete acme-sh, letsencypt and lego folders" + - name: "Delete acme-sh, letsencypt and lego folders" run: | sudo rm -rf lego/* sudo rm -rf acme-sh/* sudo rm -rf certbot/* - - name: "setup a2c with openxpki_ca_handler" + - name: "Setup a2c with openxpki_ca_handler" run: | sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg sudo echo "handler_file: examples/ca_handler/openxpki_ca_handler.py" >> examples/Docker/data/acme_srv.cfg @@ -217,53 +246,61 @@ jobs: env: OPENXPKI_IP: ${{ env.RUNNER_IP }} - - name: "Test http://acme-srv/directory is accessable again" + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "prepare acme.sh container" + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "Prepare acme.sh container" run: | docker stop acme-sh docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "Eenroll via acme.sh" + - name: "Enroll via acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "revoke via acme.sh" + - name: "Revoke via acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "register certbot" + - name: "Register certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "enroll HTTP-01 single domain certbot" + - name: "Enroll certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem - - name: "revoke HTTP-01 single domain certbot" + - name: "Revoke certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - - name: "enroll lego" + - name: "Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - - name: "revoke HTTP-01 single domain lego" + - name: "Revoke HTTP-01 single domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke - - name: "[ PREPARE ] delete acme-sh, letsencypt and lego folders" + - name: "Delete acme-sh, letsencypt and lego folders" run: | sudo rm -rf certbot/* sudo rm -rf lego/* sudo rm -rf acme-sh/* - - name: "reconfigure a2c (pkcs12 support)" + - name: "Reconfigure a2c (pkcs12 support)" run: | sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg sudo echo "handler_file: examples/ca_handler/openxpki_ca_handler.py" >> examples/Docker/data/acme_srv.cfg @@ -281,39 +318,47 @@ jobs: env: OPENXPKI_IP: ${{ env.RUNNER_IP }} - - name: "Test http://acme-srv/directory is accessable again" + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "prepare acme.sh container" + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "Prepare acme.sh container" run: | docker stop acme-sh docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "Eenroll via acme.sh" + - name: "Enroll via acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "revoke via acme.sh" + - name: "Revoke via acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "register certbot" + - name: "Register certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "enroll HTTP-01 single domain certbot" + - name: "Enroll HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem - - name: "enroll lego" + - name: "Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - - name: "revoke HTTP-01 single domain lego" + - name: "Revoke HTTP-01 single domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke @@ -334,7 +379,7 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: openxpki.tar.gz + name: openxpki-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz.tar.gz path: ${{ github.workspace }}/artifact/upload/ openxpki_ca_handler_tests_rpm: diff --git a/.github/workflows/ca_handler_tests_xca.yml b/.github/workflows/ca_handler_tests_xca.yml index 556006f4..3b877382 100644 --- a/.github/workflows/ca_handler_tests_xca.yml +++ b/.github/workflows/ca_handler_tests_xca.yml @@ -9,31 +9,44 @@ on: - cron: '0 2 * * 6' jobs: - xca_handler_no_tmpl_tests: - name: "xca_handler_no_tmpl_tests" + xca_handler_tests: + name: "xca_handler_tests" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker network create acme docker-compose up -d docker-compose logs + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - - name: "[ PREPARE ] create letsencrypt and lego folder" + - name: "Create letsencrypt and lego folder" run: | + mkdir acme-sh mkdir certbot mkdir lego - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup a2c with xca_ca_handler" + - name: "Setup a2c with xca_ca_handler - no template" run: | + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py sudo mkdir -p examples/Docker/data/xca sudo chmod -R 777 examples/Docker/data/xca sudo cp test/ca/acme2certifier-clean.xdb examples/Docker/data/xca/$XCA_DB_NAME @@ -57,15 +70,22 @@ jobs: XCA_TEMPLATE: ${{ secrets.XCA_TEMPLATE }} XCA_DB_NAME: ${{ secrets.XCA_DB_NAME }} - - name: "Test http://acme-srv/directory is accessable again" + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "Prepare acme.sh container" run: | - sudo mkdir acme-sh docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ ENROLL ] acme.sh" + - name: "Acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer @@ -74,15 +94,15 @@ jobs: openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout | grep "Digital Signature, Key Encipherment" openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout | grep "TLS Web Server Authentication" - - name: "revoke via acme.sh" + - name: "Revoke via acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "[ REGISTER] certbot" + - name: "Register certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ ENROLL ] HTTP-01 single domain certbot" + - name: "Enroll certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem @@ -91,11 +111,11 @@ jobs: sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "Digital Signature, Key Encipherment" sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "TLS Web Server Authentication" - - name: "revoke HTTP-01 single domain certbot" + - name: "Revoke certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - - name: "[ ENROLL ] lego" + - name: "Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt @@ -104,53 +124,11 @@ jobs: sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout | grep "Digital Signature, Key Encipherment" sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout | grep "TLS Web Server Authentication" - - name: "revoke HTTP-01 single domain lego" + - name: "Revoke lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ - sudo cp -rp certbot/ ${{ github.workspace }}/artifact/certbot/ - sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh certbot lego - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: xca_handler_no_tmpl_tests.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - xca_handler_tmpl_tests: - name: "xca_handler_tmpl_tests" - runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" - working-directory: examples/Docker/ - run: | - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "[ PREPARE ] create letsencrypt and lego folder" - run: | - mkdir certbot - mkdir lego - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup a2c with xca_ca_handler" + - name: "Setup a2c with xca_ca_handler - with template" run: | sudo mkdir -p examples/Docker/data/xca sudo chmod -R 777 examples/Docker/data/xca @@ -175,15 +153,18 @@ jobs: XCA_TEMPLATE: ${{ secrets.XCA_TEMPLATE }} XCA_DB_NAME: ${{ secrets.XCA_DB_NAME }} - - name: "Test http://acme-srv/directory is accessable again" + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" - run: | - sudo mkdir acme-sh - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - name: "[ ENROLL ] acme.sh" + - name: "Enroll acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer @@ -191,15 +172,16 @@ jobs: openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout | grep "TLS Web Server Authentication, TLS Web Client Authentication" - - name: "revoke via acme.sh" + - name: "Revoke via acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "[ REGISTER] certbot" + - name: "Register certbot" run: | + sudo rm -rf certbot/* docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ ENROLL ] HTTP-01 single domain certbot" + - name: "Enroll certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem @@ -207,11 +189,11 @@ jobs: sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "TLS Web Server Authentication, TLS Web Client Authentication" - - name: "revoke HTTP-01 single domain certbot" + - name: "Revoke certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - - name: "[ ENROLL ] lego" + - name: "Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt @@ -219,7 +201,7 @@ jobs: sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout | grep "TLS Web Server Authentication, TLS Web Client Authentication" - - name: "revoke HTTP-01 single domain lego" + - name: "Revoke lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke @@ -239,7 +221,7 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: xca_handler_tmpl_tests.tar.gz + name: xca_handler-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ xca_handler_no_tmpl_tests_rpm: diff --git a/.github/workflows/caddy-application-test.yml b/.github/workflows/caddy-application-test.yml index 2624156a..41263a4a 100644 --- a/.github/workflows/caddy-application-test.yml +++ b/.github/workflows/caddy-application-test.yml @@ -9,282 +9,44 @@ on: - cron: '0 2 * * 6' jobs: - caddy_apache2_wsgi: - name: "caddy_apache2_wsgi" + caddy_container_tests: + name: "caddy_container_tests" runs-on: ubuntu-latest strategy: fail-fast: false matrix: ports: ['-p 80:80 -p 443:443', '-p 443:443'] - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "Build docker-compose (apache2_wsgi)" - working-directory: examples/Docker/ - run: | - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "Setup openssl ca_handler" - run: | - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg - sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem - cd examples/Docker/ - docker-compose restart - docker-compose logs - - - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "Test if https://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - - - name: "Create caddy folder and copy configuratation files" - run: | - mkdir caddy - cp .github/Caddyfile caddy/ - cp .github/acme2certifier_cabundle.pem caddy - - - name: "Enroll certificate with Caddy" - run: | - docker run -d --rm ${{ matrix.ports }} --network acme -v $PWD/caddy/Caddyfile:/etc/caddy/Caddyfile -v$PWD/caddy/acme2certifier_cabundle.pem:/tmp/acme2certifier_cabundle.pem -v $(pwd)/caddy/config:/config -v $(pwd)/caddy/data:/data --name=caddy caddy:2 - - - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s - - - name: "Check for logs indicating successful enrollment" - run: | - docker logs caddy 2>&1 | grep "successfully downloaded available certificate chains" - docker logs caddy 2>&1 | grep "certificate obtained successfully" - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp caddy/ ${{ github.workspace }}/artifact/caddy/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/a2c.log - docker logs caddy 2> ${{ github.workspace }}/artifact/caddy.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log caddy.log data caddy + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: caddy_apache2_wsgi-${{ github.run_id }}.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - - caddy_apache2_django: - name: "caddy_apache2_django" - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - ports: ['-p 80:80 -p 443:443', '-p 443:443'] steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "Build docker-compose (apache2_django)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | - sed -i "s/wsgi/django/g" .env sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker network create acme docker-compose up -d docker-compose logs + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - name: "Setup openssl ca_handler" run: | - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg - sudo cp .github/django_settings.py examples/Docker/data/settings.py sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem - cd examples/Docker/ - docker-compose restart - docker-compose logs - - - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "Test if https://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - - - name: "Create caddy folder and copy configuratation files" - run: | - mkdir caddy - cp .github/Caddyfile caddy/ - cp .github/acme2certifier_cabundle.pem caddy - - - name: "Enroll certificate with Caddy" - run: | - docker run -d --rm ${{ matrix.ports }} --network acme -v $PWD/caddy/Caddyfile:/etc/caddy/Caddyfile -v$PWD/caddy/acme2certifier_cabundle.pem:/tmp/acme2certifier_cabundle.pem -v $(pwd)/caddy/config:/config -v $(pwd)/caddy/data:/data --name=caddy caddy:2 - - - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s - - - name: "Check for logs indicating successful enrollment" - run: | - docker logs caddy 2>&1 | grep "successfully downloaded available certificate chains" - docker logs caddy 2>&1 | grep "certificate obtained successfully" - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp caddy/ ${{ github.workspace }}/artifact/caddy/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/a2c.log - docker logs caddy 2> ${{ github.workspace }}/artifact/caddy.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log caddy.log data caddy - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: caddy_apache2_django-${{ github.run_id }}.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - - caddy_nginx_wsgi: - name: "caddy_nginx_wsgi" - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - ports: ['-p 80:80 -p 443:443', '-p 443:443'] - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "Build docker-compose (nginx_wsgi)" - working-directory: examples/Docker/ - run: | - sed -i "s/apache2/nginx/g" .env - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "Setup openssl ca_handler" - run: | - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem - cd examples/Docker/ - docker-compose restart - docker-compose logs - - - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "Test if https://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - - - name: "Create caddy folder and copy configuratation files" - run: | - mkdir caddy - cp .github/Caddyfile caddy/ - cp .github/acme2certifier_cabundle.pem caddy - - - name: " enroll certificate with Caddy" - run: | - docker run -d --rm ${{ matrix.ports }} --network acme -v $PWD/caddy/Caddyfile:/etc/caddy/Caddyfile -v$PWD/caddy/acme2certifier_cabundle.pem:/tmp/acme2certifier_cabundle.pem -v $(pwd)/caddy/config:/config -v $(pwd)/caddy/data:/data --name=caddy caddy:2 - - - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s - - - name: "Check for logs indicating successful enrollment" - run: | - docker logs caddy 2>&1 | grep "successfully downloaded available certificate chains" - docker logs caddy 2>&1 | grep "certificate obtained successfully" - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp caddy/ ${{ github.workspace }}/artifact/caddy/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/a2c.log - docker logs caddy 2> ${{ github.workspace }}/artifact/caddy.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log caddy.log data caddy - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: caddy_nginx_wsgi-${{ github.run_id }}.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - caddy_nginx_django: - name: "caddy_nginx_django" - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - ports: ['-p 80:80 -p 443:443', '-p 443:443'] - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "Build docker-compose (nginx_django)" - working-directory: examples/Docker/ - run: | - sed -i "s/wsgi/django/g" .env - sed -i "s/apache2/nginx/g" .env - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "Setup openssl ca_handler" - run: | + sudo cp .github/django_settings.py examples/Docker/data/settings.py sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py sudo mkdir -p examples/Docker/data/acme_ca/certs sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg - sudo cp .github/django_settings.py examples/Docker/data/settings.py - sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem - sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem cd examples/Docker/ docker-compose restart docker-compose logs @@ -335,5 +97,5 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: caddy_nginx_django-${{ github.run_id }}.tar.gz + name: caddy_container_tests-${{ github.run_id }}.${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ diff --git a/.github/workflows/certbot-application-test.yml b/.github/workflows/certbot-application-test.yml index df7d1b09..7d902341 100644 --- a/.github/workflows/certbot-application-test.yml +++ b/.github/workflows/certbot-application-test.yml @@ -10,218 +10,44 @@ on: jobs: - certbot_apache2_wsgi: - name: "certbot_apache2_wsgi" + certbot_tests: + name: "certbot_tests" runs-on: ubuntu-latest strategy: fail-fast: false matrix: keylength: [2048, 4096] + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker network create acme docker-compose up -d docker-compose logs + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - name: "[ PREPARE ] Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: time: 10s - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] setup openssl ca_handler" run: | - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - docker-compose restart - docker-compose logs - - - name: "[ PREPARE ] create letsencrypt folder" - run: | - mkdir certbot - - - name: "[ REGISTER] certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - - name: "[ ENROLL ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --rsa-key-size ${{ matrix.keylength }} --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem - - - name: "[ RENEW ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --rsa-key-size ${{ matrix.keylength }} --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem - - - name: "[ REVOKE ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - - - name: "[ ENROLL ] HTTP-01 2x domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --rsa-key-size ${{ matrix.keylength }} --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme -d certbot. --cert-name certbot - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem - - - name: "[ RENEW ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --rsa-key-size ${{ matrix.keylength }} --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme -d certbot. --cert-name certbot - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem - - - name: "[ REVOKE ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme -d certbot. --cert-name certbot - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp certbot/ ${{ github.workspace }}/artifact/certbot/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data certbot - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: certbot_key-${{ matrix.keylength }}.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - certbot_apache2_django: - name: "certbot_apache2_django" - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - keylength: [2048, 4096] - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (apache2_django)" - working-directory: examples/Docker/ - run: | - sed -i "s/wsgi/django/g" .env - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup openssl ca_handler and django config" - run: | - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem sudo cp .github/django_settings.py examples/Docker/data/settings.py - cd examples/Docker/ - docker-compose restart - docker-compose logs - - - name: "[ PREPARE ] create letsencrypt folder" - run: | - mkdir certbot - - - name: "[ REGISTER] certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - - name: "[ ENROLL ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --rsa-key-size ${{ matrix.keylength }} --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem - - - name: "[ RENEW ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --rsa-key-size ${{ matrix.keylength }} --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem - - - name: "[ REVOKE ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - - - name: "[ ENROLL ] HTTP-01 2x domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --rsa-key-size ${{ matrix.keylength }} --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme -d certbot. --cert-name certbot - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem - - - name: "[ RENEW ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --rsa-key-size ${{ matrix.keylength }} --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme -d certbot. --cert-name certbot - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem - - - name: "[ REVOKE ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme -d certbot. --cert-name certbot - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp certbot/ ${{ github.workspace }}/artifact/certbot/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data certbot - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: certbot_key-${{ matrix.keylength }}.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - certbot_nginx_wsgi: - name: "certbot_nginx_wsgi" - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - keylength: [2048, 4096] - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (nginx_django)" - working-directory: examples/Docker/ - run: | - sed -i "s/apache2/nginx/g" .env - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup openssl ca_handler" - run: | sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py sudo mkdir -p examples/Docker/data/acme_ca/certs sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ @@ -230,81 +56,7 @@ jobs: docker-compose restart docker-compose logs - - name: "[ PREPARE ] create letsencrypt folder" - run: | - mkdir certbot - - - name: "[ REGISTER] certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - - name: "[ ENROLL ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --rsa-key-size ${{ matrix.keylength }} --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem - - - name: "[ RENEW ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --rsa-key-size ${{ matrix.keylength }} --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem - - - name: "[ REVOKE ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - - - name: "[ ENROLL ] HTTP-01 2x domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --rsa-key-size ${{ matrix.keylength }} --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme -d certbot. --cert-name certbot - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem - - - name: "[ RENEW ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --rsa-key-size ${{ matrix.keylength }} --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme -d certbot. --cert-name certbot - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem - - - name: "[ REVOKE ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme -d certbot. --cert-name certbot - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp certbot/ ${{ github.workspace }}/artifact/certbot/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data certbot - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: certbot_key-${{ matrix.keylength }}.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - certbot_nginx_django: - name: "certbot_nginx_django" - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - keylength: [2048, 4096] - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (nginx_django)" - working-directory: examples/Docker/ - run: | - sed -i "s/wsgi/django/g" .env - sed -i "s/apache2/nginx/g" .env - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "[ PREPARE ] Sleep for 10s" + - name: "Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -312,16 +64,8 @@ jobs: - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] setup openssl ca_handler and django config" - run: | - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg - sudo cp .github/django_settings.py examples/Docker/data/settings.py - cd examples/Docker/ - docker-compose restart - docker-compose logs + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - name: "[ PREPARE ] create letsencrypt folder" run: | @@ -373,5 +117,6 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: certbot_key-${{ matrix.keylength }}.tar.gz + name: certbot_key-${{ matrix.keylength }}-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ + diff --git a/.github/workflows/certmanager-application-test.yml b/.github/workflows/certmanager-application-test.yml index 1104d4b8..81178125 100644 --- a/.github/workflows/certmanager-application-test.yml +++ b/.github/workflows/certmanager-application-test.yml @@ -12,488 +12,30 @@ jobs: certmgr_http01_apwsgi: name: "apache2 wsgi - certmgr http01 challenge tests" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] get runner ip" + - name: "Get runner ip" run: | echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV - run: echo "runner IP is ${{ env.RUNNER_IP }}" - - name: "[ PREPARE ] install microk8s" - run: | - sudo snap install microk8s --classic - sudo microk8s status --wait-ready - sudo microk8s enable helm3 - sudo microk8s enable ingress - - name: "[ PREPARE ] install dnsmasq" - run: | - sudo mkdir -p data - sudo cp .github/dnsmasq.conf data - sudo cp .github/dnsmasq.yml data - sudo chmod -R 777 data/dnsmasq.conf - sudo chmod -R 777 data/dnsmasq.yml - sudo sed -i "s/RUNNER_IP/${{ env.RUNNER_IP }}/g" data/dnsmasq.conf - sudo sed -i "s/RUNNER_PATH/${{ env.RUNNER_PATH }}/g" data/dnsmasq.yml - cat data/dnsmasq.conf - cat data/dnsmasq.yml - docker pull gigantuar/dnsmasq:latest-amd64 - docker save gigantuar/dnsmasq -o dnsmasq.tar - sudo microk8s ctr image import dnsmasq.tar - sudo microk8s ctr images ls | grep -i gigantuar - - name: "[ PREPARE ] deploy dnsmasq pod" - run: | - sudo microk8s.kubectl apply -f data/dnsmasq.yml - - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s - - - name: "[ CHECK ] check status dnsmasq pod and grab ip" - run: | - sudo microk8s.kubectl get pods -n dnsmasq - sudo microk8s.kubectl -n dnsmasq describe pod dnsmasq - sudo microk8s.kubectl get pods -n dnsmasq | grep -i Running - sudo microk8s.kubectl -n dnsmasq describe pod dnsmasq | grep " IP:" | cut -d ' ' -f 5 - echo DNSMASQ_IP=$(sudo microk8s.kubectl -n dnsmasq describe pod dnsmasq | grep " IP:" | cut -d ' ' -f 5) >> $GITHUB_ENV - - run: echo "dnsmasq pod IP is ${{ env.DNSMASQ_IP }}" - - - name: "[ PREPARE ] change and test dns" - run: | - sudo cp .github/k8s-acme-srv.yml data/ - sudo chmod 777 data/k8s-acme-srv.yml - sudo sed -i "s/DNSMASQ_IP/${{ env.DNSMASQ_IP }}/g" data/k8s-acme-srv.yml - cat data/k8s-acme-srv.yml - host www.bar.local ${{ env.DNSMASQ_IP }} - - - name: "[ PREPARE ] install cert-manager charts" - run: | - sudo microk8s.kubectl create namespace cert-manager - sudo microk8s.helm3 repo add jetstack https://charts.jetstack.io - sudo microk8s.helm3 repo update - sudo microk8s.helm3 install cert-manager jetstack/cert-manager --namespace cert-manager --set installCRDs=true --set podDnsPolicy="None",podDnsConfig.nameservers={${{ env.DNSMASQ_IP }}} - echo CERTMGR_VERSION=$(sudo microk8s.helm3 show chart jetstack/cert-manager | grep version) >> $GITHUB_ENV - - run: echo "cert-manager ${{ env.CERTMGR_VERSION }}" - - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" - run: | - cat examples/Docker/apache2/wsgi/Dockerfile | docker build -t grindsa/acme2certifier:devel -f - . --no-cache - # docker pull grindsa/acme2certifier:devel - docker save grindsa/acme2certifier > a2c.tar - sudo microk8s ctr image import a2c.tar - sudo microk8s ctr images ls | grep -i grindsa - - name: "[ PREPARE ] Create a2c configuration" - run: | - sudo mkdir -p data - sudo cp examples/ca_handler/openssl_ca_handler.py data/ca_handler.py - sudo mkdir -p data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg data/acme_srv.cfg - sudo chmod 777 data/acme_srv.cfg - - name: "[ DEPLOY ] deploy a2c pod" - run: | - sudo microk8s.kubectl apply -f data/k8s-acme-srv.yml - sudo microk8s.kubectl get pods -n cert-manager-acme - - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s - - - name: "[ CHECK ] check status a2c pod and grab ip of a2c pod" - run: | - sudo microk8s.kubectl get pods -n cert-manager-acme - sudo microk8s.kubectl -n cert-manager-acme describe pod acme2certifier - sudo microk8s.kubectl get pods -n cert-manager-acme | grep -i Running - sudo microk8s.kubectl -n cert-manager-acme describe pod acme2certifier | grep " IP:" | cut -d ' ' -f 5 - echo ACME_IP=$(sudo microk8s.kubectl -n cert-manager-acme describe pod acme2certifier | grep " IP:" | cut -d ' ' -f 5) >> $GITHUB_ENV - - run: echo "a2c pod IP is ${{ env.ACME_IP }}" - - - name: "[ DEPLOY ] deploy cert-manager and trigger enrollment" - run: | - sudo cp .github/k8s-cert-mgr-http-01.yml data - sudo chmod -R 777 data/k8s-cert-mgr-http-01.yml - sudo sed -i "s/ACME_SRV/${{ env.ACME_IP }}/g" data/k8s-cert-mgr-http-01.yml - sudo microk8s.kubectl apply -f data/k8s-cert-mgr-http-01.yml - - - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 20s - - - name: "[ CHECK ] check issuer and challenge" - run: | - sudo microk8s.kubectl describe ClusterIssuer acme2certifier - sudo microk8s.kubectl describe challenge - - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 20s - - - name: "[ CHECK ] check issuer and challenge" - run: | - sudo microk8s.kubectl describe ClusterIssuer acme2certifier - sudo microk8s.kubectl describe challenge - - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 20s - - - name: "[ CHECK ] check issuer and challenge" - run: | - sudo microk8s.kubectl describe ClusterIssuer acme2certifier - sudo microk8s.kubectl describe challenge - sudo microk8s.kubectl describe certificate - sudo microk8s.kubectl describe certificates | grep -i "The certificate has been successfully issued" - - name: "[ * ] collecting test logs" - - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ - sudo microk8s.kubectl logs acme2certifier -n cert-manager-acme > ${{ github.workspace }}/artifact/acme2certifier.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz acme2certifier.log data - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: cert-manager-http-apwsgi.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - - certmgr_http01_apdjango: - name: "apache2 django - certmgr http01 challenge tests" - runs-on: ubuntu-latest - steps: - - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] get runner ip" - run: | - echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV - echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV - - run: echo "runner IP is ${{ env.RUNNER_IP }}" - - - name: "[ PREPARE ] install microk8s" - run: | - sudo snap install microk8s --classic - sudo microk8s status --wait-ready - sudo microk8s enable helm3 - sudo microk8s enable ingress - - name: "[ PREPARE ] install dnsmasq" - run: | - sudo mkdir -p data - sudo cp .github/dnsmasq.conf data - sudo cp .github/dnsmasq.yml data - sudo chmod -R 777 data/dnsmasq.conf - sudo chmod -R 777 data/dnsmasq.yml - sudo sed -i "s/RUNNER_IP/${{ env.RUNNER_IP }}/g" data/dnsmasq.conf - sudo sed -i "s/RUNNER_PATH/${{ env.RUNNER_PATH }}/g" data/dnsmasq.yml - cat data/dnsmasq.conf - cat data/dnsmasq.yml - docker pull gigantuar/dnsmasq:latest-amd64 - docker save gigantuar/dnsmasq -o dnsmasq.tar - sudo microk8s ctr image import dnsmasq.tar - sudo microk8s ctr images ls | grep -i gigantuar - - name: "[ PREPARE ] deploy dnsmasq pod" - run: | - sudo microk8s.kubectl apply -f data/dnsmasq.yml - - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s - - - name: "[ CHECK ] check status dnsmasq pod and grab ip" - run: | - sudo microk8s.kubectl get pods -n dnsmasq - sudo microk8s.kubectl -n dnsmasq describe pod dnsmasq - sudo microk8s.kubectl get pods -n dnsmasq | grep -i Running - sudo microk8s.kubectl -n dnsmasq describe pod dnsmasq | grep " IP:" | cut -d ' ' -f 5 - echo DNSMASQ_IP=$(sudo microk8s.kubectl -n dnsmasq describe pod dnsmasq | grep " IP:" | cut -d ' ' -f 5) >> $GITHUB_ENV - - run: echo "dnsmasq pod IP is ${{ env.DNSMASQ_IP }}" - - - name: "[ PREPARE ] change and test dns" - run: | - sudo cp .github/k8s-acme-srv.yml data/ - sudo chmod 777 data/k8s-acme-srv.yml - sudo sed -i "s/DNSMASQ_IP/${{ env.DNSMASQ_IP }}/g" data/k8s-acme-srv.yml - cat data/k8s-acme-srv.yml - host www.bar.local ${{ env.DNSMASQ_IP }} - - - name: "[ PREPARE ] install cert-manager charts" - run: | - sudo microk8s.kubectl create namespace cert-manager - sudo microk8s.helm3 repo add jetstack https://charts.jetstack.io - sudo microk8s.helm3 repo update - sudo microk8s.helm3 install cert-manager jetstack/cert-manager --namespace cert-manager --set installCRDs=true --set podDnsPolicy="None",podDnsConfig.nameservers={${{ env.DNSMASQ_IP }}} - echo CERTMGR_VERSION=$(sudo microk8s.helm3 show chart jetstack/cert-manager | grep version) >> $GITHUB_ENV - - run: echo "cert-manager ${{ env.CERTMGR_VERSION }}" - - - name: "[ PREPARE ] Build docker-compose (apache2_django)" - run: | - cat examples/Docker/apache2/django/Dockerfile | docker build -t grindsa/acme2certifier:devel -f - . --no-cache - docker save grindsa/acme2certifier > a2c.tar - sudo microk8s ctr image import a2c.tar - - - name: "[ PREPARE ] Create a2c configuration" - run: | - sudo mkdir -p data - sudo cp examples/ca_handler/openssl_ca_handler.py data/ca_handler.py - sudo mkdir -p data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem data/acme_ca/ - sudo cp .github/django_settings.py data/settings.py - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg data/acme_srv.cfg - sudo chmod 777 data/acme_srv.cfg - - - name: "[ DEPLOY ] deploy a2c pod" - run: | - sudo microk8s.kubectl apply -f data/k8s-acme-srv.yml - sudo microk8s.kubectl get pods -n cert-manager-acme - - - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s - - - name: "[ CHECK ] check status a2c pod and grab ip of a2c pod" - run: | - sudo microk8s.kubectl get pods -n cert-manager-acme - sudo microk8s.kubectl -n cert-manager-acme describe pod acme2certifier - sudo microk8s.kubectl get pods -n cert-manager-acme | grep -i Running - sudo microk8s.kubectl -n cert-manager-acme describe pod acme2certifier | grep " IP:" | cut -d ' ' -f 5 - echo ACME_IP=$(sudo microk8s.kubectl -n cert-manager-acme describe pod acme2certifier | grep " IP:" | cut -d ' ' -f 5) >> $GITHUB_ENV - - run: echo "a2c pod IP is ${{ env.ACME_IP }}" - - - name: "[ DEPLOY ] deploy cert-manager and trigger enrollment" - run: | - sudo cp .github/k8s-cert-mgr-http-01.yml data - sudo chmod -R 777 data/k8s-cert-mgr-http-01.yml - sudo sed -i "s/ACME_SRV/${{ env.ACME_IP }}/g" data/k8s-cert-mgr-http-01.yml - sudo microk8s.kubectl apply -f data/k8s-cert-mgr-http-01.yml - - - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 20s - - - name: "[ CHECK ] check issuer and challenge" - run: | - sudo microk8s.kubectl describe ClusterIssuer acme2certifier - sudo microk8s.kubectl describe challenge - - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 20s - - - name: "[ CHECK ] check issuer and challenge" - run: | - sudo microk8s.kubectl describe ClusterIssuer acme2certifier - sudo microk8s.kubectl describe challenge - - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 20s - - - name: "[ CHECK ] check issuer and challenge" - run: | - sudo microk8s.kubectl describe ClusterIssuer acme2certifier - sudo microk8s.kubectl describe challenge - sudo microk8s.kubectl describe certificate - sudo microk8s.kubectl describe certificates | grep -i "The certificate has been successfully issued" - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ - sudo microk8s.kubectl logs acme2certifier -n cert-manager-acme > ${{ github.workspace }}/artifact/acme2certifier.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz acme2certifier.log data - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: cert-manager-http-apdjango.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - certmgr_http01_nginxwsgi: - name: "nginx wsgi - certmgr http01 challenge tests" - runs-on: ubuntu-latest - steps: - - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] get runner ip" - run: | - echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV - echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV - - run: echo "runner IP is ${{ env.RUNNER_IP }}" - - - name: "[ PREPARE ] install microk8s" + - name: "Install microk8s" run: | sudo snap install microk8s --classic sudo microk8s status --wait-ready sudo microk8s enable helm3 sudo microk8s enable ingress - - name: "[ PREPARE ] install dnsmasq" - run: | - sudo mkdir -p data - sudo cp .github/dnsmasq.conf data - sudo cp .github/dnsmasq.yml data - sudo chmod -R 777 data/dnsmasq.conf - sudo chmod -R 777 data/dnsmasq.yml - sudo sed -i "s/RUNNER_IP/${{ env.RUNNER_IP }}/g" data/dnsmasq.conf - sudo sed -i "s/RUNNER_PATH/${{ env.RUNNER_PATH }}/g" data/dnsmasq.yml - cat data/dnsmasq.conf - cat data/dnsmasq.yml - docker pull gigantuar/dnsmasq:latest-amd64 - docker save gigantuar/dnsmasq -o dnsmasq.tar - sudo microk8s ctr image import dnsmasq.tar - sudo microk8s ctr images ls | grep -i gigantuar - - name: "[ PREPARE ] deploy dnsmasq pod" - run: | - sudo microk8s.kubectl apply -f data/dnsmasq.yml - - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s - - - name: "[ CHECK ] check status dnsmasq pod and grab ip" - run: | - sudo microk8s.kubectl get pods -n dnsmasq - sudo microk8s.kubectl -n dnsmasq describe pod dnsmasq - sudo microk8s.kubectl get pods -n dnsmasq | grep -i Running - sudo microk8s.kubectl -n dnsmasq describe pod dnsmasq | grep " IP:" | cut -d ' ' -f 5 - echo DNSMASQ_IP=$(sudo microk8s.kubectl -n dnsmasq describe pod dnsmasq | grep " IP:" | cut -d ' ' -f 5) >> $GITHUB_ENV - - run: echo "dnsmasq pod IP is ${{ env.DNSMASQ_IP }}" - - - name: "[ PREPARE ] change and test dns" - run: | - sudo cp .github/k8s-acme-srv.yml data/ - sudo chmod 777 data/k8s-acme-srv.yml - sudo sed -i "s/DNSMASQ_IP/${{ env.DNSMASQ_IP }}/g" data/k8s-acme-srv.yml - cat data/k8s-acme-srv.yml - host www.bar.local ${{ env.DNSMASQ_IP }} - - - name: "[ PREPARE ] install cert-manager charts" - run: | - sudo microk8s.kubectl create namespace cert-manager - sudo microk8s.helm3 repo add jetstack https://charts.jetstack.io - sudo microk8s.helm3 repo update - sudo microk8s.helm3 install cert-manager jetstack/cert-manager --namespace cert-manager --set installCRDs=true --set podDnsPolicy="None",podDnsConfig.nameservers={${{ env.DNSMASQ_IP }}} - echo CERTMGR_VERSION=$(sudo microk8s.helm3 show chart jetstack/cert-manager | grep version) >> $GITHUB_ENV - - run: echo "cert-manager ${{ env.CERTMGR_VERSION }}" - - - name: "[ PREPARE ] Build docker-compose (nginx_wsgi)" - run: | - cat examples/Docker/nginx/wsgi/Dockerfile | docker build -t grindsa/acme2certifier:devel -f - . --no-cache - # docker pull grindsa/acme2certifier:devel - docker save grindsa/acme2certifier > a2c.tar - sudo microk8s ctr image import a2c.tar - sudo microk8s ctr images ls | grep -i grindsa - - name: "[ PREPARE ] Create a2c configuration" - run: | - sudo mkdir -p data - sudo cp examples/ca_handler/openssl_ca_handler.py data/ca_handler.py - sudo mkdir -p data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg data/acme_srv.cfg - sudo chmod 777 data/acme_srv.cfg - - name: "[ DEPLOY ] deploy a2c pod" - run: | - sudo microk8s.kubectl apply -f data/k8s-acme-srv.yml - sudo microk8s.kubectl get pods -n cert-manager-acme - - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s - - - name: "[ CHECK ] check status a2c pod and grab ip of a2c pod" - run: | - sudo microk8s.kubectl get pods -n cert-manager-acme - sudo microk8s.kubectl -n cert-manager-acme describe pod acme2certifier - sudo microk8s.kubectl get pods -n cert-manager-acme | grep -i Running - sudo microk8s.kubectl -n cert-manager-acme describe pod acme2certifier | grep " IP:" | cut -d ' ' -f 5 - echo ACME_IP=$(sudo microk8s.kubectl -n cert-manager-acme describe pod acme2certifier | grep " IP:" | cut -d ' ' -f 5) >> $GITHUB_ENV - - run: echo "a2c pod IP is ${{ env.ACME_IP }}" - - - name: "[ DEPLOY ] deploy cert-manager and trigger enrollment" - run: | - sudo cp .github/k8s-cert-mgr-http-01.yml data - sudo chmod -R 777 data/k8s-cert-mgr-http-01.yml - sudo sed -i "s/ACME_SRV/${{ env.ACME_IP }}/g" data/k8s-cert-mgr-http-01.yml - sudo microk8s.kubectl apply -f data/k8s-cert-mgr-http-01.yml - - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 20s - - - name: "[ CHECK ] check issuer and challenge" - run: | - sudo microk8s.kubectl describe ClusterIssuer acme2certifier - sudo microk8s.kubectl describe challenge - - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 20s - - - name: "[ CHECK ] check issuer and challenge" - run: | - sudo microk8s.kubectl describe ClusterIssuer acme2certifier - sudo microk8s.kubectl describe challenge - - name: "[ WAIT ] Sleep for 20s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 20s - - - name: "[ CHECK ] check issuer and challenge" - run: | - sudo microk8s.kubectl describe ClusterIssuer acme2certifier - sudo microk8s.kubectl describe challenge - sudo microk8s.kubectl describe certificate - sudo microk8s.kubectl describe certificates | grep -i "The certificate has been successfully issued" - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ - sudo microk8s.kubectl logs acme2certifier -n cert-manager-acme > ${{ github.workspace }}/artifact/acme2certifier.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz acme2certifier.log data - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: cert-manager-http-nginxwsgi.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - certmgr_http01_nginxdjango: - name: "nginx wsgi - certmgr http01 challenge tests" - runs-on: ubuntu-latest - steps: - - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] get runner ip" - run: | - echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV - echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV - - run: echo "runner IP is ${{ env.RUNNER_IP }}" - - - name: "[ PREPARE ] install microk8s" - run: | - sudo snap install microk8s --classic - sudo microk8s status --wait-ready - sudo microk8s enable helm3 - sudo microk8s enable ingress - - - name: "[ PREPARE ] install dnsmasq" + - name: "Install dnsmasq" run: | sudo mkdir -p data sudo cp .github/dnsmasq.conf data @@ -509,7 +51,7 @@ jobs: sudo microk8s ctr image import dnsmasq.tar sudo microk8s ctr images ls | grep -i gigantuar - - name: "[ PREPARE ] deploy dnsmasq pod" + - name: "Deploy dnsmasq pod" run: | sudo microk8s.kubectl apply -f data/dnsmasq.yml @@ -518,7 +60,7 @@ jobs: with: time: 10s - - name: "[ CHECK ] check status dnsmasq pod and grab ip" + - name: "Check status dnsmasq pod and grab ip" run: | sudo microk8s.kubectl get pods -n dnsmasq sudo microk8s.kubectl -n dnsmasq describe pod dnsmasq @@ -527,7 +69,7 @@ jobs: echo DNSMASQ_IP=$(sudo microk8s.kubectl -n dnsmasq describe pod dnsmasq | grep " IP:" | cut -d ' ' -f 5) >> $GITHUB_ENV - run: echo "dnsmasq pod IP is ${{ env.DNSMASQ_IP }}" - - name: "[ PREPARE ] change and test dns" + - name: "Change and test dns" run: | sudo cp .github/k8s-acme-srv.yml data/ sudo chmod 777 data/k8s-acme-srv.yml @@ -535,7 +77,7 @@ jobs: cat data/k8s-acme-srv.yml host www.bar.local ${{ env.DNSMASQ_IP }} - - name: "[ PREPARE ] install cert-manager charts" + - name: "Install cert-manager charts" run: | sudo microk8s.kubectl create namespace cert-manager sudo microk8s.helm3 repo add jetstack https://charts.jetstack.io @@ -544,35 +86,40 @@ jobs: echo CERTMGR_VERSION=$(sudo microk8s.helm3 show chart jetstack/cert-manager | grep version) >> $GITHUB_ENV - run: echo "cert-manager ${{ env.CERTMGR_VERSION }}" - - name: "[ PREPARE ] Build docker-compose (nginx_django)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" run: | - cat examples/Docker/nginx/django/Dockerfile | docker build -t grindsa/acme2certifier:devel -f - . --no-cache - # docker pull grindsa/acme2certifier:devel + cat examples/Docker/$WEB_SRV/$DB_HANDLER/Dockerfile | docker build -t grindsa/acme2certifier:devel -f - . --no-cache docker save grindsa/acme2certifier > a2c.tar sudo microk8s ctr image import a2c.tar sudo microk8s ctr images ls | grep -i grindsa + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - - name: "[ PREPARE ] Create a2c configuration" + - name: "Create a2c configuration" run: | sudo mkdir -p data + sudo cp .github/acme2certifier.pem data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem data/acme2certifier_key.pem + sudo cp .github/django_settings.py data/settings.py sudo cp examples/ca_handler/openssl_ca_handler.py data/ca_handler.py sudo mkdir -p data/acme_ca/certs sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem data/acme_ca/ - sudo cp .github/django_settings.py data/settings.py sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg data/acme_srv.cfg sudo chmod 777 data/acme_srv.cfg - - name: "[ DEPLOY ] deploy a2c pod" + - name: "Deploy a2c pod" run: | sudo microk8s.kubectl apply -f data/k8s-acme-srv.yml sudo microk8s.kubectl get pods -n cert-manager-acme - - name: "[ WAIT ] Sleep for 10s" + - name: "Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: time: 10s - - name: "[ CHECK ] check status a2c pod and grab ip of a2c pod" + - name: "Check status a2c pod and grab ip of a2c pod" run: | sudo microk8s.kubectl get pods -n cert-manager-acme sudo microk8s.kubectl -n cert-manager-acme describe pod acme2certifier @@ -581,29 +128,29 @@ jobs: echo ACME_IP=$(sudo microk8s.kubectl -n cert-manager-acme describe pod acme2certifier | grep " IP:" | cut -d ' ' -f 5) >> $GITHUB_ENV - run: echo "a2c pod IP is ${{ env.ACME_IP }}" - - name: "[ DEPLOY ] deploy cert-manager and trigger enrollment" + - name: "Deploy cert-manager and trigger enrollment" run: | sudo cp .github/k8s-cert-mgr-http-01.yml data sudo chmod -R 777 data/k8s-cert-mgr-http-01.yml sudo sed -i "s/ACME_SRV/${{ env.ACME_IP }}/g" data/k8s-cert-mgr-http-01.yml sudo microk8s.kubectl apply -f data/k8s-cert-mgr-http-01.yml - - name: "[ WAIT ] Sleep for 20s" + - name: "Sleep for 20s" uses: juliangruber/sleep-action@v2.0.3 with: time: 20s - - name: "[ CHECK ] check issuer and challenge" + - name: "Check issuer and challenge" run: | sudo microk8s.kubectl describe ClusterIssuer acme2certifier sudo microk8s.kubectl describe challenge - - name: "[ WAIT ] Sleep for 20s" + - name: "Sleep for 20s" uses: juliangruber/sleep-action@v2.0.3 with: time: 20s - - name: "[ CHECK ] check issuer and challenge" + - name: "Check issuer and challenge" run: | sudo microk8s.kubectl describe ClusterIssuer acme2certifier sudo microk8s.kubectl describe challenge @@ -612,14 +159,14 @@ jobs: with: time: 20s - - name: "[ CHECK ] check issuer and challenge" + - name: "Check issuer and challenge" run: | sudo microk8s.kubectl describe ClusterIssuer acme2certifier sudo microk8s.kubectl describe challenge sudo microk8s.kubectl describe certificate sudo microk8s.kubectl describe certificates | grep -i "The certificate has been successfully issued" - - name: "[ * ] collecting test logs" + if: ${{ failure() }} run: | mkdir -p ${{ github.workspace }}/artifact/upload @@ -631,12 +178,19 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: cert-manager-http-nginxdjango.tar.gz + name: cert-manager-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ + certmgr_dns01_apwsgi: name: "apache2 wsgi - certmgr dns01 challenge tests" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] + steps: - name: "checkout GIT" @@ -673,23 +227,30 @@ jobs: echo CERTMGR_VERSION=$(sudo microk8s.helm3 show chart jetstack/cert-manager | grep version) >> $GITHUB_ENV - run: echo "cert-manager ${{ env.CERTMGR_VERSION }}" - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" run: | - cat examples/Docker/apache2/wsgi/Dockerfile | docker build -t grindsa/acme2certifier:devel -f - . --no-cache - # docker pull grindsa/acme2certifier:devel + cat examples/Docker/$WEB_SRV/$DB_HANDLER/Dockerfile | docker build -t grindsa/acme2certifier:devel -f - . --no-cache docker save grindsa/acme2certifier > a2c.tar sudo microk8s ctr image import a2c.tar sudo microk8s ctr images ls | grep -i grindsa + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - - name: "[ PREPARE ] Create a2c configuration" + - name: "Create a2c configuration" run: | + sudo mkdir -p data + sudo cp .github/acme2certifier.pem data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem data/acme2certifier_key.pem + sudo cp .github/django_settings.py data/settings.py sudo cp examples/ca_handler/openssl_ca_handler.py data/ca_handler.py sudo mkdir -p data/acme_ca/certs sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem data/acme_ca/ sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg data/acme_srv.cfg sudo chmod 777 data/acme_srv.cfg - - name: "[ DEPLOY ] deploy a2c pod" + - name: "Deploy a2c pod" run: | sudo microk8s.kubectl apply -f data/k8s-acme-srv.yml sudo microk8s.kubectl get pods -n cert-manager-acme @@ -699,7 +260,7 @@ jobs: with: time: 10s - - name: "[ CHECK ] check status a2c pod and grab ip of a2c pod" + - name: "Check status a2c pod and grab ip of a2c pod" run: | sudo microk8s.kubectl get pods -n cert-manager-acme sudo microk8s.kubectl -n cert-manager-acme describe pod acme2certifier @@ -708,7 +269,7 @@ jobs: echo ACME_IP=$(sudo microk8s.kubectl -n cert-manager-acme describe pod acme2certifier | grep " IP:" | cut -d ' ' -f 5) >> $GITHUB_ENV - run: echo "a2c pod IP is ${{ env.ACME_IP }}" - - name: "[ DEPLOY ] deploy cert-manager" + - name: "Deploy cert-manager" run: | sudo cp .github/k8s-cert-mgr-dns-01.yml data sudo chmod -R 777 data/k8s-cert-mgr-dns-01.yml @@ -716,67 +277,67 @@ jobs: sudo sed -i "s/CF_TOKEN/${{ secrets.CF_TOKEN }}/g" data/k8s-cert-mgr-dns-01.yml sudo sed -i "s/MY_EMAIL/${{ secrets.EMAIL }}/g" data/k8s-cert-mgr-dns-01.yml - - name: "[ DEPLOY ] deploy cert-manager and trigger enrollment" + - name: "Deploy cert-manager and trigger enrollment" run: | sudo microk8s.kubectl apply -f data/k8s-cert-mgr-dns-01.yml - - name: "[ WAIT ] Sleep for 20s" + - name: "Sleep for 20s" uses: juliangruber/sleep-action@v2.0.3 with: time: 20s - - name: "[ CHECK ] check issuer and challenge" + - name: "Check issuer and challenge" run: | sudo microk8s.kubectl describe issuer acme2certifier -n cert-manager-acme sudo microk8s.kubectl describe challenge -n cert-manager-acme - - name: "[ WAIT ] Sleep for 30s" + - name: "Sleep for 30s" uses: juliangruber/sleep-action@v2.0.3 with: time: 60s - - name: "[ CHECK ] check issuer and challenge" + - name: "Check issuer and challenge" run: | sudo microk8s.kubectl describe issuer acme2certifier -n cert-manager-acme sudo microk8s.kubectl describe challenge -n cert-manager-acme - - name: "[ WAIT ] Sleep for 60s" + - name: "Sleep for 60s" uses: juliangruber/sleep-action@v2.0.3 with: time: 60s - - name: "[ CHECK ] check issuer and challenge" + - name: "Check issuer and challenge" run: | sudo microk8s.kubectl describe issuer acme2certifier -n cert-manager-acme sudo microk8s.kubectl describe challenge -n cert-manager-acme - - name: "[ WAIT ] Sleep for 60s" + - name: "Sleep for 60s" uses: juliangruber/sleep-action@v2.0.3 with: time: 60s - - name: "[ CHECK ] check challenge and certificate" + - name: "Check challenge and certificate" run: | sudo microk8s.kubectl describe challenge -n cert-manager-acme sudo microk8s.kubectl describe certificates acme-cert -n cert-manager-acme sudo microk8s.kubectl describe certificates acme-cert -n cert-manager-acme | grep -i "The certificate has been successfully issued" - - name: "[ PREPARE ] reconfigure YAML to wildcard domain" + - name: "Reconfigure YAML to wildcard domain" run: | sudo microk8s.kubectl delete -f data/k8s-cert-mgr-dns-01.yml sudo sed -i "s/commonName: k8.acme.dynamop.de/commonName: '*.acme.dynamop.de'/g" data/k8s-cert-mgr-dns-01.yml sudo sed -i "s/- k8.acme.dynamop.de/- '*.acme.dynamop.de'/g" data/k8s-cert-mgr-dns-01.yml - - name: "[ DEPLOY ] deploy cert-manager and trigger enrollment" + - name: "Deploy cert-manager and trigger enrollment" run: | sudo microk8s.kubectl apply -f data/k8s-cert-mgr-dns-01.yml - - name: "[ WAIT ] Sleep for 20s" + - name: "Sleep for 20s" uses: juliangruber/sleep-action@v2.0.3 with: time: 20s - - name: "[ CHECK ] check issuer and challenge" + - name: "Check issuer and challenge" run: | sudo microk8s.kubectl describe issuer acme2certifier -n cert-manager-acme sudo microk8s.kubectl describe challenge -n cert-manager-acme @@ -785,27 +346,27 @@ jobs: with: time: 60s - - name: "[ CHECK ] check issuer and challenge" + - name: "Check issuer and challenge" run: | sudo microk8s.kubectl describe issuer acme2certifier -n cert-manager-acme sudo microk8s.kubectl describe challenge -n cert-manager-acme - - name: "[ WAIT ] Sleep for 60s" + - name: "Sleep for 60s" uses: juliangruber/sleep-action@v2.0.3 with: time: 60s - - name: "[ CHECK ] check issuer and challenge" + - name: "Check issuer and challenge" run: | sudo microk8s.kubectl describe issuer acme2certifier -n cert-manager-acme sudo microk8s.kubectl describe challenge -n cert-manager-acme - - name: "[ WAIT ] Sleep for 60s" + - name: "Sleep for 60s" uses: juliangruber/sleep-action@v2.0.3 with: time: 60s - - name: "[ CHECK ] check challenge and certificate" + - name: "Check challenge and certificate" run: | sudo microk8s.kubectl describe challenge -n cert-manager-acme sudo microk8s.kubectl describe certificates acme-cert -n cert-manager-acme @@ -823,6 +384,6 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: cert-manager-dns-apwsgi.tar.gz + name: cert-manager-dns-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ diff --git a/.github/workflows/dns-test.yml b/.github/workflows/dns-test.yml index 63d12ac9..0e4eb66d 100644 --- a/.github/workflows/dns-test.yml +++ b/.github/workflows/dns-test.yml @@ -12,27 +12,39 @@ jobs: dns_challenge_tests: name: "dns_challenge_tests" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] + steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker network create acme docker-compose up -d docker-compose logs + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup openssl ca_handler" + - name: "Setup openssl ca_handler" run: | + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py sudo mkdir -p examples/Docker/data/acme_ca/certs sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - # sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler_dns.cfg examples/Docker/data/acme_srv.cfg sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg sudo chmod 777 examples/Docker/data/acme_srv.cfg sudo sed -i "s/challenge_validation_disable: False/challenge_validation_disable: False\ndns_server_list: [\"DNS-IP\"]/g" examples/Docker/data/acme_srv.cfg @@ -40,10 +52,18 @@ jobs: docker-compose restart docker-compose logs - - name: "Test http://acme-srv/directory is accessable again" + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "Prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon sudo cp .github/dns_test.sh acme-sh/ @@ -52,7 +72,7 @@ jobs: docker exec -i acme-sh mv /acme.sh/dns_test.sh /root/.acme.sh/dnsapi/ docker exec -i acme-sh chmod +x /root/.acme.sh/dnsapi/dns_test.sh - - name: "[ PREPARE ] set DNS server" + - name: "Set DNS server" run: | cd examples/Docker/ docker-compose stop @@ -61,32 +81,32 @@ jobs: docker-compose start docker-compose logs - - name: "[ ENROLL ] acme.sh - single domain" + - name: "Enroll acme.sh - single domain" run: | docker exec -i acme-sh acme.sh --dnssleep 10 --server http://acme-srv --accountemail 'acme-sh@example.com' --issue --dns dns_test -d acme-sh.single --standalone --debug 3 --output-insecure --force openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.single_ecc/acme-sh.single.cer - - name: "[ ENROLL ] acme.sh - two domains" + - name: "Enroll acme.sh - two domains" run: | docker exec -i acme-sh acme.sh --dnssleep 10 --server http://acme-srv --accountemail 'acme-sh@example.com' --issue --dns dns_test -d acme-sh.first --dns dns_test -d acme-sh.second --standalone --debug 3 --output-insecure --force openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.first_ecc/acme-sh.first.cer - - name: "[ ENROLL ] acme.sh - single wildcard domain" + - name: "Enroll acme.sh - single wildcard domain" run: | docker exec -i acme-sh acme.sh --dnssleep 10 --server http://acme-srv --accountemail 'acme-sh@example.com' --issue --dns dns_test -d *.acme-sh.wildcard --standalone --debug 3 --output-insecure --force openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/*acme-sh.wildcard_ecc/*acme-sh.wildcard.cer - - name: "[ ENROLL ] acme.sh - double wildcard domain" + - name: "Enroll acme.sh - double wildcard domain" run: | docker exec -i acme-sh acme.sh --dnssleep 10 --server http://acme-srv --accountemail 'acme-sh@example.com' --issue --dns dns_test -d *.acme-sh.first-wildcard --dns dns_test -d *.acme-sh.second-wildcard --standalone --debug 3 --output-insecure --force openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/*.acme-sh.first-wildcard_ecc/*.acme-sh.first-wildcard.cer - - name: "[ ENROLL ] acme.sh - domain and wildcard domain" + - name: "Enroll acme.sh - domain and wildcard domain" run: | docker exec -i acme-sh acme.sh --dnssleep 10 --server http://acme-srv --accountemail 'acme-sh@example.com' --issue --dns dns_test -d acme-sh.fqdn-wildcard --dns dns_test -d *.acme-sh.fqdn-wildcard --standalone --debug 3 --output-insecure --force openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.fqdn-wildcard_ecc/acme-sh.fqdn-wildcard.cer - - name: "[ Test ] check TXT record exists" + - name: "Check TXT record exists" if: ${{ failure() }} run: | docker exec -i acme-sh ps -a @@ -113,7 +133,7 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: eab.tar.gz + name: dns_challenge_tests-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ diff --git a/.github/workflows/enrollment-timeout.yml b/.github/workflows/enrollment-timeout.yml index 42259e3f..4c112ed0 100644 --- a/.github/workflows/enrollment-timeout.yml +++ b/.github/workflows/enrollment-timeout.yml @@ -9,26 +9,44 @@ on: - cron: '0 2 * * 6' jobs: - ap_wsgi_async_enrollment_cert_reusage: - name: ap_wsgi_async_enrollment_cert_reusage + async_enrollment_cert_reusage: + name: async_enrollment_cert_reusage runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + - name: "create folders" + run: | + mkdir lego + mkdir acme-sh + mkdir certbot + + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker network create acme docker-compose up -d docker-compose logs + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup openssl ca_handler" + - name: "Setup openssl ca_handler" run: | + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py sudo chmod 777 examples/Docker/data/ca_handler.py sudo sed -i "s/import uuid/import uuid\\nimport time/g" examples/Docker/data/ca_handler.py @@ -42,158 +60,65 @@ jobs: docker-compose restart docker-compose logs - - name: "[ PREPARE ] prepare acme.sh container" - run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - - name: "[ ENROLL ] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme/acme-sh.acme.cer - - - name: "[ VERIFY ] Check timeout" - working-directory: examples/Docker/ - run: | - docker-compose logs | grep "Certificate.enroll_and_store() ended with: None:timeout" - sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) - - - name: "[ ENROLL ] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force - - - name: "[ VERIFY ] Check certificate reusage" - working-directory: examples/Docker/ - run: | - docker-compose logs | grep "Certificate._enroll(): reuse existing certificate" - - - name: "[ ENROL] lego" - run: | - mkdir lego - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --cert.timeout 150 --http run - - - name: "[ VERIFY ] Check timeout" - working-directory: examples/Docker/ - run: | - docker-compose logs | grep "Certificate.enroll_and_store() ended with: None:timeout" - sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) - - - name: "[ REGISTER ] certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - - name: "[ ENROLL ] certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - - - name: "[ VERIFY ] Check timeout" - working-directory: examples/Docker/ - run: | - docker-compose logs | grep "Certificate.enroll_and_store() ended with: None:timeout" - sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) - - - - name: "[ * ] collecting test data" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh - - - name: "[ * ] uploading artifacts" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 with: - name: ap_wsgi_async_enrollment_cert_reusage.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - ap_django_async_enrollment_cert_reusage: - name: ap_django_async_enrollment_cert_reusage - runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "Build docker-compose (apache2_django)" - working-directory: examples/Docker/ - run: | - sed -i "s/wsgi/django/g" .env - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs + time: 10s - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] setup openssl ca_handler" - run: | - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py - sudo chmod 777 examples/Docker/data/ca_handler.py - sudo sed -i "s/import uuid/import uuid\\nimport time/g" examples/Docker/data/ca_handler.py - sudo sed -i "s/ cert_raw = None/ cert_raw = None\\n time.sleep(30)/g" examples/Docker/data/ca_handler.py - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\\ncert_reusage_timeframe: 300/g" examples/Docker/data/acme_srv.cfg - sudo cp .github/django_settings.py examples/Docker/data/settings.py - cd examples/Docker/ - docker-compose restart - docker-compose logs + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" + - name: "Prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ ENROLL ] acme.sh" + - name: "Enroll acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme/acme-sh.acme.cer - - name: "[ VERIFY ] Check timeout" + - name: "Check timeout" working-directory: examples/Docker/ run: | docker-compose logs | grep "Certificate.enroll_and_store() ended with: None:timeout" sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) - - name: "[ ENROLL ] acme.sh" + - name: "Enroll acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force - - name: "[ VERIFY ] Check certificate reusage" + - name: "Check certificate reusage" working-directory: examples/Docker/ run: | docker-compose logs | grep "Certificate._enroll(): reuse existing certificate" - - name: "[ ENROL] lego" + - name: "enroll lego" run: | - mkdir lego - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --cert.timeout 180 --http run + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --cert.timeout 150 --http run - - name: "[ VERIFY ] Check timeout" + - name: "Check timeout" working-directory: examples/Docker/ run: | docker-compose logs | grep "Certificate.enroll_and_store() ended with: None:timeout" sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) - - name: "[ REGISTER ] certbot" + - name: "Register certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ ENROLL ] certbot" + - name: "Enroll certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - - name: "[ VERIFY ] Check timeout" + - name: "Check timeout" working-directory: examples/Docker/ run: | docker-compose logs | grep "Certificate.enroll_and_store() ended with: None:timeout" sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) - - name: "[ * ] collecting test data" if: ${{ failure() }} run: | @@ -208,10 +133,9 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: ap_django_async_enrollment_cert_reusage.tar.gz + name: async_enrollment_cert_reusage-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ - rpm_wsgi_async_enrollment_cert_reusage: name: "rpm_wsgi_async_enrollment_cert_reusage" runs-on: ubuntu-latest diff --git a/.github/workflows/hooks-test.yml b/.github/workflows/hooks-test.yml index 0f3bf481..78d71457 100644 --- a/.github/workflows/hooks-test.yml +++ b/.github/workflows/hooks-test.yml @@ -9,309 +9,47 @@ on: - cron: '0 2 * * 6' jobs: - hooks_ap_wsgi: - name: "hooks_ap_wsgi" + hooks_tests: + name: "hooks_tests" runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" - working-directory: examples/Docker/ - run: | - sudo mkdir -p data/hooks - sudo chmod -R 777 data/hooks - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup openssl ca_handler" - run: | - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo echo -e "\n\n[Hooks]" >> examples/Docker/data/acme_srv.cfg - sudo echo "hooks_file: /var/www/acme2certifier/examples/hooks/cn_dump_hooks.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "save_path: volume/hooks" >> examples/Docker/data/acme_srv.cfg - sudo echo "$HOOKS_CHECKSUM" > examples/Docker/data/hooks/checksums.sha256 - # sudo cat examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - docker-compose restart - docker-compose logs - env: - HOOKS_CHECKSUM: ${{ secrets.HOOKS_CHECKSUM }} - - - name: "Test http://acme-srv/directory is accessable again" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] create letsencrypt folder" - run: | - mkdir certbot - - - name: "[ REGISTER] certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - - name: "[ ENROLL ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem - - - name: "[ PREPARE ] prepare acme.sh container" - run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - - name: "[ REGISTER] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 - - - name: "[ ENROLL] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --debug 3 --output-insecure - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - - name: "[ ENROLL ] lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - - name: "[ CHECK ] compare checksums to validate hook file content" - working-directory: examples/Docker/data/hooks - run: | - sha256sum -c checksums.sha256 - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: hooks_ap_wsgi.tar.gz - path: ${{ github.workspace }}/artifact/upload/ + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] - hooks_ap_django: - name: "hooks_ap_django" - runs-on: ubuntu-latest steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" - working-directory: examples/Docker/ - run: | - sed -i "s/wsgi/django/g" .env - sudo mkdir -p data/hooks - sudo chmod -R 777 data/hooks - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "[ PREPARE ] setup openssl ca_handler" - run: | - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo echo -e "\n\n[Hooks]" >> examples/Docker/data/acme_srv.cfg - sudo echo "hooks_file: /var/www/acme2certifier/examples/hooks/cn_dump_hooks.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "save_path: volume/hooks" >> examples/Docker/data/acme_srv.cfg - sudo echo "$HOOKS_CHECKSUM" > examples/Docker/data/hooks/checksums.sha256 - # sudo cat examples/Docker/data/acme_srv.cfg - sudo cp .github/django_settings.py examples/Docker/data/settings.py - cd examples/Docker/ - docker-compose restart - docker-compose logs - env: - HOOKS_CHECKSUM: ${{ secrets.HOOKS_CHECKSUM }} - - - name: "Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 5s - - - name: "Test http://acme-srv/directory is accessable again" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] create letsencrypt folder" + - name: "Create folders" run: | + mkdir lego + mkdir acme-sh mkdir certbot - - name: "[ REGISTER] certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - - name: "[ ENROLL ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem - - - name: "[ PREPARE ] prepare acme.sh container" - run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - - name: "[ REGISTER] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 - - - name: "[ ENROLL] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --debug 3 --output-insecure - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - - name: "[ ENROLL ] lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - - name: "[ CHECK ] compare checksums to validate hook file content" - working-directory: examples/Docker/data/hooks - run: | - sha256sum -c checksums.sha256 - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: hooks_ap_django.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - hooks_nginx_wsgi: - name: "hooks_nginx_wsgi" - runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | - sed -i "s/apache2/nginx/g" .env - sudo mkdir -p data/hooks - sudo chmod -R 777 data/hooks + sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker network create acme docker-compose up -d docker-compose logs - - - name: "[ PREPARE ] setup openssl ca_handler" - run: | - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo echo -e "\n\n[Hooks]" >> examples/Docker/data/acme_srv.cfg - sudo echo "hooks_file: /var/www/acme2certifier/examples/hooks/cn_dump_hooks.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "save_path: volume/hooks" >> examples/Docker/data/acme_srv.cfg - sudo echo "$HOOKS_CHECKSUM" > examples/Docker/data/hooks/checksums.sha256 - # sudo cat examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - docker-compose restart - docker-compose logs env: - HOOKS_CHECKSUM: ${{ secrets.HOOKS_CHECKSUM }} - - - name: "Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 5s - - - name: "Test http://acme-srv/directory is accessable again" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] create letsencrypt folder" - run: | - mkdir certbot - - - name: "[ REGISTER] certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - - name: "[ ENROLL ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem - - - name: "[ PREPARE ] prepare acme.sh container" - run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - - name: "[ REGISTER] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 - - - name: "[ ENROLL] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --debug 3 --output-insecure - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - - name: "[ ENROLL ] lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - - name: "[ CHECK ] compare checksums to validate hook file content" - working-directory: examples/Docker/data/hooks - run: | - sha256sum -c checksums.sha256 - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: hooks_nginx_wsgi.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - hooks_nginx_django: - name: "hooks_nginx_django" - runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" - working-directory: examples/Docker/ - run: | - sed -i "s/apache2/nginx/g" .env - sed -i "s/wsgi/django/g" .env - sudo mkdir -p data/hooks - sudo chmod -R 777 data/hooks - docker network create acme - docker-compose up -d - docker-compose logs + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - - name: "[ PREPARE ] setup openssl ca_handler" + - name: "Setup openssl ca_handler" run: | + sudo mkdir -p examples/Docker/data/hooks + sudo chmod -R 777 examples/Docker/data/hooks + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py sudo mkdir -p examples/Docker/data/acme_ca/certs sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ @@ -322,521 +60,54 @@ jobs: sudo echo "save_path: volume/hooks" >> examples/Docker/data/acme_srv.cfg sudo echo "$HOOKS_CHECKSUM" > examples/Docker/data/hooks/checksums.sha256 # sudo cat examples/Docker/data/acme_srv.cfg - sudo cp .github/django_settings.py examples/Docker/data/settings.py cd examples/Docker/ docker-compose restart docker-compose logs env: HOOKS_CHECKSUM: ${{ secrets.HOOKS_CHECKSUM }} - - name: "Sleep for 5s" + - name: "Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: - time: 5s - - - name: "Test http://acme-srv/directory is accessable again" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] create letsencrypt folder" - run: | - mkdir certbot + time: 10s - - name: "[ REGISTER] certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - - name: "[ ENROLL ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem - - - name: "[ PREPARE ] prepare acme.sh container" - run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - - name: "[ REGISTER] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 - - - name: "[ ENROLL] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --debug 3 --output-insecure - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - - name: "[ ENROLL ] lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - - name: "[ CHECK ] compare checksums to validate hook file content" - working-directory: examples/Docker/data/hooks - run: | - sha256sum -c checksums.sha256 - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: hooks_nginx_django.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - hooks_test_rpm: - name: "hooks_test_rpm" - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - rhversion: [8, 9] - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: Retrieve Version from version.py - run: | - echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV - - run: echo "Latest tag is ${{ env.TAG_NAME }}" - - - name: update version number in spec file - run: | - # sudo sed -i "s/Source0:.*/Source0: %{name}-%{version}.tar.gz/g" examples/install_scripts/rpm/acme2certifier.spec - sudo sed -i "s/__version__/${{ env.TAG_NAME }}/g" examples/install_scripts/rpm/acme2certifier.spec - cat examples/install_scripts/rpm/acme2certifier.spec - - - name: build RPM package - id: rpm - uses: grindsa/rpmbuild@alma9 - with: - spec_file: "examples/install_scripts/rpm/acme2certifier.spec" - - - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" - - - name: "[ PREPARE ] setup environment for alma installation" - run: | - docker network create acme - sudo mkdir -p data - sudo chmod -R 777 data - sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data - sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data - - - name: "[ PREPARE ] create letsencrypt and lego folder" - run: | - mkdir acmme-sh - mkdir lego - - - name: "Retrieve rpms from SBOM repo" - run: | - git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom - cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data - env: - GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} - GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} - - - name: "[ PREPARE ] prepare acme_srv.cfg with openssl_ca_handler" - run: | - sudo mkdir -p data/acme_ca/certs - sudo mkdir -p data/acme_ca/hooks - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_choosen_handler.cfg data/acme_srv.cfg - sudo chmod 777 data/acme_srv.cfg - sudo chmod -R 777 data/acme_ca/hooks - sudo echo -e "\n\n[Hooks]" >> data/acme_srv.cfg - sudo echo "hooks_file: /opt/acme2certifier/examples/hooks/cn_dump_hooks.py" >> data/acme_srv.cfg - sudo echo "save_path: /tmp/acme2certifier/acme_ca/hooks" >> data/acme_srv.cfg - sudo echo "$HOOKS_CHECKSUM" > data/acme_ca/hooks/checksums.sha256 - env: - HOOKS_CHECKSUM: ${{ secrets.HOOKS_CHECKSUM }} - - - name: "[ PREPARE ] Almalinux instance" - run: | - sudo cp examples/Docker/almalinux-systemd/Dockerfile data - sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile - cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache - docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - - - name: "[ RUN ] Execute install scipt" - run: | - docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh - - - name: "Test http://acme-srv/directory is accessible" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ REGISTER] certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - - name: "[ ENROLL ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - sudo openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem - - - name: "[ PREPARE ] prepare acme.sh container" - run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - - name: "[ REGISTER] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 - - - name: "[ ENROLL] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --debug 3 --output-insecure - openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - - name: "[ ENROLL ] lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - sudo openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - - name: "[ CHECK ] compare checksums to validate hook file content" - working-directory: data/acme_ca/hooks - run: | - sha256sum -c checksums.sha256 - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier - sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ - sudo rm ${{ github.workspace }}/artifact/data/*.rpm - docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig - docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf - docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: hooks-rpm-rh${{ matrix.rhversion }}.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - hooks_ap_wsgi_exception_handling: - name: "hooks_ap_wsgi_exception_handling" - runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" - working-directory: examples/Docker/ - run: | - sudo mkdir -p data/hooks - sudo chmod -R 777 data/hooks - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup openssl ca_handler" - run: | - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo echo -e "\n\n[Hooks]" >> examples/Docker/data/acme_srv.cfg - sudo echo "hooks_file: /var/www/acme2certifier/examples/hooks/exception_test_hooks.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "raise_pre_hook_exception: False" >> examples/Docker/data/acme_srv.cfg - sudo echo "raise_post_hook_exception: False" >> examples/Docker/data/acme_srv.cfg - sudo echo "raise_success_hook_exception: False" >> examples/Docker/data/acme_srv.cfg - # sudo cat examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - docker-compose restart - docker-compose logs - env: - HOOKS_CHECKSUM: ${{ secrets.HOOKS_CHECKSUM }} - - - name: "Test http://acme-srv/directory is accessable again" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] prepare acme.sh container" - run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - - name: "[ REGISTER] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 - - - name: "[ ENROLL] acme.sh - *_pre_hook_failure not configured " - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --debug 3 --output-insecure - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - - name: "[ PREPARE ] reconfigure hook handler to trigger pre hook exception " - run: | - sudo sed -i "s/raise_pre_hook_exception: False/raise_pre_hook_exception: True/g" examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) - docker-compose restart - - - name: "[ FAIL ] acme.sh enrollment fails due to pre-hook exception (default behaviour)" - id: prehookfailure - continue-on-error: true - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure - - - name: "[ CHECK ] result - acme.sh enrollment failed due to pre-hook exception " - if: steps.prehookfailure.outcome != 'failure' - run: | - echo "prehookfailure outcome is ${{steps.prehookfailure.outcome }}" - exit 1 - - - name: "[ PREPARE ] reconfigure a2c to ignore pre-hook failures " - run: | - sudo echo "ignore_pre_hook_failure: True" >> examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) - docker-compose restart - - - name: "[ ENROLL] acme.sh - ignore pre_hook_failures " - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - - name: "[ PREPARE ] reconfigure hook handler to trigger success hook exception " - run: | - sudo sed -i "s/raise_pre_hook_exception: True/raise_pre_hook_exception: False/g" examples/Docker/data/acme_srv.cfg - sudo sed -i "s/raise_success_hook_exception: False/raise_success_hook_exception: True/g" examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) - docker-compose restart - - - name: "[ FAIL ] acme.sh enrollment fails due to success-hook exception (default behaviour) " - id: successhookfailure - continue-on-error: true - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure - - - name: "[ CHECK ] result - acme.sh enrollment failed due to success-hook exception " - if: steps.successhookfailure.outcome != 'failure' - run: | - echo "successhookfailure outcome is ${{steps.successhookfailure.outcome }}" - exit 1 - - - name: "[ PREPARE ] reconfigure a2c to ignore success-hook failures " - run: | - sudo sed -i "s/ignore_pre_hook_failure: True/ignore_success_hook_failure: True/g" examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) - docker-compose restart - - - name: "[ ENROLL] acme.sh - ignore sucess_hook_failures " - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - - name: "[ PREPARE ] reconfigure hook handler to trigger post hook exception " - run: | - sudo sed -i "s/raise_success_hook_exception: True/raise_success_hook_exception: False/g" examples/Docker/data/acme_srv.cfg - sudo sed -i "s/raise_post_hook_exception: False/raise_post_hook_exception: True/g" examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) - docker-compose restart - - - name: "[ ENROLL] acme.sh - ignore post_hook_failures (default behaviour) " - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - - name: "[ PREPARE ] reconfigure a2c to detect success-hook failures " - run: | - sudo sed -i "s/ignore_success_hook_failure: True/ignore_post_hook_failure: False/g" examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) - docker-compose restart - - - name: "[ FAIL ] acme.sh enrollment fails due to post-hook exception " - id: posthookfailure - continue-on-error: true - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure - - - name: "[ CHECK ] result - acme.sh enrollment failed due to post-hook exception " - if: steps.posthookfailure.outcome != 'failure' - run: | - echo "posthookfailure outcome is ${{steps.posthookfailure.outcome }}" - exit 1 - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: hooks_ap_wsgi_exception_handling.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - hooks_ap_django_exception_handling: - name: "hooks_ap_django_exception_handling" - runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" - working-directory: examples/Docker/ - run: | - sed -i "s/wsgi/django/g" .env - sudo mkdir -p data/hooks - sudo chmod -R 777 data/hooks - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "[ PREPARE ] setup openssl ca_handler" - run: | - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo echo -e "\n\n[Hooks]" >> examples/Docker/data/acme_srv.cfg - sudo echo "hooks_file: /var/www/acme2certifier/examples/hooks/exception_test_hooks.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "raise_pre_hook_exception: False" >> examples/Docker/data/acme_srv.cfg - sudo echo "raise_post_hook_exception: False" >> examples/Docker/data/acme_srv.cfg - sudo echo "raise_success_hook_exception: False" >> examples/Docker/data/acme_srv.cfg - sudo cp .github/django_settings.py examples/Docker/data/settings.py - cd examples/Docker/ - docker-compose restart - docker-compose logs - env: - HOOKS_CHECKSUM: ${{ secrets.HOOKS_CHECKSUM }} - - - name: "Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 5s - - - name: "Test http://acme-srv/directory is accessable again" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] prepare acme.sh container" - run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - - name: "[ REGISTER] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 - - - name: "[ ENROLL] acme.sh - *_pre_hook_failure not configured " - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --debug 3 --output-insecure - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - - name: "[ PREPARE ] reconfigure hook handler to trigger pre hook exception " - run: | - sudo sed -i "s/raise_pre_hook_exception: False/raise_pre_hook_exception: True/g" examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) - docker-compose restart - - - name: "[ FAIL ] acme.sh enrollment fails due to pre-hook exception (default behaviour)" - id: prehookfailure - continue-on-error: true - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure - - - name: "[ CHECK ] result - acme.sh enrollment failed due to pre-hook exception " - if: steps.prehookfailure.outcome != 'failure' - run: | - echo "prehookfailure outcome is ${{steps.prehookfailure.outcome }}" - exit 1 - - - name: "[ PREPARE ] reconfigure a2c to ignore pre-hook failures " - run: | - sudo echo "ignore_pre_hook_failure: True" >> examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) - docker-compose restart - - - name: "[ ENROLL] acme.sh - ignore pre_hook_failures " - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - - name: "[ PREPARE ] reconfigure hook handler to trigger success hook exception " - run: | - sudo sed -i "s/raise_pre_hook_exception: True/raise_pre_hook_exception: False/g" examples/Docker/data/acme_srv.cfg - sudo sed -i "s/raise_success_hook_exception: False/raise_success_hook_exception: True/g" examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) - docker-compose restart + - name: "Test http://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ FAIL ] acme.sh enrollment fails due to success-hook exception (default behaviour) " - id: successhookfailure - continue-on-error: true - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - name: "[ CHECK ] result - acme.sh enrollment failed due to success-hook exception " - if: steps.successhookfailure.outcome != 'failure' + - name: "Register certbot" run: | - echo "successhookfailure outcome is ${{steps.successhookfailure.outcome }}" - exit 1 + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ PREPARE ] reconfigure a2c to ignore success-hook failures " + - name: "Enroll certbot" run: | - sudo sed -i "s/ignore_pre_hook_failure: True/ignore_success_hook_failure: True/g" examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) - docker-compose restart + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot + sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem - - name: "[ ENROLL] acme.sh - ignore sucess_hook_failures " + - name: "Prepare acme.sh container" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ PREPARE ] reconfigure hook handler to trigger post hook exception " + - name: "Register acme.sh" run: | - sudo sed -i "s/raise_success_hook_exception: True/raise_success_hook_exception: False/g" examples/Docker/data/acme_srv.cfg - sudo sed -i "s/raise_post_hook_exception: False/raise_post_hook_exception: True/g" examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) - docker-compose restart + docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 - - name: "[ ENROLL] acme.sh - ignore post_hook_failures (default behaviour) " + - name: "Enroll acme.sh" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure + docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --debug 3 --output-insecure openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ PREPARE ] reconfigure a2c to detect success-hook failures " - run: | - sudo sed -i "s/ignore_success_hook_failure: True/ignore_post_hook_failure: False/g" examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) - docker-compose restart - - - name: "[ FAIL ] acme.sh enrollment fails due to post-hook exception " - id: posthookfailure - continue-on-error: true + - name: "Enroll lego" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - name: "[ CHECK ] result - acme.sh enrollment failed due to post-hook exception " - if: steps.posthookfailure.outcome != 'failure' + - name: "Compare checksums to validate hook file content" + working-directory: examples/Docker/data/hooks run: | - echo "posthookfailure outcome is ${{steps.posthookfailure.outcome }}" - exit 1 + sha256sum -c checksums.sha256 - name: "[ * ] collecting test logs" if: ${{ failure() }} @@ -851,200 +122,181 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: hooks_ap_django_exception_handling.tar.gz + name: hooks-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ - hooks_mgomx_wsgi_exception_handling: - name: "hooks_mgomx_wsgi_exception_handling" + hooks_test_rpm: + name: "hooks_test_rpm" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rhversion: [8, 9] steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" - working-directory: examples/Docker/ + - name: Retrieve Version from version.py run: | - sed -i "s/apache2/nginx/g" .env - sudo mkdir -p data/hooks - sudo chmod -R 777 data/hooks - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV + - run: echo "Latest tag is ${{ env.TAG_NAME }}" - - name: "[ PREPARE ] setup openssl ca_handler" + - name: update version number in spec file run: | - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo echo -e "\n\n[Hooks]" >> examples/Docker/data/acme_srv.cfg - sudo echo "hooks_file: /var/www/acme2certifier/examples/hooks/exception_test_hooks.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "raise_pre_hook_exception: False" >> examples/Docker/data/acme_srv.cfg - sudo echo "raise_post_hook_exception: False" >> examples/Docker/data/acme_srv.cfg - sudo echo "raise_success_hook_exception: False" >> examples/Docker/data/acme_srv.cfg - # sudo cat examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - docker-compose restart - docker-compose logs - env: - HOOKS_CHECKSUM: ${{ secrets.HOOKS_CHECKSUM }} + # sudo sed -i "s/Source0:.*/Source0: %{name}-%{version}.tar.gz/g" examples/install_scripts/rpm/acme2certifier.spec + sudo sed -i "s/__version__/${{ env.TAG_NAME }}/g" examples/install_scripts/rpm/acme2certifier.spec + cat examples/install_scripts/rpm/acme2certifier.spec - - name: "Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.3 + - name: build RPM package + id: rpm + uses: grindsa/rpmbuild@alma9 with: - time: 5s - - - name: "Test http://acme-srv/directory is accessable again" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] prepare acme.sh container" - run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - - name: "[ REGISTER] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 - - - name: "[ ENROLL] acme.sh - *_pre_hook_failure not configured " - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --debug 3 --output-insecure - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + spec_file: "examples/install_scripts/rpm/acme2certifier.spec" - - name: "[ PREPARE ] reconfigure hook handler to trigger pre hook exception " - run: | - sudo sed -i "s/raise_pre_hook_exception: False/raise_pre_hook_exception: True/g" examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) - docker-compose restart + - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" - - name: "[ FAIL ] acme.sh enrollment fails due to pre-hook exception (default behaviour)" - id: prehookfailure - continue-on-error: true + - name: "setup environment for alma installation" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure + docker network create acme + sudo mkdir -p data + sudo chmod -R 777 data + sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data + sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data - - name: "[ CHECK ] result - acme.sh enrollment failed due to pre-hook exception " - if: steps.prehookfailure.outcome != 'failure' + - name: "create letsencrypt and lego folder" run: | - echo "prehookfailure outcome is ${{steps.prehookfailure.outcome }}" - exit 1 + mkdir acmme-sh + mkdir lego - - name: "[ PREPARE ] reconfigure a2c to ignore pre-hook failures " + - name: "Retrieve rpms from SBOM repo" run: | - sudo echo "ignore_pre_hook_failure: True" >> examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) - docker-compose restart + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} - - name: "[ ENROLL] acme.sh - ignore pre_hook_failures " + - name: "prepare acme_srv.cfg with openssl_ca_handler" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + sudo mkdir -p data/acme_ca/certs + sudo mkdir -p data/acme_ca/hooks + sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem data/acme_ca/ + sudo cp .github/openssl_ca_handler.py_acme_srv_choosen_handler.cfg data/acme_srv.cfg + sudo chmod 777 data/acme_srv.cfg + sudo chmod -R 777 data/acme_ca/hooks + sudo echo -e "\n\n[Hooks]" >> data/acme_srv.cfg + sudo echo "hooks_file: /opt/acme2certifier/examples/hooks/cn_dump_hooks.py" >> data/acme_srv.cfg + sudo echo "save_path: /tmp/acme2certifier/acme_ca/hooks" >> data/acme_srv.cfg + sudo echo "$HOOKS_CHECKSUM" > data/acme_ca/hooks/checksums.sha256 + env: + HOOKS_CHECKSUM: ${{ secrets.HOOKS_CHECKSUM }} - - name: "[ PREPARE ] reconfigure hook handler to trigger success hook exception " + - name: "Almalinux instance" run: | - sudo sed -i "s/raise_pre_hook_exception: True/raise_pre_hook_exception: False/g" examples/Docker/data/acme_srv.cfg - sudo sed -i "s/raise_success_hook_exception: False/raise_success_hook_exception: True/g" examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) - docker-compose restart + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - - name: "[ FAIL ] acme.sh enrollment fails due to success-hook exception (default behaviour) " - id: successhookfailure - continue-on-error: true + - name: "[ RUN ] Execute install scipt" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure + docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh - - name: "[ CHECK ] result - acme.sh enrollment failed due to success-hook exception " - if: steps.successhookfailure.outcome != 'failure' - run: | - echo "successhookfailure outcome is ${{steps.successhookfailure.outcome }}" - exit 1 + - name: "Test http://acme-srv/directory is accessible" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] reconfigure a2c to ignore success-hook failures " + - name: "[ REGISTER] certbot" run: | - sudo sed -i "s/ignore_pre_hook_failure: True/ignore_success_hook_failure: True/g" examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) - docker-compose restart + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ ENROLL] acme.sh - ignore sucess_hook_failures " + - name: "[ ENROLL ] HTTP-01 single domain certbot" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot + sudo openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem - - name: "[ PREPARE ] reconfigure hook handler to trigger post hook exception " + - name: "prepare acme.sh container" run: | - sudo sed -i "s/raise_success_hook_exception: True/raise_success_hook_exception: False/g" examples/Docker/data/acme_srv.cfg - sudo sed -i "s/raise_post_hook_exception: False/raise_post_hook_exception: True/g" examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) - docker-compose restart + docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ ENROLL] acme.sh - ignore post_hook_failures (default behaviour) " + - name: "[ REGISTER] acme.sh" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 - - name: "[ PREPARE ] reconfigure a2c to detect success-hook failures " + - name: "[ ENROLL] acme.sh" run: | - sudo sed -i "s/ignore_success_hook_failure: True/ignore_post_hook_failure: False/g" examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) - docker-compose restart + docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --debug 3 --output-insecure + openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ FAIL ] acme.sh enrollment fails due to post-hook exception " - id: posthookfailure - continue-on-error: true + - name: "[ ENROLL ] lego" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + sudo openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - name: "[ CHECK ] result - acme.sh enrollment failed due to post-hook exception " - if: steps.posthookfailure.outcome != 'failure' + - name: "[ CHECK ] compare checksums to validate hook file content" + working-directory: data/acme_ca/hooks run: | - echo "posthookfailure outcome is ${{steps.posthookfailure.outcome }}" - exit 1 + sha256sum -c checksums.sha256 - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data + docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier + sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf + docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh - name: "[ * ] uploading artificates" uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: hooks_mgomx_wsgi_exception_handling.tar.gz + name: hooks-rpm-rh${{ matrix.rhversion }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ - hooks_nginx_django_exception_handling: - name: "hooks_nginx_django_exception_handling" + hooks_exception_handling: + name: "hooks_exception_handling" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + - name: "create folders" + run: | + mkdir lego + mkdir acme-sh + mkdir certbot + + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | - sed -i "s/apache2/nginx/g" .env - sed -i "s/apache2/nginx/g" .env - sudo mkdir -p data/hooks - sudo chmod -R 777 data/hooks + sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker network create acme docker-compose up -d docker-compose logs + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - - name: "[ PREPARE ] setup openssl ca_handler" + - name: "setup openssl ca_handler" run: | + sudo mkdir -p examples/Docker/data/hooks + sudo chmod -R 777 examples/Docker/data/hooks + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py sudo mkdir -p examples/Docker/data/acme_ca/certs sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ @@ -1055,22 +307,25 @@ jobs: sudo echo "raise_pre_hook_exception: False" >> examples/Docker/data/acme_srv.cfg sudo echo "raise_post_hook_exception: False" >> examples/Docker/data/acme_srv.cfg sudo echo "raise_success_hook_exception: False" >> examples/Docker/data/acme_srv.cfg - sudo cp .github/django_settings.py examples/Docker/data/settings.py + # sudo cat examples/Docker/data/acme_srv.cfg cd examples/Docker/ docker-compose restart docker-compose logs env: HOOKS_CHECKSUM: ${{ secrets.HOOKS_CHECKSUM }} - - name: "Sleep for 5s" + - name: "Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: - time: 5s + time: 10s - - name: "Test http://acme-srv/directory is accessable again" + - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon @@ -1191,13 +446,9 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: hooks_nginx_django_exception_handling.tar.gz + name: hooks_exception_handling-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ - - - - hooks_exception_handling_rpm: name: "hooks_exception_handling_rpm" runs-on: ubuntu-latest @@ -1228,7 +479,7 @@ jobs: - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" - - name: "[ PREPARE ] setup environment for alma installation" + - name: "setup environment for alma installation" run: | docker network create acme sudo mkdir -p data @@ -1236,7 +487,7 @@ jobs: sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data - - name: "[ PREPARE ] create letsencrypt and lego folder" + - name: "create letsencrypt and lego folder" run: | mkdir acmme-sh mkdir lego @@ -1249,7 +500,7 @@ jobs: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} - - name: "[ PREPARE ] prepare acme_srv.cfg with openssl_ca_handler" + - name: "prepare acme_srv.cfg with openssl_ca_handler" run: | sudo mkdir -p data/acme_ca/certs sudo mkdir -p data/acme_ca/hooks @@ -1265,7 +516,7 @@ jobs: env: HOOKS_CHECKSUM: ${{ secrets.HOOKS_CHECKSUM }} - - name: "[ PREPARE ] Almalinux instance" + - name: "Almalinux instance" run: | sudo cp examples/Docker/almalinux-systemd/Dockerfile data sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile @@ -1279,7 +530,7 @@ jobs: - name: "Test http://acme-srv/directory is accessible" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" + - name: "prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon diff --git a/.github/workflows/ip-address-tests.yml b/.github/workflows/ip-address-tests.yml index f2a4980f..ff781334 100644 --- a/.github/workflows/ip-address-tests.yml +++ b/.github/workflows/ip-address-tests.yml @@ -9,9 +9,14 @@ on: - cron: '0 2 * * 6' jobs: - ip_apache2_wsgi: - name: "ip_apache2_wsgi" + ip_tests: + name: "ip_tests" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -22,245 +27,30 @@ jobs: echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV - run: echo "runner IP is ${{ env.RUNNER_IP }}" - - name: "Build docker-compose (apache2_wsgi)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker network create acme docker-compose up -d docker-compose logs - - - name: "Setup openssl ca_handler" - run: | - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg - sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem - cd examples/Docker/ - docker-compose restart - docker-compose logs - - - name: "Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 5s - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "Test if https://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - - name: "create lego folder" - run: | - mkdir lego - - - name: "Enroll HTTP-01 single domain and ip address " - run: | - docker run -i -p 80:80 -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme -d $RUNNER_IP --http run - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - sudo openssl x509 -in lego/certificates/lego.acme.crt --text --noout | grep "IP Address" env: - RUNNER_IP: ${{ env.RUNNER_IP }} - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: ip_apache2_wsgi.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - ip_apache2_django: - name: "ip_apache2_django" - runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] get runner ip" - run: | - echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV - echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV - - run: echo "runner IP is ${{ env.RUNNER_IP }}" - - - name: "Build docker-compose (apache2_django)" - working-directory: examples/Docker/ - run: | - sed -i "s/wsgi/django/g" .env - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - name: "Setup openssl ca_handler" run: | - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg - sudo cp .github/django_settings.py examples/Docker/data/settings.py sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem - cd examples/Docker/ - docker-compose restart - docker-compose logs - - - name: "Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 5s - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "Test if https://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - - name: "create lego folder" - run: | - mkdir lego - - - name: "Enroll HTTP-01 single domain and ip address " - run: | - docker run -i -p 80:80 -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme -d $RUNNER_IP --http run - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - sudo openssl x509 -in lego/certificates/lego.acme.crt --text --noout | grep "IP Address" - env: - RUNNER_IP: ${{ env.RUNNER_IP }} - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: ip_apache2_django.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - ip_nginx_wsgi: - name: "ip_nginx_wsgi" - runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] get runner ip" - run: | - echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV - echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV - - run: echo "runner IP is ${{ env.RUNNER_IP }}" - - - name: "Build docker-compose (nginx_wsgi)" - working-directory: examples/Docker/ - run: | - sed -i "s/apache2/nginx/g" .env - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "Setup openssl ca_handler" - run: | - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem - cd examples/Docker/ - docker-compose restart - docker-compose logs - - - name: "Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 5s - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "Test if https://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - - name: "create lego folder" - run: | - mkdir lego - - - name: "Enroll HTTP-01 single domain and ip address " - run: | - docker run -i -p 80:80 -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme -d $RUNNER_IP --http run - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - sudo openssl x509 -in lego/certificates/lego.acme.crt --text --noout | grep "IP Address" - env: - RUNNER_IP: ${{ env.RUNNER_IP }} - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: ip_nginx_wsgi.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - ip_nginx_django: - name: "ip_nginx_django" - runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] get runner ip" - run: | - echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV - echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV - - run: echo "runner IP is ${{ env.RUNNER_IP }}" - - - name: "Build docker-compose (nginx_django)" - working-directory: examples/Docker/ - run: | - sed -i "s/wsgi/django/g" .env - sed -i "s/apache2/nginx/g" .env - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "Setup openssl ca_handler" - run: | + sudo cp .github/django_settings.py examples/Docker/data/settings.py sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py sudo mkdir -p examples/Docker/data/acme_ca/certs sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg - sudo cp .github/django_settings.py examples/Docker/data/settings.py - sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem - sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem cd examples/Docker/ docker-compose restart docker-compose logs @@ -302,7 +92,7 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: ip_nginx_django.tar.gz + name: ip_tests-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ ip_wsgi_rpm: diff --git a/.github/workflows/ipv6-test.yml b/.github/workflows/ipv6-test.yml index b40c1f45..a03c9e92 100644 --- a/.github/workflows/ipv6-test.yml +++ b/.github/workflows/ipv6-test.yml @@ -6,194 +6,72 @@ on: branches: [ devel ] jobs: - ipv6_apache2_wsgi: - name: "ipv6_apache2_wsgi" + ipv6_tests: + name: "ipv6_tests" runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" - working-directory: examples/Docker/ - run: | - sudo mkdir -p data - docker network create acme --ipv6 --subnet "fdbb:6445:65b4:0a60::/64" - docker-compose up -d - docker-compose logs - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] setup openssl ca_handler" - run: | - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - docker-compose restart - docker-compose logs - - name: "[ PREPARE ] prepare acme.sh container" - run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ ENROLL ] HTTP-01 single domain acme.sh using ipv6" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --listen-v6 --debug 3 --output-insecure - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer - - name: "[ ENROLL ] HTTP-01 single domain acme.sh using ipv6 with ipv4 fallback" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --listen-v4 --debug 3 --output-insecure --force - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: ipv6_apache2_wsgi.tar.gz - path: ${{ github.workspace }}/artifact/upload/ + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] - ipv6_nginx_wsgi: - name: "ipv6_nginx_wsgi" - runs-on: ubuntu-latest steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (nginx_wsgi)" - working-directory: examples/Docker/ - run: | - sed -i "s/apache2/nginx/g" .env - sudo mkdir -p data - docker network create acme --ipv6 --subnet "fdbb:6445:65b4:0a60::/64" - docker-compose up -d - docker-compose logs - - name: "[ PREPARE ] setup openssl ca_handler" - run: | - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - docker-compose restart - docker-compose logs - - name: "[ PREPARE ] prepare acme.sh container" - run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ ENROLL ] HTTP-01 single domain acme.sh using ipv6" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --listen-v6 --debug 3 --output-insecure - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer - - name: "[ ENROLL ] HTTP-01 single domain acme.sh using ipv6 with ipv4 fallback" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --listen-v4 --debug 3 --output-insecure --force - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: ipv6_nginx_wsgi.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - ipv6_apache2_django: - name: "ipv6_apache2_django" - runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (apache2_django)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | - sed -i "s/wsgi/django/g" .env sudo mkdir -p data - docker network create acme --ipv6 --subnet "fdbb:6445:65b4:0a60::/64" + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env + docker network create acme docker-compose up -d docker-compose logs - - name: "[ PREPARE ] setup openssl ca_handler" + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} + + - name: "Setup openssl ca_handler" run: | + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py sudo mkdir -p examples/Docker/data/acme_ca/certs sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg - sudo cp .github/django_settings.py examples/Docker/data/settings.py cd examples/Docker/ docker-compose restart docker-compose logs - - name: "[ PREPARE ] prepare acme.sh container" - run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ ENROLL ] HTTP-01 single domain acme.sh using ipv6" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --listen-v6 --debug 3 --output-insecure - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer - - name: "[ ENROLL ] HTTP-01 single domain acme.sh using ipv6 with ipv4 fallback" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --listen-v4 --debug 3 --output-insecure --force - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} + + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 with: - name: ipv6_apache2_django.tar.gz - path: ${{ github.workspace }}/artifact/upload/ + time: 10s - ipv6_nginx_django: - name: "ipv6_nginx_django" - runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (nginx_django)" - working-directory: examples/Docker/ - run: | - sed -i "s/wsgi/django/g" .env - sed -i "s/apache2/nginx/g" .env - sudo mkdir -p data - docker network create acme --ipv6 --subnet "fdbb:6445:65b4:0a60::/64" - docker-compose up -d - docker-compose logs - - name: "[ PREPARE ] setup openssl ca_handler" - run: | - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg - sudo cp .github/django_settings.py examples/Docker/data/settings.py - cd examples/Docker/ - docker-compose restart - docker-compose logs + - name: "Test http://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "Prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ ENROLL ] HTTP-01 single domain acme.sh using ipv6" + + - name: "Enroll acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --listen-v6 --debug 3 --output-insecure openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer - - name: "[ ENROLL ] HTTP-01 single domain acme.sh using ipv6 with ipv4 fallback" + + - name: "Enroll acme.sh using ipv6 with ipv4 fallback" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --listen-v4 --debug 3 --output-insecure --force openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer - - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | @@ -207,10 +85,9 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: ipv6_nginx_django.tar.gz + name: ipv6_tests-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ - rpm_wsgi_ipv6: name: "rpm_wsgi_ipv6" runs-on: ubuntu-latest diff --git a/.github/workflows/lego-application-test.yml b/.github/workflows/lego-application-test.yml index c188ac1c..daeca1da 100644 --- a/.github/workflows/lego-application-test.yml +++ b/.github/workflows/lego-application-test.yml @@ -10,205 +10,43 @@ on: jobs: - lego_apache2_wsgi: - name: "lego_apache2_wsgi" + lego_tests: + name: "lego_tests" runs-on: ubuntu-latest strategy: fail-fast: false matrix: keylength: [rsa2048, rsa4096, ec256] + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" - working-directory: examples/Docker/ - run: | - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup openssl ca_handler" - run: | - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - docker-compose restart - docker-compose logs - - - name: "create lego folder" + - name: "create folders" run: | mkdir lego - - name: "[ ENROLL ] HTTP-01 single domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme --http run - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - - name: "[ RENEW ] HTTP-01 single domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme --http renew - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - - name: "[ REVOKE ] HTTP-01 single domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme revoke - - - name: "[ ENROLL ] HTTP-01 2x domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme -d lego --http run - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - - name: "[ RENEW ] HTTP-01 2x domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme -d lego --http renew - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - - name: "[ REVOKE ] HTTP-01 2x domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme revoke - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: lego_key-${{ matrix.keylength }}.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - lego_apache2_django: - name: "lego_apache2_django" - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - keylength: [rsa2048, rsa4096, ec256] - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (apache2_django)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | - sed -i "s/wsgi/django/g" .env sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker network create acme docker-compose up -d docker-compose logs + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup openssl ca_handler and django config" + - name: "Setup openssl ca_handler" run: | - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem sudo cp .github/django_settings.py examples/Docker/data/settings.py - cd examples/Docker/ - docker-compose restart - docker-compose logs - - - name: "create lego folder" - run: | - mkdir lego - - - name: "[ ENROLL ] HTTP-01 single domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme --http run - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - - name: "[ RENEW ] HTTP-01 single domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme --http renew - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - - name: "[ REVOKE ] HTTP-01 single domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme revoke - - - name: "[ ENROLL ] HTTP-01 2x domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme -d lego --http run - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - - name: "[ RENEW ] HTTP-01 2x domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme -d lego --http renew - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - - name: "[ REVOKE ] HTTP-01 2x domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme revoke - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: lego_key-${{ matrix.keylength }}.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - lego_nginx_wsgi: - name: "lego_nginx_wsgi" - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - keylength: [rsa2048, rsa4096, ec256] - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (nginx_django)" - working-directory: examples/Docker/ - run: | - sed -i "s/apache2/nginx/g" .env - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup openssl ca_handler" - run: | sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py sudo mkdir -p examples/Docker/data/acme_ca/certs sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ @@ -217,77 +55,7 @@ jobs: docker-compose restart docker-compose logs - - name: "create lego folder" - run: | - mkdir lego - - - name: "[ ENROLL ] HTTP-01 single domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme --http run - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - - name: "[ RENEW ] HTTP-01 single domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme --http renew - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - - name: "[ REVOKE ] HTTP-01 single domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme revoke - - - name: "[ ENROLL ] HTTP-01 2x domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme -d lego --http run - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - - name: "[ RENEW ] HTTP-01 2x domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme -d lego --http renew - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - - name: "[ REVOKE ] HTTP-01 2x domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme revoke - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: lego_key-${{ matrix.keylength }}.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - lego_nginx_django: - name: "lego_nginx_django" - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - keylength: [rsa2048, rsa4096, ec256] - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (nginx_django)" - working-directory: examples/Docker/ - run: | - sed -i "s/wsgi/django/g" .env - sed -i "s/apache2/nginx/g" .env - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "[ WAIT ] Sleep for 10s" + - name: "Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -295,46 +63,34 @@ jobs: - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] setup openssl ca_handler and django config" - run: | - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg - sudo cp .github/django_settings.py examples/Docker/data/settings.py - cd examples/Docker/ - docker-compose restart - docker-compose logs - - - name: "create lego folder" - run: | - mkdir lego + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - name: "[ ENROLL ] HTTP-01 single domain lego" + - name: "Enroll HTTP-01 single domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme --http run sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - name: "[ RENEW ] HTTP-01 single domain lego" + - name: "Renew HTTP-01 single domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme --http renew sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - name: "[ REVOKE ] HTTP-01 single domain lego" + - name: "Revoke HTTP-01 single domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme revoke - - name: "[ ENROLL ] HTTP-01 2x domain lego" + - name: "Enroll HTTP-01 2x domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme -d lego --http run sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - name: "[ RENEW ] HTTP-01 2x domain lego" + - name: "Renew HTTP-01 2x domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme -d lego --http renew sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - name: "[ REVOKE ] HTTP-01 2x domain lego" + - name: "Revoke HTTP-01 2x domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme revoke @@ -352,5 +108,6 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: lego_key-${{ matrix.keylength }}.tar.gz + name: lego_tests-${{ matrix.keylength }}-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ + diff --git a/.github/workflows/proxy-test.yml b/.github/workflows/proxy-test.yml index 88133bc5..1ca326eb 100644 --- a/.github/workflows/proxy-test.yml +++ b/.github/workflows/proxy-test.yml @@ -12,12 +12,18 @@ jobs: proxy_tests: name: "proxy_tests" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + websrv: ['apache2'] + dbhandler: ['wsgi', 'django'] + steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] get runner ip" + - name: "get runner ip" run: | echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV @@ -43,38 +49,45 @@ jobs: RUNNER_IP: ${{ env.RUNNER_IP }} WES_HOST: ${{ secrets.WES_HOST }} - - name: "[ PREPARE ] test dns resulution" + - name: "test dns resulution" run: | host $WES_HOST 127.0.0.1 env: WES_HOST: ${{ secrets.WES_HOST }} - - name: "[ PREPARE ] create network" + - name: "create network" run: | docker network create acme - - name: "[ PREPARE ] proxy container" + - name: "proxy container" run: | docker pull mosajjal/pproxy:latest docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & - - name: "[ PREPARE ] Sleep for 10s" + - name: "Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: time: 10s - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker-compose up -d docker-compose logs + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup openssl ca_handler" + - name: "setup openssl ca_handler" run: | + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py sudo mkdir -p examples/Docker/data/acme_ca/certs sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ @@ -85,38 +98,46 @@ jobs: docker-compose restart docker-compose logs - - name: "Test http://acme-srv/directory is accessable again" + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "Prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ ENROLL ] acme.sh - http challenge validation" + - name: "Enroll acme.sh - http challenge validation" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme -d acme-sh. --standalone --debug 3 --output-insecure --force openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ CHECK ] proxy logs" + - name: "Check proxy logs" run: | docker logs proxy | grep socks5 | grep -- "->" docker logs proxy | grep http | grep -- "->" docker stop proxy docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & - - name: "[ ENROLL ] acme.sh - alpn challenge validation" + - name: "Enroll acme.sh - alpn challenge validation" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn -d acme-sh. --alpn --standalone --debug 3 --output-insecure --force openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ CHECK ] proxy logs" + - name: "Check proxy logs" run: | docker logs proxy | grep socks5 | grep -- "->" docker logs proxy | grep http | grep -- "->" docker stop proxy docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & - - name: "[ PREPARE ] setup certifier ca_handler for proxy usage" + - name: "setup certifier ca_handler for proxy usage" run: | sudo cp examples/ca_handler/certifier_ca_handler.py examples/Docker/data/ca_handler.py sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg @@ -132,7 +153,12 @@ jobs: docker-compose restart docker-compose logs - - name: "[ ENROLL ] via certifier ca_handler" + - name: "Sleep for 5s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 5s + + - name: "Enroll via certifier ca_handler" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer @@ -142,19 +168,19 @@ jobs: run: | docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "[ CHECK ] proxy logs" + - name: "Check proxy logs" run: | docker logs proxy | grep socks5 | grep -- "->" docker stop proxy docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & - - name: "[ PREPARE ] patch est_ca handler for testrfc7030.com" + - name: "patch est_ca handler for testrfc7030.com" run: | sudo apt-get install curl openssl patch sudo cp examples/ca_handler/est_ca_handler.py examples/Docker/data/ca_handler.py # sudo patch examples/Docker/data/ca_handler.py .github/est_handler.patch - - name: "[ PREPARE ] setup using http-basic-auth for proxy usage" + - name: "setup using http-basic-auth for proxy usage" run: | sudo mkdir -p examples/Docker/data/est sudo chmod -R 777 examples/Docker/data/est @@ -178,17 +204,22 @@ jobs: docker-compose restart docker-compose logs - - name: "[ ENROLL ] via EST using http-basic-auth" + - name: "Sleep for 5s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 5s + + - name: "Enroll via EST using http-basic-auth" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force - - name: "[ CHECK ] proxy logs" + - name: "Check proxy logs" run: | docker logs proxy | grep socks5 | grep -- "->" docker stop proxy docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & - #- name: "[ PREPARE ] setup using tls-client-auth" + #- name: "setup using tls-client-auth" # run: | # sudo head -n -4 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg # sudo echo "est_host: https://testrfc7030.com:9443" >> examples/Docker/data/acme_srv.cfg @@ -200,18 +231,18 @@ jobs: # docker-compose restart # docker-compose logs - # - name: "[ ENROLL ] via est using tls-client-auth" + # - name: "Enroll via est using tls-client-auth" # run: | # docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force # # openssl verify -CAfile acme.sh/acme-sh.acme/ca.cer acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - #- name: "[ CHECK ] proxy logs" + #- name: "Check proxy logs" # run: | # docker logs proxy | grep http | grep -- "->" # docker stop proxy # docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & - - name: "[ PREPARE ] setup nclm ca_handler for proxy usage" + - name: "setup nclm ca_handler for proxy usage" run: | sudo cp examples/ca_handler/nclm_ca_handler.py examples/Docker/data/ca_handler.py sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg @@ -228,18 +259,23 @@ jobs: docker-compose restart docker-compose logs - - name: "[ ENROLL ] via nclm ca_handler" + - name: "Sleep for 5s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 5s + + - name: "Enroll via nclm ca_handler" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force # openssl verify -CAfile acme.sh/acme-sh.acme/ca.cer acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ CHECK ] proxy logs" + - name: "Check proxy logs" run: | docker logs proxy | grep http | grep -- "->" docker stop proxy docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & - - name: "[ PREPARE ] setup msca ca_handler for proxy usage" + - name: "setup msca ca_handler for proxy usage" run: | sudo cp examples/ca_handler/mscertsrv_ca_handler.py examples/Docker/data/ca_handler.py sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg @@ -257,7 +293,7 @@ jobs: docker-compose restart docker-compose logs - - name: "[ PREPARE ] ssh environment on ramdisk" + - name: "ssh environment on ramdisk" run: | sudo mkdir -p /tmp/rd sudo mount -t tmpfs -o size=5M none /tmp/rd @@ -268,25 +304,25 @@ jobs: SSH_KEY: ${{ secrets.WCCE_SSH_ACCESS_KEY }} KNOWN_HOSTS: ${{ secrets.WCCE_SSH_KNOWN_HOSTS }} - - name: "[ PREPARE ] establish SSH connection" - run: sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -p $SSH_PORT -o UserKnownHostsFile=/tmp/rd/known_hosts -L 443:$WES_IP:443 -g ping -c 180 $WES_IP & + - name: "establish SSH connection" + run: sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -p $SSH_PORT -o UserKnownHostsFile=/tmp/rd/known_hosts -L 443:$WES_IP:443 -g ping -c 120 $WES_IP & env: SSH_USER: ${{ secrets.CMP_SSH_USER }} SSH_HOST: ${{ secrets.CMP_SSH_HOST }} SSH_PORT: ${{ secrets.CMP_SSH_PORT }} WES_IP: ${{ secrets.WES_IP }} - - name: "[ PREPARE ] Sleep for 5s" + - name: "Sleep for 5s" uses: juliangruber/sleep-action@v2.0.3 with: time: 5s - - name: "[ ENROLL ] via msca ca_handler" + - name: "Enroll via msca ca_handler" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force # openssl verify -CAfile acme.sh/acme-sh.acme/ca.cer acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ CHECK ] proxy logs" + - name: "Check proxy logs" run: | docker logs proxy | grep socks5 | grep -- "->" docker stop proxy @@ -309,7 +345,7 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: proxy.tar.gz + name: proxy-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ @@ -325,7 +361,7 @@ jobs: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] get runner ip" + - name: "get runner ip" run: | echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV @@ -351,7 +387,7 @@ jobs: RUNNER_IP: ${{ env.RUNNER_IP }} WES_HOST: ${{ secrets.WES_HOST }} - - name: "[ PREPARE ] test dns resulution" + - name: "test dns resulution" run: | host $WES_HOST 127.0.0.1 env: @@ -376,7 +412,7 @@ jobs: - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" - - name: "[ PREPARE ] setup environment for alma installation" + - name: "setup environment for alma installation" run: | docker network create acme sudo mkdir -p data @@ -393,12 +429,12 @@ jobs: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} - - name: "[ PREPARE ] proxy container" + - name: "proxy container" run: | docker pull mosajjal/pproxy:latest docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & - - name: "[ PREPARE ] Sleep for 10s" + - name: "Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -408,7 +444,7 @@ jobs: echo PROXY_IP=$(docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' proxy) >> $GITHUB_ENV - run: echo "Latest tag is ${{ env.PROXY_IP }}" - - name: "[ PREPARE ] setup openssl ca_handler" + - name: "setup openssl ca_handler" run: | sudo mkdir -p data/acme_ca/certs sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem data/acme_ca/ @@ -416,7 +452,7 @@ jobs: sudo chmod 777 data/acme_srv.cfg sudo sed -i "s/debug: True/debug: True\nproxy_server_list: {\"acme-sh.acme\$\": \"socks5:\/\/${{ env.PROXY_IP }}:8080\", \"acme-sh.\$\": \"http\:\/\/${{ env.PROXY_IP }}:8080\"}/g" data/acme_srv.cfg - - name: "[ PREPARE ] Almalinux instance" + - name: "Almalinux instance" run: | sudo cp examples/Docker/almalinux-systemd/Dockerfile data sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile @@ -430,35 +466,35 @@ jobs: - name: "Test if http://acme-srv/directory is accessible" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" + - name: "Prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ ENROLL ] acme.sh - http challenge validation" + - name: "Enroll acme.sh - http challenge validation" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme -d acme-sh. --standalone --debug 3 --output-insecure --force openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ CHECK ] proxy logs" + - name: "Check proxy logs" run: | docker logs proxy | grep socks5 | grep -- "->" docker logs proxy | grep http | grep -- "->" docker stop proxy docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & - - name: "[ ENROLL ] acme.sh - alpn challenge validation" + - name: "Enroll acme.sh - alpn challenge validation" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn -d acme-sh. --alpn --standalone --debug 3 --output-insecure --force openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ CHECK ] proxy logs" + - name: "Check proxy logs" run: | docker logs proxy | grep socks5 | grep -- "->" docker logs proxy | grep http | grep -- "->" docker stop proxy docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & - - name: "[ PREPARE ] prepare acme_srv.cfg with certifier_ca_handler and proxy usage" + - name: "Prepare acme_srv.cfg with certifier_ca_handler and proxy usage" run: | mkdir -p data/acme_ca sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem @@ -494,13 +530,13 @@ jobs: run: | docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "[ CHECK ] proxy logs" + - name: "Check proxy logs" run: | docker logs proxy | grep socks5 | grep -- "->" docker stop proxy docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & - - name: "[ PREPARE ] setup esthandler using http-basic-auth" + - name: "setup esthandler using http-basic-auth" run: | sudo mkdir -p data/acme_ca sudo chmod -R 777 data/acme_ca @@ -527,17 +563,17 @@ jobs: run: | docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart - - name: "[ ENROLL ] via EST using http-basic-auth" + - name: "Enroll via EST using http-basic-auth" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force - - name: "[ CHECK ] proxy logs" + - name: "Check proxy logs" run: | docker logs proxy | grep socks5 | grep -- "->" docker stop proxy docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & - #- name: "[ PREPARE ] setup using tls-client-auth" + #- name: "setup using tls-client-auth" # run: | # sudo head -n -4 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/acme_srv.cfg # sudo echo "handler_file: /opt/acme2certifier/examples/ca_handler/est_ca_handler.py" >> data/acme_srv.cfg @@ -551,18 +587,18 @@ jobs: # run: | # docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart - #- name: "[ ENROLL ] via est using tls-client-auth" + #- name: "Enroll via est using tls-client-auth" # run: | # docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force - #- name: "[ CHECK ] proxy logs" + #- name: "Check proxy logs" # run: | # docker logs proxy | grep socks5 | grep -- "->" - - name: "[ PREPARE ] setup using nclm_ca_handler" + - name: "setup using nclm_ca_handler" run: | - - name: "[ PREPARE ] prepare acme_srv.cfg with nclm_ca_handler" + - name: "Prepare acme_srv.cfg with nclm_ca_handler" run: | mkdir -p data/acme_ca sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem @@ -590,17 +626,17 @@ jobs: run: | docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart - - name: "[ ENROLL ] via nclm_ca_handler" + - name: "Enroll via nclm_ca_handler" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force & docker stop proxy docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & - #- name: "[ CHECK ] proxy logs" + #- name: "Check proxy logs" # run: | # docker logs proxy | grep socks5 | grep -- "->" - - name: "[ PREPARE ] ssh environment on ramdisk" + - name: "ssh environment on ramdisk" run: | sudo mkdir -p /tmp/rd sudo mount -t tmpfs -o size=5M none /tmp/rd @@ -611,7 +647,7 @@ jobs: SSH_KEY: ${{ secrets.WCCE_SSH_ACCESS_KEY }} KNOWN_HOSTS: ${{ secrets.WCCE_SSH_KNOWN_HOSTS }} - - name: "[ PREPARE ] establish SSH connection" + - name: "establish SSH connection" run: sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -p $SSH_PORT -o UserKnownHostsFile=/tmp/rd/known_hosts -L 443:$WES_IP:443 -g ping -c 180 $WES_IP & env: SSH_USER: ${{ secrets.CMP_SSH_USER }} @@ -619,12 +655,12 @@ jobs: SSH_PORT: ${{ secrets.CMP_SSH_PORT }} WES_IP: ${{ secrets.WES_IP }} - - name: "[ PREPARE ] Sleep for 5s" + - name: "Sleep for 5s" uses: juliangruber/sleep-action@v2.0.3 with: time: 5s - - name: "[ PREPARE ] setup msca ca_handler for proxy usage" + - name: "setup msca ca_handler for proxy usage" run: | mkdir -p data/acme_ca sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem @@ -650,13 +686,13 @@ jobs: run: | docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart - - name: "[ ENROLL ] via msca ca_handler" + - name: "Enroll via msca ca_handler" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force & # sleep 45 # openssl verify -CAfile data/acme_ca/ca_certs.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ CHECK ] proxy logs" + - name: "Check proxy logs" run: | docker logs proxy | grep socks5 | grep -- "->" docker stop proxy diff --git a/.github/workflows/test_headerinfo.yml b/.github/workflows/test_headerinfo.yml index 04d1725a..fd29e058 100644 --- a/.github/workflows/test_headerinfo.yml +++ b/.github/workflows/test_headerinfo.yml @@ -9,204 +9,46 @@ on: - cron: '0 2 * * 6' jobs: - ap_wsgi_header_info_tests: - name: "ap_wsgi_header_info_tests" + header_info_tests: + name: "header_info_tests" runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "Build docker-compose (apache2_wsgi)" - working-directory: examples/Docker/ - run: | - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "create letsencrypt and lego folder" - run: | - mkdir lego - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "setup a2c with xca_ca_handler" - run: | - sudo mkdir -p examples/Docker/data/xca - sudo chmod -R 777 examples/Docker/data/xca - sudo cp test/ca/acme2certifier-clean.xdb examples/Docker/data/xca/$XCA_DB_NAME - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo touch examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg - sudo echo "handler_file: /var/www/acme2certifier/examples/ca_handler/xca_ca_handler.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "xdb_file: volume/xca/$XCA_DB_NAME" >> examples/Docker/data/acme_srv.cfg - sudo echo "issuing_ca_name: $XCA_ISSUING_CA" >> examples/Docker/data/acme_srv.cfg - sudo echo "passphrase: $XCA_PASSPHRASE" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_cert_chain_list: [\"root-ca\"]" >> examples/Docker/data/acme_srv.cfg - sudo echo "template_name: $XCA_TEMPLATE" >> examples/Docker/data/acme_srv.cfg - sudo sed -i "s/tnauthlist_support: False/tnauthlist_support: False\nheader_info_list: [\"HTTP_USER_AGENT\"]/g" examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - docker-compose restart - docker-compose logs - env: - XCA_PASSPHRASE: ${{ secrets.XCA_PASSPHRASE }} - XCA_ISSUING_CA: ${{ secrets.XCA_ISSUING_CA }} - XCA_TEMPLATE: ${{ secrets.XCA_TEMPLATE }} - XCA_DB_NAME: ${{ secrets.XCA_DB_NAME }} - - - name: "Test http://acme-srv/directory is accessable again" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent foo-bar-doo -d lego.acme --http run - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - - name: "[ WAIT ] Sleep for 15s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 15s - - - name: "check header info" - run: | - cd examples/Docker/ - docker-compose logs | grep foo-bar-doo - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: ap_wsgi_header_info.tar.gz - path: ${{ github.workspace }}/artifact/upload/ + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] - ap_django_header_info_tests: - name: "ap_django_header_info_tests" - runs-on: ubuntu-latest steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "Build docker-compose (apache2_wsgi)" - working-directory: examples/Docker/ - run: | - sed -i "s/wsgi/django/g" .env - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "create letsencrypt and lego folder" + - name: "create folders" run: | mkdir lego + mkdir acme-sh + mkdir certbot - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "setup a2c with xca_ca_handler" - run: | - sudo mkdir -p examples/Docker/data/xca - sudo chmod -R 777 examples/Docker/data/xca - sudo cp test/ca/acme2certifier-clean.xdb examples/Docker/data/xca/$XCA_DB_NAME - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo touch examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg - sudo echo "handler_file: /var/www/acme2certifier/examples/ca_handler/xca_ca_handler.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "xdb_file: volume/xca/$XCA_DB_NAME" >> examples/Docker/data/acme_srv.cfg - sudo echo "issuing_ca_name: $XCA_ISSUING_CA" >> examples/Docker/data/acme_srv.cfg - sudo echo "passphrase: $XCA_PASSPHRASE" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_cert_chain_list: [\"root-ca\"]" >> examples/Docker/data/acme_srv.cfg - sudo echo "template_name: $XCA_TEMPLATE" >> examples/Docker/data/acme_srv.cfg - sudo sed -i "s/tnauthlist_support: False/tnauthlist_support: False\nheader_info_list: [\"HTTP_USER_AGENT\"]/g" examples/Docker/data/acme_srv.cfg - sudo cp .github/django_settings.py examples/Docker/data/settings.py - cd examples/Docker/ - docker-compose restart - docker-compose logs - env: - XCA_PASSPHRASE: ${{ secrets.XCA_PASSPHRASE }} - XCA_ISSUING_CA: ${{ secrets.XCA_ISSUING_CA }} - XCA_TEMPLATE: ${{ secrets.XCA_TEMPLATE }} - XCA_DB_NAME: ${{ secrets.XCA_DB_NAME }} - - - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s - - - name: "Test http://acme-srv/directory is accessable again" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent foo-bar-doo -d lego.acme --http run - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - - name: "[ WAIT ] Sleep for 15s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 15s - - - name: "check header info" - run: | - cd examples/Docker/ - docker-compose logs | grep foo-bar-doo - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: ap_django_header_info_tests.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - nginx_wsgi_header_info_tests: - name: "nginx_wsgi_header_info_tests" - runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "Build docker-compose (apache2_wsgi)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | - sed -i "s/apache2/nginx/g" .env sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker network create acme docker-compose up -d docker-compose logs + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - - name: "create letsencrypt and lego folder" - run: | - mkdir lego - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - name: "setup a2c with xca_ca_handler" run: | + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py sudo mkdir -p examples/Docker/data/xca sudo chmod -R 777 examples/Docker/data/xca sudo cp test/ca/acme2certifier-clean.xdb examples/Docker/data/xca/$XCA_DB_NAME @@ -231,109 +73,16 @@ jobs: XCA_TEMPLATE: ${{ secrets.XCA_TEMPLATE }} XCA_DB_NAME: ${{ secrets.XCA_DB_NAME }} - - name: "[ WAIT ] Sleep for 15s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 15s - - - name: "Test http://acme-srv/directory is accessable again" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent foo-bar-doo -d lego.acme --http run - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - - name: "[ WAIT ] Sleep for 15s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 15s - - - name: "check header info" - run: | - cd examples/Docker/ - docker-compose logs | grep foo-bar-doo - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: nginx_wsgi_header_info_tests.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - nginx_django_header_info_tests: - name: "nginx_django_header_info_tests" - runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "Build docker-compose (apache2_wsgi)" - working-directory: examples/Docker/ - run: | - sed -i "s/apache2/nginx/g" .env - sed -i "s/wsgi/django/g" .env - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "[ WAIT ] Sleep for 10s" + - name: "Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: time: 10s - - name: "create letsencrypt and lego folder" - run: | - mkdir lego - - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "setup a2c with xca_ca_handler" - run: | - sudo mkdir -p examples/Docker/data/xca - sudo chmod -R 777 examples/Docker/data/xca - sudo cp test/ca/acme2certifier-clean.xdb examples/Docker/data/xca/$XCA_DB_NAME - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo touch examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg - sudo echo "handler_file: /var/www/acme2certifier/examples/ca_handler/xca_ca_handler.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "xdb_file: volume/xca/$XCA_DB_NAME" >> examples/Docker/data/acme_srv.cfg - sudo echo "issuing_ca_name: $XCA_ISSUING_CA" >> examples/Docker/data/acme_srv.cfg - sudo echo "passphrase: $XCA_PASSPHRASE" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_cert_chain_list: [\"root-ca\"]" >> examples/Docker/data/acme_srv.cfg - sudo echo "template_name: $XCA_TEMPLATE" >> examples/Docker/data/acme_srv.cfg - sudo sed -i "s/tnauthlist_support: False/tnauthlist_support: False\nheader_info_list: [\"HTTP_USER_AGENT\"]/g" examples/Docker/data/acme_srv.cfg - sudo cp .github/django_settings.py examples/Docker/data/settings.py - cd examples/Docker/ - docker-compose restart - docker-compose logs - env: - XCA_PASSPHRASE: ${{ secrets.XCA_PASSPHRASE }} - XCA_ISSUING_CA: ${{ secrets.XCA_ISSUING_CA }} - XCA_TEMPLATE: ${{ secrets.XCA_TEMPLATE }} - XCA_DB_NAME: ${{ secrets.XCA_DB_NAME }} - - - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s - - - name: "Test http://acme-srv/directory is accessable again" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - name: "lego" run: | @@ -364,7 +113,7 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: nginx_django_header_info_tests.tar.gz + name: _wsgi_header_info-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ header_info_tests_rpm: diff --git a/.github/workflows/tnauth-test.yml b/.github/workflows/tnauth-test.yml index 2ca6b83f..c75351a8 100644 --- a/.github/workflows/tnauth-test.yml +++ b/.github/workflows/tnauth-test.yml @@ -12,23 +12,36 @@ jobs: tnauth_tests: name: "tnauth_tests" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] + steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker network create acme docker-compose up -d docker-compose logs + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup openssl ca_handler" + - name: "Setup openssl ca_handler" run: | + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py sudo mkdir -p examples/Docker/data/acme_ca/certs sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ @@ -38,17 +51,28 @@ jobs: docker-compose restart docker-compose logs - - name: "[ CURL ] install curl and socat and test connction" + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Test http://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "Install curl and socat and test connction" run: | sudo apt-get install -y curl socat curl -f http://localhost:22280 - - name: "[ ACME.SH ] install acme.sh" + - name: "Install acme.sh" run: | mkdir /tmp/acme_sh curl -kL https://github.com/grindsa/acme.sh/archive/tnauth_list_support.tar.gz | tar xz -C /tmp/acme_sh --strip-components=1 - - name: "[ ACME.SH ] enroll certificate using tnauth identifier" + - name: "Enroll certificate using tnauth identifier" run: | cd /tmp/acme_sh /tmp/acme_sh/acme.sh --server http://127.0.0.1:22280 --accountemail grindsa@tnauth.acme --issue -d cert.acme.local --tnauth 123456 --spctoken 1234 --standalone --force --debug 2 @@ -66,10 +90,9 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: tnauth.tar.gz + name: tnauth-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ - tnauth_rpm_tests: name: "tnauth_rpm_tests" runs-on: ubuntu-latest diff --git a/.github/workflows/traffic-application-test.yml b/.github/workflows/traffic-application-test.yml index e7d65ab7..327bc5bf 100644 --- a/.github/workflows/traffic-application-test.yml +++ b/.github/workflows/traffic-application-test.yml @@ -10,13 +10,15 @@ on: jobs: - traefik_apache2_wsgi: - name: "traefik_apache2_wsgi" + traefik_tests: + name: "traefik_tests" runs-on: ubuntu-latest strategy: fail-fast: false matrix: challenge_type: [tlschallenge=true, httpchallenge.entrypoint=web] + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -29,19 +31,26 @@ jobs: - run: echo "runner IP is ${{ env.RUNNER_IP }}" - run: echo "runner hostname is ${{ env.RUNNER_HOSTNAME }}" - - name: "Build docker-compose (apache2_wsgi)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker network create acme docker-compose up -d docker-compose logs - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - name: "setup openssl ca_handler" run: | + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py sudo mkdir -p examples/Docker/data/acme_ca/certs sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ @@ -50,6 +59,17 @@ jobs: docker-compose restart docker-compose logs + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Test http://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + - name: "setup and instanciate traefik" run: | mkdir traefik @@ -85,6 +105,6 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: traffic-${{ matrix.challenge_type }}.tar.gz + name: traffic-${{ matrix.challenge_type }}-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ From ce75f5744ece20b281d28d445dc18070dfee3e7d Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 16 Mar 2024 07:42:01 +0100 Subject: [PATCH 110/460] [fix] fix string format error --- acme_srv/certificate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme_srv/certificate.py b/acme_srv/certificate.py index 088a4e00..3841b7ac 100644 --- a/acme_srv/certificate.py +++ b/acme_srv/certificate.py @@ -790,7 +790,7 @@ def enroll_and_store(self, certificate_name: str, csr: str, order_name: str = No twrv = ThreadWithReturnValue(target=self._enroll_and_store, args=(certificate_name, csr, order_name)) twrv.start() enroll_result = twrv.join(timeout=self.enrollment_timeout) - self.logger.debug('Certificate.enroll_and_store() ThreadWithReturnValue ended', certificate_name, order_name) + self.logger.debug('Certificate.enroll_and_store() ThreadWithReturnValue ended') if enroll_result: try: (result, error, detail) = enroll_result From be4eedee35bdddd066bbf4cd61ff66c6d51ce2d4 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 16 Mar 2024 17:05:56 +0100 Subject: [PATCH 111/460] [wf] increase ssh timer in cmp wf --- .github/workflows/ca_handler_tests_cmp.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ca_handler_tests_cmp.yml b/.github/workflows/ca_handler_tests_cmp.yml index d3867bb3..42c92ac5 100644 --- a/.github/workflows/ca_handler_tests_cmp.yml +++ b/.github/workflows/ca_handler_tests_cmp.yml @@ -111,7 +111,7 @@ jobs: KNOWN_HOSTS: ${{ secrets.WCCE_SSH_KNOWN_HOSTS }} - name: "Establish SSH connection" - run: sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -p $SSH_PORT -o UserKnownHostsFile=/tmp/rd/known_hosts -L 8086:$CMP_HOST:8086 -g ping -c 180 $CMP_HOST & + run: sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -p $SSH_PORT -o UserKnownHostsFile=/tmp/rd/known_hosts -L 8086:$CMP_HOST:8086 -g ping -c 270 $CMP_HOST & env: SSH_USER: ${{ secrets.CMP_SSH_USER }} SSH_HOST: ${{ secrets.CMP_SSH_HOST }} From 375d4427db13df1210cc5dd439708f1563c41ecc Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 16 Mar 2024 17:56:05 +0100 Subject: [PATCH 112/460] [fix] sanitizing identifiers --- acme_srv/helper.py | 45 +++++++++++++++++- acme_srv/order.py | 13 +++++- test/test_helper.py | 109 +++++++++++++++++++++++++++++++++++++++++++- test/test_order.py | 45 +++++++++++++++--- 4 files changed, 200 insertions(+), 12 deletions(-) diff --git a/acme_srv/helper.py b/acme_srv/helper.py index 6d4ab66c..7f0b8add 100644 --- a/acme_srv/helper.py +++ b/acme_srv/helper.py @@ -969,7 +969,8 @@ def error_dic_get(logger: logging.Logger) -> Dict[str, str]: 'unsupportedidentifier': 'urn:ietf:params:acme:error:unsupportedIdentifier', 'ordernotready': 'urn:ietf:params:acme:error:orderNotReady', 'ratelimited': 'urn:ietf:params:acme:error:rateLimited', - 'badrevocationreason': 'urn:ietf:params:acme:error:badRevocationReason'} + 'badrevocationreason': 'urn:ietf:params:acme:error:badRevocationReason', + 'rejectedidentifier': 'urn:ietf:params:acme:error:rejectedIdentifier'} return error_dic @@ -1203,7 +1204,7 @@ def servercert_get(logger: logging.Logger, hostname: str, port: int = 443, proxy try: # this does not work on RH8 context.minimum_version = ssl.TLSVersion.TLSv1_2 - except Exception: + except Exception: # pragma: no cover pass context.options |= ssl.OP_NO_SSLv3 context.options |= ssl.OP_NO_TLSv1 @@ -1260,6 +1261,46 @@ def validate_email(logger: logging.Logger, contact_list: List[str]) -> bool: logger.debug('# validate: %s result: %s', contact_list, result) return result +def validate_identifier(logger: logging.Logger, type: str, identifier: str, tnauthlist_support: bool = False) -> bool: + """ validate identifier """ + logger.debug('validate_identifier()') + + if identifier: + if type == 'dns': + result = validate_fqdn(logger, identifier) + elif type == 'ip': + result = validate_ip(logger, identifier) + elif type == 'tnauthlist' and tnauthlist_support: + result = True + else: + result = False + + logger.debug('validate_identifier() ended with: %s', result) + return result + +def validate_ip(logger: logging.Logger, ip: str) -> bool: + """ validate ip address """ + logger.debug('validate_ip()') + try: + ipaddress.ip_address(ip) + result = True + except ValueError: + result = False + logger.debug('validate_ip() ended with: %s', result) + return result + +def validate_fqdn(logger: logging.Logger, fqdn: str) -> bool: + """ validate fqdn """ + logger.debug('validate_fqdn()') + + result = False + regex = r"^(([a-z0-9]\-*[a-z0-9]*){1,63}\.?){1,255}$" + p = re.compile(regex) + if(re.search(p, fqdn)): + result = True + + logger.debug('validate_fqdn() ended with: %s', result) + return result def handle_exception(exc_type, exc_value, exc_traceback): # pragma: no cover """ exception handler """ diff --git a/acme_srv/order.py b/acme_srv/order.py index ad732d38..764c60e2 100644 --- a/acme_srv/order.py +++ b/acme_srv/order.py @@ -3,7 +3,7 @@ from __future__ import print_function import json from typing import List, Tuple, Dict -from acme_srv.helper import b64_url_recode, generate_random_string, load_config, parse_url, uts_to_date_utc, uts_now, error_dic_get +from acme_srv.helper import b64_url_recode, generate_random_string, load_config, parse_url, uts_to_date_utc, uts_now, error_dic_get, validate_identifier from acme_srv.certificate import Certificate from acme_srv.db_handler import DBstore from acme_srv.message import Message @@ -188,6 +188,10 @@ def _identifiers_check(self, identifiers_list: List[str]) -> str: if identifier['type'].lower() not in allowed_identifers: error = self.error_msg_dic['unsupportedidentifier'] break + else: + if not validate_identifier(self.logger, identifier['type'].lower(), identifier['value'], self.tnauthlist_support): + error = self.error_msg_dic['rejectedidentifier'] + break else: error = self.error_msg_dic['malformed'] else: @@ -469,10 +473,15 @@ def new(self, content: str) -> Dict[str, str]: for auth_name, value in auth_dic.items(): response_dic['data']['authorizations'].append(f'{self.server_name}{self.path_dic["authz_path"]}{auth_name}') response_dic['data']['identifiers'].append(value) + elif error == self.error_msg_dic['rejectedidentifier']: + code = 403 + message = error + detail = 'Some of the requested identifiers got rejected' else: code = 400 message = error - detail = 'could not process order' + detail = 'Could not process order' + # prepare/enrich response status_dic = {'code': code, 'type': message, 'detail': detail} response_dic = self.message.prepare_response(response_dic, status_dic) diff --git a/test/test_helper.py b/test/test_helper.py index 1f4401cc..f078a9bc 100644 --- a/test/test_helper.py +++ b/test/test_helper.py @@ -26,7 +26,7 @@ def setUp(self): """ setup unittest """ import logging logging.basicConfig(level=logging.CRITICAL) - from acme_srv.helper import b64decode_pad, b64_decode, b64_encode, b64_url_encode, b64_url_recode, convert_string_to_byte, convert_byte_to_string, decode_message, decode_deserialize, get_url, generate_random_string, signature_check, validate_email, uts_to_date_utc, date_to_uts_utc, load_config, cert_serial_get, cert_san_get, cert_san_pyopenssl_get, cert_dates_get, build_pem_file, date_to_datestr, datestr_to_date, dkeys_lower, csr_cn_get, cert_pubkey_get, csr_pubkey_get, url_get, url_get_with_own_dns, dns_server_list_load, csr_san_get, csr_san_byte_get, csr_extensions_get, fqdn_resolve, fqdn_in_san_check, sha256_hash, sha256_hash_hex, cert_der2pem, cert_pem2der, cert_extensions_get, csr_dn_get, logger_setup, logger_info, print_debug, jwk_thumbprint_get, allowed_gai_family, patched_create_connection, validate_csr, servercert_get, txt_get, proxystring_convert, proxy_check, handle_exception, ca_handler_load, eab_handler_load, hooks_load, error_dic_get, _logger_nonce_modify, _logger_certificate_modify, _logger_token_modify, _logger_challenges_modify, config_check, cert_issuer_get, cert_cn_get, string_sanitize, pembundle_to_list, certid_asn1_get, certid_check, certid_hex_get, v6_adjust, ipv6_chk, ip_validate, header_info_get, encode_url, uts_now, cert_ski_get, cert_ski_pyopenssl_get, cert_aki_get, cert_aki_pyopenssl_get + from acme_srv.helper import b64decode_pad, b64_decode, b64_encode, b64_url_encode, b64_url_recode, convert_string_to_byte, convert_byte_to_string, decode_message, decode_deserialize, get_url, generate_random_string, signature_check, validate_email, uts_to_date_utc, date_to_uts_utc, load_config, cert_serial_get, cert_san_get, cert_san_pyopenssl_get, cert_dates_get, build_pem_file, date_to_datestr, datestr_to_date, dkeys_lower, csr_cn_get, cert_pubkey_get, csr_pubkey_get, url_get, url_get_with_own_dns, dns_server_list_load, csr_san_get, csr_san_byte_get, csr_extensions_get, fqdn_resolve, fqdn_in_san_check, sha256_hash, sha256_hash_hex, cert_der2pem, cert_pem2der, cert_extensions_get, csr_dn_get, logger_setup, logger_info, print_debug, jwk_thumbprint_get, allowed_gai_family, patched_create_connection, validate_csr, servercert_get, txt_get, proxystring_convert, proxy_check, handle_exception, ca_handler_load, eab_handler_load, hooks_load, error_dic_get, _logger_nonce_modify, _logger_certificate_modify, _logger_token_modify, _logger_challenges_modify, config_check, cert_issuer_get, cert_cn_get, string_sanitize, pembundle_to_list, certid_asn1_get, certid_check, certid_hex_get, v6_adjust, ipv6_chk, ip_validate, header_info_get, encode_url, uts_now, cert_ski_get, cert_ski_pyopenssl_get, cert_aki_get, cert_aki_pyopenssl_get, validate_fqdn, validate_ip, validate_identifier self.logger = logging.getLogger('test_a2c') self.allowed_gai_family = allowed_gai_family self.b64_decode = b64_decode @@ -95,6 +95,9 @@ def setUp(self): self.url_get_with_own_dns = url_get_with_own_dns self.uts_to_date_utc = uts_to_date_utc self.validate_email = validate_email + self.validate_ip = validate_ip + self.validate_fqdn = validate_fqdn + self.validate_identifier = validate_identifier self.validate_csr = validate_csr self.sha256_hash = sha256_hash self.sha256_hash_hex = sha256_hash_hex @@ -1814,7 +1817,8 @@ def test_237_error_dic_get(self): 'unsupportedidentifier': 'urn:ietf:params:acme:error:unsupportedIdentifier', 'ordernotready': 'urn:ietf:params:acme:error:orderNotReady', 'ratelimited': 'urn:ietf:params:acme:error:rateLimited', - 'badrevocationreason': 'urn:ietf:params:acme:error:badRevocationReason'} + 'badrevocationreason': 'urn:ietf:params:acme:error:badRevocationReason', + 'rejectedidentifier': 'urn:ietf:params:acme:error:rejectedIdentifier'} self.assertEqual(result, self.error_dic_get(self.logger)) def test_238_logger_nonce_modify(self): @@ -2190,6 +2194,107 @@ def test_285_aki_get(self, mock_load): self.assertFalse(self.cert_aki_pyopenssl_get(self.logger, cert)) self.assertIn('ERROR:test_a2c:cert_ski_pyopenssl_get(): No AKI found in certificate', lcm.output) + def test_286_validate_fqdn(self): + """ test validate_fqdn() """ + self.assertTrue(self.validate_fqdn(self.logger, 'foo.bar.com')) + + def test_287_validate_fqdn(self): + """ test validate_fqdn() """ + self.assertFalse(self.validate_fqdn(self.logger, '-foo.bar.com')) + + def test_288_validate_fqdn(self): + """ test validate_fqdn() """ + self.assertFalse(self.validate_fqdn(self.logger, 'foo.bar.com/foo')) + + def test_289_validate_fqdn(self): + """ test validate_fqdn() """ + self.assertFalse(self.validate_fqdn(self.logger, 'foo.bar.com#foo')) + + def test_290_validate_fqdn(self): + """ test validate_fqdn() """ + self.assertFalse(self.validate_fqdn(self.logger, 'foo.bar.com?foo=foo')) + + def test_291_validate_fqdn(self): + """ test validate_fqdn() """ + self.assertFalse(self.validate_fqdn(self.logger, '2a01:c22:b0cf:600:74be:80a7:4feb:bfe8')) + + def test_292_validate_fqdn(self): + """ test validate_fqdn() """ + self.assertFalse(self.validate_fqdn(self.logger, 'foo.bar.com:8080')) + + def test_293_validate_fqdn(self): + """ test validate_fqdn() """ + self.assertFalse(self.validate_fqdn(self.logger, 'foo@bar.local')) + + def test_294_validate_ip(self): + """ test validate_ip() """ + self.assertTrue(self.validate_ip(self.logger, '10.0.0.1')) + + def test_295_validate_ip(self): + """ test validate_ip() """ + self.assertTrue(self.validate_ip(self.logger, '2a01:c22:b0cf:600:74be:80a7:4feb:bfe8')) + + def test_296_validate_ip(self): + """ test validate_ip() """ + self.assertFalse(self.validate_ip(self.logger, 'foo.bar.local')) + + def test_297_validate_ip(self): + """ test validate_ip() """ + self.assertFalse(self.validate_ip(self.logger, 'foo@bar.local')) + + def test_298_validate_ip(self): + """ test validate_ip() """ + self.assertFalse(self.validate_ip(self.logger, '301.0.0.1')) + + @patch('acme_srv.helper.validate_fqdn') + @patch('acme_srv.helper.validate_ip') + def test_299_validate_identifier(self, mock_ip, mock_fqdn): + """ test validate_identifier """ + mock_fqdn.return_value = 'dns' + mock_ip.return_value = 'ip' + self.assertEqual('dns', self.validate_identifier(self.logger, 'dns', 'foo.bar.com')) + self.assertTrue(mock_fqdn.called) + self.assertFalse(mock_ip.called) + + @patch('acme_srv.helper.validate_fqdn') + @patch('acme_srv.helper.validate_ip') + def test_300_validate_identifier(self, mock_ip, mock_fqdn): + """ test validate_identifier """ + mock_fqdn.return_value = 'dns' + mock_ip.return_value = 'ip' + self.assertEqual('ip', self.validate_identifier(self.logger, 'ip', 'ip')) + self.assertFalse(mock_fqdn.called) + self.assertTrue(mock_ip.called) + + @patch('acme_srv.helper.validate_fqdn') + @patch('acme_srv.helper.validate_ip') + def test_301_validate_identifier(self, mock_ip, mock_fqdn): + """ test validate_identifier """ + mock_fqdn.return_value = 'dns' + mock_ip.return_value = 'ip' + self.assertFalse(self.validate_identifier(self.logger, 'unk', 'ip')) + self.assertFalse(mock_fqdn.called) + self.assertFalse(mock_ip.called) + + @patch('acme_srv.helper.validate_fqdn') + @patch('acme_srv.helper.validate_ip') + def test_302_validate_identifier(self, mock_ip, mock_fqdn): + """ test validate_identifier """ + mock_fqdn.return_value = 'dns' + mock_ip.return_value = 'ip' + self.assertFalse(self.validate_identifier(self.logger, 'tnauthlist', 'ip')) + self.assertFalse(mock_fqdn.called) + self.assertFalse(mock_ip.called) + + @patch('acme_srv.helper.validate_fqdn') + @patch('acme_srv.helper.validate_ip') + def test_303_validate_identifier(self, mock_ip, mock_fqdn): + """ test validate_identifier """ + mock_fqdn.return_value = 'dns' + mock_ip.return_value = 'ip' + self.assertTrue(self.validate_identifier(self.logger, 'tnauthlist', 'ip', True)) + self.assertFalse(mock_fqdn.called) + self.assertFalse(mock_ip.called) if __name__ == '__main__': unittest.main() diff --git a/test/test_order.py b/test/test_order.py index ef0caa12..e6b004e9 100644 --- a/test/test_order.py +++ b/test/test_order.py @@ -101,7 +101,7 @@ def test_006_order_new(self, mock_mcheck, mock_orderadd, mock_nnonce): mock_orderadd.return_value = ('urn:ietf:params:acme:error:malformed', None, None, None) mock_nnonce.return_value = 'new_nonce' message = '{"foo" : "bar"}' - self.assertEqual({'header': {'Replay-Nonce': 'new_nonce'}, 'code': 400, 'data': {'status': 400, 'type': 'urn:ietf:params:acme:error:malformed', 'detail': 'could not process order'}}, self.order.new(message)) + self.assertEqual({'header': {'Replay-Nonce': 'new_nonce'}, 'code': 400, 'data': {'status': 400, 'type': 'urn:ietf:params:acme:error:malformed', 'detail': 'Could not process order'}}, self.order.new(message)) self.assertTrue(mock_nnonce.called) @patch('acme_srv.nonce.Nonce.generate_and_add') @@ -124,10 +124,7 @@ def test_008_order_new(self, mock_mcheck, mock_orderadd, mock_nnonce): mock_orderadd.return_value = (None, 'foo_order', {'foo_auth1': {u'type': u'dns', u'value': u'acme1.nclm-samba.local'}, 'foo_auth2': {u'type': u'dns', u'value': u'acme2.nclm-samba.local'}}, 'expires') mock_nnonce.return_value = 'new_nonce' message = '{"foo" : "bar"}' - if sys.version_info[0] < 3: - self.assertEqual({'header': {'Location': 'http://tester.local/acme/order/foo_order', 'Replay-Nonce': 'new_nonce'}, 'code': 201, 'data': {'status': 'pending', 'identifiers': [{'type': 'dns', 'value': 'acme2.nclm-samba.local'}, {'type': 'dns', 'value': 'acme1.nclm-samba.local'}], 'authorizations': ['http://tester.local/acme/authz/foo_auth2', 'http://tester.local/acme/authz/foo_auth1'], 'finalize': 'http://tester.local/acme/order/foo_order/finalize', 'expires': 'expires'}}, self.order.new(message)) - else: - self.assertEqual({'header': {'Location': 'http://tester.local/acme/order/foo_order', 'Replay-Nonce': 'new_nonce'}, 'code': 201, 'data': {'status': 'pending', 'identifiers': [{'type': 'dns', 'value': 'acme1.nclm-samba.local'}, {'type': 'dns', 'value': 'acme2.nclm-samba.local'}], 'authorizations': ['http://tester.local/acme/authz/foo_auth1', 'http://tester.local/acme/authz/foo_auth2'], 'finalize': 'http://tester.local/acme/order/foo_order/finalize', 'expires': 'expires'}}, self.order.new(message)) + self.assertEqual({'header': {'Location': 'http://tester.local/acme/order/foo_order', 'Replay-Nonce': 'new_nonce'}, 'code': 201, 'data': {'status': 'pending', 'identifiers': [{'type': 'dns', 'value': 'acme1.nclm-samba.local'}, {'type': 'dns', 'value': 'acme2.nclm-samba.local'}], 'authorizations': ['http://tester.local/acme/authz/foo_auth1', 'http://tester.local/acme/authz/foo_auth2'], 'finalize': 'http://tester.local/acme/order/foo_order/finalize', 'expires': 'expires'}}, self.order.new(message)) @patch('acme_srv.nonce.Nonce.generate_and_add') @patch('acme_srv.order.Order._add') @@ -140,6 +137,18 @@ def test_009_order_new(self, mock_mcheck, mock_orderadd, mock_nnonce): message = '{"foo" : "bar"}' self.assertEqual({'header': {'Location': 'http://tester.local/acme/order/foo_order', 'Replay-Nonce': 'new_nonce'}, 'code': 201, 'data': {'status': 'pending', 'identifiers': [], 'authorizations': [], 'finalize': 'http://tester.local/acme/order/foo_order/finalize', 'expires': 'expires'}}, self.order.new(message)) + @patch('acme_srv.nonce.Nonce.generate_and_add') + @patch('acme_srv.order.Order._add') + @patch('acme_srv.message.Message.check') + def test_010_order_new(self, mock_mcheck, mock_orderadd, mock_nnonce): + """ Order.new() failed bcs of db_add failed """ + mock_mcheck.return_value = (200, None, None, 'protected', {"status" : "foo"}, 'account_name') + mock_orderadd.return_value = ('urn:ietf:params:acme:error:rejectedIdentifier', None, None, None) + mock_nnonce.return_value = 'new_nonce' + message = '{"foo" : "bar"}' + self.assertEqual({'header': {'Replay-Nonce': 'new_nonce'}, 'code': 403, 'data': {'status': 403, 'type': 'urn:ietf:params:acme:error:rejectedIdentifier', 'detail': 'Some of the requested identifiers got rejected'}}, self.order.new(message)) + self.assertTrue(mock_nnonce.called) + @patch('acme_srv.order.Order._info') def test_010_order__lookup(self, mock_oinfo): """ test order lookup with empty hash """ @@ -497,7 +506,7 @@ def test_053_order__identifiers_check(self): def test_054_order__identifiers_check(self): """ order identifers check with tnauthlist identifier and support True """ self.order.tnauthlist_support = True - self.assertEqual(None, self.order._identifiers_check([{'type': 'TNAuthList', 'value': 'value'}, {'type': 'dns', 'value': 'value'}])) + self.assertEqual(None, self.order._identifiers_check([{'type': 'TNAuthList', 'value': 'value'}, {'type': 'dns', 'value': 'foo.bar.local'}])) def test_055_order__identifiers_check(self): """ order identifers check with tnauthlist identifier and support True """ @@ -519,6 +528,30 @@ def test_058_order__identifiers_check(self): self.order.tnauthlist_support = True self.assertEqual(None, self.order._identifiers_check([{'type': 'dns', 'value': 'value'}])) + @patch('acme_srv.order.validate_identifier') + def test_059_order__identifiers_check(self, mock_vali): + """ order identifers check with correct identifer """ + mock_vali.side_effect = [True] + self.assertEqual(None, self.order._identifiers_check([{'type': 'dns', 'value': 'value'}])) + + @patch('acme_srv.order.validate_identifier') + def test_060_order__identifiers_check(self, mock_vali): + """ order identifers check with correct identifer """ + mock_vali.side_effect = [False] + self.assertEqual('urn:ietf:params:acme:error:rejectedIdentifier', self.order._identifiers_check([{'type': 'dns', 'value': 'value'}])) + + @patch('acme_srv.order.validate_identifier') + def test_060_order__identifiers_check(self, mock_vali): + """ order identifers check with correct identifer """ + mock_vali.side_effect = [True, False] + self.assertEqual('urn:ietf:params:acme:error:rejectedIdentifier', self.order._identifiers_check([{'type': 'dns', 'value': 'value'}, {'type': 'dns', 'value': 'value'}])) + + @patch('acme_srv.order.validate_identifier') + def test_061_order__identifiers_check(self, mock_vali): + """ order identifers check with correct identifer """ + mock_vali.side_effect = [False, True] + self.assertEqual('urn:ietf:params:acme:error:rejectedIdentifier', self.order._identifiers_check([{'type': 'dns', 'value': 'value'}, {'type': 'dns', 'value': 'value'}])) + def test_059_order__process(self): """ Order.prcoess() without url in protected header """ order_name = 'order_name' From 92fce37ccabf3ceaf862db2400a4bfe4a0b4d98c Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 17 Mar 2024 07:33:19 +0100 Subject: [PATCH 113/460] [fix] validate_identifier() --- acme_srv/helper.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/acme_srv/helper.py b/acme_srv/helper.py index 7f0b8add..3b3b9d5b 100644 --- a/acme_srv/helper.py +++ b/acme_srv/helper.py @@ -1265,6 +1265,7 @@ def validate_identifier(logger: logging.Logger, type: str, identifier: str, tnau """ validate identifier """ logger.debug('validate_identifier()') + result = False if identifier: if type == 'dns': result = validate_fqdn(logger, identifier) @@ -1272,8 +1273,6 @@ def validate_identifier(logger: logging.Logger, type: str, identifier: str, tnau result = validate_ip(logger, identifier) elif type == 'tnauthlist' and tnauthlist_support: result = True - else: - result = False logger.debug('validate_identifier() ended with: %s', result) return result From f547b52599fbc9fbe9f83179b18916922cc77d30 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 17 Mar 2024 07:33:39 +0100 Subject: [PATCH 114/460] [fix] nginx rate-limiting --- examples/nginx/nginx_acme_srv.conf | 7 +++++++ examples/nginx/nginx_acme_srv_ssl.conf | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/examples/nginx/nginx_acme_srv.conf b/examples/nginx/nginx_acme_srv.conf index 4d5c5a80..bd864f3e 100644 --- a/examples/nginx/nginx_acme_srv.conf +++ b/examples/nginx/nginx_acme_srv.conf @@ -1,6 +1,13 @@ +# zone with 10mb memory which is 160k/s - 5requests per client per second +limit_req_zone $binary_remote_addr zone=ip:10m rate=5r/s; + server { listen 80 default_server; listen [::]:80 default_server; + + # first 5 requests go trough instantly 5more requests evey 100ms + limit_req zone=ip burst=10 delay=5; + server_name _; location = favicon.ico { access_log off; log_not_found off; } location / { diff --git a/examples/nginx/nginx_acme_srv_ssl.conf b/examples/nginx/nginx_acme_srv_ssl.conf index 9d80f4eb..ba053942 100644 --- a/examples/nginx/nginx_acme_srv_ssl.conf +++ b/examples/nginx/nginx_acme_srv_ssl.conf @@ -1,6 +1,12 @@ +# zone with 10mb memory which is 160k/s - 5requests per client per second +limit_req_zone $binary_remote_addr zone=ip:10m rate=5r/s; server { listen 443 ssl default_server; listen [::]:443 ssl default_server; + + # first 5 requests go trough instantly 5more requests evey 100ms + limit_req zone=ip burst=10 delay=5; + server_name _; location = favicon.ico { access_log off; log_not_found off; } location / { From d264eddabf6acb3116f198cfe40bb0cf1993555f Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 17 Mar 2024 07:54:12 +0100 Subject: [PATCH 115/460] [fix] remove redundant zone definition in nginx ssl config --- examples/nginx/nginx_acme_srv_ssl.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/nginx/nginx_acme_srv_ssl.conf b/examples/nginx/nginx_acme_srv_ssl.conf index ba053942..0a9f34fc 100644 --- a/examples/nginx/nginx_acme_srv_ssl.conf +++ b/examples/nginx/nginx_acme_srv_ssl.conf @@ -1,5 +1,5 @@ # zone with 10mb memory which is 160k/s - 5requests per client per second -limit_req_zone $binary_remote_addr zone=ip:10m rate=5r/s; +# limit_req_zone $binary_remote_addr zone=ip:10m rate=5r/s; server { listen 443 ssl default_server; listen [::]:443 ssl default_server; From 316d6a8222d4d59fbf25aba795025c421deb2aa2 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 17 Mar 2024 08:17:42 +0100 Subject: [PATCH 116/460] [fix] disable burst parameter in nginx.conf to ensure backwards compatibility with RH8 --- examples/nginx/nginx_acme_srv.conf | 2 +- examples/nginx/nginx_acme_srv_ssl.conf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/nginx/nginx_acme_srv.conf b/examples/nginx/nginx_acme_srv.conf index bd864f3e..11131785 100644 --- a/examples/nginx/nginx_acme_srv.conf +++ b/examples/nginx/nginx_acme_srv.conf @@ -6,7 +6,7 @@ server { listen [::]:80 default_server; # first 5 requests go trough instantly 5more requests evey 100ms - limit_req zone=ip burst=10 delay=5; + limit_req zone=ip burst=10; # delay=5; server_name _; location = favicon.ico { access_log off; log_not_found off; } diff --git a/examples/nginx/nginx_acme_srv_ssl.conf b/examples/nginx/nginx_acme_srv_ssl.conf index 0a9f34fc..947d38a0 100644 --- a/examples/nginx/nginx_acme_srv_ssl.conf +++ b/examples/nginx/nginx_acme_srv_ssl.conf @@ -5,7 +5,7 @@ server { listen [::]:443 ssl default_server; # first 5 requests go trough instantly 5more requests evey 100ms - limit_req zone=ip burst=10 delay=5; + limit_req zone=ip burst=10; # delay=5; server_name _; location = favicon.ico { access_log off; log_not_found off; } From 80b4c4498ba71aa9fa2a0952deaaa1750a28e593 Mon Sep 17 00:00:00 2001 From: grindsa Date: Mon, 18 Mar 2024 19:19:58 +0100 Subject: [PATCH 117/460] [fix] liniting --- acme_srv/helper.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/acme_srv/helper.py b/acme_srv/helper.py index 3b3b9d5b..5cd78111 100644 --- a/acme_srv/helper.py +++ b/acme_srv/helper.py @@ -1204,7 +1204,7 @@ def servercert_get(logger: logging.Logger, hostname: str, port: int = 443, proxy try: # this does not work on RH8 context.minimum_version = ssl.TLSVersion.TLSv1_2 - except Exception: # pragma: no cover + except Exception: # pragma: no cover pass context.options |= ssl.OP_NO_SSLv3 context.options |= ssl.OP_NO_TLSv1 @@ -1261,6 +1261,7 @@ def validate_email(logger: logging.Logger, contact_list: List[str]) -> bool: logger.debug('# validate: %s result: %s', contact_list, result) return result + def validate_identifier(logger: logging.Logger, type: str, identifier: str, tnauthlist_support: bool = False) -> bool: """ validate identifier """ logger.debug('validate_identifier()') @@ -1277,6 +1278,7 @@ def validate_identifier(logger: logging.Logger, type: str, identifier: str, tnau logger.debug('validate_identifier() ended with: %s', result) return result + def validate_ip(logger: logging.Logger, ip: str) -> bool: """ validate ip address """ logger.debug('validate_ip()') @@ -1288,6 +1290,7 @@ def validate_ip(logger: logging.Logger, ip: str) -> bool: logger.debug('validate_ip() ended with: %s', result) return result + def validate_fqdn(logger: logging.Logger, fqdn: str) -> bool: """ validate fqdn """ logger.debug('validate_fqdn()') @@ -1295,12 +1298,13 @@ def validate_fqdn(logger: logging.Logger, fqdn: str) -> bool: result = False regex = r"^(([a-z0-9]\-*[a-z0-9]*){1,63}\.?){1,255}$" p = re.compile(regex) - if(re.search(p, fqdn)): + if re.search(p, fqdn): result = True logger.debug('validate_fqdn() ended with: %s', result) return result + def handle_exception(exc_type, exc_value, exc_traceback): # pragma: no cover """ exception handler """ if issubclass(exc_type, KeyboardInterrupt): From 858e6cfc978cc1ac39d35ff369e9cf64ae1754a1 Mon Sep 17 00:00:00 2001 From: grindsa Date: Mon, 18 Mar 2024 19:27:55 +0100 Subject: [PATCH 118/460] [wf] refactor eab workflow --- .github/workflows/eab-test.yml | 420 +++------------------------------ 1 file changed, 34 insertions(+), 386 deletions(-) diff --git a/.github/workflows/eab-test.yml b/.github/workflows/eab-test.yml index b6126e08..55259f42 100644 --- a/.github/workflows/eab-test.yml +++ b/.github/workflows/eab-test.yml @@ -12,408 +12,56 @@ jobs: eab_apache2_wsgi: name: "eab_apache2_wsgi" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" - working-directory: examples/Docker/ - run: | - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup openssl ca_handler" - run: | - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo echo -e "\n\n[EABhandler]" >> examples/Docker/data/acme_srv.cfg - sudo echo "eab_handler_file: /var/www/acme2certifier/examples/eab_handler/json_handler.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "key_file: examples/eab_handler/key_file.json" >> examples/Docker/data/acme_srv.cfg - # sudo cat examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - docker-compose restart - docker-compose logs - - - name: "Test http://acme-srv/directory is accessable again" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] create letsencrypt folder" - run: | - mkdir certbot - - - name: "[ FAIL ] certbot without eab-credentials" - id: certbotfail - continue-on-error: true - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - - name: "[ CHECK ] certbot result " - if: steps.certbotfail.outcome != 'failure' - run: | - echo "certbot outcome is ${{steps.certbotfail.outcome }}" - exit 1 - - - name: "[ REGISTER] certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email --eab-kid keyid_02 --eab-hmac-key=bWFjXzAy - - - name: "[ ENROLL ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem - - - name: "[ PREPARE ] prepare acme.sh container" - run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - - name: "[ FAIL] acme.sh" - id: acmeshfail - continue-on-error: true - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 - - - name: "[ CHECK ] acme.sh result " - if: steps.acmeshfail.outcome != 'failure' - run: | - echo "acmeshfail outcome is ${{steps.acmeshfail.outcome }}" - exit 1 - - - name: "[ REGISTER] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key bWFjXzAy --debug 3 - - - name: "[ ENROLL] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --debug 3 --output-insecure - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - - name: "[ FAIL ] lego" - id: legofail - continue-on-error: true - run: | - mkdir lego - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - - - name: "[ CHECK ] lego result " - if: steps.legofail.outcome != 'failure' - run: | - echo "legofail outcome is ${{steps.legofail.outcome }}" - exit 1 - - - name: "[ ENROLL ] lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac bWFjXzAy -d lego.acme --http run - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: eab_apache2_wsgi.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - eab_apache2_django: - name: "eab_apache2_django" - runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | - sed -i "s/wsgi/django/g" .env sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker network create acme docker-compose up -d docker-compose logs + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - name: "[ PREPARE ] setup openssl ca_handler" run: | - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo echo -e "\n\n[EABhandler]" >> examples/Docker/data/acme_srv.cfg - sudo echo "eab_handler_file: /var/www/acme2certifier/examples/eab_handler/json_handler.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "key_file: examples/eab_handler/key_file.json" >> examples/Docker/data/acme_srv.cfg + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem sudo cp .github/django_settings.py examples/Docker/data/settings.py - cd examples/Docker/ - docker-compose restart - docker-compose logs - - - name: "Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 5s - - - name: "Test http://acme-srv/directory is accessable again" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] create letsencrypt folder" - run: | - mkdir certbot - - - name: "[ FAIL ] certbot without eab-credentials" - id: certbotfail - continue-on-error: true - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - - name: "[ CHECK ] certbot result " - if: steps.certbotfail.outcome != 'failure' - run: | - echo "certbot outcome is ${{steps.certbotfail.outcome }}" - exit 1 - - - name: "[ REGISTER] certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email --eab-kid keyid_02 --eab-hmac-key=bWFjXzAy - - - name: "[ ENROLL ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem - - - name: "[ PREPARE ] prepare acme.sh container" - run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - - name: "[ FAIL] acme.sh" - id: acmeshfail - continue-on-error: true - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 - - - name: "[ CHECK ] acme.sh result " - if: steps.acmeshfail.outcome != 'failure' - run: | - echo "acmeshfail outcome is ${{steps.acmeshfail.outcome }}" - exit 1 - - - name: "[ REGISTER] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key bWFjXzAy --debug 3 - - - name: "[ ENROLL] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --debug 3 --output-insecure - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - - name: "[ FAIL ] lego" - id: legofail - continue-on-error: true - run: | - mkdir lego - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - - - name: "[ CHECK ] lego result " - if: steps.legofail.outcome != 'failure' - run: | - echo "legofail outcome is ${{steps.legofail.outcome }}" - exit 1 - - - name: "[ ENROLL ] lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac bWFjXzAy -d lego.acme --http run - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: eab_apache2_django.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - eab_nginx_wsgi: - name: "eab_nginx_wsgi" - runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" - working-directory: examples/Docker/ - run: | - sed -i "s/apache2/nginx/g" .env - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "[ PREPARE ] setup openssl ca_handler" - run: | - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py sudo mkdir -p examples/Docker/data/acme_ca/certs sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg + sudo cp .github/openssl_ca_handler.py_acme_srv_choosen_handler.cfg examples/Docker/data/acme_srv.cfg sudo chmod 777 examples/Docker/data/acme_srv.cfg sudo echo -e "\n\n[EABhandler]" >> examples/Docker/data/acme_srv.cfg sudo echo "eab_handler_file: /var/www/acme2certifier/examples/eab_handler/json_handler.py" >> examples/Docker/data/acme_srv.cfg sudo echo "key_file: examples/eab_handler/key_file.json" >> examples/Docker/data/acme_srv.cfg - # sudo cat examples/Docker/data/acme_srv.cfg cd examples/Docker/ docker-compose restart docker-compose logs - - name: "Sleep for 5s" + - name: "Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: - time: 5s + time: 10s - - name: "Test http://acme-srv/directory is accessable again" + - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] create letsencrypt folder" - run: | - mkdir certbot - - - name: "[ FAIL ] certbot without eab-credentials" - id: certbotfail - continue-on-error: true - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - - name: "[ CHECK ] certbot result " - if: steps.certbotfail.outcome != 'failure' - run: | - echo "certbot outcome is ${{steps.certbotfail.outcome }}" - exit 1 - - - name: "[ REGISTER] certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email --eab-kid keyid_02 --eab-hmac-key=bWFjXzAy - - - name: "[ ENROLL ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem - - - name: "[ PREPARE ] prepare acme.sh container" - run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - - name: "[ FAIL] acme.sh" - id: acmeshfail - continue-on-error: true - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 - - - name: "[ CHECK ] acme.sh result " - if: steps.acmeshfail.outcome != 'failure' - run: | - echo "acmeshfail outcome is ${{steps.acmeshfail.outcome }}" - exit 1 - - - name: "[ REGISTER] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key bWFjXzAy --debug 3 - - - name: "[ ENROLL] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --debug 3 --output-insecure - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - - name: "[ FAIL ] lego" - id: legofail - continue-on-error: true - run: | - mkdir lego - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - - - name: "[ CHECK ] lego result " - if: steps.legofail.outcome != 'failure' - run: | - echo "legofail outcome is ${{steps.legofail.outcome }}" - exit 1 - - - name: "[ ENROLL ] lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac bWFjXzAy -d lego.acme --http run - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: eab_nginx_wsgi.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - eab_nginx_django: - name: "eab_nginx_django" - runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" - working-directory: examples/Docker/ - run: | - sed -i "s/apache2/nginx/g" .env - sed -i "s/apache2/nginx/g" .env - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "[ PREPARE ] setup openssl ca_handler" - run: | - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo echo -e "\n\n[EABhandler]" >> examples/Docker/data/acme_srv.cfg - sudo echo "eab_handler_file: /var/www/acme2certifier/examples/eab_handler/json_handler.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "key_file: examples/eab_handler/key_file.json" >> examples/Docker/data/acme_srv.cfg - sudo cp .github/django_settings.py examples/Docker/data/settings.py - cd examples/Docker/ - docker-compose restart - docker-compose logs - - - name: "Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 5s - - - name: "Test http://acme-srv/directory is accessable again" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - name: "[ PREPARE ] create letsencrypt folder" run: | @@ -478,10 +126,10 @@ jobs: echo "legofail outcome is ${{steps.legofail.outcome }}" exit 1 - - name: "[ ENROLL ] lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac bWFjXzAy -d lego.acme --http run - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + #- name: "[ ENROLL ] lego" + # run: | + # docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac bWFjXzAy -d lego.acme --http run + # sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - name: "[ * ] collecting test logs" if: ${{ failure() }} @@ -496,7 +144,7 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: eab_nginx_django.tar.gz + name: eab-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ eab_wsgi_rpm: @@ -633,10 +281,10 @@ jobs: echo "legofail outcome is ${{steps.legofail.outcome }}" exit 1 - - name: "[ ENROLL ] lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac bWFjXzAy -d lego.acme --http run - sudo openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + #- name: "[ ENROLL ] lego" + # run: | + # docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac bWFjXzAy -d lego.acme --http run + # sudo openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - name: "[ * ] collecting test logs" if: ${{ failure() }} @@ -810,10 +458,10 @@ jobs: echo "legofail outcome is ${{steps.legofail.outcome }}" exit 1 - - name: "[ ENROLL ] lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac bWFjXzAy -d lego.acme --http run - sudo openssl verify -CAfile data/volume/acme_ca/root-ca-cert.pem -untrusted data/volume/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + #- name: "[ ENROLL ] lego" + # run: | + # docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac bWFjXzAy -d lego.acme --http run + # sudo openssl verify -CAfile data/volume/acme_ca/root-ca-cert.pem -untrusted data/volume/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - name: "[ * ] collecting test logs" if: ${{ failure() }} From f4ca8c37e6ca9910f1b3af3b97e4a76a42652107 Mon Sep 17 00:00:00 2001 From: grindsa Date: Tue, 19 Mar 2024 07:42:43 +0100 Subject: [PATCH 119/460] [fix] eab hmac longer than 256 bits --- examples/eab_handler/key_file.csv | 8 ++++---- examples/eab_handler/key_file.json | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/eab_handler/key_file.csv b/examples/eab_handler/key_file.csv index 8c584043..125e093e 100644 --- a/examples/eab_handler/key_file.csv +++ b/examples/eab_handler/key_file.csv @@ -1,5 +1,5 @@ eab_kid,eab_mac -keyid_00,bWFjXzAw -keyid_01,bWFjXzAx -keyid_02,bWFjXzAy -keyid_03,bWFjXzAz +keyid_00,V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw +keyid_01,YW5vdXRoZXJfdmVyeV9sb25nX2htYWNfZm9yX2tleWlkXzAxX3doaWNoIHdpbGxfYmUgdXNlZF9kdXJpbmcgcmVncmVzc2lvbg +keyid_02,dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM +keyid_03,YW5kX2ZpbmFsbHlfdGhlX2xhc3RfaG1hY19rZXlfd2hpY2hfaXNfbG9uZ2VyX3RoYW5fMjU2X2JpdHNfYW5kX3Nob3VsZF93b3Jr diff --git a/examples/eab_handler/key_file.json b/examples/eab_handler/key_file.json index 4989b504..d91c0a61 100644 --- a/examples/eab_handler/key_file.json +++ b/examples/eab_handler/key_file.json @@ -1,6 +1,6 @@ { - "keyid_01": "bWFjXzAw", - "keyid_01": "bWFjXzAx", - "keyid_02": "bWFjXzAy", - "keyid_03": "bWFjXzAz" + "keyid_00": "V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw", + "keyid_01": "YW5vdXRoZXJfdmVyeV9sb25nX2htYWNfZm9yX2tleWlkXzAxX3doaWNoIHdpbGxfYmUgdXNlZF9kdXJpbmcgcmVncmVzc2lvbg", + "keyid_02": "dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM", + "keyid_03": "YW5kX2ZpbmFsbHlfdGhlX2xhc3RfaG1hY19rZXlfd2hpY2hfaXNfbG9uZ2VyX3RoYW5fMjU2X2JpdHNfYW5kX3Nob3VsZF93b3Jr" } From 10476d5393f512a6aeb2c4f1c698355e260a8801 Mon Sep 17 00:00:00 2001 From: grindsa Date: Tue, 19 Mar 2024 08:19:52 +0100 Subject: [PATCH 120/460] [fix] eab_worflow with longer hmac --- .github/workflows/eab-test.yml | 414 +++------------------------------ 1 file changed, 31 insertions(+), 383 deletions(-) diff --git a/.github/workflows/eab-test.yml b/.github/workflows/eab-test.yml index b6126e08..3b2932e8 100644 --- a/.github/workflows/eab-test.yml +++ b/.github/workflows/eab-test.yml @@ -12,408 +12,56 @@ jobs: eab_apache2_wsgi: name: "eab_apache2_wsgi" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" - working-directory: examples/Docker/ - run: | - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup openssl ca_handler" - run: | - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo echo -e "\n\n[EABhandler]" >> examples/Docker/data/acme_srv.cfg - sudo echo "eab_handler_file: /var/www/acme2certifier/examples/eab_handler/json_handler.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "key_file: examples/eab_handler/key_file.json" >> examples/Docker/data/acme_srv.cfg - # sudo cat examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - docker-compose restart - docker-compose logs - - - name: "Test http://acme-srv/directory is accessable again" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] create letsencrypt folder" - run: | - mkdir certbot - - - name: "[ FAIL ] certbot without eab-credentials" - id: certbotfail - continue-on-error: true - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - - name: "[ CHECK ] certbot result " - if: steps.certbotfail.outcome != 'failure' - run: | - echo "certbot outcome is ${{steps.certbotfail.outcome }}" - exit 1 - - - name: "[ REGISTER] certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email --eab-kid keyid_02 --eab-hmac-key=bWFjXzAy - - - name: "[ ENROLL ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem - - - name: "[ PREPARE ] prepare acme.sh container" - run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - - name: "[ FAIL] acme.sh" - id: acmeshfail - continue-on-error: true - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 - - - name: "[ CHECK ] acme.sh result " - if: steps.acmeshfail.outcome != 'failure' - run: | - echo "acmeshfail outcome is ${{steps.acmeshfail.outcome }}" - exit 1 - - - name: "[ REGISTER] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key bWFjXzAy --debug 3 - - - name: "[ ENROLL] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --debug 3 --output-insecure - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - - name: "[ FAIL ] lego" - id: legofail - continue-on-error: true - run: | - mkdir lego - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - - - name: "[ CHECK ] lego result " - if: steps.legofail.outcome != 'failure' - run: | - echo "legofail outcome is ${{steps.legofail.outcome }}" - exit 1 - - - name: "[ ENROLL ] lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac bWFjXzAy -d lego.acme --http run - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: eab_apache2_wsgi.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - eab_apache2_django: - name: "eab_apache2_django" - runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | - sed -i "s/wsgi/django/g" .env sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker network create acme docker-compose up -d docker-compose logs + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - name: "[ PREPARE ] setup openssl ca_handler" run: | - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo echo -e "\n\n[EABhandler]" >> examples/Docker/data/acme_srv.cfg - sudo echo "eab_handler_file: /var/www/acme2certifier/examples/eab_handler/json_handler.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "key_file: examples/eab_handler/key_file.json" >> examples/Docker/data/acme_srv.cfg + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem sudo cp .github/django_settings.py examples/Docker/data/settings.py - cd examples/Docker/ - docker-compose restart - docker-compose logs - - - name: "Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 5s - - - name: "Test http://acme-srv/directory is accessable again" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] create letsencrypt folder" - run: | - mkdir certbot - - - name: "[ FAIL ] certbot without eab-credentials" - id: certbotfail - continue-on-error: true - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - - name: "[ CHECK ] certbot result " - if: steps.certbotfail.outcome != 'failure' - run: | - echo "certbot outcome is ${{steps.certbotfail.outcome }}" - exit 1 - - - name: "[ REGISTER] certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email --eab-kid keyid_02 --eab-hmac-key=bWFjXzAy - - - name: "[ ENROLL ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem - - - name: "[ PREPARE ] prepare acme.sh container" - run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - - name: "[ FAIL] acme.sh" - id: acmeshfail - continue-on-error: true - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 - - - name: "[ CHECK ] acme.sh result " - if: steps.acmeshfail.outcome != 'failure' - run: | - echo "acmeshfail outcome is ${{steps.acmeshfail.outcome }}" - exit 1 - - - name: "[ REGISTER] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key bWFjXzAy --debug 3 - - - name: "[ ENROLL] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --debug 3 --output-insecure - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - - name: "[ FAIL ] lego" - id: legofail - continue-on-error: true - run: | - mkdir lego - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - - - name: "[ CHECK ] lego result " - if: steps.legofail.outcome != 'failure' - run: | - echo "legofail outcome is ${{steps.legofail.outcome }}" - exit 1 - - - name: "[ ENROLL ] lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac bWFjXzAy -d lego.acme --http run - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: eab_apache2_django.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - eab_nginx_wsgi: - name: "eab_nginx_wsgi" - runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" - working-directory: examples/Docker/ - run: | - sed -i "s/apache2/nginx/g" .env - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "[ PREPARE ] setup openssl ca_handler" - run: | - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py sudo mkdir -p examples/Docker/data/acme_ca/certs sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg + sudo cp .github/openssl_ca_handler.py_acme_srv_choosen_handler.cfg examples/Docker/data/acme_srv.cfg sudo chmod 777 examples/Docker/data/acme_srv.cfg sudo echo -e "\n\n[EABhandler]" >> examples/Docker/data/acme_srv.cfg sudo echo "eab_handler_file: /var/www/acme2certifier/examples/eab_handler/json_handler.py" >> examples/Docker/data/acme_srv.cfg sudo echo "key_file: examples/eab_handler/key_file.json" >> examples/Docker/data/acme_srv.cfg - # sudo cat examples/Docker/data/acme_srv.cfg cd examples/Docker/ docker-compose restart docker-compose logs - - name: "Sleep for 5s" + - name: "Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: - time: 5s + time: 10s - - name: "Test http://acme-srv/directory is accessable again" + - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] create letsencrypt folder" - run: | - mkdir certbot - - - name: "[ FAIL ] certbot without eab-credentials" - id: certbotfail - continue-on-error: true - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - - name: "[ CHECK ] certbot result " - if: steps.certbotfail.outcome != 'failure' - run: | - echo "certbot outcome is ${{steps.certbotfail.outcome }}" - exit 1 - - - name: "[ REGISTER] certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email --eab-kid keyid_02 --eab-hmac-key=bWFjXzAy - - - name: "[ ENROLL ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem - - - name: "[ PREPARE ] prepare acme.sh container" - run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - - name: "[ FAIL] acme.sh" - id: acmeshfail - continue-on-error: true - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 - - - name: "[ CHECK ] acme.sh result " - if: steps.acmeshfail.outcome != 'failure' - run: | - echo "acmeshfail outcome is ${{steps.acmeshfail.outcome }}" - exit 1 - - - name: "[ REGISTER] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key bWFjXzAy --debug 3 - - - name: "[ ENROLL] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --debug 3 --output-insecure - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - - name: "[ FAIL ] lego" - id: legofail - continue-on-error: true - run: | - mkdir lego - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - - - name: "[ CHECK ] lego result " - if: steps.legofail.outcome != 'failure' - run: | - echo "legofail outcome is ${{steps.legofail.outcome }}" - exit 1 - - - name: "[ ENROLL ] lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac bWFjXzAy -d lego.acme --http run - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: eab_nginx_wsgi.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - eab_nginx_django: - name: "eab_nginx_django" - runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" - working-directory: examples/Docker/ - run: | - sed -i "s/apache2/nginx/g" .env - sed -i "s/apache2/nginx/g" .env - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "[ PREPARE ] setup openssl ca_handler" - run: | - sudo cp examples/ca_handler/openssl_ca_handler.py examples/Docker/data/ca_handler.py - sudo mkdir -p examples/Docker/data/acme_ca/certs - sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo echo -e "\n\n[EABhandler]" >> examples/Docker/data/acme_srv.cfg - sudo echo "eab_handler_file: /var/www/acme2certifier/examples/eab_handler/json_handler.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "key_file: examples/eab_handler/key_file.json" >> examples/Docker/data/acme_srv.cfg - sudo cp .github/django_settings.py examples/Docker/data/settings.py - cd examples/Docker/ - docker-compose restart - docker-compose logs - - - name: "Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 5s - - - name: "Test http://acme-srv/directory is accessable again" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - name: "[ PREPARE ] create letsencrypt folder" run: | @@ -433,7 +81,7 @@ jobs: - name: "[ REGISTER] certbot" run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email --eab-kid keyid_02 --eab-hmac-key=bWFjXzAy + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email --eab-kid keyid_02 --eab-hmac-key=dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM - name: "[ ENROLL ] HTTP-01 single domain certbot" run: | @@ -458,7 +106,7 @@ jobs: - name: "[ REGISTER] acme.sh" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key bWFjXzAy --debug 3 + docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM --debug 3 - name: "[ ENROLL] acme.sh" run: | @@ -480,7 +128,7 @@ jobs: - name: "[ ENROLL ] lego" run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac bWFjXzAy -d lego.acme --http run + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM -d lego.acme --http run sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - name: "[ * ] collecting test logs" @@ -496,7 +144,7 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: eab_nginx_django.tar.gz + name: eab-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ eab_wsgi_rpm: @@ -588,7 +236,7 @@ jobs: - name: "[ REGISTER] certbot" run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email --eab-kid keyid_02 --eab-hmac-key=bWFjXzAy + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email --eab-kid keyid_02 --eab-hmac-key=dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM - name: "[ ENROLL ] HTTP-01 single domain certbot" run: | @@ -613,7 +261,7 @@ jobs: - name: "[ REGISTER] acme.sh" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key bWFjXzAy --debug 3 + docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM --debug 3 - name: "[ ENROLL] acme.sh" run: | @@ -635,7 +283,7 @@ jobs: - name: "[ ENROLL ] lego" run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac bWFjXzAy -d lego.acme --http run + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM -d lego.acme --http run sudo openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - name: "[ * ] collecting test logs" @@ -765,7 +413,7 @@ jobs: - name: "[ REGISTER] certbot" run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email --eab-kid keyid_02 --eab-hmac-key=bWFjXzAy + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email --eab-kid keyid_02 --eab-hmac-key=dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM - name: "[ ENROLL ] HTTP-01 single domain certbot" run: | @@ -790,7 +438,7 @@ jobs: - name: "[ REGISTER] acme.sh" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key bWFjXzAy --debug 3 + docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM --debug 3 - name: "[ ENROLL] acme.sh" run: | @@ -812,7 +460,7 @@ jobs: - name: "[ ENROLL ] lego" run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac bWFjXzAy -d lego.acme --http run + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM -d lego.acme --http run sudo openssl verify -CAfile data/volume/acme_ca/root-ca-cert.pem -untrusted data/volume/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt - name: "[ * ] collecting test logs" From 6c220067c0406785de079e1eabc26dd079d622df Mon Sep 17 00:00:00 2001 From: grindsa Date: Tue, 19 Mar 2024 17:48:27 +0100 Subject: [PATCH 121/460] [fix] linting --- docs/install_rpm.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/install_rpm.md b/docs/install_rpm.md index ff95647d..ed957764 100644 --- a/docs/install_rpm.md +++ b/docs/install_rpm.md @@ -29,13 +29,11 @@ Backports of these packages being part of RHEL9 can be found in the [the a2c rpm - [python3-dns-2.1.0-6.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/rhel8/python3-dns-2.1.0-6.el8.noarch.rpm) - [python3-jwcrypto-0.8-4.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/rhel8/python3-jwcrypto-0.8-4.el8.noarch.rpm) - Depending on your packages would be needed as well: - [python3-impacket-0.11.0-1.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/rhel8/python3-impacket-0.11.0-1.el8.noarch.rpm) for the [MS wcce handler](https://github.com/grindsa/acme2certifier/blob/master/docs/mswcce.md) - [python3-ntlm-auth-1.5.0-2.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/rhel8/python3-ntlm-auth-1.5.0-2.el8.noarch.rpm) for the [MS wes handler](https://github.com/grindsa/acme2certifier/blob/master/docs/mscertsrv.md) - [python3-requests-pkcs12-1.16-1.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/rhel8/python3-requests_ntlm-1.1.0-14.el8.noarch.rpm) for the [EST](https://github.com/grindsa/acme2certifier/blob/master/docs/est.md) and [Ejbca](https://github.com/grindsa/acme2certifier/blob/master/docs/ejbca.md) handler - Depending on your ca_handler you may need additional modules: - [python3-impacket-0.11.0-1.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/rhel8/python3-impacket-0.11.0-1.el8.noarch.rpm) when using [MS wcce handler](https://github.com/grindsa/acme2certifier/blob/master/docs/mswcce.md) From 30a31d38fa04a84b9590c7f7e55accccb1a51dea Mon Sep 17 00:00:00 2001 From: grindsa Date: Thu, 21 Mar 2024 17:59:17 +0100 Subject: [PATCH 122/460] [fix] certmanager wf --- .../workflows/certmanager-application-test.yml | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/.github/workflows/certmanager-application-test.yml b/.github/workflows/certmanager-application-test.yml index 81178125..b497280b 100644 --- a/.github/workflows/certmanager-application-test.yml +++ b/.github/workflows/certmanager-application-test.yml @@ -9,8 +9,8 @@ on: - cron: '0 2 * * 6' jobs: - certmgr_http01_apwsgi: - name: "apache2 wsgi - certmgr http01 challenge tests" + certmgr_http01_tests: + name: certmgr_http01_tests runs-on: ubuntu-latest strategy: fail-fast: false @@ -133,6 +133,7 @@ jobs: sudo cp .github/k8s-cert-mgr-http-01.yml data sudo chmod -R 777 data/k8s-cert-mgr-http-01.yml sudo sed -i "s/ACME_SRV/${{ env.ACME_IP }}/g" data/k8s-cert-mgr-http-01.yml + sudo sed -i "s/k8.acme.dynamop.de/k8.${{ matrix.websrv }}-${{ matrix.dbhandler }}.acme.dynamop.de/g" data/k8s-cert-mgr-http-01.yml sudo microk8s.kubectl apply -f data/k8s-cert-mgr-http-01.yml - name: "Sleep for 20s" @@ -178,12 +179,12 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: cert-manager-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz + name: cert-certmgr_http01-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ - certmgr_dns01_apwsgi: - name: "apache2 wsgi - certmgr dns01 challenge tests" + certmgr_dns01_tests: + name: certmgr_dns01_tests runs-on: ubuntu-latest strategy: fail-fast: false @@ -276,6 +277,7 @@ jobs: sudo sed -i "s/ACME_SRV/${{ env.ACME_IP }}/g" data/k8s-cert-mgr-dns-01.yml sudo sed -i "s/CF_TOKEN/${{ secrets.CF_TOKEN }}/g" data/k8s-cert-mgr-dns-01.yml sudo sed -i "s/MY_EMAIL/${{ secrets.EMAIL }}/g" data/k8s-cert-mgr-dns-01.yml + sudo sed -i "s/k8.acme.dynamop.de/k8.${{ matrix.websrv }}-${{ matrix.dbhandler }}.acme.dynamop.de/g" data/k8s-cert-mgr-dns-01.yml - name: "Deploy cert-manager and trigger enrollment" run: | @@ -326,7 +328,7 @@ jobs: run: | sudo microk8s.kubectl delete -f data/k8s-cert-mgr-dns-01.yml sudo sed -i "s/commonName: k8.acme.dynamop.de/commonName: '*.acme.dynamop.de'/g" data/k8s-cert-mgr-dns-01.yml - sudo sed -i "s/- k8.acme.dynamop.de/- '*.acme.dynamop.de'/g" data/k8s-cert-mgr-dns-01.yml + sudo sed -i "s/- k8.${{ matrix.websrv }}-${{ matrix.dbhandler }}.acme.dynamop.de/- k8.${{ matrix.websrv }}-${{ matrix.dbhandler }}.acme.dynamop.de\n - '*.${{ matrix.websrv }}-${{ matrix.dbhandler }}.acme.dynamop.de'/g" data/k8s-cert-mgr-dns-01.yml - name: "Deploy cert-manager and trigger enrollment" run: | @@ -384,6 +386,6 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: cert-manager-dns-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz + name: certmgr_dns01-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ From 83ea681b90806d5a3bc1bc705a141022d830aa4a Mon Sep 17 00:00:00 2001 From: grindsa Date: Thu, 21 Mar 2024 20:57:47 +0100 Subject: [PATCH 123/460] [fix] limit number of identifers per order request --- acme_srv/order.py | 46 +++++-- docs/acme_srv.md | 1 + test/test_order.py | 318 +++++++++++++++++++++++++++++---------------- 3 files changed, 240 insertions(+), 125 deletions(-) diff --git a/acme_srv/order.py b/acme_srv/order.py index 764c60e2..4214e51b 100644 --- a/acme_srv/order.py +++ b/acme_srv/order.py @@ -26,6 +26,7 @@ def __init__(self, debug: bool = None, srv_name: str = None, logger: object = No self.retry_after = 600 self.tnauthlist_support = False self.sectigo_sim = False + self.identifier_limit = 20 self.header_info_list = [] def __enter__(self): @@ -136,6 +137,10 @@ def _config_orderconfig_load(self, config_dic: Dict[str, str]): self.validity = int(config_dic['Order']['validity']) except Exception: self.logger.warning('Order._config_load(): failed to parse validity: %s', config_dic['Order']['validity']) + try: + self.identifier_limit = int(config_dic.get('Order', 'identifier_limit', fallback=20)) + except Exception: + self.logger.warning('Order._config_load(): failed to parse identifier_limit: %s', config_dic['Order']['identifier_limit']) self.logger.debug('Order._config_orderconfig_load() ended') @@ -171,9 +176,9 @@ def _name_get(self, url: str) -> str: self.logger.debug('Order._name_get() ended') return order_name - def _identifiers_check(self, identifiers_list: List[str]) -> str: - """ check validity of identifers in order """ - self.logger.debug('Order._identifiers_check(%s)', identifiers_list) + def _identifiers_allowed(self, identifiers_list: List[str]) -> bool: + """ check if identifiers are allowed """ + self.logger.debug('Order._identifiers_allowed()') error = None allowed_identifers = ['dns', 'ip'] @@ -182,18 +187,31 @@ def _identifiers_check(self, identifiers_list: List[str]) -> str: if self.tnauthlist_support: allowed_identifers.append('tnauthlist') - if identifiers_list and isinstance(identifiers_list, list): - for identifier in identifiers_list: - if 'type' in identifier: - if identifier['type'].lower() not in allowed_identifers: - error = self.error_msg_dic['unsupportedidentifier'] - break - else: - if not validate_identifier(self.logger, identifier['type'].lower(), identifier['value'], self.tnauthlist_support): - error = self.error_msg_dic['rejectedidentifier'] - break + for identifier in identifiers_list: + if 'type' in identifier: + # pylint: disable=R1723 + if identifier['type'].lower() not in allowed_identifers: + error = self.error_msg_dic['unsupportedidentifier'] + break else: - error = self.error_msg_dic['malformed'] + if not validate_identifier(self.logger, identifier['type'].lower(), identifier['value'], self.tnauthlist_support): + error = self.error_msg_dic['rejectedidentifier'] + break + else: + error = self.error_msg_dic['malformed'] + + self.logger.debug('Order._identifiers_allowed() ended with: %s', error) + return error + + def _identifiers_check(self, identifiers_list: List[str]) -> str: + """ check validity of identifers in order """ + self.logger.debug('Order._identifiers_check(%s)', identifiers_list) + + if identifiers_list and isinstance(identifiers_list, list): + if len(identifiers_list) > self.identifier_limit: + error = self.error_msg_dic['rejectedidentifier'] + else: + error = self._identifiers_allowed(identifiers_list) else: error = self.error_msg_dic['malformed'] diff --git a/docs/acme_srv.md b/docs/acme_srv.md index fb158f48..738f6041 100644 --- a/docs/acme_srv.md +++ b/docs/acme_srv.md @@ -36,6 +36,7 @@ | `Order` | `expiry_check_disable` | Disable order expiration | True/False | False| | `Order` | `header_info_list` | HTTP header fields to be passed to ca handler | ["HTTP_USER_AGENT", "FOO_BAR"] |[]| | `Order` | `retry_after_timeout` | Retry-After value to be send to client in case a certificate enrollment request gets pending on CA server | Integer |120| +| `Order` | `identifier_limit` | Maximum number of identifiers submitted in a single order request which translate later into SANs per certificate | Integer |20| | `Order` | [`tnauthlist_support`](tnauthlist.md) | accept [TNAuthList identifiers](https://tools.ietf.org/html/draft-ietf-acme-authority-token-tnauthlist-03) and challenges containing [tkauth-01 type](https://tools.ietf.org/html/draft-ietf-acme-authority-token-03) | True/False | False| | `Order` | `validity` | Order validity in seconds | Integer |86400| diff --git a/test/test_order.py b/test/test_order.py index e6b004e9..97ead73d 100644 --- a/test/test_order.py +++ b/test/test_order.py @@ -150,34 +150,34 @@ def test_010_order_new(self, mock_mcheck, mock_orderadd, mock_nnonce): self.assertTrue(mock_nnonce.called) @patch('acme_srv.order.Order._info') - def test_010_order__lookup(self, mock_oinfo): + def test_011_order__lookup(self, mock_oinfo): """ test order lookup with empty hash """ mock_oinfo.return_value = {} self.assertEqual({}, self.order._lookup('foo')) @patch('acme_srv.order.Order._info') - def test_011_order__lookup(self, mock_oinfo): + def test_012_order__lookup(self, mock_oinfo): """ test order lookup with wrong hash and wrong authorization hash""" self.order.dbstore.authorization_lookup.return_value = [{'identifier_key' : 'identifier_value'}] mock_oinfo.return_value = {'status_key' : 'status_value'} self.assertEqual({'authorizations': []}, self.order._lookup('foo')) @patch('acme_srv.order.Order._info') - def test_012_order__lookup(self, mock_oinfo): + def test_013_order__lookup(self, mock_oinfo): """ test order lookup with wrong hash and correct authorization hash""" self.order.dbstore.authorization_lookup.return_value = [{'name' : 'name', 'identifier_key' : 'identifier_value'}] mock_oinfo.return_value = {'status_key' : 'status_value'} self.assertEqual({'authorizations': ['http://tester.local/acme/authz/name']}, self.order._lookup('foo')) @patch('acme_srv.order.Order._info') - def test_013_order__lookup(self, mock_oinfo): + def test_014_order__lookup(self, mock_oinfo): """ test order lookup with wrong hash and authorization hash having multiple entries""" self.order.dbstore.authorization_lookup.return_value = [{'name' : 'name', 'identifier_key' : 'identifier_value'}, {'name' : 'name2', 'identifier_key' : 'identifier_value2'}] mock_oinfo.return_value = {'status_key' : 'status_value'} self.assertEqual({'authorizations': ['http://tester.local/acme/authz/name', 'http://tester.local/acme/authz/name2']}, self.order._lookup('foo')) @patch('acme_srv.order.Order._info') - def test_014_order__lookup(self, mock_oinfo): + def test_015_order__lookup(self, mock_oinfo): """ test order lookup status in dict and authorization dict having multiple entries""" self.order.dbstore.authorization_lookup.return_value = [{'name' : 'name', 'identifier_key' : 'identifier_value'}, {'name' : 'name2', 'identifier_key' : 'identifier_value2'}] mock_oinfo.return_value = {'status' : 'status_value'} @@ -185,7 +185,7 @@ def test_014_order__lookup(self, mock_oinfo): self.assertEqual(e_result, self.order._lookup('foo')) @patch('acme_srv.order.Order._info') - def test_015_order__lookup(self, mock_oinfo): + def test_016_order__lookup(self, mock_oinfo): """ test order lookup status, expires in dict and authorization dict having multiple entries""" self.order.dbstore.authorization_lookup.return_value = [{'name' : 'name', 'identifier_key' : 'identifier_value'}, {'name' : 'name2', 'identifier_key' : 'identifier_value2'}] mock_oinfo.return_value = {'status' : 'status_value', 'expires' : 1543640400} @@ -193,7 +193,7 @@ def test_015_order__lookup(self, mock_oinfo): self.assertEqual(e_result, self.order._lookup('foo')) @patch('acme_srv.order.Order._info') - def test_016_order__lookup(self, mock_oinfo): + def test_017_order__lookup(self, mock_oinfo): """ test order lookup status, expires, notbefore (0) in dict and authorization dict having multiple entries""" self.order.dbstore.authorization_lookup.return_value = [{'name' : 'name', 'identifier_key' : 'identifier_value'}, {'name' : 'name2', 'identifier_key' : 'identifier_value2'}] mock_oinfo.return_value = {'status' : 'status_value', 'expires' : 1543640400, 'notbefore' : 0} @@ -201,7 +201,7 @@ def test_016_order__lookup(self, mock_oinfo): self.assertEqual(e_result, self.order._lookup('foo')) @patch('acme_srv.order.Order._info') - def test_017_order__lookup(self, mock_oinfo): + def test_018_order__lookup(self, mock_oinfo): """ test order lookup status, expires, notbefore and notafter (0) in dict and authorization dict having multiple entries""" self.order.dbstore.authorization_lookup.return_value = [{'name' : 'name', 'identifier_key' : 'identifier_value'}, {'name' : 'name2', 'identifier_key' : 'identifier_value2'}] mock_oinfo.return_value = {'status' : 'status_value', 'expires' : 1543640400, 'notbefore' : 0, 'notafter' : 0} @@ -209,7 +209,7 @@ def test_017_order__lookup(self, mock_oinfo): self.assertEqual(e_result, self.order._lookup('foo')) @patch('acme_srv.order.Order._info') - def test_018_order__lookup(self, mock_oinfo): + def test_019_order__lookup(self, mock_oinfo): """ test order lookup status, expires, notbefore and notafter (valid) in dict and authorization dict having multiple entries""" self.order.dbstore.authorization_lookup.return_value = [{'name' : 'name', 'identifier_key' : 'identifier_value'}, {'name' : 'name2', 'identifier_key' : 'identifier_value2'}] mock_oinfo.return_value = {'status' : 'status_value', 'expires' : 1543640400, 'notbefore' : 1543640400, 'notafter' : 1543640400} @@ -217,7 +217,7 @@ def test_018_order__lookup(self, mock_oinfo): self.assertEqual(e_result, self.order._lookup('foo')) @patch('acme_srv.order.Order._info') - def test_019_order__lookup(self, mock_oinfo): + def test_020_order__lookup(self, mock_oinfo): """ test order lookup status, expires, notbefore and notafter (valid), identifier, in dict and authorization dict having multiple entries""" self.order.dbstore.authorization_lookup.return_value = [{'name' : 'name', 'identifier_key' : 'identifier_value'}, {'name' : 'name2', 'identifier_key' : 'identifier_value2'}] mock_oinfo.return_value = {'status' : 'status_value', 'expires' : 1543640400, 'notbefore' : 1543640400, 'notafter' : 1543640400, 'identifier': '"{"foo" : "bar"}"'} @@ -225,7 +225,7 @@ def test_019_order__lookup(self, mock_oinfo): self.assertEqual(e_result, self.order._lookup('foo')) @patch('acme_srv.order.Order._info') - def test_020_order__lookup(self, mock_oinfo): + def test_021_order__lookup(self, mock_oinfo): """ test order lookup status, expires, notbefore and notafter (valid), identifier, in dict and worng authorization""" self.order.dbstore.authorization_lookup.return_value = 'foo' mock_oinfo.return_value = {'status' : 'status_value', 'expires' : 1543640400, 'notbefore' : 1543640400, 'notafter' : 1543640400, 'identifier': '"{"foo" : "bar"}"'} @@ -233,7 +233,7 @@ def test_020_order__lookup(self, mock_oinfo): self.assertEqual(e_result, self.order._lookup('foo')) @patch('acme_srv.order.Order._info') - def test_021_order__lookup(self, mock_oinfo): + def test_022_order__lookup(self, mock_oinfo): """ test order lookup correct identifier for oder info""" self.order.dbstore.authorization_lookup.return_value = 'foo' mock_oinfo.return_value = {'status' : 'status_value', 'expires' : 1543640400, 'notbefore' : 1543640400, 'notafter' : 1543640400, 'identifiers': '{"foo": "bar"}'} @@ -241,7 +241,7 @@ def test_021_order__lookup(self, mock_oinfo): self.assertEqual(e_result, self.order._lookup('foo')) @patch('acme_srv.order.Order._info') - def test_022_order__lookup(self, mock_oinfo): + def test_023_order__lookup(self, mock_oinfo): """ test order lookup incorrect identifier for oder info""" self.order.dbstore.authorization_lookup.return_value = 'foo' mock_oinfo.return_value = {'status' : 'status_value', 'expires' : 1543640400, 'notbefore' : 1543640400, 'notafter' : 1543640400, 'identifiers': 'wrongvalue'} @@ -252,7 +252,7 @@ def test_022_order__lookup(self, mock_oinfo): @patch('acme_srv.order.Order._update') @patch('acme_srv.order.Order._info') - def test_023_order__lookup(self, mock_oinfo, mock_update): + def test_024_order__lookup(self, mock_oinfo, mock_update): """ test order lookup correct identifier for oder info status - pending order-update """ self.order.dbstore.authorization_lookup.return_value = [{'name': 'name', 'status__name': 'valid'}] mock_oinfo.return_value = {'status' : 'pending', 'expires' : 1543640400, 'notbefore' : 1543640400, 'notafter' : 1543640400, 'identifiers': '{"foo": "bar"}'} @@ -262,7 +262,7 @@ def test_023_order__lookup(self, mock_oinfo, mock_update): @patch('acme_srv.order.Order._update') @patch('acme_srv.order.Order._info') - def test_024_order__lookup(self, mock_oinfo, mock_update): + def test_025_order__lookup(self, mock_oinfo, mock_update): """ test order lookup correct identifier for oder info status - pending order-update """ self.order.dbstore.authorization_lookup.return_value = [{'name': 'name', 'status__name': 'valid'}] mock_oinfo.return_value = {'status' : 'notpending', 'expires' : 1543640400, 'notbefore' : 1543640400, 'notafter' : 1543640400, 'identifiers': '{"foo": "bar"}'} @@ -272,7 +272,7 @@ def test_024_order__lookup(self, mock_oinfo, mock_update): @patch('acme_srv.order.Order._update') @patch('acme_srv.order.Order._info') - def test_025_order__lookup(self, mock_oinfo, mock_update): + def test_026_order__lookup(self, mock_oinfo, mock_update): """ test order lookup correct identifier for oder info status - invalid statusname """ self.order.dbstore.authorization_lookup.return_value = [{'name': 'name', 'status__name': 'invalid'}] mock_oinfo.return_value = {'status' : 'pending', 'expires' : 1543640400, 'notbefore' : 1543640400, 'notafter' : 1543640400, 'identifiers': '{"foo": "bar"}'} @@ -281,7 +281,7 @@ def test_025_order__lookup(self, mock_oinfo, mock_update): self.assertFalse(mock_update.called) @patch('acme_srv.order.Order._info') - def test_026_order__csr_process(self, mock_oinfo): + def test_027_order__csr_process(self, mock_oinfo): """ test order prcoess_csr with empty order_dic """ mock_oinfo.return_value = {} self.assertEqual((400, 'urn:ietf:params:acme:error:unauthorized', 'order: order_name not found'), self.order._csr_process('order_name', 'csr', 'header_info')) @@ -289,7 +289,7 @@ def test_026_order__csr_process(self, mock_oinfo): @patch('importlib.import_module') @patch('acme_srv.certificate.Certificate.store_csr') @patch('acme_srv.order.Order._info') - def test_027_order__csr_process(self, mock_oinfo, mock_certname, mock_import): + def test_028_order__csr_process(self, mock_oinfo, mock_certname, mock_import): """ test order prcoess_csr with failed csr dbsave""" mock_oinfo.return_value = {'foo', 'bar'} mock_certname.return_value = None @@ -300,7 +300,7 @@ def test_027_order__csr_process(self, mock_oinfo, mock_certname, mock_import): @patch('acme_srv.certificate.Certificate.enroll_and_store') @patch('acme_srv.certificate.Certificate.store_csr') @patch('acme_srv.order.Order._info') - def test_028_order__csr_process(self, mock_oinfo, mock_certname, mock_enroll, mock_import): + def test_029_order__csr_process(self, mock_oinfo, mock_certname, mock_enroll, mock_import): """ test order prcoess_csr with failed cert enrollment""" mock_oinfo.return_value = {'foo', 'bar'} mock_certname.return_value = 'foo' @@ -312,7 +312,7 @@ def test_028_order__csr_process(self, mock_oinfo, mock_certname, mock_enroll, mo @patch('acme_srv.certificate.Certificate.enroll_and_store') @patch('acme_srv.certificate.Certificate.store_csr') @patch('acme_srv.order.Order._info') - def test_029_order__csr_process(self, mock_oinfo, mock_certname, mock_enroll, mock_import): + def test_030_order__csr_process(self, mock_oinfo, mock_certname, mock_enroll, mock_import): """ test order prcoess_csr with successful cert enrollment""" mock_oinfo.return_value = {'foo', 'bar'} mock_certname.return_value = 'foo' @@ -320,29 +320,29 @@ def test_029_order__csr_process(self, mock_oinfo, mock_certname, mock_enroll, mo mock_import.return_value = importlib.import_module('examples.ca_handler.skeleton_ca_handler') self.assertEqual((200, 'foo', None), self.order._csr_process('order_name', 'csr', 'header_info')) - def test_030_order__name_get(self): + def test_031_order__name_get(self): """ Order.name_get() http""" self.assertEqual('foo', self.order._name_get('http://tester.local/acme/order/foo')) - def test_031_order__name_get(self): + def test_032_order__name_get(self): """ Order.name_get() http with further path (finalize)""" self.assertEqual('foo', self.order._name_get('http://tester.local/acme/order/foo/bar')) - def test_032_order__name_get(self): + def test_033_order__name_get(self): """ Order.name_get() http with parameters""" self.assertEqual('foo', self.order._name_get('http://tester.local/acme/order/foo?bar')) - def test_033_order__name_get(self): + def test_034_order__name_get(self): """ Order.name_get() http with key/value parameters""" self.assertEqual('foo', self.order._name_get('http://tester.local/acme/order/foo?key=value')) - def test_034_order__name_get(self): + def test_035_order__name_get(self): """ Order.name_get() https with key/value parameters""" self.assertEqual('foo', self.order._name_get('https://tester.local/acme/order/foo?key=value')) @patch('acme_srv.nonce.Nonce.generate_and_add') @patch('acme_srv.message.Message.check') - def test_035_order_parse(self, mock_mcheck, mock_nnonce): + def test_036_order_parse(self, mock_mcheck, mock_nnonce): """ Order.parse() failed bcs. of failed message check """ mock_mcheck.return_value = (400, 'message', 'detail', None, None, 'account_name') message = '{"foo" : "bar"}' @@ -352,7 +352,7 @@ def test_035_order_parse(self, mock_mcheck, mock_nnonce): @patch('acme_srv.nonce.Nonce.generate_and_add') @patch('acme_srv.message.Message.check') - def test_036_order_parse(self, mock_mcheck, mock_nnonce): + def test_037_order_parse(self, mock_mcheck, mock_nnonce): """ Order.parse() failed bcs. no url key in protected """ mock_mcheck.return_value = (200, None, None, {'foo_protected' : 'bar_protected'}, {"foo_payload" : "bar_payload"}, 'account_name') message = '{"foo" : "bar"}' @@ -363,7 +363,7 @@ def test_036_order_parse(self, mock_mcheck, mock_nnonce): @patch('acme_srv.nonce.Nonce.generate_and_add') @patch('acme_srv.order.Order._name_get') @patch('acme_srv.message.Message.check') - def test_037_order_parse(self, mock_mcheck, mock_oname, mock_nnonce): + def test_038_order_parse(self, mock_mcheck, mock_oname, mock_nnonce): """ Order.parse() name_get failed """ mock_mcheck.return_value = (200, None, None, {'url' : 'bar_url/finalize'}, {"foo_payload" : "bar_payload"}, 'account_name') mock_oname.return_value = None @@ -376,7 +376,7 @@ def test_037_order_parse(self, mock_mcheck, mock_oname, mock_nnonce): @patch('acme_srv.order.Order._lookup') @patch('acme_srv.order.Order._name_get') @patch('acme_srv.message.Message.check') - def test_038_order_parse(self, mock_mcheck, mock_oname, mock_lookup, mock_nnonce): + def test_039_order_parse(self, mock_mcheck, mock_oname, mock_lookup, mock_nnonce): """ Order.parse() failed as order lookup failed """ mock_mcheck.return_value = (200, None, None, {'url' : 'bar_url/finalize'}, {"foo_payload" : "bar_payload"}, 'account_name') mock_oname.return_value = 'foo' @@ -391,7 +391,7 @@ def test_038_order_parse(self, mock_mcheck, mock_oname, mock_lookup, mock_nnonce @patch('acme_srv.order.Order._lookup') @patch('acme_srv.order.Order._name_get') @patch('acme_srv.message.Message.check') - def test_039_order_parse(self, mock_mcheck, mock_oname, mock_lookup, mock_process, mock_nnonce): + def test_040_order_parse(self, mock_mcheck, mock_oname, mock_lookup, mock_process, mock_nnonce): """ Order.parse() succ, oder process returned non 200 """ mock_mcheck.return_value = (200, None, None, {'url' : 'bar_url/finalize'}, {"foo_payload" : "bar_payload"}, 'account_name') mock_oname.return_value = 'foo' @@ -407,7 +407,7 @@ def test_039_order_parse(self, mock_mcheck, mock_oname, mock_lookup, mock_proces @patch('acme_srv.order.Order._lookup') @patch('acme_srv.order.Order._name_get') @patch('acme_srv.message.Message.check') - def test_040_order_parse(self, mock_mcheck, mock_oname, mock_lookup, mock_process, mock_nnonce): + def test_041_order_parse(self, mock_mcheck, mock_oname, mock_lookup, mock_process, mock_nnonce): """ Order.parse() succ, oder process returned 200 and no certname """ mock_mcheck.return_value = (200, None, None, {'url' : 'bar_url/finalize'}, {"foo_payload" : "bar_payload"}, 'account_name') mock_oname.return_value = 'foo' @@ -422,7 +422,7 @@ def test_040_order_parse(self, mock_mcheck, mock_oname, mock_lookup, mock_proces @patch('acme_srv.order.Order._lookup') @patch('acme_srv.order.Order._name_get') @patch('acme_srv.message.Message.check') - def test_041_order_parse(self, mock_mcheck, mock_oname, mock_lookup, mock_process, mock_nnonce): + def test_042_order_parse(self, mock_mcheck, mock_oname, mock_lookup, mock_process, mock_nnonce): """ Order.parse() succ, oder process returned 200 and certname and valid status """ mock_mcheck.return_value = (200, None, None, {'url' : 'bar_url/finalize'}, {"foo_payload" : "bar_payload"}, 'account_name') mock_oname.return_value = 'foo' @@ -437,7 +437,7 @@ def test_041_order_parse(self, mock_mcheck, mock_oname, mock_lookup, mock_proces @patch('acme_srv.order.Order._lookup') @patch('acme_srv.order.Order._name_get') @patch('acme_srv.message.Message.check') - def test_042_order_parse(self, mock_mcheck, mock_oname, mock_lookup, mock_process, mock_nnonce): + def test_043_order_parse(self, mock_mcheck, mock_oname, mock_lookup, mock_process, mock_nnonce): """ Order.parse() succ, oder process returned 200 and certname without status """ mock_mcheck.return_value = (200, None, None, {'url' : 'bar_url/finalize'}, {"foo_payload" : "bar_payload"}, 'account_name') mock_oname.return_value = 'foo' @@ -452,7 +452,7 @@ def test_042_order_parse(self, mock_mcheck, mock_oname, mock_lookup, mock_proces @patch('acme_srv.order.Order._lookup') @patch('acme_srv.order.Order._name_get') @patch('acme_srv.message.Message.check') - def test_043_order_parse(self, mock_mcheck, mock_oname, mock_lookup, mock_process, mock_nnonce): + def test_044_order_parse(self, mock_mcheck, mock_oname, mock_lookup, mock_process, mock_nnonce): """ Order.parse() succ, oder process returned 200 and certname and non-valid status """ mock_mcheck.return_value = (200, None, None, {'url' : 'bar_url/finalize'}, {"foo_payload" : "bar_payload"}, 'account_name') mock_oname.return_value = 'foo' @@ -462,104 +462,118 @@ def test_043_order_parse(self, mock_mcheck, mock_oname, mock_lookup, mock_proces message = '{"foo" : "bar"}' self.assertEqual({'code': 200, 'data': {'finalize': 'http://tester.local/acme/order/foo/finalize', 'foo': 'bar', 'status': 'foobar'}, 'header': {'Location': 'http://tester.local/acme/order/foo', 'Replay-Nonce': 'nonce'}}, self.order.parse(message)) - def test_044_order__identifiers_check(self): + def test_045_order__identifiers_check(self): """ order identifers check with empty identifer list""" self.assertEqual('urn:ietf:params:acme:error:malformed', self.order._identifiers_check([])) - def test_045_order__identifiers_check(self): + def test_046_order__identifiers_check(self): """ order identifers check with string identifier """ self.assertEqual('urn:ietf:params:acme:error:malformed', self.order._identifiers_check('foo')) - def test_046_order__identifiers_check(self): + def test_047_order__identifiers_check(self): """ order identifers check with dictionary identifier """ self.assertEqual('urn:ietf:params:acme:error:malformed', self.order._identifiers_check({'type': 'dns', 'value': 'foo.bar'})) - def test_047_order__identifiers_check(self): + def test_048_order__identifiers_check(self): """ order identifers check with correct identifer but case-insensitive """ self.assertEqual('urn:ietf:params:acme:error:malformed', self.order._identifiers_check([{'Type': 'dns', 'value': 'value'}])) - def test_048_order__identifiers_check(self): + def test_049_order__identifiers_check(self): """ order identifers check with wrong identifer in list""" self.assertEqual('urn:ietf:params:acme:error:unsupportedIdentifier', self.order._identifiers_check([{'type': 'foo', 'value': 'value'}])) - def test_049_order__identifiers_check(self): + def test_050_order__identifiers_check(self): """ order identifers check with correct identifer in list""" self.assertEqual(None, self.order._identifiers_check([{'type': 'dns', 'value': 'value'}])) - def test_050_order__identifiers_check(self): + def test_051_order__identifiers_check(self): """ order identifers check with two identifers in list (one wrong) """ self.assertEqual('urn:ietf:params:acme:error:unsupportedIdentifier', self.order._identifiers_check([{'type': 'dns', 'value': 'value'}, {'type': 'foo', 'value': 'value'}])) - def test_051_order__identifiers_check(self): + def test_052_order__identifiers_check(self): """ order identifers check with two identifers in list (one wrong) """ self.assertEqual('urn:ietf:params:acme:error:unsupportedIdentifier', self.order._identifiers_check([{'type': 'foo', 'value': 'value'}, {'type': 'dns', 'value': 'value'}])) - def test_052_order__identifiers_check(self): + def test_053_order__identifiers_check(self): """ order identifers check with two identifers in list (one wrong) """ self.assertEqual(None, self.order._identifiers_check([{'type': 'dns', 'value': 'value'}, {'type': 'dns', 'value': 'value'}])) - def test_053_order__identifiers_check(self): + def test_054_order__identifiers_check(self): """ order identifers check with tnauthlist identifier and support false """ self.order.tnauthlist_support = False self.assertEqual('urn:ietf:params:acme:error:unsupportedIdentifier', self.order._identifiers_check([{'type': 'TNAuthList', 'value': 'value'}, {'type': 'dns', 'value': 'value'}])) - def test_054_order__identifiers_check(self): + def test_055_order__identifiers_check(self): """ order identifers check with tnauthlist identifier and support True """ self.order.tnauthlist_support = True self.assertEqual(None, self.order._identifiers_check([{'type': 'TNAuthList', 'value': 'value'}, {'type': 'dns', 'value': 'foo.bar.local'}])) - def test_055_order__identifiers_check(self): + def test_056_order__identifiers_check(self): """ order identifers check with tnauthlist identifier and support True """ self.order.tnauthlist_support = True self.assertEqual(None, self.order._identifiers_check([{'type': 'TNAuthList', 'value': 'value'}])) - def test_056_order__identifiers_check(self): + def test_057_order__identifiers_check(self): """ order identifers check with tnauthlist identifier a wrong identifer and support True """ self.order.tnauthlist_support = True self.assertEqual('urn:ietf:params:acme:error:unsupportedIdentifier', self.order._identifiers_check([{'type': 'TNAuthList', 'value': 'value'}, {'type': 'type', 'value': 'value'}])) - def test_057_order__identifiers_check(self): + def test_058_order__identifiers_check(self): """ order identifers check with wrong identifer in list and tnauthsupport true""" self.order.tnauthlist_support = True self.assertEqual('urn:ietf:params:acme:error:unsupportedIdentifier', self.order._identifiers_check([{'type': 'foo', 'value': 'value'}])) - def test_058_order__identifiers_check(self): + def test_059_order__identifiers_check(self): """ order identifers check with correct identifer in list and tnauthsupport true""" self.order.tnauthlist_support = True self.assertEqual(None, self.order._identifiers_check([{'type': 'dns', 'value': 'value'}])) + def test_060_order__identifiers_check(self): + """ order identifers check with 3 identifiers and no indentifier limit """ + self.assertEqual(None, self.order._identifiers_check([{'type': 'dns', 'value': 'value'}, {'type': 'dns', 'value': 'value'}, {'type': 'dns', 'value': 'value'}])) + + def test_061_order__identifiers_check(self): + """ order identifers check with 3 identifiers and identifier limit of 3 """ + self.order.identifier_limit = 3 + self.assertEqual(None, self.order._identifiers_check([{'type': 'dns', 'value': 'value'}, {'type': 'dns', 'value': 'value'}, {'type': 'dns', 'value': 'value'}])) + + def test_062_order__identifiers_check(self): + """ order identifers check with 3 identifiers and identifier limit of 2 """ + self.order.identifier_limit = 2 + self.assertEqual('urn:ietf:params:acme:error:rejectedIdentifier', self.order._identifiers_check([{'type': 'dns', 'value': 'value'}, {'type': 'dns', 'value': 'value'}, {'type': 'dns', 'value': 'value'}])) + @patch('acme_srv.order.validate_identifier') - def test_059_order__identifiers_check(self, mock_vali): + def test_063_order__identifiers_check(self, mock_vali): """ order identifers check with correct identifer """ mock_vali.side_effect = [True] self.assertEqual(None, self.order._identifiers_check([{'type': 'dns', 'value': 'value'}])) @patch('acme_srv.order.validate_identifier') - def test_060_order__identifiers_check(self, mock_vali): + def test_064_order__identifiers_check(self, mock_vali): """ order identifers check with correct identifer """ mock_vali.side_effect = [False] self.assertEqual('urn:ietf:params:acme:error:rejectedIdentifier', self.order._identifiers_check([{'type': 'dns', 'value': 'value'}])) @patch('acme_srv.order.validate_identifier') - def test_060_order__identifiers_check(self, mock_vali): + def test_065_order__identifiers_check(self, mock_vali): """ order identifers check with correct identifer """ mock_vali.side_effect = [True, False] self.assertEqual('urn:ietf:params:acme:error:rejectedIdentifier', self.order._identifiers_check([{'type': 'dns', 'value': 'value'}, {'type': 'dns', 'value': 'value'}])) @patch('acme_srv.order.validate_identifier') - def test_061_order__identifiers_check(self, mock_vali): + def test_066_order__identifiers_check(self, mock_vali): """ order identifers check with correct identifer """ mock_vali.side_effect = [False, True] self.assertEqual('urn:ietf:params:acme:error:rejectedIdentifier', self.order._identifiers_check([{'type': 'dns', 'value': 'value'}, {'type': 'dns', 'value': 'value'}])) - def test_059_order__process(self): + def test_067_order__process(self): """ Order.prcoess() without url in protected header """ order_name = 'order_name' protected = 'protected' payload = 'payload' self.assertEqual((400, 'urn:ietf:params:acme:error:malformed', 'url is missing in protected', None), self.order._process(order_name, protected, payload)) - def test_060_order__process(self): + def test_068_order__process(self): """ Order.prcoess() polling request with failed certificate lookup """ order_name = 'order_name' protected = {'url': 'foo'} @@ -567,7 +581,7 @@ def test_060_order__process(self): self.order.dbstore.certificate_lookup.return_value = {} self.assertEqual((200, None, None, None), self.order._process(order_name, protected, payload)) - def test_061_order__process(self): + def test_069_order__process(self): """ Order.prcoess() polling request with successful certificate lookup """ order_name = 'order_name' protected = {'url': 'foo'} @@ -576,7 +590,7 @@ def test_061_order__process(self): self.assertEqual((200, None, None, 'cert_name'), self.order._process(order_name, protected, payload)) @patch('acme_srv.order.Order._info') - def test_062_order__process(self, mock_info): + def test_070_order__process(self, mock_info): """ Order.prcoess() finalize request with empty orderinfo """ mock_info.return_value = {} order_name = 'order_name' @@ -585,7 +599,7 @@ def test_062_order__process(self, mock_info): self.assertEqual((403, 'urn:ietf:params:acme:error:orderNotReady', 'Order is not ready', None), self.order._process(order_name, protected, payload)) @patch('acme_srv.order.Order._info') - def test_063_order__process(self, mock_info): + def test_071_order__process(self, mock_info): """ Order.prcoess() finalize request with orderinfo without status""" mock_info.return_value = {'foo': 'bar'} order_name = 'order_name' @@ -594,7 +608,7 @@ def test_063_order__process(self, mock_info): self.assertEqual((403, 'urn:ietf:params:acme:error:orderNotReady', 'Order is not ready', None), self.order._process(order_name, protected, payload)) @patch('acme_srv.order.Order._info') - def test_064_order__process(self, mock_info): + def test_072_order__process(self, mock_info): """ Order.prcoess() finalize request with orderinfo with wrong status""" mock_info.return_value = {'status': 'bar'} order_name = 'order_name' @@ -603,7 +617,7 @@ def test_064_order__process(self, mock_info): self.assertEqual((403, 'urn:ietf:params:acme:error:orderNotReady', 'Order is not ready', None), self.order._process(order_name, protected, payload)) @patch('acme_srv.order.Order._info') - def test_065_order__process(self, mock_info): + def test_073_order__process(self, mock_info): """ Order.prcoess() finalize request without CSR """ mock_info.return_value = {'status': 'ready'} order_name = 'order_name' @@ -613,7 +627,7 @@ def test_065_order__process(self, mock_info): @patch('acme_srv.order.Order._csr_process') @patch('acme_srv.order.Order._info') - def test_066_order__process(self, mock_info, mock_process_csr): + def test_074_order__process(self, mock_info, mock_process_csr): """ Order.prcoess() finalize request with CSR but csr_process failed """ mock_info.return_value = {'status': 'ready'} order_name = 'order_name' @@ -625,7 +639,7 @@ def test_066_order__process(self, mock_info, mock_process_csr): @patch('acme_srv.order.Order._update') @patch('acme_srv.order.Order._csr_process') @patch('acme_srv.order.Order._info') - def test_067_order__process(self, mock_info, mock_process_csr, mock_update): + def test_075_order__process(self, mock_info, mock_process_csr, mock_update): """ Order.prcoess() finalize request with CSR but all good """ mock_info.return_value = {'status': 'ready'} order_name = 'order_name' @@ -639,7 +653,7 @@ def test_067_order__process(self, mock_info, mock_process_csr, mock_update): @patch('acme_srv.order.Order._update') @patch('acme_srv.order.Order._csr_process') @patch('acme_srv.order.Order._info') - def test_068_order__process(self, mock_info, mock_process_csr, mock_update): + def test_076_order__process(self, mock_info, mock_process_csr, mock_update): """ Order.prcoess() timeout in csr processing """ mock_info.return_value = {'status': 'ready'} order_name = 'order_name' @@ -653,7 +667,7 @@ def test_068_order__process(self, mock_info, mock_process_csr, mock_update): @patch('acme_srv.order.Order._update') @patch('acme_srv.order.Order._csr_process') @patch('acme_srv.order.Order._info') - def test_069_order__process(self, mock_info, mock_process_csr, mock_update): + def test_077_order__process(self, mock_info, mock_process_csr, mock_update): """ Order.prcoess() finalize request with detail none """ mock_info.return_value = {'status': 'ready'} order_name = 'order_name' @@ -668,7 +682,7 @@ def test_069_order__process(self, mock_info, mock_process_csr, mock_update): @patch('acme_srv.certificate.Certificate.enroll_and_store') @patch('acme_srv.certificate.Certificate.store_csr') @patch('acme_srv.order.Order._info') - def test_070_order__csr_process(self, mock_oinfo, mock_certname, mock_enroll, mock_import): + def test_078_order__csr_process(self, mock_oinfo, mock_certname, mock_enroll, mock_import): """ test order prcoess_csr with failed cert enrollment with internal error (response code must be corrected by 500)""" mock_oinfo.return_value = {'foo', 'bar'} mock_certname.return_value = 'foo' @@ -681,7 +695,7 @@ def test_070_order__csr_process(self, mock_oinfo, mock_certname, mock_enroll, mo @patch('acme_srv.order.Order._lookup') @patch('acme_srv.order.Order._name_get') @patch('acme_srv.message.Message.check') - def test_071_order_parse(self, mock_mcheck, mock_oname, mock_lookup, mock_process, mock_nnonce): + def test_079_order_parse(self, mock_mcheck, mock_oname, mock_lookup, mock_process, mock_nnonce): """ Order.parse() succ, oder process returned 200 and certname processing status default retry after-header """ mock_mcheck.return_value = (200, None, None, {'url' : 'bar_url/finalize'}, {"foo_payload" : "bar_payload"}, 'account_name') mock_oname.return_value = 'foo' @@ -696,7 +710,7 @@ def test_071_order_parse(self, mock_mcheck, mock_oname, mock_lookup, mock_proces @patch('acme_srv.order.Order._lookup') @patch('acme_srv.order.Order._name_get') @patch('acme_srv.message.Message.check') - def test_072_order_parse(self, mock_mcheck, mock_oname, mock_lookup, mock_process, mock_nnonce): + def test_080_order_parse(self, mock_mcheck, mock_oname, mock_lookup, mock_process, mock_nnonce): """ Order.parse() succ, oder process returned 200 and certname processing status configurable retry after-header """ self.order.retry_after = 60 mock_mcheck.return_value = (200, None, None, {'url' : 'bar_url/finalize'}, {"foo_payload" : "bar_payload"}, 'account_name') @@ -707,38 +721,38 @@ def test_072_order_parse(self, mock_mcheck, mock_oname, mock_lookup, mock_proces message = '{"foo" : "bar"}' self.assertEqual({'code': 200, 'data': {'finalize': 'http://tester.local/acme/order/foo/finalize', 'foo': 'bar', 'status': 'processing'}, 'header': {'Location': 'http://tester.local/acme/order/foo', 'Replay-Nonce': 'nonce', 'Retry-After': '60'}}, self.order.parse(message)) - def test_073_order_invalidate(self): + def test_081_order_invalidate(self): """ test Order.invalidate() empty order list """ self.order.dbstore.orders_invalid_search.return_value = [] self.assertEqual((['id', 'name', 'expires', 'identifiers', 'created_at', 'status__id', 'status__name', 'account__id', 'account__name', 'account__contact'], []), self.order.invalidate()) - def test_074_order_invalidate(self): + def test_082_order_invalidate(self): """ test Certificate._fieldlist_normalize() - wrong return list (no status__name included) """ self.order.dbstore.orders_invalid_search.return_value = [{'foo': 'bar'}] self.assertEqual((['id', 'name', 'expires', 'identifiers', 'created_at', 'status__id', 'status__name', 'account__id', 'account__name', 'account__contact'], []), self.order.invalidate()) - def test_075_order_invalidate(self): + def test_083_order_invalidate(self): """ test Certificate._fieldlist_normalize() - no name but status__name """ self.order.dbstore.orders_invalid_search.return_value = [{'foo': 'bar', 'status__name': 'foo'}] self.assertEqual((['id', 'name', 'expires', 'identifiers', 'created_at', 'status__id', 'status__name', 'account__id', 'account__name', 'account__contact'], []), self.order.invalidate()) - def test_076_order_invalidate(self): + def test_084_order_invalidate(self): """ test Certificate._fieldlist_normalize() - name but no status__name """ self.order.dbstore.orders_invalid_search.return_value = [{'foo': 'bar', 'name': 'foo'}] self.assertEqual((['id', 'name', 'expires', 'identifiers', 'created_at', 'status__id', 'status__name', 'account__id', 'account__name', 'account__contact'], []), self.order.invalidate()) - def test_077_order_invalidate(self): + def test_085_order_invalidate(self): """ test Certificate._fieldlist_normalize() - name and status__name but invalid """ self.order.dbstore.orders_invalid_search.return_value = [{'foo': 'bar', 'name': 'foo', 'status__name': 'invalid'}] self.assertEqual((['id', 'name', 'expires', 'identifiers', 'created_at', 'status__id', 'status__name', 'account__id', 'account__name', 'account__contact'], []), self.order.invalidate()) - def test_078_order_invalidate(self): + def test_086_order_invalidate(self): """ test Certificate._fieldlist_normalize() - name and status__name but invalid """ self.order.dbstore.orders_invalid_search.return_value = [{'foo': 'bar', 'name': 'foo', 'status__name': 'foobar'}] self.assertEqual((['id', 'name', 'expires', 'identifiers', 'created_at', 'status__id', 'status__name', 'account__id', 'account__name', 'account__contact'], [{'foo': 'bar', 'name': 'foo', 'status__name': 'foobar'}]), self.order.invalidate()) @patch('acme_srv.order.Order._identifiers_check') - def test_079_order__add(self, mock_idchk): + def test_087_order__add(self, mock_idchk): """ test Order._add - dbstore.authorization_add() raises an exception """ self.order.dbstore.authorization_add.side_effect = Exception('exc_order_add') self.order.dbstore.order_add.return_value = 'oid' @@ -748,7 +762,7 @@ def test_079_order__add(self, mock_idchk): self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Order._add() authz: exc_order_add', lcm.output) @patch('acme_srv.order.Order._identifiers_check') - def test_080_order__add(self, mock_idchk): + def test_088_order__add(self, mock_idchk): """ test Order._add - dbstore.order_add() raises an exception """ self.order.dbstore.order_add.side_effect = Exception('exc_order_add') mock_idchk.return_value = False @@ -756,21 +770,21 @@ def test_080_order__add(self, mock_idchk): self.order._add({'foo': 'bar', 'identifiers': 'identifiers'}, 'aname') self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Order._add() order: exc_order_add', lcm.output) - def test_081_order__info(self): + def test_089_order__info(self): """ test Order._info - dbstore.order_lookup() raises an exception """ self.order.dbstore.order_lookup.side_effect = Exception('exc_order_info') with self.assertLogs('test_a2c', level='INFO') as lcm: self.order._info('oname') self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Order._info(): exc_order_info', lcm.output) - def test_082_order__process(self): + def test_090_order__process(self): """ test Order._process - dbstore.order_lookup() raises an exception """ self.order.dbstore.certificate_lookup.side_effect = Exception('exc_order_process') with self.assertLogs('test_a2c', level='INFO') as lcm: self.order._process('oname', {'url': 'url'}, 'payload') self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Order._process(): exc_order_process', lcm.output) - def test_083_order__update(self): + def test_091_order__update(self): """ test Order._update - dbstore.order_update() raises an exception """ self.order.dbstore.order_update.side_effect = Exception('exc_order_upd') with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -778,7 +792,7 @@ def test_083_order__update(self): self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Order._update(): exc_order_upd', lcm.output) @patch('acme_srv.order.Order._info') - def test_084_order__lookup(self, mock_info): + def test_092_order__lookup(self, mock_info): """ test Order._lookup - dbstore.authorization_lookup() raises an exception """ self.order.dbstore.authorization_lookup.side_effect = Exception('exc_authz_lookup') mock_info.return_value = {'status': 'valid'} @@ -786,7 +800,7 @@ def test_084_order__lookup(self, mock_info): self.order._lookup('oname') self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Order._authz_list_lookup(): exc_authz_lookup', lcm.output) - def test_085_order_invalidate(self): + def test_093_order_invalidate(self): """ test Order.invalidate - dbstore.order_update() raises an exception """ self.order.dbstore.order_update.side_effect = Exception('exc_order_upd') self.order.dbstore.order_invalid_search.return_value = ['foo'] @@ -795,7 +809,7 @@ def test_085_order_invalidate(self): self.order.invalidate(timestamp) self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Order._invalidate() upd: exc_order_upd', lcm.output) - def test_086_order_invalidate(self): + def test_094_order_invalidate(self): """ test Order.invalidate - dbstore.order_update() raises an exception """ self.order.dbstore.orders_invalid_search.side_effect = Exception('exc_order_search') timestamp = 1543640400 @@ -804,14 +818,14 @@ def test_086_order_invalidate(self): self.assertIn('CRITICAL:test_a2c:acme2certifier database error in Order._invalidate() search: exc_order_search', lcm.output) @patch('acme_srv.order.Order._config_load') - def test_087__enter__(self, mock_cfg): + def test_095__enter__(self, mock_cfg): """ test enter """ mock_cfg.return_value = True self.order.__enter__() self.assertTrue(mock_cfg.called) @patch('acme_srv.order.load_config') - def test_088_config_load(self, mock_load_cfg): + def test_096_config_load(self, mock_load_cfg): """ test _config_load empty config """ parser = configparser.ConfigParser() mock_load_cfg.return_value = parser @@ -820,7 +834,7 @@ def test_088_config_load(self, mock_load_cfg): self.assertFalse(self.order.header_info_list) @patch('acme_srv.order.load_config') - def test_089_config_load(self, mock_load_cfg): + def test_097_config_load(self, mock_load_cfg): """ test _config_load """ parser = configparser.ConfigParser() parser['Order'] = {'foo': 'bar'} @@ -830,7 +844,7 @@ def test_089_config_load(self, mock_load_cfg): self.assertFalse(self.order.header_info_list) @patch('acme_srv.order.load_config') - def test_090_config_load(self, mock_load_cfg): + def test_098_config_load(self, mock_load_cfg): """ test _config_load """ parser = configparser.ConfigParser() parser['Order'] = {'tnauthlist_support': False} @@ -840,7 +854,7 @@ def test_090_config_load(self, mock_load_cfg): self.assertFalse(self.order.header_info_list) @patch('acme_srv.order.load_config') - def test_091_config_load(self, mock_load_cfg): + def test_099_config_load(self, mock_load_cfg): """ test _config_load """ parser = configparser.ConfigParser() parser['Order'] = {'tnauthlist_support': True} @@ -854,7 +868,7 @@ def test_091_config_load(self, mock_load_cfg): self.assertFalse(self.order.header_info_list) @patch('acme_srv.order.load_config') - def test_092_config_load(self, mock_load_cfg): + def test_100_config_load(self, mock_load_cfg): """ test _config_load """ parser = configparser.ConfigParser() parser['Order'] = {'expiry_check_disable': False} @@ -867,9 +881,10 @@ def test_092_config_load(self, mock_load_cfg): self.assertEqual(86400, self.order.validity) self.assertEqual(86400, self.order.authz_validity) self.assertFalse(self.order.header_info_list) + self.assertEqual(20, self.order.identifier_limit) @patch('acme_srv.order.load_config') - def test_093_config_load(self, mock_load_cfg): + def test_101_config_load(self, mock_load_cfg): """ test _config_load """ parser = configparser.ConfigParser() parser['Order'] = {'expiry_check_disable': True} @@ -882,9 +897,10 @@ def test_093_config_load(self, mock_load_cfg): self.assertEqual(86400, self.order.validity) self.assertEqual(86400, self.order.authz_validity) self.assertFalse(self.order.header_info_list) + self.assertEqual(20, self.order.identifier_limit) @patch('acme_srv.order.load_config') - def test_094_config_load(self, mock_load_cfg): + def test_102_config_load(self, mock_load_cfg): """ test _config_load """ parser = configparser.ConfigParser() parser['Order'] = {'retry_after_timeout': 1200} @@ -897,9 +913,10 @@ def test_094_config_load(self, mock_load_cfg): self.assertEqual(86400, self.order.validity) self.assertEqual(86400, self.order.authz_validity) self.assertFalse(self.order.header_info_list) + self.assertEqual(20, self.order.identifier_limit) @patch('acme_srv.order.load_config') - def test_095_config_load(self, mock_load_cfg): + def test_103_config_load(self, mock_load_cfg): """ test _config_load """ parser = configparser.ConfigParser() parser['Order'] = {'retry_after_timeout': '1200'} @@ -912,9 +929,10 @@ def test_095_config_load(self, mock_load_cfg): self.assertEqual(86400, self.order.validity) self.assertEqual(86400, self.order.authz_validity) self.assertFalse(self.order.header_info_list) + self.assertEqual(20, self.order.identifier_limit) @patch('acme_srv.order.load_config') - def test_096_config_load(self, mock_load_cfg): + def test_104_config_load(self, mock_load_cfg): """ test _config_load """ parser = configparser.ConfigParser() parser['Order'] = {'retry_after_timeout': 'foo'} @@ -929,9 +947,10 @@ def test_096_config_load(self, mock_load_cfg): self.assertEqual(86400, self.order.authz_validity) self.assertIn('WARNING:test_a2c:Order._config_load(): failed to parse retry_after: foo', lcm.output) self.assertFalse(self.order.header_info_list) + self.assertEqual(20, self.order.identifier_limit) @patch('acme_srv.order.load_config') - def test_097_config_load(self, mock_load_cfg): + def test_105_config_load(self, mock_load_cfg): """ test _config_load """ parser = configparser.ConfigParser() parser['Order'] = {'validity': 1200} @@ -944,9 +963,10 @@ def test_097_config_load(self, mock_load_cfg): self.assertEqual(1200, self.order.validity) self.assertEqual(86400, self.order.authz_validity) self.assertFalse(self.order.header_info_list) + self.assertEqual(20, self.order.identifier_limit) @patch('acme_srv.order.load_config') - def test_098_config_load(self, mock_load_cfg): + def test_106_config_load(self, mock_load_cfg): """ test _config_load """ parser = configparser.ConfigParser() parser['Order'] = {'validity': '1200'} @@ -959,9 +979,10 @@ def test_098_config_load(self, mock_load_cfg): self.assertEqual(1200, self.order.validity) self.assertEqual(86400, self.order.authz_validity) self.assertFalse(self.order.header_info_list) + self.assertEqual(20, self.order.identifier_limit) @patch('acme_srv.order.load_config') - def test_099_config_load(self, mock_load_cfg): + def test_107_config_load(self, mock_load_cfg): """ test _config_load """ parser = configparser.ConfigParser() parser['Order'] = {'validity': 'foo'} @@ -976,9 +997,10 @@ def test_099_config_load(self, mock_load_cfg): self.assertEqual(86400, self.order.authz_validity) self.assertIn('WARNING:test_a2c:Order._config_load(): failed to parse validity: foo', lcm.output) self.assertFalse(self.order.header_info_list) + self.assertEqual(20, self.order.identifier_limit) @patch('acme_srv.order.load_config') - def test_100_config_load(self, mock_load_cfg): + def test_108_config_load(self, mock_load_cfg): """ test _config_load """ parser = configparser.ConfigParser() parser['Authorization'] = {'validity': 1200} @@ -991,9 +1013,10 @@ def test_100_config_load(self, mock_load_cfg): self.assertEqual(86400, self.order.validity) self.assertEqual(1200, self.order.authz_validity) self.assertFalse(self.order.header_info_list) + self.assertEqual(20, self.order.identifier_limit) @patch('acme_srv.order.load_config') - def test_101_config_load(self, mock_load_cfg): + def test_109_config_load(self, mock_load_cfg): """ test _config_load """ parser = configparser.ConfigParser() parser['Authorization'] = {'validity': '1200'} @@ -1006,9 +1029,10 @@ def test_101_config_load(self, mock_load_cfg): self.assertEqual(86400, self.order.validity) self.assertEqual(1200, self.order.authz_validity) self.assertFalse(self.order.header_info_list) + self.assertEqual(20, self.order.identifier_limit) @patch('acme_srv.order.load_config') - def test_102_config_load(self, mock_load_cfg): + def test_110_config_load(self, mock_load_cfg): """ test _config_load """ parser = configparser.ConfigParser() parser['Authorization'] = {'validity': 'foo'} @@ -1023,9 +1047,10 @@ def test_102_config_load(self, mock_load_cfg): self.assertEqual(86400, self.order.authz_validity) self.assertIn('WARNING:test_a2c:Order._config_load(): failed to parse authz validity: foo', lcm.output) self.assertFalse(self.order.header_info_list) + self.assertEqual(20, self.order.identifier_limit) @patch('acme_srv.order.load_config') - def test_103_config_load(self, mock_load_cfg): + def test_111_config_load(self, mock_load_cfg): """ test _config_load """ parser = configparser.ConfigParser() parser['Directory'] = {'url_prefix': 'url_prefix'} @@ -1034,9 +1059,10 @@ def test_103_config_load(self, mock_load_cfg): self.assertFalse(self.order.tnauthlist_support) self.assertEqual({'authz_path': 'url_prefix/acme/authz/', 'cert_path': 'url_prefix/acme/cert/', 'order_path': 'url_prefix/acme/order/'}, self.order.path_dic) self.assertFalse(self.order.header_info_list) + self.assertEqual(20, self.order.identifier_limit) @patch('acme_srv.order.load_config') - def test_104_config_load(self, mock_load_cfg): + def test_112_config_load(self, mock_load_cfg): """ test _config_load """ parser = configparser.ConfigParser() parser['Challenge'] = {'sectigo_sim': True} @@ -1049,9 +1075,10 @@ def test_104_config_load(self, mock_load_cfg): self.assertEqual(86400, self.order.validity) self.assertEqual(86400, self.order.authz_validity) self.assertFalse(self.order.header_info_list) + self.assertEqual(20, self.order.identifier_limit) @patch('acme_srv.order.load_config') - def test_105_config_load(self, mock_load_cfg): + def test_113_config_load(self, mock_load_cfg): """ test _config_load """ parser = configparser.ConfigParser() parser['Challenge'] = {'sectigo_sim': False} @@ -1064,9 +1091,10 @@ def test_105_config_load(self, mock_load_cfg): self.assertEqual(86400, self.order.validity) self.assertEqual(86400, self.order.authz_validity) self.assertFalse(self.order.header_info_list) + self.assertEqual(20, self.order.identifier_limit) @patch('acme_srv.order.load_config') - def test_106_config_load(self, mock_load_cfg): + def test_114_config_load(self, mock_load_cfg): """ test _config_load """ parser = configparser.ConfigParser() parser['Order'] = {'header_info_list': '["foo", "bar"]'} @@ -1079,9 +1107,10 @@ def test_106_config_load(self, mock_load_cfg): self.assertEqual(86400, self.order.validity) self.assertEqual(86400, self.order.authz_validity) self.assertEqual(['foo', 'bar'], self.order.header_info_list) + self.assertEqual(20, self.order.identifier_limit) @patch('acme_srv.order.load_config') - def test_107_config_load(self, mock_load_cfg): + def test_115_config_load(self, mock_load_cfg): """ test _config_load """ parser = configparser.ConfigParser() parser['Order'] = {'header_info_list': 'foo'} @@ -1096,10 +1125,77 @@ def test_107_config_load(self, mock_load_cfg): self.assertEqual(86400, self.order.authz_validity) self.assertFalse(self.order.header_info_list) self.assertIn('WARNING:test_a2c:Order._config_orderconfig_load() header_info_list failed with error: Expecting value: line 1 column 1 (char 0)', lcm.output) + self.assertEqual(20, self.order.identifier_limit) + + @patch('acme_srv.order.load_config') + def test_116_config_load(self, mock_load_cfg): + """ test _config_load """ + parser = configparser.ConfigParser() + parser['Challenge'] = {'sectigo_sim': False} + mock_load_cfg.return_value = parser + self.order._config_load() + self.assertFalse(self.order.tnauthlist_support) + self.assertFalse(self.order.sectigo_sim) + self.assertFalse(self.order.expiry_check_disable) + self.assertEqual(600, self.order.retry_after) + self.assertEqual(86400, self.order.validity) + self.assertEqual(86400, self.order.authz_validity) + self.assertFalse(self.order.header_info_list) + self.assertEqual(20, self.order.identifier_limit) + + @patch('acme_srv.order.load_config') + def test_117_config_load(self, mock_load_cfg): + """ test _config_load """ + parser = configparser.ConfigParser() + parser['Order'] = {'identifier_limit': 40} + mock_load_cfg.return_value = parser + self.order._config_load() + self.assertFalse(self.order.tnauthlist_support) + self.assertFalse(self.order.sectigo_sim) + self.assertFalse(self.order.expiry_check_disable) + self.assertEqual(600, self.order.retry_after) + self.assertEqual(86400, self.order.validity) + self.assertEqual(86400, self.order.authz_validity) + self.assertFalse(self.order.header_info_list) + self.assertEqual(40, self.order.identifier_limit) + + @patch('acme_srv.order.load_config') + def test_118_config_load(self, mock_load_cfg): + """ test _config_load """ + parser = configparser.ConfigParser() + parser['Order'] = {'identifier_limit': '40'} + mock_load_cfg.return_value = parser + self.order._config_load() + self.assertFalse(self.order.tnauthlist_support) + self.assertFalse(self.order.sectigo_sim) + self.assertFalse(self.order.expiry_check_disable) + self.assertEqual(600, self.order.retry_after) + self.assertEqual(86400, self.order.validity) + self.assertEqual(86400, self.order.authz_validity) + self.assertFalse(self.order.header_info_list) + self.assertEqual(40, self.order.identifier_limit) + + @patch('acme_srv.order.load_config') + def test_119_config_load(self, mock_load_cfg): + """ test _config_load """ + parser = configparser.ConfigParser() + parser['Order'] = {'identifier_limit': 'aa'} + mock_load_cfg.return_value = parser + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.order._config_load() + self.assertFalse(self.order.tnauthlist_support) + self.assertFalse(self.order.sectigo_sim) + self.assertFalse(self.order.expiry_check_disable) + self.assertEqual(600, self.order.retry_after) + self.assertEqual(86400, self.order.validity) + self.assertEqual(86400, self.order.authz_validity) + self.assertFalse(self.order.header_info_list) + self.assertEqual(20, self.order.identifier_limit) + self.assertIn('WARNING:test_a2c:Order._config_load(): failed to parse identifier_limit: aa', lcm.output) @patch('acme_srv.order.DBstore.authorization_add') @patch('acme_srv.order.generate_random_string') - def test_108__auth_add(self, mock_name, mock_order_add): + def test_120__auth_add(self, mock_name, mock_order_add): """ test _auth_add() """ mock_name.return_value = 'name' auth_dic = {} @@ -1108,7 +1204,7 @@ def test_108__auth_add(self, mock_name, mock_order_add): self.assertFalse(mock_order_add.called) @patch('acme_srv.order.generate_random_string') - def test_109__auth_add(self, mock_name): + def test_121__auth_add(self, mock_name): """ test _auth_add() """ mock_name.return_value = 'name' auth_dic = {} @@ -1119,7 +1215,7 @@ def test_109__auth_add(self, mock_name): self.assertFalse(self.order.dbstore.authorization_update.called) @patch('acme_srv.order.generate_random_string') - def test_110__auth_add(self, mock_name): + def test_122__auth_add(self, mock_name): """ test _auth_add() """ mock_name.return_value = 'name' auth_dic = {} @@ -1130,37 +1226,37 @@ def test_110__auth_add(self, mock_name): self.assertTrue(self.order.dbstore.authorization_add.called) self.assertTrue(self.order.dbstore.authorization_update.called) - def test_111__header_info_lookup(self): + def test_123__header_info_lookup(self): """ test _header_info_lookup() """ header = {'foo1': 'bar1', 'foo2': 'bar2'} self.order.header_info_list = ['foo1', 'foo2'] self.assertEqual('{"foo1": "bar1", "foo2": "bar2"}', self.order._header_info_lookup(header)) - def test_112__header_info_lookup(self): + def test_124__header_info_lookup(self): """ test _header_info_lookup() """ header = {'foo1': 'bar1', 'foo2': 'bar2'} self.order.header_info_list = ['foo2'] self.assertEqual('{"foo2": "bar2"}', self.order._header_info_lookup(header)) - def test_113__header_info_lookup(self): + def test_125__header_info_lookup(self): """ test _header_info_lookup() """ header = {'foo1': 'bar1', 'foo2': 'bar2'} self.order.header_info_list = ['foo1'] self.assertEqual('{"foo1": "bar1"}', self.order._header_info_lookup(header)) - def test_114__header_info_lookup(self): + def test_126__header_info_lookup(self): """ test _header_info_lookup() """ header = {'foo1': 'bar1', 'foo2': 'bar2'} self.order.header_info_list = ['foo1', 'foo3'] self.assertEqual('{"foo1": "bar1"}', self.order._header_info_lookup(header)) - def test_115__header_info_lookup(self): + def test_127__header_info_lookup(self): """ test _header_info_lookup() """ header = None self.order.header_info_list = ['foo1', 'foo3'] self.assertFalse(self.order._header_info_lookup(header)) - def test_116__header_info_lookup(self): + def test_128__header_info_lookup(self): """ test _header_info_lookup() """ header = {'foo1': 'bar1', 'foo2': 'bar2'} self.order.header_info_list = False From e73c305b503c9e81d9e663b2aaf22824dca97e0a Mon Sep 17 00:00:00 2001 From: grindsa Date: Fri, 22 Mar 2024 06:53:19 +0100 Subject: [PATCH 124/460] [doc] install_rpm.md --- docs/install_rpm.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/docs/install_rpm.md b/docs/install_rpm.md index ed957764..2c284a24 100644 --- a/docs/install_rpm.md +++ b/docs/install_rpm.md @@ -29,11 +29,6 @@ Backports of these packages being part of RHEL9 can be found in the [the a2c rpm - [python3-dns-2.1.0-6.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/rhel8/python3-dns-2.1.0-6.el8.noarch.rpm) - [python3-jwcrypto-0.8-4.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/rhel8/python3-jwcrypto-0.8-4.el8.noarch.rpm) -Depending on your packages would be needed as well: - - [python3-impacket-0.11.0-1.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/rhel8/python3-impacket-0.11.0-1.el8.noarch.rpm) for the [MS wcce handler](https://github.com/grindsa/acme2certifier/blob/master/docs/mswcce.md) - - [python3-ntlm-auth-1.5.0-2.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/rhel8/python3-ntlm-auth-1.5.0-2.el8.noarch.rpm) for the [MS wes handler](https://github.com/grindsa/acme2certifier/blob/master/docs/mscertsrv.md) - - [python3-requests-pkcs12-1.16-1.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/rhel8/python3-requests_ntlm-1.1.0-14.el8.noarch.rpm) for the [EST](https://github.com/grindsa/acme2certifier/blob/master/docs/est.md) and [Ejbca](https://github.com/grindsa/acme2certifier/blob/master/docs/ejbca.md) handler - Depending on your ca_handler you may need additional modules: - [python3-impacket-0.11.0-1.el8.noarch.rpm](https://github.com/grindsa/sbom/raw/main/rpm-repo/RPMs/rhel8/python3-impacket-0.11.0-1.el8.noarch.rpm) when using [MS wcce handler](https://github.com/grindsa/acme2certifier/blob/master/docs/mswcce.md) From 128a84163c89843767790f7fbc581982160392f1 Mon Sep 17 00:00:00 2001 From: Christopher Cook Date: Fri, 22 Mar 2024 16:59:50 +0800 Subject: [PATCH 125/460] Update a2c_response.py problem_json content type --- examples/django/acme_srv/a2c_response.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/django/acme_srv/a2c_response.py b/examples/django/acme_srv/a2c_response.py index 9cca8769..c01cd0da 100644 --- a/examples/django/acme_srv/a2c_response.py +++ b/examples/django/acme_srv/a2c_response.py @@ -23,7 +23,7 @@ def __init__(self, data, encoder=DjangoJSONEncoder, safe=True, json_dumps_params = {} if 'status' in kwargs and kwargs['status'] > 201: - kwargs.setdefault('content_type', 'problem+json') + kwargs.setdefault('content_type', 'application/problem+json') else: kwargs.setdefault('content_type', 'application/json') From 27da25c3f3139ad1c3b0b585ddc5c14913dea438 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 23 Mar 2024 06:31:21 +0100 Subject: [PATCH 126/460] [fix] timing EST handler --- .github/workflows/ca_handler_tests_est.yml | 32 ++++++++++++---------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/.github/workflows/ca_handler_tests_est.yml b/.github/workflows/ca_handler_tests_est.yml index 338f4210..85a9fbe8 100644 --- a/.github/workflows/ca_handler_tests_est.yml +++ b/.github/workflows/ca_handler_tests_est.yml @@ -43,7 +43,7 @@ jobs: WEB_SRV: ${{ matrix.websrv }} DB_HANDLER: ${{ matrix.dbhandler }} - - name: "[ PREPARE ] setup esthandler using http-basic-auth" + - name: "setup esthandler using http-basic-auth" run: | sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem @@ -68,6 +68,8 @@ jobs: sudo echo "est_user: estuser" >> examples/Docker/data/acme_srv.cfg sudo echo "est_password: estpwd" >> examples/Docker/data/acme_srv.cfg sudo echo "ca_bundle: False" >> examples/Docker/data/acme_srv.cfg + sudo echo "request_timeout: 30" >> examples/Docker/data/acme_srv.cfg + sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout: 40/g" examples/Docker/data/acme_srv.cfg cd examples/Docker/ docker-compose restart docker-compose logs @@ -87,14 +89,14 @@ jobs: run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - # - name: "Enroll acme-sh" - # run: | - # docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force - - name: "Enroll lego" run: | docker run -i -v $PWD/lego/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + - name: "Enroll acme-sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force + - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | @@ -141,7 +143,7 @@ jobs: - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" - - name: "[ PREPARE ] setup environment for alma installation" + - name: "setup environment for alma installation" run: | docker network create acme sudo mkdir -p data @@ -149,7 +151,7 @@ jobs: sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data - - name: "[ PREPARE ] create acme-sh and lego folder" + - name: "create acme-sh and lego folder" run: | mkdir acme-sh mkdir lego @@ -162,7 +164,7 @@ jobs: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} - - name: "[ PREPARE ] setup esthandler using http-basic-auth" + - name: "setup esthandler using http-basic-auth" run: | sudo mkdir -p data/acme_ca sudo touch $HOME/.rnd @@ -185,36 +187,38 @@ jobs: sudo echo "est_user: estuser" >> data/acme_srv.cfg sudo echo "est_password: estpwd" >> data/acme_srv.cfg sudo echo "ca_bundle: False" >> data/acme_srv.cfg + sudo echo "request_timeout: 30" >> data/acme_srv.cfg + sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout: 40/g" data/acme_srv.cfg - - name: "[ PREPARE ] Almalinux instance" + - name: "Almalinux instance" run: | sudo cp examples/Docker/almalinux-systemd/Dockerfile data sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - - name: "[ RUN ] Execute install scipt" + - name: "Execute install scipt" run: | docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh - name: "Test http://acme-srv/directory is accessible" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" + - name: "prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ ENROLL ] via EST using http-basic-auth" + - name: "Enroll via EST using http-basic-auth" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force # openssl verify -CAfile data/acme_ca/ca_bundle.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ ENROLL ] lego" + - name: "Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run # sudo openssl verify -CAfile data/acme_ca/ca_bundle.pem lego/certificates/lego.acme.crt - - name: "[ PREPARE ] delete lego and acme.sh" + - name: "delete lego and acme.sh" run: | sudo rm -rf lego/* sudo rm -rf acme-sh/* From 5f04481d1257a64794106f613745688c9c0cda8e Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 23 Mar 2024 07:27:17 +0100 Subject: [PATCH 127/460] [feat] supress_product_information feature --- acme_srv/directory.py | 30 ++++++-- docs/acme_srv.md | 2 + test/test_directory.py | 115 ++++++++++++++++++++++++++++--- test/test_wsgi_acme2certifier.py | 1 + 4 files changed, 130 insertions(+), 18 deletions(-) diff --git a/acme_srv/directory.py b/acme_srv/directory.py index d382a6cb..8d6bcc20 100644 --- a/acme_srv/directory.py +++ b/acme_srv/directory.py @@ -17,6 +17,8 @@ def __init__(self, debug=None, srv_name=None, logger=None): self.logger = logger self.dbstore = DBstore(debug, self.logger) self.supress_version = False + self.suppress_product_information = False + self.home = 'https://github.com/grindsa/acme2certifier' self.tos_url = None self.version = __version__ self.dbversion = __dbversion__ @@ -48,6 +50,13 @@ def _config_load(self): if 'Directory' in config_dic and 'url_prefix' in config_dic['Directory']: self.url_prefix = config_dic['Directory']['url_prefix'] + self.home = config_dic.get('Directory', 'home', fallback='https://github.com/grindsa/acme2certifier') + + try: + self.suppress_product_information = config_dic.getboolean('Directory', 'suppress_product_information', fallback= False) + except Exception as err_: + self.logger.error('Directory._config_load() suppress_product_information not set: %s', err_) + self.logger.debug('Directory._config_load() ended') def directory_get(self) -> Dict[str, str]: @@ -62,16 +71,22 @@ def directory_get(self) -> Dict[str, str]: 'revokeCert': self.server_name + self.url_prefix + '/acme/revokecert', 'keyChange': self.server_name + self.url_prefix + '/acme/key-change', 'renewalInfo': self.server_name + self.url_prefix + '/acme/renewal-info', - 'meta': { - 'home': 'https://github.com/grindsa/acme2certifier', + 'meta': {} + } + + if not self.suppress_product_information: + d_dic['meta'] = { + 'home': self.home, 'author': 'grindsa ', 'name': 'acme2certifier' - }, - } + } + # show version information in meta tags if not disabled.... + if not self.supress_version: + d_dic['meta']['version'] = self.version + else: + if self.home != 'https://github.com/grindsa/acme2certifier': + d_dic['meta']['home'] = self.home - # show version information in meta tags if not disabled.... - if not self.supress_version: - d_dic['meta']['version'] = self.version # add terms of service if self.tos_url: @@ -96,6 +111,7 @@ def directory_get(self) -> Dict[str, str]: # generate random key in json as recommended by LE d_dic[uuid.uuid4().hex] = 'https://community.letsencrypt.org/t/adding-random-entries-to-the-directory/33417' + return d_dic def servername_get(self) -> str: diff --git a/docs/acme_srv.md b/docs/acme_srv.md index 738f6041..22546cbe 100644 --- a/docs/acme_srv.md +++ b/docs/acme_srv.md @@ -23,6 +23,8 @@ | `Challenge` | `sectigo_sim` | provide `sectigo-email-01` challenges - Only for development and testing! | True/False | False | | `DBhandler` | `dbfile` | path and name of database file. If not specified `acme_srv/acme_srv.db` will be used. Parameter is only available for a wsgi handler and will be ignored if django handler is getting used | 'acme/database.db' | `acme_srv/acme_srv.db`| | `Directory` | `db_check` | check database connection compare schemes and report as OK/NOK in meta information | True/False | False| +| `Directory` | `home` | homepage string to be shown when fetching the directory ressource | 'string' | 'https://github.com/grindsa/acme2certifier' | +| `Directory` | `supress_product_information` | Do not show product name, author and version when fetching the directory resource | True/False | False| | `Directory` | `supress_version` | Do not show version information when fetching the directory resource | True/False | False| | `Directory` | `tos_url` | Terms of Service URL | URL | None| | `Directory` | `url_prefix` | url prefix for acme2certifier resources | '/foo' | None| diff --git a/test/test_directory.py b/test/test_directory.py index 501170aa..6b6f8d1c 100644 --- a/test/test_directory.py +++ b/test/test_directory.py @@ -122,8 +122,43 @@ def test_012_directory_directory_get(self): self.assertTrue(output_dic.items() <= result.items()) self.assertEqual('NOK', result['meta']['db_check']) + def test_013_directory_directory_get(self): + """ test Directory.get_directory() method and check for "meta" tag in output""" + self.directory.home = 'home' + self.directory.version = '0.1' + output_dic = {'meta': {'home': 'home', 'author': 'grindsa ', 'name': 'acme2certifier', 'version': '0.1'}} + self.assertTrue(output_dic.items() <= self.directory.directory_get().items()) + + def test_014_directory_directory_get(self): + """ test Directory.get_directory() method and check for "meta" tag in output""" + self.directory.home = 'home' + self.directory.version = '0.1' + output_dic = {'home': 'home', 'author': 'grindsa ', 'name': 'acme2certifier', 'version': '0.1'} + self.assertEqual(output_dic, self.directory.directory_get()['meta']) + + def test_015_directory_directory_get(self): + """ test Directory.get_directory() method and check for "meta" tag in output""" + self.directory.home = 'home' + self.directory.version = '0.1' + self.directory.suppress_product_information = True + output_dic = {'home': 'home'} + self.assertEqual(output_dic, self.directory.directory_get()['meta']) + + def test_016_directory_directory_get(self): + """ test Directory.get_directory() method and check for "meta" tag in output""" + self.directory.suppress_product_information = True + output_dic = {} + self.assertEqual(output_dic, self.directory.directory_get()['meta']) + + def test_017_directory_directory_get(self): + """ test Directory.get_directory() method and check for "meta" tag in output""" + self.directory.suppress_product_information = False + self.directory.version = '0.1' + output_dic = {'home': 'https://github.com/grindsa/acme2certifier', 'author': 'grindsa ', 'name': 'acme2certifier', 'version': '0.1'} + self.assertEqual(output_dic, self.directory.directory_get()['meta']) + @patch('acme_srv.directory.load_config') - def test_013_config_load(self, mock_load_cfg): + def test_018_config_load(self, mock_load_cfg): """ test _config_load empty config """ parser = configparser.ConfigParser() # parser['Account'] = {'foo': 'bar'} @@ -135,7 +170,7 @@ def test_013_config_load(self, mock_load_cfg): self.assertFalse(self.directory.db_check) @patch('acme_srv.directory.load_config') - def test_014_config_load(self, mock_load_cfg): + def test_019_config_load(self, mock_load_cfg): """ test _config_load with unknown values config """ parser = configparser.ConfigParser() parser['Account'] = {'foo': 'bar'} @@ -147,7 +182,7 @@ def test_014_config_load(self, mock_load_cfg): self.assertFalse(self.directory.db_check) @patch('acme_srv.directory.load_config') - def test_015_config_load(self, mock_load_cfg): + def test_020_config_load(self, mock_load_cfg): """ test _config_load with unknown values config """ parser = configparser.ConfigParser() parser['Directory'] = {'foo': 'bar'} @@ -159,7 +194,7 @@ def test_015_config_load(self, mock_load_cfg): self.assertFalse(self.directory.db_check) @patch('acme_srv.directory.load_config') - def test_016_config_load(self, mock_load_cfg): + def test_021_config_load(self, mock_load_cfg): """ test _config_load supress version number """ parser = configparser.ConfigParser() parser['Directory'] = {'supress_version': True} @@ -171,7 +206,7 @@ def test_016_config_load(self, mock_load_cfg): self.assertFalse(self.directory.db_check) @patch('acme_srv.directory.load_config') - def test_017_config_load(self, mock_load_cfg): + def test_022_config_load(self, mock_load_cfg): """ test _config_load tos url """ parser = configparser.ConfigParser() parser['Directory'] = {'tos_url': 'tos_url'} @@ -183,7 +218,7 @@ def test_017_config_load(self, mock_load_cfg): self.assertFalse(self.directory.db_check) @patch('acme_srv.directory.load_config') - def test_018_config_load(self, mock_load_cfg): + def test_023_config_load(self, mock_load_cfg): """ test _config_load eab """ parser = configparser.ConfigParser() parser['EABhandler'] = {'eab_handler_file': 'eab_handler_file'} @@ -197,7 +232,7 @@ def test_018_config_load(self, mock_load_cfg): self.assertFalse(self.directory.db_check) @patch('acme_srv.directory.load_config') - def test_019_config_load(self, mock_load_cfg): + def test_024_config_load(self, mock_load_cfg): """ test _config_load all parameters set """ parser = configparser.ConfigParser() parser['EABhandler'] = {'eab_handler_file': 'eab_handler_file'} @@ -210,7 +245,7 @@ def test_019_config_load(self, mock_load_cfg): self.assertFalse(self.directory.db_check) @patch('acme_srv.directory.load_config') - def test_020_config_load(self, mock_load_cfg): + def test_025_config_load(self, mock_load_cfg): """ test _config_load eab """ parser = configparser.ConfigParser() parser['Directory'] = {'url_prefix': 'url_prefix'} @@ -223,7 +258,7 @@ def test_020_config_load(self, mock_load_cfg): self.assertFalse(self.directory.db_check) @patch('acme_srv.directory.load_config') - def test_021_config_load(self, mock_load_cfg): + def test_026_config_load(self, mock_load_cfg): """ test _config_load eab """ parser = configparser.ConfigParser() parser['Directory'] = {'db_check': True} @@ -233,9 +268,10 @@ def test_021_config_load(self, mock_load_cfg): self.assertFalse(self.directory.tos_url) self.assertFalse(self.directory.eab) self.assertTrue(self.directory.db_check) + self.assertEqual(False, self.directory.suppress_product_information) @patch('acme_srv.directory.load_config') - def test_022_config_load(self, mock_load_cfg): + def test_027_config_load(self, mock_load_cfg): """ test _config_load eab """ parser = configparser.ConfigParser() parser['Directory'] = {'db_check': False} @@ -245,9 +281,66 @@ def test_022_config_load(self, mock_load_cfg): self.assertFalse(self.directory.tos_url) self.assertFalse(self.directory.eab) self.assertFalse(self.directory.db_check) + self.assertEqual('https://github.com/grindsa/acme2certifier', self.directory.home) + self.assertEqual(False, self.directory.suppress_product_information) + + @patch('acme_srv.directory.load_config') + def test_028_config_load(self, mock_load_cfg): + """ test _config_load eab """ + parser = configparser.ConfigParser() + parser['Directory'] = {'home': 'home'} + mock_load_cfg.return_value = parser + self.directory._config_load() + self.assertFalse(self.directory.supress_version) + self.assertFalse(self.directory.tos_url) + self.assertFalse(self.directory.eab) + self.assertFalse(self.directory.db_check) + self.assertEqual('home', self.directory.home) + self.assertEqual(False, self.directory.suppress_product_information) + + @patch('acme_srv.directory.load_config') + def test_029_config_load(self, mock_load_cfg): + """ test _config_load eab """ + parser = configparser.ConfigParser() + parser['Directory'] = {'suppress_product_information': True} + mock_load_cfg.return_value = parser + self.directory._config_load() + self.assertFalse(self.directory.supress_version) + self.assertFalse(self.directory.tos_url) + self.assertFalse(self.directory.eab) + self.assertFalse(self.directory.db_check) + self.assertEqual(True, self.directory.suppress_product_information) + + @patch('acme_srv.directory.load_config') + def test_030_config_load(self, mock_load_cfg): + """ test _config_load eab """ + parser = configparser.ConfigParser() + parser['Directory'] = {'suppress_product_information': False} + mock_load_cfg.return_value = parser + self.directory._config_load() + self.assertFalse(self.directory.supress_version) + self.assertFalse(self.directory.tos_url) + self.assertFalse(self.directory.eab) + self.assertFalse(self.directory.db_check) + self.assertEqual(False, self.directory.suppress_product_information) + + @patch('acme_srv.directory.load_config') + def test_031_config_load(self, mock_load_cfg): + """ test _config_load eab """ + parser = configparser.ConfigParser() + parser['Directory'] = {'suppress_product_information': 'aa'} + mock_load_cfg.return_value = parser + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.directory._config_load() + self.assertFalse(self.directory.supress_version) + self.assertFalse(self.directory.tos_url) + self.assertFalse(self.directory.eab) + self.assertFalse(self.directory.db_check) + self.assertEqual(False, self.directory.suppress_product_information) + self.assertIn('ERROR:test_a2c:Directory._config_load() suppress_product_information not set: Not a boolean: aa', lcm.output) @patch('acme_srv.directory.Directory._config_load') - def test_023__enter__(self, mock_cfg): + def test_032__enter__(self, mock_cfg): """ test enter """ mock_cfg.return_value = True self.directory.__enter__() diff --git a/test/test_wsgi_acme2certifier.py b/test/test_wsgi_acme2certifier.py index 38a80ee6..65a5cec0 100644 --- a/test/test_wsgi_acme2certifier.py +++ b/test/test_wsgi_acme2certifier.py @@ -586,6 +586,7 @@ def test_051_application(self): environ = {'REQUEST_METHOD': 'UNK', 'REMOTE_ADDR': 'REMOTE_ADDR', 'PATH_INFO': 'url_prefix/directory'} result_expected = {"newAuthz": "http://localhost/acme/new-authz", "newNonce": "http://localhost/acme/newnonce", "newAccount": "http://localhost/acme/newaccount", "newOrder": "http://localhost/acme/neworders", "revokeCert": "http://localhost/acme/revokecert", "keyChange": "http://localhost/acme/key-change", "meta": {"home": "https://github.com/grindsa/acme2certifier", "author": "grindsa ", "name": "acme2certifier"}} result_func = json.loads(self.application(environ, Mock())[0]) + print(result_func) del(result_func['meta']['version']) self.assertTrue(result_expected['meta'].items() <= result_func['meta'].items()) self.assertEqual(result_expected['newAuthz'], result_func['newAuthz']) From 2a44e1218bf26dfbc54619b2d6ed1a081ee73f7b Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 23 Mar 2024 07:30:10 +0100 Subject: [PATCH 128/460] [fix] linting --- acme_srv/directory.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/acme_srv/directory.py b/acme_srv/directory.py index 8d6bcc20..914e7f49 100644 --- a/acme_srv/directory.py +++ b/acme_srv/directory.py @@ -53,7 +53,7 @@ def _config_load(self): self.home = config_dic.get('Directory', 'home', fallback='https://github.com/grindsa/acme2certifier') try: - self.suppress_product_information = config_dic.getboolean('Directory', 'suppress_product_information', fallback= False) + self.suppress_product_information = config_dic.getboolean('Directory', 'suppress_product_information', fallback=False) except Exception as err_: self.logger.error('Directory._config_load() suppress_product_information not set: %s', err_) @@ -87,7 +87,6 @@ def directory_get(self) -> Dict[str, str]: if self.home != 'https://github.com/grindsa/acme2certifier': d_dic['meta']['home'] = self.home - # add terms of service if self.tos_url: d_dic['meta']['termsOfService'] = self.tos_url From 27d6d1909600647d21d960903f7c4bba75b1960a Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 23 Mar 2024 08:26:22 +0100 Subject: [PATCH 129/460] [fix] nclm_handler workflow --- .github/workflows/ca_handler_tests_nclm.yml | 8 +++++--- examples/ca_handler/nclm_ca_handler.py | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ca_handler_tests_nclm.yml b/.github/workflows/ca_handler_tests_nclm.yml index a554e51e..9ca5adfb 100644 --- a/.github/workflows/ca_handler_tests_nclm.yml +++ b/.github/workflows/ca_handler_tests_nclm.yml @@ -58,7 +58,8 @@ jobs: sudo echo "tsg_name: $NCLM_TSG_NAME" >> examples/Docker/data/acme_srv.cfg sudo echo "ca_name: $NCLM_CA_NAME" >> examples/Docker/data/acme_srv.cfg sudo echo "ca_id_list: [$NCLM_CA_ID_LIST]" >> examples/Docker/data/acme_srv.cfg - sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout: 45/g" examples/Docker/data/acme_srv.cfg + sudo echo "request_timeout: 40" >> examples/Docker/data/acme_srv.cfg + sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout: 40/g" examples/Docker/data/acme_srv.cfg cd examples/Docker/ docker-compose restart docker-compose logs @@ -152,7 +153,7 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: nclm.tar.gz + name: nclm_handler_tests-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ @@ -221,7 +222,8 @@ jobs: sudo echo "tsg_name: $NCLM_TSG_NAME" >> data/acme_srv.cfg sudo echo "ca_name: $NCLM_CA_NAME" >> data/acme_srv.cfg sudo echo "ca_id_list: [$NCLM_CA_ID_LIST]" >> data/acme_srv.cfg - sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout: 30/g" data/acme_srv.cfg + sudo echo "request_timeout: 40" >> data/acme_srv.cfg + sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout: 60/g" data/acme_srv.cfg env: NCLM_API_HOST: ${{ secrets.NCLM_API_HOST }} diff --git a/examples/ca_handler/nclm_ca_handler.py b/examples/ca_handler/nclm_ca_handler.py index dfe7ebb5..e28947ed 100644 --- a/examples/ca_handler/nclm_ca_handler.py +++ b/examples/ca_handler/nclm_ca_handler.py @@ -198,9 +198,9 @@ def _cert_list_lookup(self, csr_cn: str) -> Dict[str, str]: try: if csr_cn: - url = self.api_host + '/certificates?freeText==' + str(csr_cn) + '&stateCurrent=false&stateHistory=false&stateWaiting=false&stateManual=false&stateUnattached=false&expiresAfter=%22%22&expiresBefore=%22%22&sortAttribute=createdAt&sortOrder=desc&containerId=' + str(self.tsg_info_dic['id']) + url = self.api_host + '/certificates?freeText==' + str(csr_cn) + '&stateCurrent=false&stateHistory=false&stateWaiting=false&stateManual=false&stateUnattached=false&expiresAfter=%22%22&expiresBefore=%22%22&sortAttribute=createdAt&limit=500&sortOrder=desc&containerId=' + str(self.tsg_info_dic['id']) else: - url = self.api_host + '/certificates?stateCurrent=false&stateHistory=false&stateWaiting=false&stateManual=false&stateUnattached=false&expiresAfter=%22%22&expiresBefore=%22%22&sortAttribute=createdAt&sortOrder=desc&containerId=' + str(self.tsg_info_dic['id']) + url = self.api_host + '/certificates?stateCurrent=false&stateHistory=false&stateWaiting=false&stateManual=false&stateUnattached=false&expiresAfter=%22%22&expiresBefore=%22%22&sortAttribute=createdAt&limit=500&sortOrder=desc&containerId=' + str(self.tsg_info_dic['id']) cert_list = self._cert_list_fetch(url) except Exception as err_: self.logger.error('CAhandler._cert_id_lookup() returned error: %s', str(err_)) From b912e38b99030b4ef7e7787da54630340e154bfe Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 23 Mar 2024 08:52:48 +0100 Subject: [PATCH 130/460] [fix] msca_handler --- .github/workflows/ca_handler_tests_msca.yml | 34 +++++++++++++-------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ca_handler_tests_msca.yml b/.github/workflows/ca_handler_tests_msca.yml index d393d7fb..3e5c62d9 100644 --- a/.github/workflows/ca_handler_tests_msca.yml +++ b/.github/workflows/ca_handler_tests_msca.yml @@ -101,6 +101,7 @@ jobs: sudo echo "ca_name: $WCCE_CA_NAME" >> examples/Docker/data/acme_srv.cfg sudo echo "target_domain: $WCCE_ADS_DOMAIN" >> examples/Docker/data/acme_srv.cfg sudo echo "ca_bundle: volume/ca_certs.pem" >> examples/Docker/data/acme_srv.cfg + sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout: 40/g" examples/Docker/data/acme_srv.cfg cd examples/Docker/ docker-compose restart docker-compose logs @@ -137,13 +138,14 @@ jobs: KNOWN_HOSTS: ${{ secrets.WCCE_SSH_KNOWN_HOSTS }} - name: "Establish SSH connection" - run: sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -p $SSH_PORT -o UserKnownHostsFile=/tmp/rd/known_hosts -L 445:$WCCE_HOST:445 -L 88:$WCCE_HOST:88 -L 443:$WES_IP:443 -g ping -c 300 $WCCE_HOST & + run: sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -p $SSH_PORT -o UserKnownHostsFile=/tmp/rd/known_hosts -L 445:$WCCE_HOST:445 -L 88:$WCCE_HOST:88 -L 443:$WES_IP:443 -g ping -c 300 $CMP_HOST & env: SSH_USER: ${{ secrets.WCCE_SSH_USER }} SSH_HOST: ${{ secrets.WCCE_SSH_HOST }} SSH_PORT: ${{ secrets.WCCE_SSH_PORT }} WCCE_HOST: ${{ secrets.WCCE_HOST }} WES_IP: ${{ secrets.WES_IP }} + CMP_HOST: ${{ secrets.CMP_HOST }} - name: "Sleep for 5s" uses: juliangruber/sleep-action@v2.0.3 @@ -191,6 +193,7 @@ jobs: sudo echo "domain_controller: $RUNNER_IP" >> examples/Docker/data/acme_srv.cfg sudo echo "ca_bundle: volume/ca_certs.pem" >> examples/Docker/data/acme_srv.cfg sudo echo "use_kerberos: True" >> examples/Docker/data/acme_srv.cfg + sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout: 40/g" examples/Docker/data/acme_srv.cfg cd examples/Docker/ docker-compose restart docker-compose logs @@ -255,6 +258,8 @@ jobs: sudo echo "template: $WES_TEMPLATE" >> examples/Docker/data/acme_srv.cfg sudo echo "ca_bundle: volume/ca_certs.pem" >> examples/Docker/data/acme_srv.cfg sudo echo "WCCE_HOST: $WCCE_HOST" >> examples/Docker/data/acme_srv.cfg + sudo echo "request_timeout: 30" >> examples/Docker/data/acme_srv.cfg + sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout: 40/g" examples/Docker/data/acme_srv.cfg cd examples/Docker/ docker-compose restart docker-compose logs @@ -277,11 +282,6 @@ jobs: - name: "Test if https://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - #- name: "Enroll acme.sh" - # run: | - # docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force - # openssl verify -CAfile examples/Docker/data/ca_certs.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "Register certbot" run: | sudo rm -rf certbot/ @@ -297,6 +297,11 @@ jobs: docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run sudo openssl verify -CAfile examples/Docker/data/ca_certs.pem lego/certificates/lego.acme.crt + - name: "Enroll acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force + openssl verify -CAfile examples/Docker/data/ca_certs.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | @@ -424,6 +429,7 @@ jobs: sudo echo "ca_name: $WCCE_CA_NAME" >> data/acme_srv.cfg sudo echo "target_domain: $WCCE_ADS_DOMAIN" >> data/acme_srv.cfg sudo echo "ca_bundle: /opt/acme2certifier/volume/acme_ca/ca_certs.pem" >> data/acme_srv.cfg + sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout: 40/g" data/acme_srv.cfg env: RUNNER_IP: ${{ env.RUNNER_IP }} WCCE_USER: ${{ secrets.WCCE_USER }} @@ -474,13 +480,14 @@ jobs: KNOWN_HOSTS: ${{ secrets.WCCE_SSH_KNOWN_HOSTS }} - name: "Establish SSH connection" - run: sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -p $SSH_PORT -o UserKnownHostsFile=/tmp/rd/known_hosts -L 445:$WCCE_HOST:445 -L 88:$WCCE_HOST:88 -L 443:$WES_IP:443 -g ping -c 300 $WCCE_HOST & + run: sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -p $SSH_PORT -o UserKnownHostsFile=/tmp/rd/known_hosts -L 445:$WCCE_HOST:445 -L 88:$WCCE_HOST:88 -L 443:$WES_IP:443 -g ping -c 300 $CMP_HOST & env: SSH_USER: ${{ secrets.WCCE_SSH_USER }} SSH_HOST: ${{ secrets.WCCE_SSH_HOST }} SSH_PORT: ${{ secrets.WCCE_SSH_PORT }} WCCE_HOST: ${{ secrets.WCCE_HOST }} WES_IP: ${{ secrets.WES_IP }} + CMP_HOST: ${{ secrets.CMP_HOST }} - name: "Sleep for 5s" uses: juliangruber/sleep-action@v2.0.3 @@ -525,6 +532,7 @@ jobs: sudo echo "domain_controller: $RUNNER_IP" >> data/acme_srv.cfg sudo echo "ca_bundle: /opt/acme2certifier/volume/acme_ca/ca_certs.pem" >> data/acme_srv.cfg sudo echo "use_kerberos: True" >> data/acme_srv.cfg + sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout: 40/g" data/acme_srv.cfg env: RUNNER_IP: ${{ env.RUNNER_IP }} WCCE_USER: ${{ secrets.WCCE_USER }} @@ -581,6 +589,8 @@ jobs: sudo echo "auth_method: $WES_AUTHMETHOD" >> data/acme_srv.cfg sudo echo "template: $WES_TEMPLATE" >> data/acme_srv.cfg sudo echo "ca_bundle: volume/acme_ca/ca_certs.pem" >> data/acme_srv.cfg + sudo echo "request_timeout: 30" >> data/acme_srv.cfg + sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout: 40/g" data/acme_srv.cfg env: WES_HOST: ${{ secrets.WES_HOST }} WES_USER: ${{ secrets.WES_USER }} @@ -600,11 +610,6 @@ jobs: - name: "Test http://acme-srv/directory is accessable " run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - #- name: "Enroll acme.sh" - # run: | - # docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force - # openssl verify -CAfile data/acme_ca/ca_certs.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "Register certbot" run: | sudo rm -rf certbot/* @@ -620,6 +625,11 @@ jobs: docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run sudo openssl verify -CAfile data/acme_ca/ca_certs.pem lego/certificates/lego.acme.crt + - name: "Enroll acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force + openssl verify -CAfile data/acme_ca/ca_certs.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | From bc4cd7d2cda486576659493bff2023d924bf70da Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 23 Mar 2024 08:58:41 +0100 Subject: [PATCH 131/460] [fix] time adjustment in async wf --- .github/workflows/enrollment-timeout.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/enrollment-timeout.yml b/.github/workflows/enrollment-timeout.yml index 4c112ed0..2d7cb2f0 100644 --- a/.github/workflows/enrollment-timeout.yml +++ b/.github/workflows/enrollment-timeout.yml @@ -198,8 +198,8 @@ jobs: sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem data/acme_ca/ sudo cp .github/openssl_ca_handler.py_acme_srv_choosen_handler.cfg data/acme_srv.cfg sudo chmod 777 data/acme_srv.cfg - sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\\ncert_reusage_timeframe: 1800/g" data/acme_srv.cfg - sudo sed -i "s/retry_after_timeout: 15/retry_after_timeout: 30\\nenrollment_timeout: 15/g" data/acme_srv.cfg + sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\\ncert_reusage_timeframe: 1800\\nenrollment_timeout: 15/g" data/acme_srv.cfg + # sudo sed -i "s/retry_after_timeout: 15/retry_after_timeout: 30\\nenrollment_timeout: 15/g" data/acme_srv.cfg sudo sed -i "s/handler_file: examples\/ca_handler\/openssl_ca_handler.py/handler_file: \/opt\/acme2certifier\/volume\/acme_ca\/ca_handler.py/g" data/acme_srv.cfg - name: "[ PREPARE ] Almalinux instance" @@ -358,8 +358,8 @@ jobs: sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem data/volume/acme_ca/ sudo cp .github/openssl_ca_handler.py_acme_srv_choosen_handler.cfg data/volume/acme_srv.cfg sudo chmod 777 data/volume/acme_srv.cfg - sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\\ncert_reusage_timeframe: 1800/g" data/volume/acme_srv.cfg - sudo sed -i "s/retry_after_timeout: 15/retry_after_timeout: 30\\nenrollment_timeout: 15/g" data/volume/acme_srv.cfg + sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\\ncert_reusage_timeframe: 1800\\nenrollment_timeout: 15/g" data/volume/acme_srv.cfg + # sudo sed -i "s/retry_after_timeout: 15/retry_after_timeout: 30\\nenrollment_timeout: 15/g" data/volume/acme_srv.cfg sudo sed -i "s/handler_file: examples\/ca_handler\/openssl_ca_handler.py/handler_file: \/opt\/acme2certifier\/volume\/acme_ca\/ca_handler.py/g" data/volume/acme_srv.cfg - name: "[ PREPARE ] Almalinux instance" From 28a53ae3b6677bb0512f4c0c32539d64c8bbf75e Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 23 Mar 2024 09:07:48 +0100 Subject: [PATCH 132/460] [fix] sleep timer in est hander workflow --- .github/workflows/ca_handler_tests_est.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/ca_handler_tests_est.yml b/.github/workflows/ca_handler_tests_est.yml index 85a9fbe8..e1dfbd61 100644 --- a/.github/workflows/ca_handler_tests_est.yml +++ b/.github/workflows/ca_handler_tests_est.yml @@ -93,6 +93,11 @@ jobs: run: | docker run -i -v $PWD/lego/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + - name: "Enroll acme-sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force @@ -213,6 +218,11 @@ jobs: docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force # openssl verify -CAfile data/acme_ca/ca_bundle.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + - name: "Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run From af7d2203add423badcf7ca8faa2bc208edd35e95 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 23 Mar 2024 17:33:11 +0100 Subject: [PATCH 133/460] [wf] max-parallel: 1 in some matrix workflows --- .github/workflows/ca_handler_tests_cmp.yml | 1 + .github/workflows/ca_handler_tests_est.yml | 2 ++ .github/workflows/ca_handler_tests_msca.yml | 5 +++++ .github/workflows/enrollment-timeout.yml | 3 +++ 4 files changed, 11 insertions(+) diff --git a/.github/workflows/ca_handler_tests_cmp.yml b/.github/workflows/ca_handler_tests_cmp.yml index 42c92ac5..27bf001e 100644 --- a/.github/workflows/ca_handler_tests_cmp.yml +++ b/.github/workflows/ca_handler_tests_cmp.yml @@ -13,6 +13,7 @@ jobs: name: "cmp_handler_tests" runs-on: ubuntu-latest strategy: + max-parallel: 1 fail-fast: false matrix: websrv: ['apache2', 'nginx'] diff --git a/.github/workflows/ca_handler_tests_est.yml b/.github/workflows/ca_handler_tests_est.yml index e1dfbd61..6436251d 100644 --- a/.github/workflows/ca_handler_tests_est.yml +++ b/.github/workflows/ca_handler_tests_est.yml @@ -14,6 +14,7 @@ jobs: name: "est_handler_tests" runs-on: ubuntu-latest strategy: + max-parallel: 1 fail-fast: false matrix: websrv: ['apache2', 'nginx'] @@ -122,6 +123,7 @@ jobs: name: "est_handler_tests_rpm" runs-on: ubuntu-latest strategy: + max-parallel: 1 fail-fast: false matrix: rhversion: [8, 9] diff --git a/.github/workflows/ca_handler_tests_msca.yml b/.github/workflows/ca_handler_tests_msca.yml index 3e5c62d9..44f20d66 100644 --- a/.github/workflows/ca_handler_tests_msca.yml +++ b/.github/workflows/ca_handler_tests_msca.yml @@ -14,6 +14,7 @@ jobs: runs-on: ubuntu-latest strategy: fail-fast: false + max-parallel: 1 matrix: websrv: ['apache2', 'nginx'] dbhandler: ['wsgi', 'django'] @@ -101,6 +102,7 @@ jobs: sudo echo "ca_name: $WCCE_CA_NAME" >> examples/Docker/data/acme_srv.cfg sudo echo "target_domain: $WCCE_ADS_DOMAIN" >> examples/Docker/data/acme_srv.cfg sudo echo "ca_bundle: volume/ca_certs.pem" >> examples/Docker/data/acme_srv.cfg + sudo echo "ssh_host: $SSH_HOST:$SSH_PORT" >> examples/Docker/data/acme_srv.cfg sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout: 40/g" examples/Docker/data/acme_srv.cfg cd examples/Docker/ docker-compose restart @@ -114,6 +116,8 @@ jobs: WCCE_ADS_DOMAIN: ${{ secrets.WCCE_ADS_DOMAIN }} WCCE_CA_BUNDLE: ${{ secrets.WCCE_CA_BUNDLE }} WCCE_HOST: ${{ secrets.WCCE_HOST }} + SSH_HOST: ${{ secrets.WCCE_SSH_HOST }} + SSH_PORT: ${{ secrets.WCCE_SSH_PORT }} - name: "Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 @@ -326,6 +330,7 @@ jobs: name: "msca_handler_tests_rpm" runs-on: ubuntu-latest strategy: + max-parallel: 1 fail-fast: false matrix: rhversion: [8, 9] diff --git a/.github/workflows/enrollment-timeout.yml b/.github/workflows/enrollment-timeout.yml index 2d7cb2f0..e20789c0 100644 --- a/.github/workflows/enrollment-timeout.yml +++ b/.github/workflows/enrollment-timeout.yml @@ -13,6 +13,7 @@ jobs: name: async_enrollment_cert_reusage runs-on: ubuntu-latest strategy: + max-parallel: 1 fail-fast: false matrix: websrv: ['apache2', 'nginx'] @@ -140,6 +141,7 @@ jobs: name: "rpm_wsgi_async_enrollment_cert_reusage" runs-on: ubuntu-latest strategy: + max-parallel: 1 fail-fast: false matrix: rhversion: [8, 9] @@ -257,6 +259,7 @@ jobs: name: "rpm_django_async_enrollment_cert_reusage" runs-on: ubuntu-latest strategy: + max-parallel: 1 fail-fast: false matrix: rhversion: [8, 9] From 94179e9babefcbba966800ecd6fbd9a7fc041749 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 23 Mar 2024 18:17:24 +0100 Subject: [PATCH 134/460] [wf] max-parallel: 1 in asa_ca_handler workflow --- .github/workflows/ca_handler_tests_asa.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ca_handler_tests_asa.yml b/.github/workflows/ca_handler_tests_asa.yml index fd58159d..67bd3ad9 100644 --- a/.github/workflows/ca_handler_tests_asa.yml +++ b/.github/workflows/ca_handler_tests_asa.yml @@ -13,6 +13,7 @@ jobs: name: "asa_handler_tests" runs-on: ubuntu-latest strategy: + max-parallel: 1 fail-fast: false matrix: websrv: ['apache2', 'nginx'] @@ -219,6 +220,7 @@ jobs: name: "asa_handler_tests_rpm" runs-on: ubuntu-latest strategy: + max-parallel: 1 fail-fast: false matrix: rhversion: [8, 9] From 8be525fe3df7e85131c5829bb2488b1805ea0aee Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 23 Mar 2024 18:50:35 +0100 Subject: [PATCH 135/460] [fix] validate_fqd - allow wildcard domains --- acme_srv/helper.py | 7 +++++++ test/test_helper.py | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/acme_srv/helper.py b/acme_srv/helper.py index 5cd78111..0d7dbacd 100644 --- a/acme_srv/helper.py +++ b/acme_srv/helper.py @@ -1301,6 +1301,13 @@ def validate_fqdn(logger: logging.Logger, fqdn: str) -> bool: if re.search(p, fqdn): result = True + if not result: + logger.debug('validate_fqdn(): invalid fqdn. Check for wildcard : %s', fqdn) + regex = r"^\*\.[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$" + p = re.compile(regex) + if re.search(p, fqdn): + result = True + logger.debug('validate_fqdn() ended with: %s', result) return result diff --git a/test/test_helper.py b/test/test_helper.py index f078a9bc..85adb9a1 100644 --- a/test/test_helper.py +++ b/test/test_helper.py @@ -2226,6 +2226,10 @@ def test_293_validate_fqdn(self): """ test validate_fqdn() """ self.assertFalse(self.validate_fqdn(self.logger, 'foo@bar.local')) + def test_294_validate_fqdn(self): + """ test validate_fqdn() """ + self.assertTrue(self.validate_fqdn(self.logger, '*.bar.local')) + def test_294_validate_ip(self): """ test validate_ip() """ self.assertTrue(self.validate_ip(self.logger, '10.0.0.1')) From 25c22934820d268dbdd9fd6bc0acfdae83a1c14e Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 23 Mar 2024 19:21:15 +0100 Subject: [PATCH 136/460] [wf] fix upgrade tests --- .github/workflows/upgrade_tests..yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/upgrade_tests..yml b/.github/workflows/upgrade_tests..yml index 9e376be9..4137c577 100644 --- a/.github/workflows/upgrade_tests..yml +++ b/.github/workflows/upgrade_tests..yml @@ -713,6 +713,7 @@ jobs: docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier docker exec acme-srv tar cvfz /tmp/acme2certifier/nginx.tgz /etc/nginx sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh @@ -896,6 +897,7 @@ jobs: docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier docker exec acme-srv tar cvfz /tmp/acme2certifier/nginx.tgz /etc/nginx sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh @@ -1061,6 +1063,7 @@ jobs: docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier docker exec acme-srv tar cvfz /tmp/acme2certifier/nginx.tgz /etc/nginx sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh @@ -1254,6 +1257,7 @@ jobs: docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier docker exec acme-srv tar cvfz /tmp/acme2certifier/nginx.tgz /etc/nginx sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh From 94d6125486bf171133727bc16f3752decb368694 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 23 Mar 2024 19:56:44 +0100 Subject: [PATCH 137/460] [fix] upgrade tests --- .github/workflows/upgrade_tests..yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/upgrade_tests..yml b/.github/workflows/upgrade_tests..yml index 4137c577..a2f0e9ea 100644 --- a/.github/workflows/upgrade_tests..yml +++ b/.github/workflows/upgrade_tests..yml @@ -602,6 +602,8 @@ jobs: sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data sudo cp .github/acme2certifier_cert.pem data/nginx/acme2certifier_cert.pem sudo cp .github/acme2certifier_key.pem data/nginx/acme2certifier_key.pem + sudo cp examples/nginx/nginx_acme_srv.conf data/nginx/conf.d + sudo sed -i "s/\/var\/www\/acme2certifier\/volume/\/etc\/nginx/g" data/nginx/conf.d/nginx_acme_srv.conf sudo cp examples/nginx/nginx_acme_srv_ssl.conf data/nginx/conf.d sudo sed -i "s/\/var\/www\/acme2certifier\/volume/\/etc\/nginx/g" data/nginx/conf.d/nginx_acme_srv_ssl.conf @@ -770,6 +772,8 @@ jobs: sudo cp .github/django_settings_mariadb.py data/acme2certifier/settings.py # sudo sed -i "s/\/var\/www\//\/opt\//g" data/acme2certifier/settings.py sudo sed -i "s/USE_I18N = True/USE_I18N = False/g" data/acme2certifier/settings.py + sudo cp examples/nginx/nginx_acme_srv.conf data/nginx/conf.d + sudo sed -i "s/\/var\/www\/acme2certifier\/volume/\/etc\/nginx/g" data/nginx/conf.d/nginx_acme_srv.conf sudo cp examples/nginx/nginx_acme_srv_ssl.conf data/nginx/conf.d sudo sed -i "s/\/var\/www\/acme2certifier\/volume/\/etc\/nginx/g" data/nginx/conf.d/nginx_acme_srv_ssl.conf @@ -954,6 +958,8 @@ jobs: sudo cp .github/django_settings.py data/acme2certifier/settings.py sudo sed -i "s/\/var\/www\//\/opt\//g" data/acme2certifier/settings.py sudo sed -i "s/USE_I18N = True/USE_I18N = False/g" data/acme2certifier/settings.py + sudo cp examples/nginx/nginx_acme_srv.conf data/nginx/conf.d + sudo sed -i "s/\/var\/www\/acme2certifier\/volume/\/etc\/nginx/g" data/nginx/conf.d/nginx_acme_srv.conf sudo cp examples/nginx/nginx_acme_srv_ssl.conf data/nginx/conf.d sudo sed -i "s/\/var\/www\/acme2certifier\/volume/\/etc\/nginx/g" data/nginx/conf.d/nginx_acme_srv_ssl.conf @@ -1120,10 +1126,11 @@ jobs: sudo cp .github/django_settings_psql.py data/acme2certifier/settings.py # sudo sed -i "s/\/var\/www\//\/opt\//g" data/acme2certifier/settings.py sudo sed -i "s/USE_I18N = True/USE_I18N = False/g" data/acme2certifier/settings.py + sudo cp examples/nginx/nginx_acme_srv.conf data/nginx/conf.d + sudo sed -i "s/\/var\/www\/acme2certifier\/volume/\/etc\/nginx/g" data/nginx/conf.d/nginx_acme_srv.conf sudo cp examples/nginx/nginx_acme_srv_ssl.conf data/nginx/conf.d sudo sed -i "s/\/var\/www\/acme2certifier\/volume/\/etc\/nginx/g" data/nginx/conf.d/nginx_acme_srv_ssl.conf - - name: "[ PREPARE ] postgres environment" run: | sudo mkdir -p /tmp/data/pgsql From 75928f4f9a5338ac339d4bd1ca5a752defe78c9e Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 24 Mar 2024 05:09:01 +0100 Subject: [PATCH 138/460] [wf] removed comment in hooks.yml --- .github/workflows/hooks-test.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/hooks-test.yml b/.github/workflows/hooks-test.yml index 78d71457..74eda6aa 100644 --- a/.github/workflows/hooks-test.yml +++ b/.github/workflows/hooks-test.yml @@ -5,7 +5,6 @@ on: pull_request: branches: [ devel ] schedule: - # * is a special character in YAML so you have to quote this string - cron: '0 2 * * 6' jobs: From 60eb332f68de32e962f8382e17efe44ccbb41e63 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 24 Mar 2024 06:37:20 +0100 Subject: [PATCH 139/460] [feat] headerinfo support in mscertserv_ca_handler.py --- examples/ca_handler/mscertsrv_ca_handler.py | 41 +++++++++++- test/test_msca_handler.py | 72 ++++++++++++++++++++- 2 files changed, 111 insertions(+), 2 deletions(-) diff --git a/examples/ca_handler/mscertsrv_ca_handler.py b/examples/ca_handler/mscertsrv_ca_handler.py index 9378098c..01078241 100644 --- a/examples/ca_handler/mscertsrv_ca_handler.py +++ b/examples/ca_handler/mscertsrv_ca_handler.py @@ -9,7 +9,7 @@ from cryptography.hazmat.primitives.serialization.pkcs7 import load_pem_pkcs7_certificates, load_der_pkcs7_certificates # pylint: disable=e0401, e0611 from examples.ca_handler.certsrv import Certsrv -from acme_srv.helper import load_config, b64_url_recode, convert_byte_to_string, proxy_check, convert_string_to_byte +from acme_srv.helper import load_config, b64_url_recode, convert_byte_to_string, proxy_check, convert_string_to_byte, header_info_get class CAhandler(object): @@ -24,6 +24,7 @@ def __init__(self, _debug: bool = False, logger: object = None): self.ca_bundle = False self.template = None self.proxy = None + self.header_info_field = False def __enter__(self): """ Makes CAhandler a Context Manager """ @@ -59,6 +60,18 @@ def _cert_bundle_create(self, ca_pem: str = None, cert_raw: str = None) -> Tuple return (error, cert_bundle, cert_raw) + def _config_headerinfo_get(self, config_dic: Dict[str, str]): + """ load parameters """ + self.logger.debug('_config_header_info()') + + if 'Order' in config_dic and 'header_info_list' in config_dic['Order'] and config_dic['Order']['header_info_list']: + try: + self.header_info_field = json.loads(config_dic['Order']['header_info_list'])[0] + except Exception as err_: + self.logger.warning('Order._config_orderconfig_load() header_info_list failed with error: %s', err_) + + self.logger.debug('_config_header_info() ended') + def _config_user_load(self, config_dic: Dict[str, str]): """ load username """ self.logger.debug('CAhandler._config_user_load()') @@ -146,6 +159,7 @@ def _config_load(self): self._config_user_load(config_dic) self._config_password_load(config_dic) self._config_parameters_load(config_dic) + self._config_headerinfo_get(config_dic) # load proxy config self._config_proxy_load(config_dic) @@ -177,6 +191,27 @@ def _pkcs7_to_pem(self, pkcs7_content: str, outform: str = 'string') -> List[str self.logger.debug('Certificate._pkcs7_to_pem() ended') return result + def _template_name_get(self, csr: str) -> str: + """ get templaate from csr """ + self.logger.debug('CAhandler._template_name_get(%s)', csr) + template_name = None + + # parse profileid from http_header + header_info = header_info_get(self.logger, csr=csr) + if header_info: + try: + header_info_dic = json.loads(header_info[-1]['header_info']) + if self.header_info_field in header_info_dic: + for ele in header_info_dic[self.header_info_field].split(' '): + if 'template' in ele.lower(): + template_name = ele.split('=')[1] + break + except Exception as err: + self.logger.error('CAhandler._template_name_get() could not parse template: %s', err) + + self.logger.debug('CAhandler._template_name_get() ended with: %s', template_name) + return template_name + def enroll(self, csr: str) -> Tuple[str, str, str, bool]: """ enroll certificate from via MS certsrv """ self.logger.debug('CAhandler.enroll(%s)', self.template) @@ -184,6 +219,10 @@ def enroll(self, csr: str) -> Tuple[str, str, str, bool]: error = None cert_raw = None + # lookup http header information from request + if self.header_info_field: + self.template = self._template_name_get(csr) + if self.host and self.user and self.password and self.template: # setup certserv ca_server = Certsrv(self.host, self.user, self.password, self.auth_method, self.ca_bundle, proxies=self.proxy) diff --git a/test/test_msca_handler.py b/test/test_msca_handler.py index 1b5246c6..3bc81bd9 100644 --- a/test/test_msca_handler.py +++ b/test/test_msca_handler.py @@ -361,12 +361,13 @@ def test_038_enroll(self, mock_certserver, mock_credchk): mock_credchk.return_value = False self.assertEqual(('Connection or Credentialcheck failed.', None, None, None), self.cahandler.enroll('csr')) + @patch('examples.ca_handler.mscertsrv_ca_handler.CAhandler._template_name_get') @patch('examples.ca_handler.mscertsrv_ca_handler.CAhandler._pkcs7_to_pem') @patch('examples.ca_handler.mscertsrv_ca_handler.convert_byte_to_string') @patch('textwrap.fill') @patch('examples.ca_handler.mscertsrv_ca_handler.CAhandler._check_credentials') @patch('examples.ca_handler.mscertsrv_ca_handler.Certsrv') - def test_039_enroll(self, mock_certserver, mock_credchk, mockwrap, mock_b2s, mock_p2p): + def test_039_enroll(self, mock_certserver, mock_credchk, mockwrap, mock_b2s, mock_p2p, mock_tmpl): """ enroll enroll successful """ self.cahandler.host = 'host' self.cahandler.user = 'user' @@ -381,6 +382,31 @@ def test_039_enroll(self, mock_certserver, mock_credchk, mockwrap, mock_b2s, moc mock_b2s.side_effect = ['get_chain', 'get_cert'] mock_p2p.return_value = 'p2p' self.assertEqual((None, 'get_certp2p', 'get_cert', None), self.cahandler.enroll('csr')) + self.assertFalse(mock_tmpl.called) + + @patch('examples.ca_handler.mscertsrv_ca_handler.CAhandler._template_name_get') + @patch('examples.ca_handler.mscertsrv_ca_handler.CAhandler._pkcs7_to_pem') + @patch('examples.ca_handler.mscertsrv_ca_handler.convert_byte_to_string') + @patch('textwrap.fill') + @patch('examples.ca_handler.mscertsrv_ca_handler.CAhandler._check_credentials') + @patch('examples.ca_handler.mscertsrv_ca_handler.Certsrv') + def test_139_enroll(self, mock_certserver, mock_credchk, mockwrap, mock_b2s, mock_p2p, mock_tmpl): + """ enroll enroll successful """ + self.cahandler.host = 'host' + self.cahandler.user = 'user' + self.cahandler.password = 'password' + self.cahandler.template = 'template' + self.cahandler.header_info_field = 'header_info' + mockresponse = MagicMock() + mockresponse.get_chain.return_value = "get_chain" + mockresponse.get_cert.return_value = "get_cert" + mock_certserver = mockresponse + mock_credchk.return_value = True + mockwrap.return_value = 'mockwrap' + mock_b2s.side_effect = ['get_chain', 'get_cert'] + mock_p2p.return_value = 'p2p' + self.assertEqual((None, 'get_certp2p', 'get_cert', None), self.cahandler.enroll('csr')) + self.assertTrue(mock_tmpl.called) @patch('examples.ca_handler.mscertsrv_ca_handler.CAhandler._pkcs7_to_pem') @patch('examples.ca_handler.mscertsrv_ca_handler.convert_byte_to_string') @@ -430,6 +456,50 @@ def test_041_enroll(self, mock_certserver, mock_credchk, mockwrap, mock_b2s, moc self.assertIn('ERROR:test_a2c:ca_server.get_cert() failed with error: get_cert', lcm.output) self.assertIn('ERROR:test_a2c:cert bundling failed', lcm.output) + @patch('examples.ca_handler.mscertsrv_ca_handler.header_info_get') + def test_096_template_name_get(self, mock_header): + """ test _template_name_get()""" + mock_header.return_value = [{'header_info': '{"header_field": "template=foo lego-cli/4.14.2 xenolf-acme/4.14.2 (release; linux; amd64)"}'}] + self.cahandler.header_info_field = 'header_field' + self.assertEqual('foo', self.cahandler._template_name_get('csr')) + + @patch('examples.ca_handler.mscertsrv_ca_handler.header_info_get') + def test_097_template_name_get(self, mock_header): + """ test _template_name_get()""" + mock_header.return_value = [{'header_info': '{"header_field": "Template=foo lego-cli/4.14.2 xenolf-acme/4.14.2 (release; linux; amd64)"}'}] + self.cahandler.header_info_field = 'header_field' + self.assertEqual('foo', self.cahandler._template_name_get('csr')) + + @patch('examples.ca_handler.mscertsrv_ca_handler.header_info_get') + def test_098_template_name_get(self, mock_header): + """ test _template_name_get()""" + mock_header.return_value = [{'header_info': 'header_info'}] + self.cahandler.header_info_field = 'header_field' + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.cahandler._template_name_get('csr')) + self.assertIn('ERROR:test_a2c:CAhandler._template_name_get() could not parse template: Expecting value: line 1 column 1 (char 0)', lcm.output) + + def test_098_config_headerinfo_get(self): + """ test config_headerinfo_get()""" + config_dic = {'Order': {'header_info_list': '["foo", "bar", "foobar"]'}} + self.cahandler._config_headerinfo_get(config_dic) + self.assertEqual( 'foo', self.cahandler.header_info_field) + + def test_099_config_headerinfo_get(self): + """ test config_headerinfo_get()""" + config_dic = {'Order': {'header_info_list': '["foo"]'}} + self.cahandler._config_headerinfo_get(config_dic) + self.assertEqual( 'foo', self.cahandler.header_info_field) + + def test_100_config_headerinfo_get(self): + """ test config_headerinfo_get()""" + config_dic = {'Order': {'header_info_list': 'foo'}} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.cahandler._config_headerinfo_get(config_dic) + self.assertFalse(self.cahandler.header_info_field) + self.assertIn('WARNING:test_a2c:Order._config_orderconfig_load() header_info_list failed with error: Expecting value: line 1 column 1 (char 0)', lcm.output) + + if __name__ == '__main__': unittest.main() From cf12bf07e9f281f8c083c32bccb18ada5e3e043a Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 24 Mar 2024 06:48:35 +0100 Subject: [PATCH 140/460] [doc] headerinfo feature in mscertsrv_ca_handler.py --- docs/mscertsrv.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/docs/mscertsrv.md b/docs/mscertsrv.md index cfb14315..09a7bfac 100644 --- a/docs/mscertsrv.md +++ b/docs/mscertsrv.md @@ -80,3 +80,27 @@ template: - ca_bundle - CA certificate bundle in pem format needed to validate the server certificate - auth_method - authentication method (either "basic" or "ntlm") - template - certificate template used for enrollment + +## Passing a template from client to server + +The handler makes use of the [header_info_list feature](header_info.md) allowing an acme-client to specify a template name to be used during certificate enrollment. This feature is disabled by default and must be activate in `acme_srv.cfg` as shown below + +```config +[Order] +... +header_info_list: ["HTTP_USER_AGENT"] +``` + +The acme-client can then specify the temmplate name as part of its user-agent string. + +Example for acme.sh: + +```bash +docker exec -i acme-sh acme.sh --server http:// --issue -d --standalone --useragent template=foo --debug 3 --output-insecure +``` + +Example for lego: + +```bash +docker run -i -v $PWD/lego:/.lego/ --rm --name lego goacme/lego -s http:// -a --email "lego@example.com" --user-agent template=foo -d --http run +``` From a2a6760739c7d3d61b9251a59a8bcd740331f97e Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 24 Mar 2024 09:15:30 +0100 Subject: [PATCH 141/460] [feat] header_info support in mswcce_ca_handler --- docs/mswcce.md | 23 ++++ examples/ca_handler/mscertsrv_ca_handler.py | 4 +- examples/ca_handler/mswcce_ca_handler.py | 44 ++++++- test/test_msca_handler.py | 46 +++++-- test/test_mswcce_ca_handler.py | 127 +++++++++++++++++--- 5 files changed, 215 insertions(+), 29 deletions(-) diff --git a/docs/mswcce.md b/docs/mswcce.md index 42c4df21..d71c97e2 100644 --- a/docs/mswcce.md +++ b/docs/mswcce.md @@ -52,3 +52,26 @@ use_kerberos: False - ca_bundle - CA certificate chain in pem format delievered along with the client certificate - template - certificate template used for enrollment - use_kerberos - use kerboros for authentication; if set to `False` authentication will be done via NTLM. Considering a [Microsoft accouncement from October 2023](https://techcommunity.microsoft.com/t5/windows-it-pro-blog/the-evolution-of-windows-authentication/ba-p/3926848) the usage of Kerberos should be preferred. Nevertheless, for backwards compatibility reasons the default setting is `False` + +## Passing a template from client to server + +The handler makes use of the [header_info_list feature](header_info.md) allowing an acme-client to specify a template name to be used during certificate enrollment. This feature is disabled by default and must be activate in `acme_srv.cfg` as shown below + +```config +[Order] +... +header_info_list: ["HTTP_USER_AGENT"] +``` + +The acme-client can then specify the temmplate name as part of its user-agent string. + +Example for acme.sh: + +```bash +docker exec -i acme-sh acme.sh --server http:// --issue -d --standalone --useragent template=foo --debug 3 --output-insecure +``` + +Example for lego: + +```bash +docker run -i -v $PWD/lego:/.lego/ --rm --name lego goacme/lego -s http:// -a --email "lego@example.com" --user-agent template=foo -d --http run diff --git a/examples/ca_handler/mscertsrv_ca_handler.py b/examples/ca_handler/mscertsrv_ca_handler.py index 01078241..fb558f5b 100644 --- a/examples/ca_handler/mscertsrv_ca_handler.py +++ b/examples/ca_handler/mscertsrv_ca_handler.py @@ -221,7 +221,9 @@ def enroll(self, csr: str) -> Tuple[str, str, str, bool]: # lookup http header information from request if self.header_info_field: - self.template = self._template_name_get(csr) + user_template = self._template_name_get(csr) + if user_template: + self.template = user_template if self.host and self.user and self.password and self.template: # setup certserv diff --git a/examples/ca_handler/mswcce_ca_handler.py b/examples/ca_handler/mswcce_ca_handler.py index 4a5da473..656952ac 100644 --- a/examples/ca_handler/mswcce_ca_handler.py +++ b/examples/ca_handler/mswcce_ca_handler.py @@ -15,7 +15,8 @@ convert_byte_to_string, convert_string_to_byte, proxy_check, - build_pem_file + build_pem_file, + header_info_get ) @@ -34,6 +35,7 @@ def __init__(self, _debug: bool = False, logger: object = None): self.ca_name = None self.ca_bundle = False self.use_kerberos = False + self.header_info_field = None def __enter__(self): """Makes CAhandler a Context Manager""" @@ -44,6 +46,18 @@ def __enter__(self): def __exit__(self, *args): """close the connection at the end of the context""" + def _config_headerinfo_get(self, config_dic: Dict[str, str]): + """ load parameters """ + self.logger.debug('_config_header_info()') + + if 'Order' in config_dic and 'header_info_list' in config_dic['Order'] and config_dic['Order']['header_info_list']: + try: + self.header_info_field = json.loads(config_dic['Order']['header_info_list'])[0] + except Exception as err_: + self.logger.warning('Order._config_orderconfig_load() header_info_list failed with error: %s', err_) + + self.logger.debug('_config_header_info() ended') + def _config_host_load(self, config_dic: Dict[str, str]): """ load host variable """ self.logger.debug("CAhandler._config_host_load()") @@ -132,6 +146,7 @@ def _config_load(self): self._config_host_load(config_dic) self._config_credentials_load(config_dic) self._config_parameters_load(config_dic) + self._config_headerinfo_get(config_dic) self._config_proxy_load(config_dic) @@ -168,6 +183,27 @@ def request_create(self) -> Request: self.logger.debug('CAhandler.request_create() ended') return request + def _template_name_get(self, csr: str) -> str: + """ get templaate from csr """ + self.logger.debug('CAhandler._template_name_get(%s)', csr) + template_name = None + + # parse profileid from http_header + header_info = header_info_get(self.logger, csr=csr) + if header_info: + try: + header_info_dic = json.loads(header_info[-1]['header_info']) + if self.header_info_field in header_info_dic: + for ele in header_info_dic[self.header_info_field].split(' '): + if 'template' in ele.lower(): + template_name = ele.split('=')[1] + break + except Exception as err: + self.logger.error('CAhandler._template_name_get() could not parse template: %s', err) + + self.logger.debug('CAhandler._template_name_get() ended with: %s', template_name) + return template_name + def enroll(self, csr: str) -> Tuple[str, str, str, str]: """enroll certificate via MS-WCCE""" self.logger.debug("CAhandler.enroll(%s)", self.template) @@ -179,6 +215,12 @@ def enroll(self, csr: str) -> Tuple[str, str, str, str]: self.logger.error("Config incomplete") return ("Config incomplete", None, None, None) + # lookup http header information from request + if self.header_info_field: + user_template = self._template_name_get(csr) + if user_template: + self.template = user_template + # create request request = self.request_create() diff --git a/test/test_msca_handler.py b/test/test_msca_handler.py index 3bc81bd9..c165a117 100644 --- a/test/test_msca_handler.py +++ b/test/test_msca_handler.py @@ -390,7 +390,7 @@ def test_039_enroll(self, mock_certserver, mock_credchk, mockwrap, mock_b2s, moc @patch('textwrap.fill') @patch('examples.ca_handler.mscertsrv_ca_handler.CAhandler._check_credentials') @patch('examples.ca_handler.mscertsrv_ca_handler.Certsrv') - def test_139_enroll(self, mock_certserver, mock_credchk, mockwrap, mock_b2s, mock_p2p, mock_tmpl): + def test_040_enroll(self, mock_certserver, mock_credchk, mockwrap, mock_b2s, mock_p2p, mock_tmpl): """ enroll enroll successful """ self.cahandler.host = 'host' self.cahandler.user = 'user' @@ -400,6 +400,7 @@ def test_139_enroll(self, mock_certserver, mock_credchk, mockwrap, mock_b2s, moc mockresponse = MagicMock() mockresponse.get_chain.return_value = "get_chain" mockresponse.get_cert.return_value = "get_cert" + mock_tmpl.return_value = 'new_template' mock_certserver = mockresponse mock_credchk.return_value = True mockwrap.return_value = 'mockwrap' @@ -407,13 +408,40 @@ def test_139_enroll(self, mock_certserver, mock_credchk, mockwrap, mock_b2s, moc mock_p2p.return_value = 'p2p' self.assertEqual((None, 'get_certp2p', 'get_cert', None), self.cahandler.enroll('csr')) self.assertTrue(mock_tmpl.called) + self.assertEqual('new_template', self.cahandler.template) + + @patch('examples.ca_handler.mscertsrv_ca_handler.CAhandler._template_name_get') + @patch('examples.ca_handler.mscertsrv_ca_handler.CAhandler._pkcs7_to_pem') + @patch('examples.ca_handler.mscertsrv_ca_handler.convert_byte_to_string') + @patch('textwrap.fill') + @patch('examples.ca_handler.mscertsrv_ca_handler.CAhandler._check_credentials') + @patch('examples.ca_handler.mscertsrv_ca_handler.Certsrv') + def test_041_enroll(self, mock_certserver, mock_credchk, mockwrap, mock_b2s, mock_p2p, mock_tmpl): + """ enroll enroll successful """ + self.cahandler.host = 'host' + self.cahandler.user = 'user' + self.cahandler.password = 'password' + self.cahandler.template = 'template' + self.cahandler.header_info_field = 'header_info' + mockresponse = MagicMock() + mockresponse.get_chain.return_value = "get_chain" + mockresponse.get_cert.return_value = "get_cert" + mock_tmpl.return_value = None + mock_certserver = mockresponse + mock_credchk.return_value = True + mockwrap.return_value = 'mockwrap' + mock_b2s.side_effect = ['get_chain', 'get_cert'] + mock_p2p.return_value = 'p2p' + self.assertEqual((None, 'get_certp2p', 'get_cert', None), self.cahandler.enroll('csr')) + self.assertTrue(mock_tmpl.called) + self.assertEqual('template', self.cahandler.template) @patch('examples.ca_handler.mscertsrv_ca_handler.CAhandler._pkcs7_to_pem') @patch('examples.ca_handler.mscertsrv_ca_handler.convert_byte_to_string') @patch('textwrap.fill') @patch('examples.ca_handler.mscertsrv_ca_handler.CAhandler._check_credentials') @patch('examples.ca_handler.mscertsrv_ca_handler.Certsrv') - def test_040_enroll(self, mock_certserver, mock_credchk, mockwrap, mock_b2s, mock_p2p): + def test_042_enroll(self, mock_certserver, mock_credchk, mockwrap, mock_b2s, mock_p2p): """ enroll exceütption in get chain """ self.cahandler.host = 'host' self.cahandler.user = 'user' @@ -437,7 +465,7 @@ def test_040_enroll(self, mock_certserver, mock_credchk, mockwrap, mock_b2s, moc @patch('textwrap.fill') @patch('examples.ca_handler.mscertsrv_ca_handler.CAhandler._check_credentials') @patch('examples.ca_handler.mscertsrv_ca_handler.Certsrv') - def test_041_enroll(self, mock_certserver, mock_credchk, mockwrap, mock_b2s, mock_p2p): + def test_043_enroll(self, mock_certserver, mock_credchk, mockwrap, mock_b2s, mock_p2p): """ enroll exceütption in get cert """ self.cahandler.host = 'host' self.cahandler.user = 'user' @@ -457,21 +485,21 @@ def test_041_enroll(self, mock_certserver, mock_credchk, mockwrap, mock_b2s, moc self.assertIn('ERROR:test_a2c:cert bundling failed', lcm.output) @patch('examples.ca_handler.mscertsrv_ca_handler.header_info_get') - def test_096_template_name_get(self, mock_header): + def test_044_template_name_get(self, mock_header): """ test _template_name_get()""" mock_header.return_value = [{'header_info': '{"header_field": "template=foo lego-cli/4.14.2 xenolf-acme/4.14.2 (release; linux; amd64)"}'}] self.cahandler.header_info_field = 'header_field' self.assertEqual('foo', self.cahandler._template_name_get('csr')) @patch('examples.ca_handler.mscertsrv_ca_handler.header_info_get') - def test_097_template_name_get(self, mock_header): + def test_045_template_name_get(self, mock_header): """ test _template_name_get()""" mock_header.return_value = [{'header_info': '{"header_field": "Template=foo lego-cli/4.14.2 xenolf-acme/4.14.2 (release; linux; amd64)"}'}] self.cahandler.header_info_field = 'header_field' self.assertEqual('foo', self.cahandler._template_name_get('csr')) @patch('examples.ca_handler.mscertsrv_ca_handler.header_info_get') - def test_098_template_name_get(self, mock_header): + def test_046_template_name_get(self, mock_header): """ test _template_name_get()""" mock_header.return_value = [{'header_info': 'header_info'}] self.cahandler.header_info_field = 'header_field' @@ -479,19 +507,19 @@ def test_098_template_name_get(self, mock_header): self.assertFalse(self.cahandler._template_name_get('csr')) self.assertIn('ERROR:test_a2c:CAhandler._template_name_get() could not parse template: Expecting value: line 1 column 1 (char 0)', lcm.output) - def test_098_config_headerinfo_get(self): + def test_047_config_headerinfo_get(self): """ test config_headerinfo_get()""" config_dic = {'Order': {'header_info_list': '["foo", "bar", "foobar"]'}} self.cahandler._config_headerinfo_get(config_dic) self.assertEqual( 'foo', self.cahandler.header_info_field) - def test_099_config_headerinfo_get(self): + def test_048_config_headerinfo_get(self): """ test config_headerinfo_get()""" config_dic = {'Order': {'header_info_list': '["foo"]'}} self.cahandler._config_headerinfo_get(config_dic) self.assertEqual( 'foo', self.cahandler.header_info_field) - def test_100_config_headerinfo_get(self): + def test_049_config_headerinfo_get(self): """ test config_headerinfo_get()""" config_dic = {'Order': {'header_info_list': 'foo'}} with self.assertLogs('test_a2c', level='INFO') as lcm: diff --git a/test/test_mswcce_ca_handler.py b/test/test_mswcce_ca_handler.py index bf3c7627..2d05103f 100644 --- a/test/test_mswcce_ca_handler.py +++ b/test/test_mswcce_ca_handler.py @@ -529,38 +529,38 @@ def test_027_config_load(self, mock_load_cfg): self.assertIn('WARNING:test_a2c:CAhandler._config_load() use_kerberos failed with error: Not a boolean: aaaa', lcm.output) @patch("builtins.open", mock_open(read_data='foo'), create=True) - def test_023__file_load(self): + def test_028__file_load(self): """ test _load file() """ self.assertEqual('foo', self.cahandler._file_load('filename')) @patch("builtins.open") - def test_024__file_load(self, mock_op): + def test_029__file_load(self, mock_op): """ test _load file() """ mock_op.side_effect = Exception('ex_mock_open') with self.assertLogs('test_a2c', level='INFO') as lcm: self.assertFalse(self.cahandler._file_load('filename')) self.assertIn('ERROR:test_a2c:CAhandler._file_load(): could not load filename. Error: ex_mock_open', lcm.output) - def test_025_revoke(self): + def test_030_revoke(self): """ test revocation """ self.assertEqual((500, 'urn:ietf:params:acme:error:serverInternal', 'Revocation is not supported.'), self.cahandler.revoke('cert', 'rev_reason', 'rev_date')) - def test_026_poll(self): + def test_031_poll(self): """ test polling """ self.assertEqual(('Method not implemented.', None, None, 'poll_identifier', False), self.cahandler.poll('cert_name', 'poll_identifier', 'csr')) - def test_027_trigger(self): + def test_032_trigger(self): """ test trigger """ self.assertEqual(('Method not implemented.', None, None), self.cahandler.trigger('payload')) @patch('examples.ca_handler.mswcce_ca_handler.CAhandler.request_create') - def test_028_enroll(self, mock_rcr): + def test_033_enroll(self, mock_rcr): """ test enrollment - unconfigured """ self.assertEqual(('Config incomplete', None, None, None), self.cahandler.enroll('csr')) self.assertFalse(mock_rcr.called) @patch('examples.ca_handler.mswcce_ca_handler.CAhandler.request_create') - def test_029_enroll(self, mock_rcr): + def test_034_enroll(self, mock_rcr): """ test enrollment - host unconfigured """ self.cahandler.host = None self.cahandler.user = 'user' @@ -570,7 +570,7 @@ def test_029_enroll(self, mock_rcr): self.assertFalse(mock_rcr.called) @patch('examples.ca_handler.mswcce_ca_handler.CAhandler.request_create') - def test_30_enroll(self, mock_rcr): + def test_035_enroll(self, mock_rcr): """ test enrollment - user unconfigured """ self.cahandler.host = 'host' self.cahandler.user = None @@ -580,7 +580,7 @@ def test_30_enroll(self, mock_rcr): self.assertFalse(mock_rcr.called) @patch('examples.ca_handler.mswcce_ca_handler.CAhandler.request_create') - def test_031_enroll(self, mock_rcr): + def test_036_enroll(self, mock_rcr): """ test enrollment - password unconfigured """ self.cahandler.host = 'host' self.cahandler.user = 'user' @@ -590,7 +590,7 @@ def test_031_enroll(self, mock_rcr): self.assertFalse(mock_rcr.called) @patch('examples.ca_handler.mswcce_ca_handler.CAhandler.request_create') - def test_032_enroll(self, mock_rcr): + def test_037_enroll(self, mock_rcr): """ test enrollment - template unconfigured """ self.cahandler.host = 'host' self.cahandler.user = 'user' @@ -604,7 +604,7 @@ def test_032_enroll(self, mock_rcr): @patch('examples.ca_handler.mswcce_ca_handler.convert_byte_to_string') @patch('examples.ca_handler.mswcce_ca_handler.CAhandler._file_load') @patch('examples.ca_handler.mswcce_ca_handler.build_pem_file') - def test_033_enroll(self, mock_pem, mock_file, mock_b2s, mock_s2b, mock_rcr): + def test_038_enroll(self, mock_pem, mock_file, mock_b2s, mock_s2b, mock_rcr): """ test enrollment - ca_server.get_cert() triggers exception """ self.cahandler.host = 'host' self.cahandler.user = 'user' @@ -625,7 +625,7 @@ def test_033_enroll(self, mock_pem, mock_file, mock_b2s, mock_s2b, mock_rcr): @patch('examples.ca_handler.mswcce_ca_handler.convert_byte_to_string') @patch('examples.ca_handler.mswcce_ca_handler.CAhandler._file_load') @patch('examples.ca_handler.mswcce_ca_handler.build_pem_file') - def test_034_enroll(self, mock_pem, mock_file, mock_b2s, mock_s2b, mock_rcr): + def test_039_enroll(self, mock_pem, mock_file, mock_b2s, mock_s2b, mock_rcr): """ test enrollment - no certificate returned by ca_server.get_cert() """ self.cahandler.host = 'host' self.cahandler.user = 'user' @@ -645,7 +645,7 @@ def test_034_enroll(self, mock_pem, mock_file, mock_b2s, mock_s2b, mock_rcr): @patch('examples.ca_handler.mswcce_ca_handler.convert_byte_to_string') @patch('examples.ca_handler.mswcce_ca_handler.CAhandler._file_load') @patch('examples.ca_handler.mswcce_ca_handler.build_pem_file') - def test_035_enroll(self, mock_pem, mock_file, mock_b2s, mock_s2b, mock_rcr): + def test_040_enroll(self, mock_pem, mock_file, mock_b2s, mock_s2b, mock_rcr): """ test enrollment - certificate and bundling successful """ self.cahandler.host = 'host' self.cahandler.user = 'user' @@ -663,7 +663,7 @@ def test_035_enroll(self, mock_pem, mock_file, mock_b2s, mock_s2b, mock_rcr): @patch('examples.ca_handler.mswcce_ca_handler.convert_byte_to_string') @patch('examples.ca_handler.mswcce_ca_handler.CAhandler._file_load') @patch('examples.ca_handler.mswcce_ca_handler.build_pem_file') - def test_036_enroll(self, mock_pem, mock_file, mock_b2s, mock_s2b, mock_rcr): + def test_041_enroll(self, mock_pem, mock_file, mock_b2s, mock_s2b, mock_rcr): """ test enrollment - certificate and bundling successful replacement test """ self.cahandler.host = 'host' self.cahandler.user = 'user' @@ -676,12 +676,13 @@ def test_036_enroll(self, mock_pem, mock_file, mock_b2s, mock_s2b, mock_rcr): self.assertEqual((None, '-----BEGIN CERTIFICATE-----\nb2s_replacement\n-----END CERTIFICATE-----\nfile_load', 'b2s_replacement', None), self.cahandler.enroll('csr')) self.assertTrue(mock_rcr.called) + @patch('examples.ca_handler.mswcce_ca_handler.CAhandler._template_name_get') @patch('examples.ca_handler.mswcce_ca_handler.CAhandler.request_create') @patch('examples.ca_handler.mswcce_ca_handler.convert_string_to_byte') @patch('examples.ca_handler.mswcce_ca_handler.convert_byte_to_string') @patch('examples.ca_handler.mswcce_ca_handler.CAhandler._file_load') @patch('examples.ca_handler.mswcce_ca_handler.build_pem_file') - def test_037_enroll(self, mock_pem, mock_file, mock_b2s, mock_s2b, mock_rcr): + def test_042_enroll(self, mock_pem, mock_file, mock_b2s, mock_s2b, mock_rcr, mock_tmpl): """ test enrollment - certificate and bundling successful replacement test """ self.cahandler.host = 'host' self.cahandler.user = 'user' @@ -693,29 +694,119 @@ def test_037_enroll(self, mock_pem, mock_file, mock_b2s, mock_s2b, mock_rcr): mock_b2s.return_value = '-----BEGIN CERTIFICATE-----\nb2s_replacement\n-----END CERTIFICATE-----\n' self.assertEqual((None, '-----BEGIN CERTIFICATE-----\nb2s_replacement\n-----END CERTIFICATE-----\n', 'b2s_replacement', None), self.cahandler.enroll('csr')) self.assertTrue(mock_rcr.called) + self.assertFalse(mock_tmpl.called) + + @patch('examples.ca_handler.mswcce_ca_handler.CAhandler._template_name_get') + @patch('examples.ca_handler.mswcce_ca_handler.CAhandler.request_create') + @patch('examples.ca_handler.mswcce_ca_handler.convert_string_to_byte') + @patch('examples.ca_handler.mswcce_ca_handler.convert_byte_to_string') + @patch('examples.ca_handler.mswcce_ca_handler.CAhandler._file_load') + @patch('examples.ca_handler.mswcce_ca_handler.build_pem_file') + def test_043_enroll(self, mock_pem, mock_file, mock_b2s, mock_s2b, mock_rcr, mock_tmpl): + """ test enrollment - certificate and bundling successful replacement test """ + self.cahandler.host = 'host' + self.cahandler.user = 'user' + self.cahandler.password = 'password' + self.cahandler.template = 'template' + self.cahandler.header_info_field = 'header_info' + mock_rcr.return_value = Mock(return_value='raw_data') + mock_file.return_value = None + mock_s2b.return_value = 's2b' + mock_b2s.return_value = '-----BEGIN CERTIFICATE-----\nb2s_replacement\n-----END CERTIFICATE-----\n' + mock_tmpl.return_value = 'new_template' + self.assertEqual((None, '-----BEGIN CERTIFICATE-----\nb2s_replacement\n-----END CERTIFICATE-----\n', 'b2s_replacement', None), self.cahandler.enroll('csr')) + self.assertTrue(mock_rcr.called) + self.assertEqual('new_template', self.cahandler.template) + + @patch('examples.ca_handler.mswcce_ca_handler.CAhandler._template_name_get') + @patch('examples.ca_handler.mswcce_ca_handler.CAhandler.request_create') + @patch('examples.ca_handler.mswcce_ca_handler.convert_string_to_byte') + @patch('examples.ca_handler.mswcce_ca_handler.convert_byte_to_string') + @patch('examples.ca_handler.mswcce_ca_handler.CAhandler._file_load') + @patch('examples.ca_handler.mswcce_ca_handler.build_pem_file') + def test_044_enroll(self, mock_pem, mock_file, mock_b2s, mock_s2b, mock_rcr, mock_tmpl): + """ test enrollment - certificate and bundling successful replacement test """ + self.cahandler.host = 'host' + self.cahandler.user = 'user' + self.cahandler.password = 'password' + self.cahandler.template = 'template' + self.cahandler.header_info_field = 'header_info' + mock_rcr.return_value = Mock(return_value='raw_data') + mock_file.return_value = None + mock_s2b.return_value = 's2b' + mock_b2s.return_value = '-----BEGIN CERTIFICATE-----\nb2s_replacement\n-----END CERTIFICATE-----\n' + mock_tmpl.return_value = None + self.assertEqual((None, '-----BEGIN CERTIFICATE-----\nb2s_replacement\n-----END CERTIFICATE-----\n', 'b2s_replacement', None), self.cahandler.enroll('csr')) + self.assertTrue(mock_rcr.called) + self.assertEqual('template', self.cahandler.template) @patch('examples.ca_handler.mswcce_ca_handler.Request') @patch('examples.ca_handler.mswcce_ca_handler.Target') - def test_038_request_create(self, mock_target, mock_request): + def test_045_request_create(self, mock_target, mock_request): """ test request create """ mock_target.return_value = True mock_request.return_value ='foo' self.assertEqual('foo', self.cahandler.request_create()) @patch('examples.ca_handler.mswcce_ca_handler.CAhandler._config_load') - def test_039__enter(self, mock_cfgload): + def test_046__enter(self, mock_cfgload): """ CAhandler._enter() with config load """ self.cahandler.host = 'host' self.cahandler.__enter__() self.assertFalse(mock_cfgload.called) @patch('examples.ca_handler.mswcce_ca_handler.CAhandler._config_load') - def test_040__enter(self, mock_cfgload): + def test_047__enter(self, mock_cfgload): """ CAhandler._enter() with config load """ self.cahandler.host = None self.cahandler.__enter__() self.assertTrue(mock_cfgload.called) + @patch('examples.ca_handler.mswcce_ca_handler.header_info_get') + def test_048_template_name_get(self, mock_header): + """ test _template_name_get()""" + mock_header.return_value = [{'header_info': '{"header_field": "template=foo lego-cli/4.14.2 xenolf-acme/4.14.2 (release; linux; amd64)"}'}] + self.cahandler.header_info_field = 'header_field' + self.assertEqual('foo', self.cahandler._template_name_get('csr')) + + @patch('examples.ca_handler.mswcce_ca_handler.header_info_get') + def test_049_template_name_get(self, mock_header): + """ test _template_name_get()""" + mock_header.return_value = [{'header_info': '{"header_field": "Template=foo lego-cli/4.14.2 xenolf-acme/4.14.2 (release; linux; amd64)"}'}] + self.cahandler.header_info_field = 'header_field' + self.assertEqual('foo', self.cahandler._template_name_get('csr')) + + @patch('examples.ca_handler.mswcce_ca_handler.header_info_get') + def test_050_template_name_get(self, mock_header): + """ test _template_name_get()""" + mock_header.return_value = [{'header_info': 'header_info'}] + self.cahandler.header_info_field = 'header_field' + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.cahandler._template_name_get('csr')) + self.assertIn('ERROR:test_a2c:CAhandler._template_name_get() could not parse template: Expecting value: line 1 column 1 (char 0)', lcm.output) + + def test_051_config_headerinfo_get(self): + """ test config_headerinfo_get()""" + config_dic = {'Order': {'header_info_list': '["foo", "bar", "foobar"]'}} + self.cahandler._config_headerinfo_get(config_dic) + self.assertEqual( 'foo', self.cahandler.header_info_field) + + def test_052_config_headerinfo_get(self): + """ test config_headerinfo_get()""" + config_dic = {'Order': {'header_info_list': '["foo"]'}} + self.cahandler._config_headerinfo_get(config_dic) + self.assertEqual( 'foo', self.cahandler.header_info_field) + + def test_053_config_headerinfo_get(self): + """ test config_headerinfo_get()""" + config_dic = {'Order': {'header_info_list': 'foo'}} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.cahandler._config_headerinfo_get(config_dic) + self.assertFalse(self.cahandler.header_info_field) + self.assertIn('WARNING:test_a2c:Order._config_orderconfig_load() header_info_list failed with error: Expecting value: line 1 column 1 (char 0)', lcm.output) + + + if __name__ == '__main__': unittest.main() From 4929111aa9b6b7ad56fb34e1613f53235cec6def Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 24 Mar 2024 09:28:10 +0100 Subject: [PATCH 142/460] [fix] md linting --- docs/mswcce.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/mswcce.md b/docs/mswcce.md index d71c97e2..adfcfcb2 100644 --- a/docs/mswcce.md +++ b/docs/mswcce.md @@ -75,3 +75,4 @@ Example for lego: ```bash docker run -i -v $PWD/lego:/.lego/ --rm --name lego goacme/lego -s http:// -a --email "lego@example.com" --user-agent template=foo -d --http run +``` \ No newline at end of file From 37f419efa7fbc137ca3ab114bfd97229a99cdaff Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 24 Mar 2024 11:15:28 +0100 Subject: [PATCH 143/460] [doc] md linting --- docs/mswcce.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/mswcce.md b/docs/mswcce.md index adfcfcb2..ae2e37b5 100644 --- a/docs/mswcce.md +++ b/docs/mswcce.md @@ -75,4 +75,4 @@ Example for lego: ```bash docker run -i -v $PWD/lego:/.lego/ --rm --name lego goacme/lego -s http:// -a --email "lego@example.com" --user-agent template=foo -d --http run -``` \ No newline at end of file +``` From 77b1402f86e1e13c3c49f117269bdf7e85c88cd7 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 23 Mar 2024 07:27:17 +0100 Subject: [PATCH 144/460] [feat] supress_product_information feature --- acme_srv/directory.py | 30 ++++++-- docs/acme_srv.md | 2 + test/test_directory.py | 115 ++++++++++++++++++++++++++++--- test/test_wsgi_acme2certifier.py | 1 + 4 files changed, 130 insertions(+), 18 deletions(-) diff --git a/acme_srv/directory.py b/acme_srv/directory.py index d382a6cb..8d6bcc20 100644 --- a/acme_srv/directory.py +++ b/acme_srv/directory.py @@ -17,6 +17,8 @@ def __init__(self, debug=None, srv_name=None, logger=None): self.logger = logger self.dbstore = DBstore(debug, self.logger) self.supress_version = False + self.suppress_product_information = False + self.home = 'https://github.com/grindsa/acme2certifier' self.tos_url = None self.version = __version__ self.dbversion = __dbversion__ @@ -48,6 +50,13 @@ def _config_load(self): if 'Directory' in config_dic and 'url_prefix' in config_dic['Directory']: self.url_prefix = config_dic['Directory']['url_prefix'] + self.home = config_dic.get('Directory', 'home', fallback='https://github.com/grindsa/acme2certifier') + + try: + self.suppress_product_information = config_dic.getboolean('Directory', 'suppress_product_information', fallback= False) + except Exception as err_: + self.logger.error('Directory._config_load() suppress_product_information not set: %s', err_) + self.logger.debug('Directory._config_load() ended') def directory_get(self) -> Dict[str, str]: @@ -62,16 +71,22 @@ def directory_get(self) -> Dict[str, str]: 'revokeCert': self.server_name + self.url_prefix + '/acme/revokecert', 'keyChange': self.server_name + self.url_prefix + '/acme/key-change', 'renewalInfo': self.server_name + self.url_prefix + '/acme/renewal-info', - 'meta': { - 'home': 'https://github.com/grindsa/acme2certifier', + 'meta': {} + } + + if not self.suppress_product_information: + d_dic['meta'] = { + 'home': self.home, 'author': 'grindsa ', 'name': 'acme2certifier' - }, - } + } + # show version information in meta tags if not disabled.... + if not self.supress_version: + d_dic['meta']['version'] = self.version + else: + if self.home != 'https://github.com/grindsa/acme2certifier': + d_dic['meta']['home'] = self.home - # show version information in meta tags if not disabled.... - if not self.supress_version: - d_dic['meta']['version'] = self.version # add terms of service if self.tos_url: @@ -96,6 +111,7 @@ def directory_get(self) -> Dict[str, str]: # generate random key in json as recommended by LE d_dic[uuid.uuid4().hex] = 'https://community.letsencrypt.org/t/adding-random-entries-to-the-directory/33417' + return d_dic def servername_get(self) -> str: diff --git a/docs/acme_srv.md b/docs/acme_srv.md index fb158f48..f2208056 100644 --- a/docs/acme_srv.md +++ b/docs/acme_srv.md @@ -23,6 +23,8 @@ | `Challenge` | `sectigo_sim` | provide `sectigo-email-01` challenges - Only for development and testing! | True/False | False | | `DBhandler` | `dbfile` | path and name of database file. If not specified `acme_srv/acme_srv.db` will be used. Parameter is only available for a wsgi handler and will be ignored if django handler is getting used | 'acme/database.db' | `acme_srv/acme_srv.db`| | `Directory` | `db_check` | check database connection compare schemes and report as OK/NOK in meta information | True/False | False| +| `Directory` | `home` | homepage string to be shown when fetching the directory ressource | 'string' | 'https://github.com/grindsa/acme2certifier' | +| `Directory` | `supress_product_information` | Do not show product name, author and version when fetching the directory resource | True/False | False| | `Directory` | `supress_version` | Do not show version information when fetching the directory resource | True/False | False| | `Directory` | `tos_url` | Terms of Service URL | URL | None| | `Directory` | `url_prefix` | url prefix for acme2certifier resources | '/foo' | None| diff --git a/test/test_directory.py b/test/test_directory.py index 501170aa..6b6f8d1c 100644 --- a/test/test_directory.py +++ b/test/test_directory.py @@ -122,8 +122,43 @@ def test_012_directory_directory_get(self): self.assertTrue(output_dic.items() <= result.items()) self.assertEqual('NOK', result['meta']['db_check']) + def test_013_directory_directory_get(self): + """ test Directory.get_directory() method and check for "meta" tag in output""" + self.directory.home = 'home' + self.directory.version = '0.1' + output_dic = {'meta': {'home': 'home', 'author': 'grindsa ', 'name': 'acme2certifier', 'version': '0.1'}} + self.assertTrue(output_dic.items() <= self.directory.directory_get().items()) + + def test_014_directory_directory_get(self): + """ test Directory.get_directory() method and check for "meta" tag in output""" + self.directory.home = 'home' + self.directory.version = '0.1' + output_dic = {'home': 'home', 'author': 'grindsa ', 'name': 'acme2certifier', 'version': '0.1'} + self.assertEqual(output_dic, self.directory.directory_get()['meta']) + + def test_015_directory_directory_get(self): + """ test Directory.get_directory() method and check for "meta" tag in output""" + self.directory.home = 'home' + self.directory.version = '0.1' + self.directory.suppress_product_information = True + output_dic = {'home': 'home'} + self.assertEqual(output_dic, self.directory.directory_get()['meta']) + + def test_016_directory_directory_get(self): + """ test Directory.get_directory() method and check for "meta" tag in output""" + self.directory.suppress_product_information = True + output_dic = {} + self.assertEqual(output_dic, self.directory.directory_get()['meta']) + + def test_017_directory_directory_get(self): + """ test Directory.get_directory() method and check for "meta" tag in output""" + self.directory.suppress_product_information = False + self.directory.version = '0.1' + output_dic = {'home': 'https://github.com/grindsa/acme2certifier', 'author': 'grindsa ', 'name': 'acme2certifier', 'version': '0.1'} + self.assertEqual(output_dic, self.directory.directory_get()['meta']) + @patch('acme_srv.directory.load_config') - def test_013_config_load(self, mock_load_cfg): + def test_018_config_load(self, mock_load_cfg): """ test _config_load empty config """ parser = configparser.ConfigParser() # parser['Account'] = {'foo': 'bar'} @@ -135,7 +170,7 @@ def test_013_config_load(self, mock_load_cfg): self.assertFalse(self.directory.db_check) @patch('acme_srv.directory.load_config') - def test_014_config_load(self, mock_load_cfg): + def test_019_config_load(self, mock_load_cfg): """ test _config_load with unknown values config """ parser = configparser.ConfigParser() parser['Account'] = {'foo': 'bar'} @@ -147,7 +182,7 @@ def test_014_config_load(self, mock_load_cfg): self.assertFalse(self.directory.db_check) @patch('acme_srv.directory.load_config') - def test_015_config_load(self, mock_load_cfg): + def test_020_config_load(self, mock_load_cfg): """ test _config_load with unknown values config """ parser = configparser.ConfigParser() parser['Directory'] = {'foo': 'bar'} @@ -159,7 +194,7 @@ def test_015_config_load(self, mock_load_cfg): self.assertFalse(self.directory.db_check) @patch('acme_srv.directory.load_config') - def test_016_config_load(self, mock_load_cfg): + def test_021_config_load(self, mock_load_cfg): """ test _config_load supress version number """ parser = configparser.ConfigParser() parser['Directory'] = {'supress_version': True} @@ -171,7 +206,7 @@ def test_016_config_load(self, mock_load_cfg): self.assertFalse(self.directory.db_check) @patch('acme_srv.directory.load_config') - def test_017_config_load(self, mock_load_cfg): + def test_022_config_load(self, mock_load_cfg): """ test _config_load tos url """ parser = configparser.ConfigParser() parser['Directory'] = {'tos_url': 'tos_url'} @@ -183,7 +218,7 @@ def test_017_config_load(self, mock_load_cfg): self.assertFalse(self.directory.db_check) @patch('acme_srv.directory.load_config') - def test_018_config_load(self, mock_load_cfg): + def test_023_config_load(self, mock_load_cfg): """ test _config_load eab """ parser = configparser.ConfigParser() parser['EABhandler'] = {'eab_handler_file': 'eab_handler_file'} @@ -197,7 +232,7 @@ def test_018_config_load(self, mock_load_cfg): self.assertFalse(self.directory.db_check) @patch('acme_srv.directory.load_config') - def test_019_config_load(self, mock_load_cfg): + def test_024_config_load(self, mock_load_cfg): """ test _config_load all parameters set """ parser = configparser.ConfigParser() parser['EABhandler'] = {'eab_handler_file': 'eab_handler_file'} @@ -210,7 +245,7 @@ def test_019_config_load(self, mock_load_cfg): self.assertFalse(self.directory.db_check) @patch('acme_srv.directory.load_config') - def test_020_config_load(self, mock_load_cfg): + def test_025_config_load(self, mock_load_cfg): """ test _config_load eab """ parser = configparser.ConfigParser() parser['Directory'] = {'url_prefix': 'url_prefix'} @@ -223,7 +258,7 @@ def test_020_config_load(self, mock_load_cfg): self.assertFalse(self.directory.db_check) @patch('acme_srv.directory.load_config') - def test_021_config_load(self, mock_load_cfg): + def test_026_config_load(self, mock_load_cfg): """ test _config_load eab """ parser = configparser.ConfigParser() parser['Directory'] = {'db_check': True} @@ -233,9 +268,10 @@ def test_021_config_load(self, mock_load_cfg): self.assertFalse(self.directory.tos_url) self.assertFalse(self.directory.eab) self.assertTrue(self.directory.db_check) + self.assertEqual(False, self.directory.suppress_product_information) @patch('acme_srv.directory.load_config') - def test_022_config_load(self, mock_load_cfg): + def test_027_config_load(self, mock_load_cfg): """ test _config_load eab """ parser = configparser.ConfigParser() parser['Directory'] = {'db_check': False} @@ -245,9 +281,66 @@ def test_022_config_load(self, mock_load_cfg): self.assertFalse(self.directory.tos_url) self.assertFalse(self.directory.eab) self.assertFalse(self.directory.db_check) + self.assertEqual('https://github.com/grindsa/acme2certifier', self.directory.home) + self.assertEqual(False, self.directory.suppress_product_information) + + @patch('acme_srv.directory.load_config') + def test_028_config_load(self, mock_load_cfg): + """ test _config_load eab """ + parser = configparser.ConfigParser() + parser['Directory'] = {'home': 'home'} + mock_load_cfg.return_value = parser + self.directory._config_load() + self.assertFalse(self.directory.supress_version) + self.assertFalse(self.directory.tos_url) + self.assertFalse(self.directory.eab) + self.assertFalse(self.directory.db_check) + self.assertEqual('home', self.directory.home) + self.assertEqual(False, self.directory.suppress_product_information) + + @patch('acme_srv.directory.load_config') + def test_029_config_load(self, mock_load_cfg): + """ test _config_load eab """ + parser = configparser.ConfigParser() + parser['Directory'] = {'suppress_product_information': True} + mock_load_cfg.return_value = parser + self.directory._config_load() + self.assertFalse(self.directory.supress_version) + self.assertFalse(self.directory.tos_url) + self.assertFalse(self.directory.eab) + self.assertFalse(self.directory.db_check) + self.assertEqual(True, self.directory.suppress_product_information) + + @patch('acme_srv.directory.load_config') + def test_030_config_load(self, mock_load_cfg): + """ test _config_load eab """ + parser = configparser.ConfigParser() + parser['Directory'] = {'suppress_product_information': False} + mock_load_cfg.return_value = parser + self.directory._config_load() + self.assertFalse(self.directory.supress_version) + self.assertFalse(self.directory.tos_url) + self.assertFalse(self.directory.eab) + self.assertFalse(self.directory.db_check) + self.assertEqual(False, self.directory.suppress_product_information) + + @patch('acme_srv.directory.load_config') + def test_031_config_load(self, mock_load_cfg): + """ test _config_load eab """ + parser = configparser.ConfigParser() + parser['Directory'] = {'suppress_product_information': 'aa'} + mock_load_cfg.return_value = parser + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.directory._config_load() + self.assertFalse(self.directory.supress_version) + self.assertFalse(self.directory.tos_url) + self.assertFalse(self.directory.eab) + self.assertFalse(self.directory.db_check) + self.assertEqual(False, self.directory.suppress_product_information) + self.assertIn('ERROR:test_a2c:Directory._config_load() suppress_product_information not set: Not a boolean: aa', lcm.output) @patch('acme_srv.directory.Directory._config_load') - def test_023__enter__(self, mock_cfg): + def test_032__enter__(self, mock_cfg): """ test enter """ mock_cfg.return_value = True self.directory.__enter__() diff --git a/test/test_wsgi_acme2certifier.py b/test/test_wsgi_acme2certifier.py index 38a80ee6..65a5cec0 100644 --- a/test/test_wsgi_acme2certifier.py +++ b/test/test_wsgi_acme2certifier.py @@ -586,6 +586,7 @@ def test_051_application(self): environ = {'REQUEST_METHOD': 'UNK', 'REMOTE_ADDR': 'REMOTE_ADDR', 'PATH_INFO': 'url_prefix/directory'} result_expected = {"newAuthz": "http://localhost/acme/new-authz", "newNonce": "http://localhost/acme/newnonce", "newAccount": "http://localhost/acme/newaccount", "newOrder": "http://localhost/acme/neworders", "revokeCert": "http://localhost/acme/revokecert", "keyChange": "http://localhost/acme/key-change", "meta": {"home": "https://github.com/grindsa/acme2certifier", "author": "grindsa ", "name": "acme2certifier"}} result_func = json.loads(self.application(environ, Mock())[0]) + print(result_func) del(result_func['meta']['version']) self.assertTrue(result_expected['meta'].items() <= result_func['meta'].items()) self.assertEqual(result_expected['newAuthz'], result_func['newAuthz']) From 49ee8beaae4c144397328c4514cc5592a63cd5eb Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 23 Mar 2024 07:30:10 +0100 Subject: [PATCH 145/460] [fix] linting --- acme_srv/directory.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/acme_srv/directory.py b/acme_srv/directory.py index 8d6bcc20..914e7f49 100644 --- a/acme_srv/directory.py +++ b/acme_srv/directory.py @@ -53,7 +53,7 @@ def _config_load(self): self.home = config_dic.get('Directory', 'home', fallback='https://github.com/grindsa/acme2certifier') try: - self.suppress_product_information = config_dic.getboolean('Directory', 'suppress_product_information', fallback= False) + self.suppress_product_information = config_dic.getboolean('Directory', 'suppress_product_information', fallback=False) except Exception as err_: self.logger.error('Directory._config_load() suppress_product_information not set: %s', err_) @@ -87,7 +87,6 @@ def directory_get(self) -> Dict[str, str]: if self.home != 'https://github.com/grindsa/acme2certifier': d_dic['meta']['home'] = self.home - # add terms of service if self.tos_url: d_dic['meta']['termsOfService'] = self.tos_url From 707d6329b9778e941f4cc22367dcd5c15f4d417d Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 24 Mar 2024 19:59:18 +0100 Subject: [PATCH 146/460] [wf] msca workflow including header_info_test --- .github/workflows/ca_handler_tests_msca.yml | 142 +++++++++++++++----- 1 file changed, 110 insertions(+), 32 deletions(-) diff --git a/.github/workflows/ca_handler_tests_msca.yml b/.github/workflows/ca_handler_tests_msca.yml index 44f20d66..0b81c28c 100644 --- a/.github/workflows/ca_handler_tests_msca.yml +++ b/.github/workflows/ca_handler_tests_msca.yml @@ -197,6 +197,7 @@ jobs: sudo echo "domain_controller: $RUNNER_IP" >> examples/Docker/data/acme_srv.cfg sudo echo "ca_bundle: volume/ca_certs.pem" >> examples/Docker/data/acme_srv.cfg sudo echo "use_kerberos: True" >> examples/Docker/data/acme_srv.cfg + sudo sed -i "s/tnauthlist_support: False/tnauthlist_support: False\nheader_info_list: [\"HTTP_USER_AGENT\"]/g" examples/Docker/data/acme_srv.cfg sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout: 40/g" examples/Docker/data/acme_srv.cfg cd examples/Docker/ docker-compose restart @@ -227,6 +228,7 @@ jobs: run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force openssl verify -CAfile examples/Docker/data/ca_certs.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Server" - name: Check for kerberos connection" working-directory: examples/Docker/ @@ -238,15 +240,32 @@ jobs: sudo rm -rf certbot/ docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "Ernoll certbot" + - name: "Enroll lego with template in acme_srv.cfg (WebServer)" run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - sudo openssl verify -CAfile examples/Docker/data/ca_certs.pem certbot/live/certbot/cert.pem + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + sudo openssl verify -CAfile examples/Docker/data/ca_certs.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Server" - - name: "Enroll lego" + - name: "Enroll acme.sh with template in acme_srv.cfg (WebServer)" run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force + openssl verify -CAfile examples/Docker/data/ca_certs.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Server" + + - name: "Enroll lego with template submitted in command line (WebServerModified)" + run: | + sudo rm -rf lego/ + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent template=WebServerModified --key-type=rsa2048 -d lego.acme --http run sudo openssl verify -CAfile examples/Docker/data/ca_certs.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Client" + + - name: "Enroll acme.sh with template submitted in command line (WebServerModified)" + run: | + sudo rm -rf acme-sh/ + docker restart acme-sh + docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --keylength 2048 --issue -d acme-sh.acme --alpn --standalone --useragent template=WebServerModified --debug 3 --output-insecure --force + openssl verify -CAfile examples/Docker/data/ca_certs.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Client" - name: "Setup a2c with mscertsrv_ca_handler" run: | @@ -263,6 +282,7 @@ jobs: sudo echo "ca_bundle: volume/ca_certs.pem" >> examples/Docker/data/acme_srv.cfg sudo echo "WCCE_HOST: $WCCE_HOST" >> examples/Docker/data/acme_srv.cfg sudo echo "request_timeout: 30" >> examples/Docker/data/acme_srv.cfg + sudo sed -i "s/tnauthlist_support: False/tnauthlist_support: False\nheader_info_list: [\"HTTP_USER_AGENT\"]/g" examples/Docker/data/acme_srv.cfg sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout: 40/g" examples/Docker/data/acme_srv.cfg cd examples/Docker/ docker-compose restart @@ -291,20 +311,42 @@ jobs: sudo rm -rf certbot/ docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "Enroll certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - sudo openssl verify -CAfile examples/Docker/data/ca_certs.pem certbot/live/certbot/cert.pem - - - name: "Enroll lego" + - name: "Enroll lego with template in acme_srv.cfg (WebServer)" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run sudo openssl verify -CAfile examples/Docker/data/ca_certs.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Server" - - name: "Enroll acme.sh" + - name: "Enroll acme.sh with template in acme_srv.cfg (WebServer)" run: | + sudo rm -rf acme-sh/ + docker restart acme-sh docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force openssl verify -CAfile examples/Docker/data/ca_certs.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Server" + + - name: "Enroll lego with template submitted in command line (WebServerModified)" + run: | + sudo rm -rf lego/ + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent template=WebServerModified --key-type=rsa2048 -d lego.acme --http run + sudo openssl verify -CAfile examples/Docker/data/ca_certs.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Client" + + - name: "Enroll acme.sh with template submitted in command line (WebServerModified)" + run: | + sudo rm -rf acme-sh/ + docker restart acme-sh + docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --keylength 2048 --issue -d acme-sh.acme --alpn --standalone --useragent template=WebServerModified --debug 3 --output-insecure --force + openssl verify -CAfile examples/Docker/data/ca_certs.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Client" + + - name: "Enroll acme.sh with template submitted in command line (WebServerModified)" + run: | + sudo rm -rf acme-sh/ + docker restart acme-sh + docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --keylength 2048 --issue -d acme-sh.acme --alpn --standalone --useragent template=WebServerModified --debug 3 --output-insecure --force + openssl verify -CAfile examples/Docker/data/ca_certs.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Client" - name: "[ * ] collecting test logs" if: ${{ failure() }} @@ -518,7 +560,7 @@ jobs: docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run sudo openssl verify -CAfile data/acme_ca/ca_certs.pem lego/certificates/lego.acme.crt - - name: "[ PREPARE ] prepare acme_srv.cfg with ms_wcce_ca_handler" + - name: "Setup a2c with ms_wcce_ca_handler (Kerboros)" run: | mkdir -p data/acme_ca sudo touch data/acme_ca/ca_certs.pem @@ -537,6 +579,7 @@ jobs: sudo echo "domain_controller: $RUNNER_IP" >> data/acme_srv.cfg sudo echo "ca_bundle: /opt/acme2certifier/volume/acme_ca/ca_certs.pem" >> data/acme_srv.cfg sudo echo "use_kerberos: True" >> data/acme_srv.cfg + sudo sed -i "s/tnauthlist_support: False/tnauthlist_support: False\nheader_info_list: [\"HTTP_USER_AGENT\"]/g" data/acme_srv.cfg sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout: 40/g" data/acme_srv.cfg env: RUNNER_IP: ${{ env.RUNNER_IP }} @@ -560,25 +603,37 @@ jobs: - name: "Test http://acme-srv/directory is accessable " run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "Enroll acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force - openssl verify -CAfile data/acme_ca/ca_certs.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "Register certbot" run: | - sudo rm -rf certbot/* + sudo rm -rf certbot/ docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "Enroll certbot" + - name: "Enroll lego with template in acme_srv.cfg (WebServer)" run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - sudo openssl verify -CAfile data/acme_ca/ca_certs.pem certbot/live/certbot/cert.pem + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + sudo openssl verify -CAfile data/acme_ca/ca_certs.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Server" - - name: "Enroll lego" + - name: "Enroll acme.sh with template in acme_srv.cfg (WebServer)" run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force + openssl verify -CAfile data/acme_ca/ca_certs.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Server" + + - name: "Enroll lego with template submitted in command line (WebServerModified)" + run: | + sudo rm -rf lego/ + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent template=WebServerModified --key-type=rsa2048 -d lego.acme --http run sudo openssl verify -CAfile data/acme_ca/ca_certs.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Client" + + - name: "Enroll acme.sh with template submitted in command line (WebServerModified)" + run: | + sudo rm -rf acme-sh/ + docker restart acme-sh + docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --keylength 2048 --issue -d acme-sh.acme --alpn --standalone --useragent template=WebServerModified --debug 3 --output-insecure --force + openssl verify -CAfile data/acme_ca/ca_certs.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Client" - name: "Setup a2c with mscertsrv_ca_handler" run: | @@ -595,6 +650,7 @@ jobs: sudo echo "template: $WES_TEMPLATE" >> data/acme_srv.cfg sudo echo "ca_bundle: volume/acme_ca/ca_certs.pem" >> data/acme_srv.cfg sudo echo "request_timeout: 30" >> data/acme_srv.cfg + sudo sed -i "s/tnauthlist_support: False/tnauthlist_support: False\nheader_info_list: [\"HTTP_USER_AGENT\"]/g" data/acme_srv.cfg sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout: 40/g" data/acme_srv.cfg env: WES_HOST: ${{ secrets.WES_HOST }} @@ -617,23 +673,45 @@ jobs: - name: "Register certbot" run: | - sudo rm -rf certbot/* + sudo rm -rf certbot/ docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "Enroll certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - sudo openssl verify -CAfile data/acme_ca/ca_certs.pem certbot/live/certbot/cert.pem - - - name: "Enroll lego" + - name: "Enroll lego with template in acme_srv.cfg (WebServer)" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run sudo openssl verify -CAfile data/acme_ca/ca_certs.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Server" - - name: "Enroll acme.sh" + - name: "Enroll acme.sh with template in acme_srv.cfg (WebServer)" run: | + sudo rm -rf acme-sh/ + docker restart acme-sh docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force openssl verify -CAfile data/acme_ca/ca_certs.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Server" + + - name: "Enroll lego with template submitted in command line (WebServerModified)" + run: | + sudo rm -rf lego/ + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent template=WebServerModified --key-type=rsa2048 -d lego.acme --http run + sudo openssl verify -CAfile data/acme_ca/ca_certs.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Client" + + - name: "Enroll acme.sh with template submitted in command line (WebServerModified)" + run: | + sudo rm -rf acme-sh/ + docker restart acme-sh + docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --keylength 2048 --issue -d acme-sh.acme --alpn --standalone --useragent template=WebServerModified --debug 3 --output-insecure --force + openssl verify -CAfile data/acme_ca/ca_certs.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Client" + + - name: "Enroll acme.sh with template submitted in command line (WebServerModified)" + run: | + sudo rm -rf acme-sh/ + docker restart acme-sh + docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --keylength 2048 --issue -d acme-sh.acme --alpn --standalone --useragent template=WebServerModified --debug 3 --output-insecure --force + openssl verify -CAfile data/acme_ca/ca_certs.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Client" - name: "[ * ] collecting test logs" if: ${{ failure() }} From af544c17e18eaca97a923a52317a2db844bec528 Mon Sep 17 00:00:00 2001 From: grindsa Date: Mon, 25 Mar 2024 06:50:31 +0100 Subject: [PATCH 147/460] [fix] address codesmells --- acme_srv/directory.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/acme_srv/directory.py b/acme_srv/directory.py index 914e7f49..bdf6b097 100644 --- a/acme_srv/directory.py +++ b/acme_srv/directory.py @@ -9,6 +9,9 @@ from .db_handler import DBstore +GH_HOME = 'https://github.com/grindsa/acme2certifier' + + class Directory(object): """ class for directory handling """ @@ -18,7 +21,7 @@ def __init__(self, debug=None, srv_name=None, logger=None): self.dbstore = DBstore(debug, self.logger) self.supress_version = False self.suppress_product_information = False - self.home = 'https://github.com/grindsa/acme2certifier' + self.home = GH_HOME self.tos_url = None self.version = __version__ self.dbversion = __dbversion__ @@ -50,7 +53,7 @@ def _config_load(self): if 'Directory' in config_dic and 'url_prefix' in config_dic['Directory']: self.url_prefix = config_dic['Directory']['url_prefix'] - self.home = config_dic.get('Directory', 'home', fallback='https://github.com/grindsa/acme2certifier') + self.home = config_dic.get('Directory', 'home', fallback=GH_HOME) try: self.suppress_product_information = config_dic.getboolean('Directory', 'suppress_product_information', fallback=False) @@ -84,7 +87,7 @@ def directory_get(self) -> Dict[str, str]: if not self.supress_version: d_dic['meta']['version'] = self.version else: - if self.home != 'https://github.com/grindsa/acme2certifier': + if self.home != GH_HOME: d_dic['meta']['home'] = self.home # add terms of service From fee9056b628a12bf507d1f38cd5ac602c04c50d2 Mon Sep 17 00:00:00 2001 From: grindsa Date: Mon, 25 Mar 2024 07:06:42 +0100 Subject: [PATCH 148/460] [fix] address codesmells reported by sonarcube --- acme_srv/helper.py | 2 +- examples/ca_handler/openssl_ca_handler.py | 8 +++----- examples/ca_handler/xca_ca_handler.py | 4 ++-- examples/db_handler/wsgi_handler.py | 2 -- test/test_openssl_ca_handler.py | 14 +++++++------- 5 files changed, 13 insertions(+), 17 deletions(-) diff --git a/acme_srv/helper.py b/acme_srv/helper.py index 0d7dbacd..46048d22 100644 --- a/acme_srv/helper.py +++ b/acme_srv/helper.py @@ -1101,7 +1101,7 @@ def txt_get(logger: logging.Logger, fqdn: str, dns_srv: List[str] = None) -> Lis def uts_now(): """ unixtimestamp in utc """ - return calendar.timegm(datetime.datetime.utcnow().utctimetuple()) + return calendar.timegm(datetime.datetime.now(datetime.timezone.utc).utctimetuple()) def uts_to_date_utc(uts: int, tformat: str = '%Y-%m-%dT%H:%M:%SZ') -> str: diff --git a/examples/ca_handler/openssl_ca_handler.py b/examples/ca_handler/openssl_ca_handler.py index 6600fc3c..1448bd3a 100644 --- a/examples/ca_handler/openssl_ca_handler.py +++ b/examples/ca_handler/openssl_ca_handler.py @@ -517,7 +517,6 @@ def _cert_expiry_get(self, cert): """ get expiry date of certificate """ self.logger.debug('CAhandler._cert_expiry_get()') - # cert.not_valid_after - datetime.datetime.utcnow() expiry_date = cert.not_valid_after self.logger.debug('CAhandler._cert_expiry_get() ended') @@ -531,7 +530,6 @@ def _cacert_expiry_get(self): if self.issuer_dict['issuing_ca_cert']: ca_list.append(self.issuer_dict['issuing_ca_cert']) - # ca_cert.not_valid_after - datetime.datetime.utcnow() expiry_days = 0 cert = None @@ -540,7 +538,7 @@ def _cacert_expiry_get(self): if os.path.exists(ca_cert): with open(ca_cert, 'rb') as fso: ca_cert = x509.load_pem_x509_certificate(fso.read(), backend=default_backend()) - _tmp_expiry_days = (self._cert_expiry_get(ca_cert) - datetime.datetime.utcnow()).days + _tmp_expiry_days = (self._cert_expiry_get(ca_cert) - datetime.datetime.now()).days if not expiry_days or _tmp_expiry_days < expiry_days: self.logger.debug('CAhandler._cacert_expiry_get(): set expiry_days to {0}'.format(_tmp_expiry_days)) expiry_days = _tmp_expiry_days @@ -556,7 +554,7 @@ def _certexpiry_date_default(self) -> datetime.datetime: self.logger.debug('CAhandler._certexpiry_date_default()') # default cert validity is taken from config - cert_validity = datetime.datetime.utcnow() + datetime.timedelta(days=self.cert_validity_days) + cert_validity = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(days=self.cert_validity_days) self.logger.debug('CAhandler._certexpiry_date_default() ended') return cert_validity @@ -588,7 +586,7 @@ def _cert_signing_prep(self, ca_cert: object, req: object, subject: str) -> obje # sign csr builder = x509.CertificateBuilder() - builder = builder.not_valid_before(datetime.datetime.utcnow()) + builder = builder.not_valid_before(datetime.datetime.now(datetime.timezone.utc)) builder = builder.not_valid_after(cert_validity) builder = builder.issuer_name(ca_cert.subject) builder = builder.subject_name(subject) diff --git a/examples/ca_handler/xca_ca_handler.py b/examples/ca_handler/xca_ca_handler.py index 2b402114..1cea337a 100644 --- a/examples/ca_handler/xca_ca_handler.py +++ b/examples/ca_handler/xca_ca_handler.py @@ -257,8 +257,8 @@ def _cert_sign(self, csr: str, request_name: str, ca_key: object, ca_cert: objec builder = x509.CertificateBuilder() # set not valid before - builder = builder.not_valid_before(datetime.datetime.utcnow()) - builder = builder.not_valid_after(datetime.datetime.utcnow() + datetime.timedelta(days=cert_validity)) + builder = builder.not_valid_before(datetime.datetime.now(datetime.timezone.utc)) + builder = builder.not_valid_after(datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(days=cert_validity)) builder = builder.issuer_name(ca_cert.subject) builder = builder.serial_number(uuid.uuid4().int & (1 << 63) - 1) builder = builder.public_key(req.public_key()) diff --git a/examples/db_handler/wsgi_handler.py b/examples/db_handler/wsgi_handler.py index 95ee428c..b0eef3e0 100644 --- a/examples/db_handler/wsgi_handler.py +++ b/examples/db_handler/wsgi_handler.py @@ -313,8 +313,6 @@ def _db_open(self): self.dbs = sqlite3.connect(self.db_name) self.dbs.row_factory = sqlite3.Row self.cursor = self.dbs.cursor() - # self.cursor.execute('''PRAGMA journal_mode=WAL''') - # self.logger.debug('DBStore._db_open() ended') def _db_update_account(self): """ update account table """ diff --git a/test/test_openssl_ca_handler.py b/test/test_openssl_ca_handler.py index f8c3d52c..5b3d809b 100644 --- a/test/test_openssl_ca_handler.py +++ b/test/test_openssl_ca_handler.py @@ -1510,7 +1510,7 @@ def test_138__cacert_expiry_get(self, mock_certload, mock_exists, mock_exp, mock """ test _cacert_expiry_get() """ mock_certload.return_value = 'cert1' mock_exp.return_value = datetime.datetime(2024, 12, 31, 5, 0, 1) - mock_now.datetime.utcnow.return_value = datetime.datetime(2023, 12, 31, 5, 0, 1) + mock_now.datetime.now.return_value = datetime.datetime(2023, 12, 31, 5, 0, 1) mock_exists.return_value = True self.cahandler.ca_cert_chain_list = ['cacert1'] self.assertEqual((366, 'cert1'), self.cahandler._cacert_expiry_get()) @@ -1524,7 +1524,7 @@ def test_139__cacert_expiry_get(self, mock_certload, mock_exists, mock_exp, mock """ test _cacert_expiry_get() """ mock_certload.side_effect = ['cert1', 'cert2'] mock_exp.side_effect = [datetime.datetime(2024, 12, 31, 5, 0, 1), datetime.datetime(2024, 11, 30, 5, 0, 1)] - mock_now.datetime.utcnow.return_value = datetime.datetime(2023, 12, 31, 5, 0, 1) + mock_now.datetime.now.return_value = datetime.datetime(2023, 12, 31, 5, 0, 1) mock_exists.return_value = True self.cahandler.ca_cert_chain_list = ['cacert1', 'cacert2'] self.assertEqual((335, 'cert2'), self.cahandler._cacert_expiry_get()) @@ -1538,7 +1538,7 @@ def test_140__cacert_expiry_get(self, mock_certload, mock_exists, mock_exp, mock """ test _cacert_expiry_get() """ mock_certload.side_effect = ['cert1', 'cert2'] mock_exp.side_effect = [datetime.datetime(2024, 10, 30, 5, 0, 1), datetime.datetime(2024, 12, 31, 5, 0, 1)] - mock_now.datetime.utcnow.return_value = datetime.datetime(2023, 12, 31, 5, 0, 1) + mock_now.datetime.now.return_value = datetime.datetime(2023, 12, 31, 5, 0, 1) mock_exists.return_value = True self.cahandler.ca_cert_chain_list = ['cacert1', 'cacert2'] self.assertEqual((304, 'cert1'), self.cahandler._cacert_expiry_get()) @@ -1552,7 +1552,7 @@ def test_141__cacert_expiry_get(self, mock_certload, mock_exists, mock_exp, mock """ test _cacert_expiry_get() """ mock_certload.side_effect = ['cert1', 'issuing_ca_cert'] mock_exp.side_effect = [datetime.datetime(2024, 12, 31, 5, 0, 1), datetime.datetime(2024, 11, 30, 5, 0, 1)] - mock_now.datetime.utcnow.return_value = datetime.datetime(2023, 12, 31, 5, 0, 1) + mock_now.datetime.now.return_value = datetime.datetime(2023, 12, 31, 5, 0, 1) mock_exists.return_value = True self.cahandler.ca_cert_chain_list = ['cacert1'] self.cahandler.issuer_dict = {'issuing_ca_cert' : 'issuing_ca_cert'} @@ -1567,7 +1567,7 @@ def test_142__cacert_expiry_get(self, mock_certload, mock_exists, mock_exp, mock """ test _cacert_expiry_get() """ mock_certload.side_effect = ['cert1', 'issuing_ca_cert'] mock_exp.side_effect = [datetime.datetime(2024, 10, 30, 5, 0, 1), datetime.datetime(2024, 12, 31, 5, 0, 1)] - mock_now.datetime.utcnow.return_value = datetime.datetime(2023, 12, 31, 5, 0, 1) + mock_now.datetime.now.return_value = datetime.datetime(2023, 12, 31, 5, 0, 1) mock_exists.return_value = True self.cahandler.ca_cert_chain_list = ['cacert1'] self.cahandler.issuer_dict = {'issuing_ca_cert' : 'issuing_ca_cert'} @@ -1582,7 +1582,7 @@ def test_143__cacert_expiry_get(self, mock_certload, mock_exists, mock_exp, mock """ test _cacert_expiry_get() """ mock_certload.side_effect = ['cert1', 'cert2'] mock_exp.side_effect = [datetime.datetime(2024, 12, 31, 5, 0, 1), datetime.datetime(2024, 11, 30, 5, 0, 1)] - mock_now.datetime.utcnow.return_value = datetime.datetime(2023, 12, 31, 5, 0, 1) + mock_now.datetime.now.return_value = datetime.datetime(2023, 12, 31, 5, 0, 1) mock_exists.side_effect = [True, False] self.cahandler.ca_cert_chain_list = ['cacert1', 'cacert2'] with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -1598,7 +1598,7 @@ def test_144__cert_expiry_get(self): @patch('examples.ca_handler.openssl_ca_handler.datetime') def test_145__certexpiry_date_default(self, mock_now): """ test _certexpiry_date_default() """ - mock_now.datetime.utcnow.return_value = datetime.datetime(2023, 12, 31, 5, 0, 1) + mock_now.datetime.now.return_value = datetime.datetime(2023, 12, 31, 5, 0, 1) mock_now.timedelta.return_value = datetime.timedelta(days=2) self.assertEqual(datetime.datetime(2024, 1, 2, 5, 0, 1), self.cahandler._certexpiry_date_default()) From bf29bcda29aeda6f9f6e5111eddae3902702535b Mon Sep 17 00:00:00 2001 From: grindsa Date: Tue, 26 Mar 2024 06:56:24 +0100 Subject: [PATCH 149/460] [doc] updated Changes.md --- CHANGES.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index db5e8bd5..a339f2bc 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,6 +5,23 @@ This is a high-level summary of the most important changes. For a full list of changes, see the [git commit log](https://github.com/grindsa/acme2certifier/commits) and pick the appropriate release branch. +# Changes in devel + +**Features and Improvements**: + +- [#144](https://github.com/grindsa/acme2certifier/issues/144) configuration option to supress product name +- [#143](https://github.com/grindsa/acme2certifier/issues/143) template name as part of the user-agent field in wcce/wes handler +- configuration option to limit the number of identifiers in a single order request +- `burst` parameter in example nginx.conf to ratelimit incoming requests +- [container images for arm64 plattforms](https://hub.docker.com/layers/grindsa/acme2certifier/apache2-wsgi/images/sha256-9092e98ad23fa94dfb17534333a9306ec447b274c2e4b5bbaee0b8bc41c6becc?context=repo) +- regression tests on arm64 plattforms + +**Bugfixes**: + +- #147(https://github.com/grindsa/acme2certifier/pull/147) correct content-type for problem+json message +- updated [eab-example files](https://github.com/grindsa/acme2certifier/tree/master/examples/eab_handler) as hmac must be longer than 256bits +- identifier sanitizing + # Changes in 0.33.3 **Features and Improvements**: From ac21a1361974574608ad99e8dc9fe0aee789289b Mon Sep 17 00:00:00 2001 From: grindsa Date: Fri, 29 Mar 2024 07:59:50 +0100 Subject: [PATCH 150/460] [wf] refactor workflows include matrix testing --- .../workflows/acme_sh-application-test.yml | 433 ++---------------- .github/workflows/alpn-test.yml | 70 +-- .github/workflows/ari-test.yml | 315 ++----------- .github/workflows/ca_handler_tests_asa.yml | 76 ++- .../workflows/ca_handler_tests_certifier.yml | 26 +- .github/workflows/ca_handler_tests_nclm.yml | 33 +- .github/workflows/caddy-application-test.yml | 303 +----------- .../workflows/certbot-application-test.yml | 354 +------------- .../certmanager-application-test.yml | 124 +++-- .github/workflows/container-tests.yml | 62 +-- .github/workflows/dns-test.yml | 74 +-- .github/workflows/eab-test.yml | 165 ++++--- .github/workflows/enrollment-timeout.yml | 197 ++------ .github/workflows/hooks-test.yml | 188 +++++--- .github/workflows/ip-address-tests.yml | 314 ++----------- .github/workflows/ipv6-test.yml | 294 ++---------- .github/workflows/lego-application-test.yml | 336 +------------- .github/workflows/proxy-test.yml | 125 ++--- .github/workflows/tnauth-test.yml | 41 +- .../workflows/traffic-application-test.yml | 33 +- 20 files changed, 856 insertions(+), 2707 deletions(-) diff --git a/.github/workflows/acme_sh-application-test.yml b/.github/workflows/acme_sh-application-test.yml index 5920afd7..eaf3ce58 100644 --- a/.github/workflows/acme_sh-application-test.yml +++ b/.github/workflows/acme_sh-application-test.yml @@ -9,290 +9,40 @@ on: - cron: '0 2 * * 6' jobs: - acme_sh_apache2_wsgi: - name: "acme_sh_apache2_wsgi" + acme_container_tests: + name: "acme_container_tests" runs-on: ubuntu-latest strategy: fail-fast: false matrix: accountkeylength: [2048, ec-256, ec-521] - keylength: [2048, 4096, ec-521] + keylength: [2048, ec-521] + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker network create acme docker-compose up -d docker-compose logs - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" - run: | - sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem - sudo touch examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg - sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_host: $NCM_API_HOST" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_user: $NCM_API_USER" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_password: $NCM_API_PASSWORD" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_name: $NCM_CA_NAME" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - docker-compose restart - docker-compose logs env: - NCM_API_HOST: ${{ secrets.NCM_API_HOST }} - NCM_API_USER: ${{ secrets.NCM_API_USER }} - NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} - NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} - NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - - name: "[ PREPARE ] prepare acme.sh container" - run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - - name: "[ ENROLL ] HTTP-01 single domain acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength ${{ matrix.keylength }} --accountkeylength ${{ matrix.accountkeylength }} --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="_ecc" - fi - awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme${ECC}/ca.cer - openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer - - - name: "[ RENEW ] HTTP-01 single domain acme.sh" - run: | - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="--ecc" - fi - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength ${{ matrix.keylength }} --renew --force ${ECC} -d acme-sh.acme --standalone --debug 3 --output-insecure - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="_ecc" - fi - openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer - - - name: "[ REVOKE ] HTTP-01 single domain acme.sh" - run: | - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="--ecc" - fi - docker exec -i acme-sh acme.sh --server http://acme-srv --revoke ${ECC} -d acme-sh.acme --standalone --debug 2 --output-insecure - - - name: "[ ENROLL ] HTTP-01 2x domain acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength ${{ matrix.keylength }} --issue -d acme-sh.acme -d acme-sh. --standalone --debug 3 --output-insecure - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="_ecc" - fi - openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer - - - name: "[ RENEW ] HTTP-01 2x domain acme.sh" - run: | - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="--ecc" - fi - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength ${{ matrix.keylength }} --renew --force ${ECC} -d acme-sh.acme -d acme-sh. --standalone --debug 3 --output-insecure - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="_ecc" - fi - openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer - - - name: "[ REVOKE ] HTTP-01 2x domain acme.sh" - run: | - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="--ecc" - fi - docker exec -i acme-sh acme.sh --server http://acme-srv --revoke ${ECC} -d acme-sh.acme -d acme-sh. --standalone --debug 3 --output-insecure - - - name: "[ DEACTIVATE ] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --deactivate-account --debug 2 --output-insecure - - - name: "[ * ] collecting test data" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh - - - name: "[ * ] uploading artifacts" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: acme_sh_apache2_wsgi-${{ matrix.accountkeylength }}_key-${{ matrix.keylength }}.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - acme_sh_apache2_django: - name: "acme_sh_apache2_django" - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - accountkeylength: [2048, ec-256, ec-521] - keylength: [2048, 4096, ec-521] - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (apache2_django)" - working-directory: examples/Docker/ - run: | - sed -i "s/wsgi/django/g" .env - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "Setup a2c with certifier_ca_handler" run: | - sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem - sudo touch examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg - sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_host: $NCM_API_HOST" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_user: $NCM_API_USER" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_password: $NCM_API_PASSWORD" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_name: $NCM_CA_NAME" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> examples/Docker/data/acme_srv.cfg + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem sudo cp .github/django_settings.py examples/Docker/data/settings.py - cd examples/Docker/ - docker-compose restart - docker-compose logs - env: - NCM_API_HOST: ${{ secrets.NCM_API_HOST }} - NCM_API_USER: ${{ secrets.NCM_API_USER }} - NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} - NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} - NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - - name: "[ PREPARE ] prepare acme.sh container" - run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - - name: "[ ENROLL ] HTTP-01 single domain acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength ${{ matrix.keylength }} --accountkeylength ${{ matrix.accountkeylength }} --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="_ecc" - fi - awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme${ECC}/ca.cer - openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer - - - name: "[ RENEW ] HTTP-01 single domain acme.sh" - run: | - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="--ecc" - fi - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength ${{ matrix.keylength }} --renew --force ${ECC} -d acme-sh.acme --standalone --debug 3 --output-insecure - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="_ecc" - fi - openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer - - - name: "[ REVOKE ] HTTP-01 single domain acme.sh" - run: | - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="--ecc" - fi - docker exec -i acme-sh acme.sh --server http://acme-srv --revoke ${ECC} -d acme-sh.acme --standalone --debug 2 --output-insecure - - - name: "[ ENROLL ] HTTP-01 2x domain acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength ${{ matrix.keylength }} --issue -d acme-sh.acme -d acme-sh. --standalone --debug 3 --output-insecure - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="_ecc" - fi - openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer - - - name: "[ RENEW ] HTTP-01 2x domain acme.sh" - run: | - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="--ecc" - fi - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength ${{ matrix.keylength }} --renew --force ${ECC} -d acme-sh.acme -d acme-sh. --standalone --debug 3 --output-insecure - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="_ecc" - fi - openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer - - - name: "[ REVOKE ] HTTP-01 2x domain acme.sh" - run: | - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="--ecc" - fi - docker exec -i acme-sh acme.sh --server http://acme-srv --revoke ${ECC} -d acme-sh.acme -d acme-sh. --standalone --debug 3 --output-insecure - - - name: "[ DEACTIVATE ] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --deactivate-account --debug 2 --output-insecure - - - name: "[ * ] collecting test data" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh - - - name: "[ * ] uploading artifacts" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: acme_sh_apache2_django-${{ matrix.accountkeylength }}_key-${{ matrix.keylength }}.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - acme_sh_nginx_wsgi: - name: "acme_sh_nginx_wsgi" - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - accountkeylength: [2048, ec-256, ec-521] - keylength: [2048, 4096, ec-521] - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (nginx_django)" - working-directory: examples/Docker/ - run: | - sed -i "s/apache2/nginx/g" .env - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" - run: | sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem sudo touch examples/Docker/data/acme_srv.cfg sudo chmod 777 examples/Docker/data/acme_srv.cfg @@ -313,107 +63,7 @@ jobs: NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "[ PREPARE ] prepare acme.sh container" - run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - - name: "[ ENROLL ] HTTP-01 single domain acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength ${{ matrix.keylength }} --accountkeylength ${{ matrix.accountkeylength }} --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="_ecc" - fi - awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme${ECC}/ca.cer - openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer - - - name: "[ RENEW ] HTTP-01 single domain acme.sh" - run: | - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="--ecc" - fi - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength ${{ matrix.keylength }} --renew --force ${ECC} -d acme-sh.acme --standalone --debug 3 --output-insecure - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="_ecc" - fi - openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer - - - name: "[ REVOKE ] HTTP-01 single domain acme.sh" - run: | - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="--ecc" - fi - docker exec -i acme-sh acme.sh --server http://acme-srv --revoke ${ECC} -d acme-sh.acme --standalone --debug 2 --output-insecure - - - name: "[ ENROLL ] HTTP-01 2x domain acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength ${{ matrix.keylength }} --issue -d acme-sh.acme -d acme-sh. --standalone --debug 3 --output-insecure - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="_ecc" - fi - openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer - - - name: "[ RENEW ] HTTP-01 2x domain acme.sh" - run: | - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="--ecc" - fi - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength ${{ matrix.keylength }} --renew --force ${ECC} -d acme-sh.acme -d acme-sh. --standalone --debug 3 --output-insecure - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="_ecc" - fi - openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer - - - name: "[ REVOKE ] HTTP-01 2x domain acme.sh" - run: | - if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then - ECC="--ecc" - fi - docker exec -i acme-sh acme.sh --server http://acme-srv --revoke ${ECC} -d acme-sh.acme -d acme-sh. --standalone --debug 3 --output-insecure - - - name: "[ DEACTIVATE ] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --deactivate-account --debug 2 --output-insecure - - - name: "[ * ] collecting test data" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh - - - name: "[ * ] uploading artifacts" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: acme_sh_nginx_wsgi-${{ matrix.accountkeylength }}_key-${{ matrix.keylength }}.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - acme_sh_nginx_django: - name: "acme_sh_nginx_django" - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - accountkeylength: [2048, ec-256, ec-521] - keylength: [2048, 4096, ec-521] - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (nginx_django)" - working-directory: examples/Docker/ - run: | - sed -i "s/wsgi/django/g" .env - sed -i "s/apache2/nginx/g" .env - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "[ WAIT ] Sleep for 10s" + - name: "Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -421,43 +71,23 @@ jobs: - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" - run: | - sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem - sudo touch examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg - sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_host: $NCM_API_HOST" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_user: $NCM_API_USER" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_password: $NCM_API_PASSWORD" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_name: $NCM_CA_NAME" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> examples/Docker/data/acme_srv.cfg - sudo cp .github/django_settings.py examples/Docker/data/settings.py - cd examples/Docker/ - docker-compose restart - docker-compose logs - env: - NCM_API_HOST: ${{ secrets.NCM_API_HOST }} - NCM_API_USER: ${{ secrets.NCM_API_USER }} - NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} - NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} - NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" + - name: "Prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ ENROLL ] HTTP-01 single domain acme.sh" + - name: "Enroll HTTP-01 single domain acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --keylength ${{ matrix.keylength }} --accountkeylength ${{ matrix.accountkeylength }} --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then ECC="_ecc" fi awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme${ECC}/ca.cer - openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer - - name: "[ RENEW ] HTTP-01 single domain acme.sh" + - name: "Renew HTTP-01 single domain acme.sh" run: | if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then ECC="--ecc" @@ -466,24 +96,24 @@ jobs: if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then ECC="_ecc" fi - openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer - - name: "[ REVOKE ] HTTP-01 single domain acme.sh" + - name: "RevokeHTTP-01 single domain acme.sh" run: | if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then ECC="--ecc" fi docker exec -i acme-sh acme.sh --server http://acme-srv --revoke ${ECC} -d acme-sh.acme --standalone --debug 2 --output-insecure - - name: "[ ENROLL ] HTTP-01 2x domain acme.sh" + - name: "Enroll HTTP-01 2x domain acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --keylength ${{ matrix.keylength }} --issue -d acme-sh.acme -d acme-sh. --standalone --debug 3 --output-insecure if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then ECC="_ecc" fi - openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer - - name: "[ RENEW ] HTTP-01 2x domain acme.sh" + - name: "Renew HTTP-01 2x domain acme.sh" run: | if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then ECC="--ecc" @@ -492,16 +122,16 @@ jobs: if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then ECC="_ecc" fi - openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme${ECC}/acme-sh.acme.cer - - name: "[ REVOKE ] HTTP-01 2x domain acme.sh" + - name: "Revoke HTTP-01 2x domain acme.sh" run: | if ([ "${{ matrix.keylength }}" == "ec-256" ] || [ "${{ matrix.keylength }}" == "ec-384" ] || [ "${{ matrix.keylength }}" == "ec-521" ]) ; then ECC="--ecc" fi docker exec -i acme-sh acme.sh --server http://acme-srv --revoke ${ECC} -d acme-sh.acme -d acme-sh. --standalone --debug 3 --output-insecure - - name: "[ DEACTIVATE ] acme.sh" + - name: "Decativate acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --deactivate-account --debug 2 --output-insecure @@ -519,5 +149,6 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: acme_sh_nginx_django-${{ matrix.accountkeylength }}_key-${{ matrix.keylength }}.tar.gz + name: acme_sh_apache2_wsgi-${{ matrix.accountkeylength }}_key-${{ matrix.keylength }}.${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ + diff --git a/.github/workflows/alpn-test.yml b/.github/workflows/alpn-test.yml index 3b08611f..73d9b32b 100644 --- a/.github/workflows/alpn-test.yml +++ b/.github/workflows/alpn-test.yml @@ -9,31 +9,43 @@ on: - cron: '0 2 * * 6' jobs: - alpn_apache2_wsgi: - name: "alpn_apache2_wsgi" + alpn_container_tests: + name: "alpn_container_tests" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] create letsencrypt and lego folder" + - name: "create letsencrypt and lego folder" run: | mkdir acmme-sh mkdir lego - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker network create acme docker-compose up -d docker-compose logs + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "setup a2c with certifier_ca_handler" run: | + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem sudo touch examples/Docker/data/acme_srv.cfg sudo chmod 777 examples/Docker/data/acme_srv.cfg @@ -54,21 +66,29 @@ jobs: NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "Test http://acme-srv/directory is accessable again" + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ ENROLL ] acme.sh" + - name: "Enroll acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer ls -la *.pem openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ ENROLL ] lego" + - name: "Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --tls run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt @@ -77,18 +97,17 @@ jobs: if: ${{ failure() }} run: | mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + # sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ + # sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ cd examples/Docker docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh lego - + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data - name: "[ * ] uploading artificates" uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: alpn.tar.gz + name: alpn_containercontainer-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ @@ -122,7 +141,7 @@ jobs: - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" - - name: "[ PREPARE ] setup environment for alma installation" + - name: "setup environment for alma installation" run: | docker network create acme sudo mkdir -p data @@ -130,7 +149,7 @@ jobs: sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data - - name: "[ PREPARE ] create letsencrypt and lego folder" + - name: "create letsencrypt and lego folder" run: | mkdir acmme-sh mkdir lego @@ -143,7 +162,7 @@ jobs: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "setup a2c with certifier_ca_handler" run: | mkdir -p data/acme_ca sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem @@ -164,36 +183,35 @@ jobs: NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "[ PREPARE ] Almalinux instance" + - name: "Almalinux instance" run: | sudo cp examples/Docker/almalinux-systemd/Dockerfile data sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - - name: "[ RUN ] Execute install scipt" + - name: "Execute install scipt" run: | docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh - name: "Test http://acme-srv/directory is accessible" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" + - name: "prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ ENROLL ] acme.sh" + - name: "Enroll acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ ENROLL ] lego" + - name: "Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --tls run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | diff --git a/.github/workflows/ari-test.yml b/.github/workflows/ari-test.yml index 0cc05ace..fdb676ee 100644 --- a/.github/workflows/ari-test.yml +++ b/.github/workflows/ari-test.yml @@ -10,195 +10,44 @@ on: jobs: - ari_apache2_wsgi: - name: "ari_apache2_wsgi" + ari_container_tests: + name: "ari_container_tests" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" - working-directory: examples/Docker/ - run: | - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" - run: | - sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem - sudo touch examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg - sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_host: $NCM_API_HOST" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_user: $NCM_API_USER" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_password: $NCM_API_PASSWORD" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_name: $NCM_CA_NAME" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> examples/Docker/data/acme_srv.cfg - sudo echo -e "\n\n[Renewalinfo]" >> examples/Docker/data/acme_srv.cfg - sudo echo "renewal_force: True" >> examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - docker-compose restart - docker-compose logs - env: - NCM_API_HOST: ${{ secrets.NCM_API_HOST }} - NCM_API_USER: ${{ secrets.NCM_API_USER }} - NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} - NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} - NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - - name: "create lego folder" + - name: "create folders" run: | mkdir lego + mkdir acme-sh + mkdir certbot - - name: "[ ENROLL ] HTTP-01 single domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - sudo chmod 777 lego/certificates/lego.acme.issuer.crt - sudo cp lego/certificates/lego.acme.issuer.crt lego.acme.issuer.crt - sudo awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < lego.acme.issuer.crt - sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - - - name: "[ RENEW ] HTTP-01 single domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep 2> ari.txt - grep "renewalInfo endpoint indicates that renewal is needed" ari.txt - cat ari.txt - sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: ari_apache2_wsgi.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - ari_apache2_django: - name: "ari_apache2_django" - runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (apache2_django)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | - sed -i "s/wsgi/django/g" .env sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker network create acme docker-compose up -d docker-compose logs - - - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" - run: | - sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem - sudo touch examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg - sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_host: $NCM_API_HOST" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_user: $NCM_API_USER" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_password: $NCM_API_PASSWORD" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_name: $NCM_CA_NAME" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> examples/Docker/data/acme_srv.cfg - sudo echo -e "\n\n[Renewalinfo]" >> examples/Docker/data/acme_srv.cfg - sudo echo "renewal_force: True" >> examples/Docker/data/acme_srv.cfg - sudo cp .github/django_settings.py examples/Docker/data/settings.py - cd examples/Docker/ - docker-compose restart - docker-compose logs env: - NCM_API_HOST: ${{ secrets.NCM_API_HOST }} - NCM_API_USER: ${{ secrets.NCM_API_USER }} - NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} - NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} - NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - - name: "create lego folder" - run: | - mkdir lego - - - name: "[ ENROLL ] HTTP-01 single domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - sudo chmod 777 lego/certificates/lego.acme.issuer.crt - sudo cp lego/certificates/lego.acme.issuer.crt lego.acme.issuer.crt - sudo awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < lego.acme.issuer.crt - sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - - - name: "[ RENEW ] HTTP-01 single domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep 2> ari.txt - grep "renewalInfo endpoint indicates that renewal is needed" ari.txt - cat ari.txt - sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: ari_apache2_django.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - ari_nginx_wsgi: - name: "ari_nginx_wsgi" - runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (nginx_django)" - working-directory: examples/Docker/ - run: | - sed -i "s/apache2/nginx/g" .env - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "setup a2c with certifier_ca_handler" run: | + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem sudo touch examples/Docker/data/acme_srv.cfg sudo chmod 777 examples/Docker/data/acme_srv.cfg @@ -221,60 +70,7 @@ jobs: NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "create lego folder" - run: | - mkdir lego - - - name: "[ ENROLL ] HTTP-01 single domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - sudo chmod 777 lego/certificates/lego.acme.issuer.crt - sudo cp lego/certificates/lego.acme.issuer.crt lego.acme.issuer.crt - sudo awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < lego.acme.issuer.crt - sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - - - name: "[ RENEW ] HTTP-01 single domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep 2> ari.txt - grep "renewalInfo endpoint indicates that renewal is needed" ari.txt - cat ari.txt - sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: ari_nginx_wsgi.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - ari_nginx_django: - name: "lego_nginx_django" - runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (nginx_django)" - working-directory: examples/Docker/ - run: | - sed -i "s/wsgi/django/g" .env - sed -i "s/apache2/nginx/g" .env - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "[ WAIT ] Sleep for 10s" + - name: "Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -282,36 +78,10 @@ jobs: - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" - run: | - sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem - sudo touch examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg - sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_host: $NCM_API_HOST" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_user: $NCM_API_USER" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_password: $NCM_API_PASSWORD" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_name: $NCM_CA_NAME" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> examples/Docker/data/acme_srv.cfg - sudo echo -e "\n\n[Renewalinfo]" >> examples/Docker/data/acme_srv.cfg - sudo echo "renewal_force: True" >> examples/Docker/data/acme_srv.cfg - sudo cp .github/django_settings.py examples/Docker/data/settings.py - cd examples/Docker/ - docker-compose restart - docker-compose logs - env: - NCM_API_HOST: ${{ secrets.NCM_API_HOST }} - NCM_API_USER: ${{ secrets.NCM_API_USER }} - NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} - NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} - NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - - name: "create lego folder" - run: | - mkdir lego + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - name: "[ ENROLL ] HTTP-01 single domain lego" + - name: "Enroll HTTP-01 single domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run sudo chmod 777 lego/certificates/lego.acme.issuer.crt @@ -319,7 +89,7 @@ jobs: sudo awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < lego.acme.issuer.crt sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - - name: "[ RENEW ] HTTP-01 single domain lego" + - name: "Renew HTTP-01 single domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep 2> ari.txt grep "renewalInfo endpoint indicates that renewal is needed" ari.txt @@ -340,10 +110,9 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: ari_nginx_django.tar.gz + name: ari_container-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ - ari_wsgi_rpm: name: "ari_wsgi_rpm" runs-on: ubuntu-latest @@ -374,7 +143,7 @@ jobs: - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" - - name: "[ PREPARE ] setup environment for alma installation" + - name: "setup environment for alma installation" run: | docker network create acme sudo mkdir -p data @@ -382,7 +151,7 @@ jobs: sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data - - name: "[ PREPARE ] create lego folder" + - name: "create lego folder" run: | mkdir lego @@ -394,7 +163,7 @@ jobs: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "setup a2c with certifier_ca_handler" run: | mkdir -p data/acme_ca sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem @@ -418,18 +187,18 @@ jobs: NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "[ PREPARE ] Almalinux instance" + - name: "Almalinux instance" run: | sudo cp examples/Docker/almalinux-systemd/Dockerfile data sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - - name: "[ RUN ] Execute install scipt" + - name: "Execute install scipt" run: | docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh - - name: "[ ENROLL ] HTTP-01 single domain lego" + - name: "Enroll HTTP-01 single domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run sudo chmod 777 lego/certificates/lego.acme.issuer.crt @@ -437,7 +206,7 @@ jobs: sudo awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < lego.acme.issuer.crt sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - - name: "[ RENEW ] HTTP-01 single domain lego" + - name: "Renew HTTP-01 single domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep 2> ari.txt grep "renewalInfo endpoint indicates that renewal is needed" ari.txt @@ -498,7 +267,7 @@ jobs: - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" - - name: "[ PREPARE ] setup environment for alma installation" + - name: "setup environment for alma installation" run: | docker network create acme sudo mkdir -p data/volume @@ -513,7 +282,7 @@ jobs: sudo sed -i "s/\/var\/www\//\/opt\//g" data/acme2certifier/settings.py sudo sed -i "s/USE_I18N = True/USE_I18N = False/g" data/acme2certifier/settings.py - - name: "[ PREPARE ] create lego folder" + - name: "create lego folder" run: | mkdir lego @@ -525,7 +294,7 @@ jobs: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} - - name: "[ PREPARE ] prepare acme_srv.cfg with openssl_ca_handler" + - name: "prepare acme_srv.cfg with openssl_ca_handler" run: | sudo mkdir -p data/volume/acme_ca/certs sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem data/volume/acme_ca/ @@ -535,7 +304,7 @@ jobs: sudo echo "renewal_force: True" >> data/volume/acme_srv.cfg - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "setup a2c with certifier_ca_handler" run: | mkdir -p data/volume/acme_ca sudo cp test/ca/certsrv_ca_certs.pem data/volume/acme_ca/ca_certs.pem @@ -559,14 +328,14 @@ jobs: NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "[ PREPARE ] Almalinux instance" + - name: "Almalinux instance" run: | sudo cp examples/Docker/almalinux-systemd/Dockerfile data sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme -p 22280:80 --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - - name: "[ RUN ] Execute install scipt" + - name: "Execute install scipt" run: | docker exec acme-srv sh /tmp/acme2certifier/django_tester.sh @@ -576,7 +345,7 @@ jobs: - name: "Test if https://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - name: "[ ENROLL ] HTTP-01 single domain lego" + - name: "Enroll HTTP-01 single domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run sudo chmod 777 lego/certificates/lego.acme.issuer.crt @@ -584,7 +353,7 @@ jobs: sudo awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < lego.acme.issuer.crt sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - - name: "[ RENEW ] HTTP-01 single domain lego" + - name: "Renew HTTP-01 single domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http renew --ari-enable --no-random-sleep 2> ari.txt grep "renewalInfo endpoint indicates that renewal is needed" ari.txt diff --git a/.github/workflows/ca_handler_tests_asa.yml b/.github/workflows/ca_handler_tests_asa.yml index 67bd3ad9..2b991a4b 100644 --- a/.github/workflows/ca_handler_tests_asa.yml +++ b/.github/workflows/ca_handler_tests_asa.yml @@ -13,7 +13,6 @@ jobs: name: "asa_handler_tests" runs-on: ubuntu-latest strategy: - max-parallel: 1 fail-fast: false matrix: websrv: ['apache2', 'nginx'] @@ -42,7 +41,7 @@ jobs: WEB_SRV: ${{ matrix.websrv }} DB_HANDLER: ${{ matrix.dbhandler }} - - name: "[ PREPARE ] setup a2c with asa_ca_handler" + - name: "setup a2c with asa_ca_handler" run: | sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem @@ -84,11 +83,11 @@ jobs: - name: "Test if https://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" + - name: "prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ ENROLL ] acme.sh" + - name: "Enroll acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --keylength 2048 --debug 3 --output-insecure --force awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer @@ -100,11 +99,11 @@ jobs: run: | docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "[ REGISTER ] certbot" + - name: "Register certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ ENROLL ] HTTP-01 single domain certbot" + - name: "Enroll HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot --key-type rsa --rsa-key-size 2048 sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem @@ -115,7 +114,7 @@ jobs: run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - - name: "[ ENROLL ] lego" + - name: "Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --key-type rsa2048 --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt @@ -126,7 +125,7 @@ jobs: run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke - - name: "[ PREPARE ] reconfiguration of a2c with a new profile" + - name: "reconfiguration of a2c with a new profile" run: | sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem sudo touch examples/Docker/data/acme_srv.cfg @@ -153,14 +152,14 @@ jobs: ASA_CA_BUNDLE: ${{ secrets.ASA_CA_BUNDLE }} ASA_PROFILE2: ${{ secrets.ASA_PROFILE2 }} - - name: "[ PREPARE ] create letsencrypt and lego folder" + - name: "create letsencrypt and lego folder" run: | sudo rm -rf certbot/* sudo rm -rf lego/* sudo rm -rf acme-sh/* docker restart acme-sh - - name: "[ ENROLL ] acme.sh" + - name: "Enroll acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --keylength 2048 --debug 3 --output-insecure --force awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer @@ -172,11 +171,11 @@ jobs: run: | docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "[ REGISTER ] certbot" + - name: "Register certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ ENROLL ] HTTP-01 single domain certbot" + - name: "Enroll HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot --force-renewal --key-type rsa --rsa-key-size 2048 sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem @@ -186,7 +185,7 @@ jobs: run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - - name: "[ ENROLL ] lego" + - name: "Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --key-type rsa2048 --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt @@ -220,7 +219,6 @@ jobs: name: "asa_handler_tests_rpm" runs-on: ubuntu-latest strategy: - max-parallel: 1 fail-fast: false matrix: rhversion: [8, 9] @@ -247,7 +245,7 @@ jobs: - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" - - name: "[ PREPARE ] setup environment for alma installation" + - name: "setup environment for alma installation" run: | docker network create acme sudo mkdir -p data @@ -255,7 +253,7 @@ jobs: sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data - - name: "[ PREPARE ] create letsencrypt and lego folder" + - name: "create letsencrypt and lego folder" run: | mkdir certbot mkdir lego @@ -269,7 +267,7 @@ jobs: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} - - name: "[ PREPARE ] prepare acme_srv.cfg with certifier_ca_handler" + - name: "prepare acme_srv.cfg with certifier_ca_handler" run: | mkdir -p data/acme_ca sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem @@ -294,25 +292,25 @@ jobs: ASA_CA_BUNDLE: ${{ secrets.ASA_CA_BUNDLE }} ASA_PROFILE1: ${{ secrets.ASA_PROFILE1 }} - - name: "[ PREPARE ] Almalinux instance" + - name: "Almalinux instance" run: | sudo cp examples/Docker/almalinux-systemd/Dockerfile data sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - - name: "[ RUN ] Execute install scipt" + - name: "Execute install scipt" run: | docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh - name: "Test http://acme-srv/directory is accessible" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" + - name: "prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ ENROLL ] acme.sh" + - name: "Enroll acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --keylength 2048 --debug 3 --output-insecure --force awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer @@ -324,11 +322,11 @@ jobs: run: | docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "[ REGISTER ] certbot" + - name: "Register certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ ENROLL ] HTTP-01 single domain certbot" + - name: "Enroll HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot --key-type rsa --rsa-key-size 2048 sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem @@ -339,7 +337,7 @@ jobs: run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - - name: "[ ENROLL ] lego" + - name: "Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --key-type rsa2048 --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt @@ -350,7 +348,7 @@ jobs: run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke - - name: "[ PREPARE ] prepare acme_srv.cfg with certifier_ca_handler" + - name: "prepare acme_srv.cfg with certifier_ca_handler" run: | sudo touch data/acme_srv.cfg sudo chmod 777 data/acme_srv.cfg @@ -377,14 +375,14 @@ jobs: run: | docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart - - name: "[ PREPARE ] create letsencrypt and lego folder" + - name: "create letsencrypt and lego folder" run: | sudo rm -rf certbot/* sudo rm -rf lego/* sudo rm -rf acme-sh/* docker restart acme-sh - - name: "[ ENROLL ] acme.sh" + - name: "Enroll acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --keylength 2048 --debug 3 --output-insecure --force awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer @@ -396,11 +394,11 @@ jobs: run: | docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "[ REGISTER ] certbot" + - name: "Register certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ ENROLL ] HTTP-01 single domain certbot" + - name: "Enroll HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot --force-renewal --key-type rsa --rsa-key-size 2048 sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem @@ -411,7 +409,7 @@ jobs: run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - - name: "[ ENROLL ] lego" + - name: "Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --key-type rsa2048 --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt @@ -450,7 +448,7 @@ jobs: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + - name: "Build docker-compose (apache2_wsgi)" working-directory: examples/Docker/ run: | sudo mkdir -p data @@ -458,14 +456,14 @@ jobs: docker-compose up -d docker-compose logs - - name: "[ PREPARE ] create lego folder" + - name: "create lego folder" run: | mkdir lego - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] reconfiguration of a2c with a new profile" + - name: "reconfiguration of a2c with a new profile" run: | sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem sudo touch examples/Docker/data/acme_srv.cfg @@ -496,35 +494,35 @@ jobs: - name: "Test http://acme-srv/directory is accessable again" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" + - name: "prepare acme.sh container" run: | sudo mkdir acme-sh docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ REGISTER] acme.sh" + - name: "Register acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 - - name: "[ ENROLL] acme.sh with profileID ACME" + - name: "Enroll acme.sh with profileID ACME" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --useragent profile_name=ACME --keylength 2048 --debug 3 --output-insecure awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature" - - name: "[ ENROLL ] lego with profileID ACME" + - name: "Enroll lego with profileID ACME" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent profile_name=ACME -d lego.acme --key-type rsa2048 --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt sudo openssl x509 -in lego/certificates/lego.acme.crt -ext keyUsage -noout | grep "Digital Signature" - - name: "[ ENROLL] acme.sh with profileID ACME_2" + - name: "Enroll acme.sh with profileID ACME_2" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --renew --force -d acme-sh.acme --standalone --useragent profile_name=ACME_2 --keylength 2048 --debug 3 --output-insecure openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext keyUsage -noout | grep "Key Encipherment, Data Encipherment" - - name: "[ ENROLL ] lego with profileID ACME_2" + - name: "Enroll lego with profileID ACME_2" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent profile_name=ACME_2 -d lego.acme --key-type rsa2048 --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt diff --git a/.github/workflows/ca_handler_tests_certifier.yml b/.github/workflows/ca_handler_tests_certifier.yml index f5e47000..0bac1375 100644 --- a/.github/workflows/ca_handler_tests_certifier.yml +++ b/.github/workflows/ca_handler_tests_certifier.yml @@ -302,7 +302,7 @@ jobs: - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" - - name: "[ PREPARE ] setup environment for alma installation" + - name: "setup environment for alma installation" run: | docker network create acme sudo mkdir -p data @@ -310,7 +310,7 @@ jobs: sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data - - name: "[ PREPARE ] create letsencrypt and lego folder" + - name: "create letsencrypt and lego folder" run: | mkdir certbot mkdir lego @@ -323,7 +323,7 @@ jobs: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} - - name: "[ PREPARE ] prepare acme_srv.cfg with certifier_ca_handler" + - name: "prepare acme_srv.cfg with certifier_ca_handler" run: | mkdir -p data/acme_ca sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem @@ -343,30 +343,30 @@ jobs: NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "[ PREPARE ] Almalinux instance" + - name: "Almalinux instance" run: | sudo cp examples/Docker/almalinux-systemd/Dockerfile data sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - - name: "[ RUN ] Execute install scipt" + - name: "Execute install scipt" run: | docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh - name: "Test http://acme-srv/directory is accessible" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" + - name: "prepare acme.sh container" run: | sudo mkdir acme-sh docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ REGISTER] acme.sh" + - name: "Register acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 - - name: "[ ENROLL] acme.sh" + - name: "Enroll acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --debug 3 --output-insecure awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer @@ -376,11 +376,11 @@ jobs: run: | docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "[ REGISTER ] certbot" + - name: "Register certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ ENROLL ] HTTP-01 single domain certbot" + - name: "Enroll HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem @@ -389,7 +389,7 @@ jobs: run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - - name: "[ ENROLL ] lego" + - name: "Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt @@ -444,11 +444,11 @@ jobs: WEB_SRV: ${{ matrix.websrv }} DB_HANDLER: ${{ matrix.dbhandler }} - - name: "[ PREPARE ] create lego folder" + - name: "create lego folder" run: | mkdir lego - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "setup a2c with certifier_ca_handler" run: | sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem diff --git a/.github/workflows/ca_handler_tests_nclm.yml b/.github/workflows/ca_handler_tests_nclm.yml index 9ca5adfb..d17e2f96 100644 --- a/.github/workflows/ca_handler_tests_nclm.yml +++ b/.github/workflows/ca_handler_tests_nclm.yml @@ -13,6 +13,7 @@ jobs: name: "nclm_handler_tests" runs-on: ubuntu-latest strategy: + max-parallel: 1 fail-fast: false matrix: websrv: ['apache2', 'nginx'] @@ -41,7 +42,7 @@ jobs: WEB_SRV: ${{ matrix.websrv }} DB_HANDLER: ${{ matrix.dbhandler }} - - name: "[ PREPARE ] setup a2c with nclm_ca_handler" + - name: "setup a2c with nclm_ca_handler" run: | sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem @@ -58,8 +59,7 @@ jobs: sudo echo "tsg_name: $NCLM_TSG_NAME" >> examples/Docker/data/acme_srv.cfg sudo echo "ca_name: $NCLM_CA_NAME" >> examples/Docker/data/acme_srv.cfg sudo echo "ca_id_list: [$NCLM_CA_ID_LIST]" >> examples/Docker/data/acme_srv.cfg - sudo echo "request_timeout: 40" >> examples/Docker/data/acme_srv.cfg - sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout: 40/g" examples/Docker/data/acme_srv.cfg + sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout: 45/g" examples/Docker/data/acme_srv.cfg cd examples/Docker/ docker-compose restart docker-compose logs @@ -153,7 +153,7 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: nclm_handler_tests-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz + name: nclm.tar.gz path: ${{ github.workspace }}/artifact/upload/ @@ -187,7 +187,7 @@ jobs: - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" - - name: "[ PREPARE ] setup environment for alma installation" + - name: "setup environment for alma installation" run: | docker network create acme sudo mkdir -p data @@ -195,7 +195,7 @@ jobs: sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data - - name: "[ PREPARE ] create letsencrypt and lego folder" + - name: "create letsencrypt and lego folder" run: | mkdir certbot mkdir lego @@ -208,7 +208,7 @@ jobs: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} - - name: "[ PREPARE ] prepare acme_srv.cfg with nclm_ca_handler" + - name: "prepare acme_srv.cfg with nclm_ca_handler" run: | mkdir -p data/acme_ca sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem @@ -222,8 +222,7 @@ jobs: sudo echo "tsg_name: $NCLM_TSG_NAME" >> data/acme_srv.cfg sudo echo "ca_name: $NCLM_CA_NAME" >> data/acme_srv.cfg sudo echo "ca_id_list: [$NCLM_CA_ID_LIST]" >> data/acme_srv.cfg - sudo echo "request_timeout: 40" >> data/acme_srv.cfg - sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout: 60/g" data/acme_srv.cfg + sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout: 30/g" data/acme_srv.cfg env: NCLM_API_HOST: ${{ secrets.NCLM_API_HOST }} @@ -233,45 +232,45 @@ jobs: NCLM_CA_NAME: ${{ secrets.NCLM_CA_NAME }} NCLM_CA_ID_LIST: ${{ secrets.NCLM_CA_ID_LIST }} - - name: "[ PREPARE ] Almalinux instance" + - name: "Almalinux instance" run: | sudo cp examples/Docker/almalinux-systemd/Dockerfile data sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - - name: "[ RUN ] Execute install scipt" + - name: "Execute install scipt" run: | docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh - name: "Test http://acme-srv/directory is accessible" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" + - name: "prepare acme.sh container" run: | sudo mkdir acme-sh docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh -e MAX_RETRY_TIMES=4 neilpang/acme.sh:latest daemon - - name: "[ REGISTER] acme.sh" + - name: "Register acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 - - name: "[ ENROLL] acme.sh" + - name: "Enroll acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --debug 3 --output-insecure awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ REGISTER ] certbot" + - name: "Register certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ ENROLL ] HTTP-01 single domain certbot" + - name: "Enroll HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem - - name: "[ ENROLL ] lego" + - name: "Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt diff --git a/.github/workflows/caddy-application-test.yml b/.github/workflows/caddy-application-test.yml index 5d0438fc..87841983 100644 --- a/.github/workflows/caddy-application-test.yml +++ b/.github/workflows/caddy-application-test.yml @@ -9,311 +9,40 @@ on: - cron: '0 2 * * 6' jobs: - caddy_apache2_wsgi: - name: "caddy_apache2_wsgi" + caddy_container_tests: + name: "caddy_container_tests" runs-on: ubuntu-latest strategy: fail-fast: false matrix: ports: ['-p 80:80 -p 443:443', '-p 443:443'] - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "Build docker-compose (apache2_wsgi)" - working-directory: examples/Docker/ - run: | - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" - run: | - sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem - sudo touch examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg - sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_host: $NCM_API_HOST" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_user: $NCM_API_USER" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_password: $NCM_API_PASSWORD" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_name: $NCM_CA_NAME" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> examples/Docker/data/acme_srv.cfg - sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem - cd examples/Docker/ - docker-compose restart - docker-compose logs - env: - NCM_API_HOST: ${{ secrets.NCM_API_HOST }} - NCM_API_USER: ${{ secrets.NCM_API_USER }} - NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} - NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} - NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] - - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "Test if https://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - - - name: "Create caddy folder and copy configuratation files" - run: | - mkdir caddy - cp .github/Caddyfile caddy/ - cp .github/acme2certifier_cabundle.pem caddy - - - name: "Enroll certificate with Caddy" - run: | - docker run -d --rm ${{ matrix.ports }} --network acme -v $PWD/caddy/Caddyfile:/etc/caddy/Caddyfile -v$PWD/caddy/acme2certifier_cabundle.pem:/tmp/acme2certifier_cabundle.pem -v $(pwd)/caddy/config:/config -v $(pwd)/caddy/data:/data --name=caddy caddy:2 - - - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s - - - name: "Check for logs indicating successful enrollment" - run: | - docker logs caddy 2>&1 | grep "successfully downloaded available certificate chains" - docker logs caddy 2>&1 | grep "certificate obtained successfully" - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp caddy/ ${{ github.workspace }}/artifact/caddy/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/a2c.log - docker logs caddy 2> ${{ github.workspace }}/artifact/caddy.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log caddy.log data caddy - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: caddy_apache2_wsgi-${{ github.run_id }}.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - - caddy_apache2_django: - name: "caddy_apache2_django" - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - ports: ['-p 80:80 -p 443:443', '-p 443:443'] steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "Build docker-compose (apache2_django)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | - sed -i "s/wsgi/django/g" .env sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker network create acme docker-compose up -d docker-compose logs - - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" - run: | - sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem - sudo touch examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg - sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_host: $NCM_API_HOST" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_user: $NCM_API_USER" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_password: $NCM_API_PASSWORD" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_name: $NCM_CA_NAME" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> examples/Docker/data/acme_srv.cfg - sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem - sudo cp .github/django_settings.py examples/Docker/data/settings.py - cd examples/Docker/ - docker-compose restart - docker-compose logs env: - NCM_API_HOST: ${{ secrets.NCM_API_HOST }} - NCM_API_USER: ${{ secrets.NCM_API_USER }} - NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} - NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} - NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "Test if https://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - - - name: "Create caddy folder and copy configuratation files" - run: | - mkdir caddy - cp .github/Caddyfile caddy/ - cp .github/acme2certifier_cabundle.pem caddy - - - name: "Enroll certificate with Caddy" - run: | - docker run -d --rm ${{ matrix.ports }} --network acme -v $PWD/caddy/Caddyfile:/etc/caddy/Caddyfile -v$PWD/caddy/acme2certifier_cabundle.pem:/tmp/acme2certifier_cabundle.pem -v $(pwd)/caddy/config:/config -v $(pwd)/caddy/data:/data --name=caddy caddy:2 - - - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - - name: "Check for logs indicating successful enrollment" + - name: "setup a2c with certifier_ca_handler" run: | - docker logs caddy 2>&1 | grep "successfully downloaded available certificate chains" - docker logs caddy 2>&1 | grep "certificate obtained successfully" - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp caddy/ ${{ github.workspace }}/artifact/caddy/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/a2c.log - docker logs caddy 2> ${{ github.workspace }}/artifact/caddy.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log caddy.log data caddy - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: caddy_apache2_django-${{ github.run_id }}.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - - caddy_nginx_wsgi: - name: "caddy_nginx_wsgi" - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - ports: ['-p 80:80 -p 443:443', '-p 443:443'] - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "Build docker-compose (nginx_wsgi)" - working-directory: examples/Docker/ - run: | - sed -i "s/apache2/nginx/g" .env - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" - run: | - sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem - sudo touch examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg - sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_host: $NCM_API_HOST" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_user: $NCM_API_USER" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_password: $NCM_API_PASSWORD" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_name: $NCM_CA_NAME" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> examples/Docker/data/acme_srv.cfg + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem - cd examples/Docker/ - docker-compose restart - docker-compose logs - env: - NCM_API_HOST: ${{ secrets.NCM_API_HOST }} - NCM_API_USER: ${{ secrets.NCM_API_USER }} - NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} - NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} - NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "Test if https://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - - - name: "Create caddy folder and copy configuratation files" - run: | - mkdir caddy - cp .github/Caddyfile caddy/ - cp .github/acme2certifier_cabundle.pem caddy - - - name: " enroll certificate with Caddy" - run: | - docker run -d --rm ${{ matrix.ports }} --network acme -v $PWD/caddy/Caddyfile:/etc/caddy/Caddyfile -v$PWD/caddy/acme2certifier_cabundle.pem:/tmp/acme2certifier_cabundle.pem -v $(pwd)/caddy/config:/config -v $(pwd)/caddy/data:/data --name=caddy caddy:2 - - - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s - - - name: "Check for logs indicating successful enrollment" - run: | - docker logs caddy 2>&1 | grep "successfully downloaded available certificate chains" - docker logs caddy 2>&1 | grep "certificate obtained successfully" - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp caddy/ ${{ github.workspace }}/artifact/caddy/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/a2c.log - docker logs caddy 2> ${{ github.workspace }}/artifact/caddy.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log caddy.log data caddy - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: caddy_nginx_wsgi-${{ github.run_id }}.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - caddy_nginx_django: - name: "caddy_nginx_django" - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - ports: ['-p 80:80 -p 443:443', '-p 443:443'] - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "Build docker-compose (nginx_django)" - working-directory: examples/Docker/ - run: | - sed -i "s/wsgi/django/g" .env - sed -i "s/apache2/nginx/g" .env - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" - run: | + sudo cp .github/django_settings.py examples/Docker/data/settings.py sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem sudo touch examples/Docker/data/acme_srv.cfg sudo chmod 777 examples/Docker/data/acme_srv.cfg @@ -324,9 +53,7 @@ jobs: sudo echo "api_password: $NCM_API_PASSWORD" >> examples/Docker/data/acme_srv.cfg sudo echo "ca_name: $NCM_CA_NAME" >> examples/Docker/data/acme_srv.cfg sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> examples/Docker/data/acme_srv.cfg - sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem - sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem - sudo cp .github/django_settings.py examples/Docker/data/settings.py + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem cd examples/Docker/ docker-compose restart docker-compose logs @@ -383,5 +110,5 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: caddy_nginx_django-${{ github.run_id }}.tar.gz + name: caddy_container_tests-${{ github.run_id }}.${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ diff --git a/.github/workflows/certbot-application-test.yml b/.github/workflows/certbot-application-test.yml index 4916e331..394cee9b 100644 --- a/.github/workflows/certbot-application-test.yml +++ b/.github/workflows/certbot-application-test.yml @@ -17,241 +17,32 @@ jobs: fail-fast: false matrix: keylength: [2048, 4096] + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker network create acme docker-compose up -d docker-compose logs - - - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" - run: | - sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem - sudo touch examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg - sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_host: $NCM_API_HOST" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_user: $NCM_API_USER" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_password: $NCM_API_PASSWORD" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_name: $NCM_CA_NAME" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - docker-compose restart - docker-compose logs env: - NCM_API_HOST: ${{ secrets.NCM_API_HOST }} - NCM_API_USER: ${{ secrets.NCM_API_USER }} - NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} - NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} - NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - - name: "[ PREPARE ] create letsencrypt folder" - run: | - mkdir certbot - - - name: "[ REGISTER] certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - - name: "[ ENROLL ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --rsa-key-size ${{ matrix.keylength }} --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - sudo chmod 777 certbot/archive/certbot/chain1.pem - sudo cp certbot/archive/certbot/chain1.pem chain1.pem - awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < chain1.pem - sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem - - - name: "[ RENEW ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --force-renew --rsa-key-size ${{ matrix.keylength }} --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem - - - name: "[ REVOKE ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - - - name: "[ ENROLL ] HTTP-01 2x domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --rsa-key-size ${{ matrix.keylength }} --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme -d certbot. --cert-name certbot - sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem - - - name: "[ RENEW ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --force-renew --rsa-key-size ${{ matrix.keylength }} --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme -d certbot. --cert-name certbot - sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem - - - name: "[ REVOKE ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme -d certbot. --cert-name certbot - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp certbot/ ${{ github.workspace }}/artifact/certbot/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data certbot + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: certbot_apache2_wsgi-${{ matrix.keylength }}.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - certbot_apache2_django: - name: "certbot_apache2_django" - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - keylength: [2048, 4096] - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (apache2_django)" - working-directory: examples/Docker/ - run: | - sed -i "s/wsgi/django/g" .env - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "setup a2c with certifier_ca_handler" run: | - sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem - sudo touch examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg - sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_host: $NCM_API_HOST" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_user: $NCM_API_USER" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_password: $NCM_API_PASSWORD" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_name: $NCM_CA_NAME" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> examples/Docker/data/acme_srv.cfg + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem sudo cp .github/django_settings.py examples/Docker/data/settings.py - cd examples/Docker/ - docker-compose restart - docker-compose logs - env: - NCM_API_HOST: ${{ secrets.NCM_API_HOST }} - NCM_API_USER: ${{ secrets.NCM_API_USER }} - NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} - NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} - NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - - name: "[ PREPARE ] create letsencrypt folder" - run: | - mkdir certbot - - - name: "[ REGISTER] certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - - name: "[ ENROLL ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --rsa-key-size ${{ matrix.keylength }} --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - sudo chmod 777 certbot/archive/certbot/chain1.pem - sudo cp certbot/archive/certbot/chain1.pem chain1.pem - awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < chain1.pem - sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem - - - name: "[ RENEW ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --force-renew --rsa-key-size ${{ matrix.keylength }} --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem - - - name: "[ REVOKE ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - - - name: "[ ENROLL ] HTTP-01 2x domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --rsa-key-size ${{ matrix.keylength }} --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme -d certbot. --cert-name certbot - sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem - - - name: "[ RENEW ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --force-renew --rsa-key-size ${{ matrix.keylength }} --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme -d certbot. --cert-name certbot - sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem - - - name: "[ REVOKE ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme -d certbot. --cert-name certbot - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp certbot/ ${{ github.workspace }}/artifact/certbot/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data certbot - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: certbot_apache2_django-${{ matrix.keylength }}.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - certbot_nginx_wsgi: - name: "certbot_nginx_wsgi" - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - keylength: [2048, 4096] - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (nginx_django)" - working-directory: examples/Docker/ - run: | - sed -i "s/apache2/nginx/g" .env - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "[ PREPARE ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" - run: | sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem sudo touch examples/Docker/data/acme_srv.cfg sudo chmod 777 examples/Docker/data/acme_srv.cfg @@ -272,84 +63,7 @@ jobs: NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "[ PREPARE ] create letsencrypt folder" - run: | - mkdir certbot - - - name: "[ REGISTER] certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - - name: "[ ENROLL ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --rsa-key-size ${{ matrix.keylength }} --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - sudo chmod 777 certbot/archive/certbot/chain1.pem - sudo cp certbot/archive/certbot/chain1.pem chain1.pem - awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < chain1.pem - sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem - - - name: "[ RENEW ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --force-renew --rsa-key-size ${{ matrix.keylength }} --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem - - - name: "[ REVOKE ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - - - name: "[ ENROLL ] HTTP-01 2x domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --rsa-key-size ${{ matrix.keylength }} --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme -d certbot. --cert-name certbot - sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem - - - name: "[ RENEW ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --force-renew --rsa-key-size ${{ matrix.keylength }} --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme -d certbot. --cert-name certbot - sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem - - - name: "[ REVOKE ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme -d certbot. --cert-name certbot - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp certbot/ ${{ github.workspace }}/artifact/certbot/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data certbot - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: certbot_nginx_wsgi-${{ matrix.keylength }}.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - certbot_nginx_django: - name: "certbot_nginx_django" - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - keylength: [2048, 4096] - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (nginx_django)" - working-directory: examples/Docker/ - run: | - sed -i "s/wsgi/django/g" .env - sed -i "s/apache2/nginx/g" .env - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "[ PREPARE ] Sleep for 10s" + - name: "Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -357,38 +71,18 @@ jobs: - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" - run: | - sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem - sudo touch examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg - sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_host: $NCM_API_HOST" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_user: $NCM_API_USER" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_password: $NCM_API_PASSWORD" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_name: $NCM_CA_NAME" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> examples/Docker/data/acme_srv.cfg - sudo cp .github/django_settings.py examples/Docker/data/settings.py - cd examples/Docker/ - docker-compose restart - docker-compose logs - env: - NCM_API_HOST: ${{ secrets.NCM_API_HOST }} - NCM_API_USER: ${{ secrets.NCM_API_USER }} - NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} - NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} - NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - name: "[ PREPARE ] create letsencrypt folder" + - name: "create letsencrypt folder" run: | mkdir certbot - - name: "[ REGISTER] certbot" + - name: "Register certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ ENROLL ] HTTP-01 single domain certbot" + - name: "Enroll HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --rsa-key-size ${{ matrix.keylength }} --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo chmod 777 certbot/archive/certbot/chain1.pem @@ -396,26 +90,26 @@ jobs: awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < chain1.pem sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem - - name: "[ RENEW ] HTTP-01 single domain certbot" + - name: "Renew HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --force-renew --rsa-key-size ${{ matrix.keylength }} --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem - - name: "[ REVOKE ] HTTP-01 single domain certbot" + - name: "Revoke HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - - name: "[ ENROLL ] HTTP-01 2x domain certbot" + - name: "Enroll HTTP-01 2x domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --rsa-key-size ${{ matrix.keylength }} --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme -d certbot. --cert-name certbot sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem - - name: "[ RENEW ] HTTP-01 single domain certbot" + - name: "Renew HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --force-renew --rsa-key-size ${{ matrix.keylength }} --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme -d certbot. --cert-name certbot sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem - - name: "[ REVOKE ] HTTP-01 single domain certbot" + - name: "Revoke HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme -d certbot. --cert-name certbot @@ -433,5 +127,5 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: certbot_nginx_django-${{ matrix.keylength }}.tar.gz + name: certbot_key-${{ matrix.keylength }}-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ diff --git a/.github/workflows/certmanager-application-test.yml b/.github/workflows/certmanager-application-test.yml index 3a186a24..e7492f78 100644 --- a/.github/workflows/certmanager-application-test.yml +++ b/.github/workflows/certmanager-application-test.yml @@ -12,24 +12,30 @@ jobs: certmgr_http01_tests: name: certmgr_http01_tests runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] get runner ip" + - name: "Get runner ip" run: | echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV - run: echo "runner IP is ${{ env.RUNNER_IP }}" - - name: "[ PREPARE ] install microk8s" + - name: "Install microk8s" run: | sudo snap install microk8s --classic sudo microk8s status --wait-ready sudo microk8s enable helm3 sudo microk8s enable ingress - - name: "[ PREPARE ] install dnsmasq" + + - name: "Install dnsmasq" run: | sudo mkdir -p data sudo cp .github/dnsmasq.conf data @@ -44,15 +50,17 @@ jobs: docker save gigantuar/dnsmasq -o dnsmasq.tar sudo microk8s ctr image import dnsmasq.tar sudo microk8s ctr images ls | grep -i gigantuar - - name: "[ PREPARE ] deploy dnsmasq pod" + + - name: "Deploy dnsmasq pod" run: | sudo microk8s.kubectl apply -f data/dnsmasq.yml + - name: "[ WAIT ] Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: time: 10s - - name: "[ CHECK ] check status dnsmasq pod and grab ip" + - name: "Check status dnsmasq pod and grab ip" run: | sudo microk8s.kubectl get pods -n dnsmasq sudo microk8s.kubectl -n dnsmasq describe pod dnsmasq @@ -61,7 +69,7 @@ jobs: echo DNSMASQ_IP=$(sudo microk8s.kubectl -n dnsmasq describe pod dnsmasq | grep " IP:" | cut -d ' ' -f 5) >> $GITHUB_ENV - run: echo "dnsmasq pod IP is ${{ env.DNSMASQ_IP }}" - - name: "[ PREPARE ] change and test dns" + - name: "Change and test dns" run: | sudo cp .github/k8s-acme-srv.yml data/ sudo chmod 777 data/k8s-acme-srv.yml @@ -69,7 +77,7 @@ jobs: cat data/k8s-acme-srv.yml host www.bar.local ${{ env.DNSMASQ_IP }} - - name: "[ PREPARE ] install cert-manager charts" + - name: "Install cert-manager charts" run: | sudo microk8s.kubectl create namespace cert-manager sudo microk8s.helm3 repo add jetstack https://charts.jetstack.io @@ -78,18 +86,24 @@ jobs: echo CERTMGR_VERSION=$(sudo microk8s.helm3 show chart jetstack/cert-manager | grep version) >> $GITHUB_ENV - run: echo "cert-manager ${{ env.CERTMGR_VERSION }}" - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" run: | - cat examples/Docker/apache2/wsgi/Dockerfile | docker build -t grindsa/acme2certifier:devel -f - . --no-cache - # docker pull grindsa/acme2certifier:devel + cat examples/Docker/$WEB_SRV/$DB_HANDLER/Dockerfile | docker build -t grindsa/acme2certifier:devel -f - . --no-cache docker save grindsa/acme2certifier > a2c.tar sudo microk8s ctr image import a2c.tar sudo microk8s ctr images ls | grep -i grindsa + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "Setup a2c with certifier_ca_handler" run: | sudo chmod 777 data mkdir -p data/acme_ca + sudo cp .github/acme2certifier.pem data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem data/acme2certifier_key.pem + sudo cp .github/django_settings.py data/settings.py sudo cp examples/ca_handler/certifier_ca_handler.py data/ca_handler.py sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem sudo touch data/acme_srv.cfg @@ -109,16 +123,17 @@ jobs: NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "[ DEPLOY ] deploy a2c pod" + - name: "Deploy a2c pod" run: | sudo microk8s.kubectl apply -f data/k8s-acme-srv.yml sudo microk8s.kubectl get pods -n cert-manager-acme - - name: "[ WAIT ] Sleep for 10s" + + - name: "Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: time: 10s - - name: "[ CHECK ] check status a2c pod and grab ip of a2c pod" + - name: "Check status a2c pod and grab ip of a2c pod" run: | sudo microk8s.kubectl get pods -n cert-manager-acme sudo microk8s.kubectl -n cert-manager-acme describe pod acme2certifier @@ -127,7 +142,7 @@ jobs: echo ACME_IP=$(sudo microk8s.kubectl -n cert-manager-acme describe pod acme2certifier | grep " IP:" | cut -d ' ' -f 5) >> $GITHUB_ENV - run: echo "a2c pod IP is ${{ env.ACME_IP }}" - - name: "[ DEPLOY ] deploy cert-manager and trigger enrollment" + - name: "Deploy cert-manager and trigger enrollment" run: | sudo cp .github/k8s-cert-mgr-http-01.yml data sudo chmod -R 777 data/k8s-cert-mgr-http-01.yml @@ -135,21 +150,22 @@ jobs: sudo sed -i "s/k8.acme.dynamop.de/k8.${{ matrix.websrv }}-${{ matrix.dbhandler }}.acme.dynamop.de/g" data/k8s-cert-mgr-http-01.yml sudo microk8s.kubectl apply -f data/k8s-cert-mgr-http-01.yml - - name: "[ WAIT ] Sleep for 20s" + - name: "Sleep for 20s" uses: juliangruber/sleep-action@v2.0.3 with: time: 20s - - name: "[ CHECK ] check issuer and challenge" + - name: "Check issuer and challenge" run: | sudo microk8s.kubectl describe ClusterIssuer acme2certifier sudo microk8s.kubectl describe challenge - - name: "[ WAIT ] Sleep for 20s" + + - name: "Sleep for 20s" uses: juliangruber/sleep-action@v2.0.3 with: time: 20s - - name: "[ CHECK ] check issuer and challenge" + - name: "Check issuer and challenge" run: | sudo microk8s.kubectl describe ClusterIssuer acme2certifier sudo microk8s.kubectl describe challenge @@ -158,7 +174,7 @@ jobs: with: time: 20s - - name: "[ CHECK ] check issuer and challenge" + - name: "Check issuer and challenge" run: | sudo microk8s.kubectl describe ClusterIssuer acme2certifier sudo microk8s.kubectl describe challenge @@ -184,12 +200,18 @@ jobs: certmgr_dns01_tests: name: certmgr_dns01_tests runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] + steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] change dns" + - name: "change dns" run: | sudo mkdir -p data sudo systemctl disable systemd-resolved @@ -202,13 +224,13 @@ jobs: sudo sed -i "s/DNSMASQ_IP/8.8.8.8/g" data/k8s-acme-srv.yml cat data/k8s-acme-srv.yml - - name: "[ PREPARE ] install microk8s" + - name: "install microk8s" run: | sudo snap install microk8s --classic sudo microk8s status --wait-ready sudo microk8s enable helm3 - - name: "[ PREPARE ] install cert-manager charts" + - name: "install cert-manager charts" run: | sudo microk8s.kubectl create namespace cert-manager sudo microk8s.helm3 repo add jetstack https://charts.jetstack.io @@ -220,18 +242,24 @@ jobs: echo CERTMGR_VERSION=$(sudo microk8s.helm3 show chart jetstack/cert-manager | grep version) >> $GITHUB_ENV - run: echo "cert-manager ${{ env.CERTMGR_VERSION }}" - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" run: | - cat examples/Docker/apache2/wsgi/Dockerfile | docker build -t grindsa/acme2certifier:devel -f - . --no-cache - # docker pull grindsa/acme2certifier:devel + cat examples/Docker/$WEB_SRV/$DB_HANDLER/Dockerfile | docker build -t grindsa/acme2certifier:devel -f - . --no-cache docker save grindsa/acme2certifier > a2c.tar sudo microk8s ctr image import a2c.tar sudo microk8s ctr images ls | grep -i grindsa + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "Setup a2c with certifier_ca_handler" run: | sudo chmod 777 data mkdir -p data/acme_ca + sudo cp .github/acme2certifier.pem data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem data/acme2certifier_key.pem + sudo cp .github/django_settings.py data/settings.py sudo cp examples/ca_handler/certifier_ca_handler.py data/ca_handler.py sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem sudo touch data/acme_srv.cfg @@ -251,7 +279,7 @@ jobs: NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "[ DEPLOY ] deploy a2c pod" + - name: "Deploy a2c pod" run: | sudo microk8s.kubectl apply -f data/k8s-acme-srv.yml sudo microk8s.kubectl get pods -n cert-manager-acme @@ -261,7 +289,7 @@ jobs: with: time: 10s - - name: "[ CHECK ] check status a2c pod and grab ip of a2c pod" + - name: "Check status a2c pod and grab ip of a2c pod" run: | sudo microk8s.kubectl get pods -n cert-manager-acme sudo microk8s.kubectl -n cert-manager-acme describe pod acme2certifier @@ -270,7 +298,7 @@ jobs: echo ACME_IP=$(sudo microk8s.kubectl -n cert-manager-acme describe pod acme2certifier | grep " IP:" | cut -d ' ' -f 5) >> $GITHUB_ENV - run: echo "a2c pod IP is ${{ env.ACME_IP }}" - - name: "[ DEPLOY ] deploy cert-manager" + - name: "Deploy cert-manager" run: | sudo cp .github/k8s-cert-mgr-dns-01.yml data sudo chmod -R 777 data/k8s-cert-mgr-dns-01.yml @@ -279,67 +307,67 @@ jobs: sudo sed -i "s/MY_EMAIL/${{ secrets.EMAIL }}/g" data/k8s-cert-mgr-dns-01.yml sudo sed -i "s/k8.acme.dynamop.de/k8.${{ matrix.websrv }}-${{ matrix.dbhandler }}.acme.dynamop.de/g" data/k8s-cert-mgr-dns-01.yml - - name: "[ DEPLOY ] deploy cert-manager and trigger enrollment" + - name: "Deploy cert-manager and trigger enrollment" run: | sudo microk8s.kubectl apply -f data/k8s-cert-mgr-dns-01.yml - - name: "[ WAIT ] Sleep for 20s" + - name: "Sleep for 20s" uses: juliangruber/sleep-action@v2.0.3 with: time: 20s - - name: "[ CHECK ] check issuer and challenge" + - name: "Check issuer and challenge" run: | sudo microk8s.kubectl describe issuer acme2certifier -n cert-manager-acme sudo microk8s.kubectl describe challenge -n cert-manager-acme - - name: "[ WAIT ] Sleep for 30s" + - name: "Sleep for 30s" uses: juliangruber/sleep-action@v2.0.3 with: time: 60s - - name: "[ CHECK ] check issuer and challenge" + - name: "Check issuer and challenge" run: | sudo microk8s.kubectl describe issuer acme2certifier -n cert-manager-acme sudo microk8s.kubectl describe challenge -n cert-manager-acme - - name: "[ WAIT ] Sleep for 60s" + - name: "Sleep for 60s" uses: juliangruber/sleep-action@v2.0.3 with: time: 60s - - name: "[ CHECK ] check issuer and challenge" + - name: "Check issuer and challenge" run: | sudo microk8s.kubectl describe issuer acme2certifier -n cert-manager-acme sudo microk8s.kubectl describe challenge -n cert-manager-acme - - name: "[ WAIT ] Sleep for 60s" + - name: "Sleep for 60s" uses: juliangruber/sleep-action@v2.0.3 with: time: 60s - - name: "[ CHECK ] check challenge and certificate" + - name: "Check challenge and certificate" run: | sudo microk8s.kubectl describe challenge -n cert-manager-acme sudo microk8s.kubectl describe certificates acme-cert -n cert-manager-acme sudo microk8s.kubectl describe certificates acme-cert -n cert-manager-acme | grep -i "The certificate has been successfully issued" - - name: "[ PREPARE ] reconfigure YAML to wildcard domain" + - name: "Reconfigure YAML to wildcard domain" run: | sudo microk8s.kubectl delete -f data/k8s-cert-mgr-dns-01.yml sudo sed -i "s/commonName: k8.acme.dynamop.de/commonName: '*.acme.dynamop.de'/g" data/k8s-cert-mgr-dns-01.yml sudo sed -i "s/- k8.${{ matrix.websrv }}-${{ matrix.dbhandler }}.acme.dynamop.de/- k8.${{ matrix.websrv }}-${{ matrix.dbhandler }}.acme.dynamop.de\n - '*.${{ matrix.websrv }}-${{ matrix.dbhandler }}.acme.dynamop.de'/g" data/k8s-cert-mgr-dns-01.yml - - name: "[ DEPLOY ] deploy cert-manager and trigger enrollment" + - name: "Deploy cert-manager and trigger enrollment" run: | sudo microk8s.kubectl apply -f data/k8s-cert-mgr-dns-01.yml - - name: "[ WAIT ] Sleep for 20s" + - name: "Sleep for 20s" uses: juliangruber/sleep-action@v2.0.3 with: time: 20s - - name: "[ CHECK ] check issuer and challenge" + - name: "Check issuer and challenge" run: | sudo microk8s.kubectl describe issuer acme2certifier -n cert-manager-acme sudo microk8s.kubectl describe challenge -n cert-manager-acme @@ -348,27 +376,27 @@ jobs: with: time: 60s - - name: "[ CHECK ] check issuer and challenge" + - name: "Check issuer and challenge" run: | sudo microk8s.kubectl describe issuer acme2certifier -n cert-manager-acme sudo microk8s.kubectl describe challenge -n cert-manager-acme - - name: "[ WAIT ] Sleep for 60s" + - name: "Sleep for 60s" uses: juliangruber/sleep-action@v2.0.3 with: time: 60s - - name: "[ CHECK ] check issuer and challenge" + - name: "Check issuer and challenge" run: | sudo microk8s.kubectl describe issuer acme2certifier -n cert-manager-acme sudo microk8s.kubectl describe challenge -n cert-manager-acme - - name: "[ WAIT ] Sleep for 60s" + - name: "Sleep for 60s" uses: juliangruber/sleep-action@v2.0.3 with: time: 60s - - name: "[ CHECK ] check challenge and certificate" + - name: "Check challenge and certificate" run: | sudo microk8s.kubectl describe challenge -n cert-manager-acme sudo microk8s.kubectl describe certificates acme-cert -n cert-manager-acme diff --git a/.github/workflows/container-tests.yml b/.github/workflows/container-tests.yml index 39b06d99..44707015 100644 --- a/.github/workflows/container-tests.yml +++ b/.github/workflows/container-tests.yml @@ -22,7 +22,7 @@ jobs: docker-compose up -d docker-compose logs - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "setup a2c with certifier_ca_handler" run: | sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem sudo touch examples/Docker/data/acme_srv.cfg @@ -50,29 +50,29 @@ jobs: run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - name: "Test if https://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" + - name: "prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ ENROLL ] register via http" + - name: "Enroll register via http" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --accountkeylength ec-256 --debug 2 - - name: "[ ENROLL ] register via https" + - name: "Enroll register via https" run: | docker exec -i acme-sh acme.sh --server https://acme-srv --register-account --accountemail 'acme-sh@example.com' --accountkeylength ec-256 --insecure --debug 2 - - name: "[ PREPARE ] test ca_handler_migration" + - name: "test ca_handler_migration" run: | sudo cp .github/openssl_ca_handler_v16.py examples/Docker/data/ca_handler.py cd examples/Docker/ docker-compose restart head -n 13 data/ca_handler.py docker-compose logs - - name: "[ PREPARE ] Sleep for 10s" + - name: "Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: time: 10s - name: "Test if http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ ENROLL ] enroll certificate to verify handler migration" + - name: "Enroll enroll certificate to verify handler migration" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug --output-insecure - name: "[ * ] collecting test data" @@ -104,7 +104,7 @@ jobs: docker-compose up -d docker-compose logs - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "setup a2c with certifier_ca_handler" run: | sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem sudo touch examples/Docker/data/acme_srv.cfg @@ -128,7 +128,7 @@ jobs: NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "[ PREPARE ] Sleep for 10s" + - name: "Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -136,29 +136,29 @@ jobs: run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - name: "Test if https://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" + - name: "prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ ENROLL ] register via http" + - name: "Enroll register via http" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --accountkeylength ec-256 --debug 2 - - name: "[ ENROLL ] register via https" + - name: "Enroll register via https" run: | docker exec -i acme-sh acme.sh --server https://acme-srv --register-account --accountemail 'acme-sh@example.com' --accountkeylength ec-256 --insecure --debug 2 - - name: "[ PREPARE ] test ca_handler_migration" + - name: "test ca_handler_migration" run: | sudo cp .github/openssl_ca_handler_v16.py examples/Docker/data/ca_handler.py cd examples/Docker/ docker-compose restart head -n 13 data/ca_handler.py docker-compose logs - - name: "[ PREPARE ] Sleep for 10s" + - name: "Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: time: 10s - name: "Test if http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ ENROLL ] enroll certificate to verify handler migration" + - name: "Enroll enroll certificate to verify handler migration" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug --output-insecure - name: "[ * ] collecting test data" @@ -190,7 +190,7 @@ jobs: docker-compose up -d docker-compose logs - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "setup a2c with certifier_ca_handler" run: | sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem sudo touch examples/Docker/data/acme_srv.cfg @@ -214,7 +214,7 @@ jobs: NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "[ PREPARE ] Sleep for 10s" + - name: "Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -222,29 +222,29 @@ jobs: run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - name: "Test if https://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" + - name: "prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ ENROLL ] register via http" + - name: "Enroll register via http" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --accountkeylength ec-256 --debug 2 - - name: "[ ENROLL ] register via https" + - name: "Enroll register via https" run: | docker exec -i acme-sh acme.sh --server https://acme-srv --register-account --accountemail 'acme-sh@example.com' --accountkeylength ec-256 --insecure --debug 2 - - name: "[ PREPARE ] test ca_handler_migration" + - name: "test ca_handler_migration" run: | sudo cp .github/openssl_ca_handler_v16.py examples/Docker/data/ca_handler.py cd examples/Docker/ docker-compose restart head -n 13 data/ca_handler.py docker-compose logs - - name: "[ PREPARE ] Sleep for 10s" + - name: "Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: time: 10s - name: "Test if http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ ENROLL ] enroll certificate to verify handler migration" + - name: "Enroll enroll certificate to verify handler migration" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug --output-insecure - name: "[ * ] collecting test data" @@ -276,7 +276,7 @@ jobs: docker-compose up -d docker-compose logs - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "setup a2c with certifier_ca_handler" run: | sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem sudo touch examples/Docker/data/acme_srv.cfg @@ -301,7 +301,7 @@ jobs: NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "[ PREPARE ] Sleep for 10s" + - name: "Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -309,29 +309,29 @@ jobs: run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - name: "Test if https://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" + - name: "prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ ENROLL ] register via http" + - name: "Enroll register via http" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --accountkeylength ec-256 --debug 2 - - name: "[ ENROLL ] register via https" + - name: "Enroll register via https" run: | docker exec -i acme-sh acme.sh --server https://acme-srv --register-account --accountemail 'acme-sh@example.com' --accountkeylength ec-256 --insecure --debug 2 - - name: "[ PREPARE ] test ca_handler_migration" + - name: "test ca_handler_migration" run: | sudo cp .github/openssl_ca_handler_v16.py examples/Docker/data/ca_handler.py cd examples/Docker/ docker-compose restart head -n 13 data/ca_handler.py docker-compose logs - - name: "[ PREPARE ] Sleep for 10s" + - name: "Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: time: 10s - name: "Test if http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ ENROLL ] enroll certificate to verify handler migration" + - name: "Enroll enroll certificate to verify handler migration" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug --output-insecure - name: "[ * ] collecting test data" diff --git a/.github/workflows/dns-test.yml b/.github/workflows/dns-test.yml index 4a470425..b46059b6 100644 --- a/.github/workflows/dns-test.yml +++ b/.github/workflows/dns-test.yml @@ -12,23 +12,35 @@ jobs: dns_challenge_tests: name: "dns_challenge_tests" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker network create acme docker-compose up -d docker-compose logs + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "setup a2c with certifier_ca_handler" run: | + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem sudo touch examples/Docker/data/acme_srv.cfg sudo chmod 777 examples/Docker/data/acme_srv.cfg @@ -49,10 +61,18 @@ jobs: NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "Test http://acme-srv/directory is accessable again" + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon sudo cp .github/dns_test.sh acme-sh/ @@ -61,7 +81,7 @@ jobs: docker exec -i acme-sh mv /acme.sh/dns_test.sh /root/.acme.sh/dnsapi/ docker exec -i acme-sh chmod +x /root/.acme.sh/dnsapi/dns_test.sh - - name: "[ PREPARE ] set DNS server" + - name: "set DNS server" run: | cd examples/Docker/ docker-compose stop @@ -70,33 +90,33 @@ jobs: docker-compose start docker-compose logs - - name: "[ ENROLL ] acme.sh - single domain" + - name: "Enroll acme.sh - single domain" run: | docker exec -i acme-sh acme.sh --dnssleep 10 --server http://acme-srv --accountemail 'acme-sh@example.com' --issue --dns dns_test -d acme-sh.single --standalone --debug 3 --output-insecure --force awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.single_ecc/ca.cer openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.single_ecc/acme-sh.single.cer - - name: "[ ENROLL ] acme.sh - two domains" + - name: "Enroll acme.sh - two domains" run: | docker exec -i acme-sh acme.sh --dnssleep 10 --server http://acme-srv --accountemail 'acme-sh@example.com' --issue --dns dns_test -d acme-sh.first --dns dns_test -d acme-sh.second --standalone --debug 3 --output-insecure --force openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.first_ecc/acme-sh.first.cer - - name: "[ ENROLL ] acme.sh - single wildcard domain" + - name: "Enroll acme.sh - single wildcard domain" run: | docker exec -i acme-sh acme.sh --dnssleep 10 --server http://acme-srv --accountemail 'acme-sh@example.com' --issue --dns dns_test -d *.acme-sh.wildcard --standalone --debug 3 --output-insecure --force openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/*acme-sh.wildcard_ecc/*acme-sh.wildcard.cer - - name: "[ ENROLL ] acme.sh - double wildcard domain" + - name: "Enroll acme.sh - double wildcard domain" run: | docker exec -i acme-sh acme.sh --dnssleep 10 --server http://acme-srv --accountemail 'acme-sh@example.com' --issue --dns dns_test -d *.acme-sh.first-wildcard --dns dns_test -d *.acme-sh.second-wildcard --standalone --debug 3 --output-insecure --force openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/*.acme-sh.first-wildcard_ecc/*.acme-sh.first-wildcard.cer - - name: "[ ENROLL ] acme.sh - domain and wildcard domain" + - name: "Enroll acme.sh - domain and wildcard domain" run: | docker exec -i acme-sh acme.sh --dnssleep 10 --server http://acme-srv --accountemail 'acme-sh@example.com' --issue --dns dns_test -d acme-sh.fqdn-wildcard --dns dns_test -d *.acme-sh.fqdn-wildcard --standalone --debug 3 --output-insecure --force openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.fqdn-wildcard_ecc/acme-sh.fqdn-wildcard.cer - - name: "[ Test ] check TXT record exists" + - name: "check TXT record exists" if: ${{ failure() }} run: | docker exec -i acme-sh ps -a @@ -123,7 +143,7 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: dns_challenge_tests.tar.gz + name: dns_challenge_tests-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ @@ -158,7 +178,7 @@ jobs: - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" - - name: "[ PREPARE ] setup environment for alma installation" + - name: "setup environment for alma installation" run: | docker network create acme sudo mkdir -p data @@ -174,7 +194,7 @@ jobs: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "setup a2c with certifier_ca_handler" run: | mkdir -p data/acme_ca sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem @@ -195,7 +215,7 @@ jobs: NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "[ PREPARE ] prepare acme.sh container" + - name: "prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon sudo cp .github/dns_test.sh acme-sh/ @@ -204,52 +224,52 @@ jobs: docker exec -i acme-sh mv /acme.sh/dns_test.sh /root/.acme.sh/dnsapi/ docker exec -i acme-sh chmod +x /root/.acme.sh/dnsapi/dns_test.sh - - name: "[ PREPARE ] set DNS server" + - name: "set DNS server" run: | docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' acme-sh sudo sed -i "s/DNS-IP/$(docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' acme-sh)/g" data/acme_srv.cfg - - name: "[ PREPARE ] Almalinux instance" + - name: "Almalinux instance" run: | sudo cp examples/Docker/almalinux-systemd/Dockerfile data sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - - name: "[ RUN ] Execute install scipt" + - name: "Execute install scipt" run: | docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ ENROLL ] acme.sh - single domain" + - name: "Enroll acme.sh - single domain" run: | docker exec -i acme-sh acme.sh --dnssleep 10 --server http://acme-srv --accountemail 'acme-sh@example.com' --issue --dns dns_test -d acme-sh.single --standalone --debug 3 --output-insecure --force awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.single_ecc/ca.cer openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.single_ecc/acme-sh.single.cer - - name: "[ ENROLL ] acme.sh - two domains" + - name: "Enroll acme.sh - two domains" run: | docker exec -i acme-sh acme.sh --dnssleep 10 --server http://acme-srv --accountemail 'acme-sh@example.com' --issue --dns dns_test -d acme-sh.first --dns dns_test -d acme-sh.second --standalone --debug 3 --output-insecure --force openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.first_ecc/acme-sh.first.cer - - name: "[ ENROLL ] acme.sh - single wildcard domain" + - name: "Enroll acme.sh - single wildcard domain" run: | docker exec -i acme-sh acme.sh --dnssleep 10 --server http://acme-srv --accountemail 'acme-sh@example.com' --issue --dns dns_test -d *.acme-sh.wildcard --standalone --debug 3 --output-insecure --force openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/*acme-sh.wildcard_ecc/*acme-sh.wildcard.cer - - name: "[ ENROLL ] acme.sh - double wildcard domain" + - name: "Enroll acme.sh - double wildcard domain" run: | docker exec -i acme-sh acme.sh --dnssleep 10 --server http://acme-srv --accountemail 'acme-sh@example.com' --issue --dns dns_test -d *.acme-sh.first-wildcard --dns dns_test -d *.acme-sh.second-wildcard --standalone --debug 3 --output-insecure --force openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/*.acme-sh.first-wildcard_ecc/*.acme-sh.first-wildcard.cer - - name: "[ ENROLL ] acme.sh - domain and wildcard domain" + - name: "Enroll acme.sh - domain and wildcard domain" run: | docker exec -i acme-sh acme.sh --dnssleep 10 --server http://acme-srv --accountemail 'acme-sh@example.com' --issue --dns dns_test -d acme-sh.fqdn-wildcard --dns dns_test -d *.acme-sh.fqdn-wildcard --standalone --debug 3 --output-insecure --force openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.fqdn-wildcard_ecc/acme-sh.fqdn-wildcard.cer - - name: "[ Test ] check TXT record exists" + - name: "check TXT record exists" if: ${{ failure() }} run: | docker exec -i acme-sh ps -a diff --git a/.github/workflows/eab-test.yml b/.github/workflows/eab-test.yml index de3aac1e..55cd1e7d 100644 --- a/.github/workflows/eab-test.yml +++ b/.github/workflows/eab-test.yml @@ -12,23 +12,35 @@ jobs: eab_apache2_wsgi: name: "eab_apache2_wsgi" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker network create acme docker-compose up -d docker-compose logs + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "setup openssl ca_handler" run: | + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem sudo touch examples/Docker/data/acme_srv.cfg sudo chmod 777 examples/Docker/data/acme_srv.cfg @@ -52,30 +64,38 @@ jobs: NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "Test http://acme-srv/directory is accessable again" + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] create letsencrypt folder" + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "create letsencrypt folder" run: | mkdir certbot - - name: "[ FAIL ] certbot without eab-credentials" + - name: "Fail - certbot without eab-credentials" id: certbotfail continue-on-error: true run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ CHECK ] certbot result " + - name: "Check certbot result " if: steps.certbotfail.outcome != 'failure' run: | echo "certbot outcome is ${{steps.certbotfail.outcome }}" exit 1 - - name: "[ REGISTER] certbot" + - name: "Register certbot" run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email --eab-kid keyid_02 --eab-hmac-key=bWFjXzAy + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email --eab-kid keyid_02 --eab-hmac-key=dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM - - name: "[ ENROLL ] HTTP-01 single domain certbot" + - name: "Enroll HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo chmod 777 certbot/archive/certbot/chain1.pem @@ -83,47 +103,47 @@ jobs: awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < chain1.pem sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem - - name: "[ PREPARE ] prepare acme.sh container" + - name: "prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ FAIL] acme.sh" + - name: "Fail - acme.sh" id: acmeshfail continue-on-error: true run: | docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 - - name: "[ CHECK ] acme.sh result " + - name: "Check acme.sh result " if: steps.acmeshfail.outcome != 'failure' run: | echo "acmeshfail outcome is ${{steps.acmeshfail.outcome }}" exit 1 - - name: "[ REGISTER] acme.sh" + - name: "Register acme.sh" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key bWFjXzAy --debug 3 + docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM --debug 3 - - name: "[ ENROLL] acme.sh" + - name: "Enroll acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --debug 3 --output-insecure openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ FAIL ] lego" + - name: "Fail - lego" id: legofail continue-on-error: true run: | mkdir lego docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - - name: "[ CHECK ] lego result " + - name: "Check lego result " if: steps.legofail.outcome != 'failure' run: | echo "legofail outcome is ${{steps.legofail.outcome }}" exit 1 - - name: "[ ENROLL ] lego" + - name: "Enroll lego" run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac bWFjXzAy -d lego.acme --http run + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM -d lego.acme --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - name: "[ * ] collecting test logs" @@ -139,10 +159,9 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: eab-${{ matrix.keylength }}.tar.gz + name: eab-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ - eab_wsgi_rpm: name: "eab_wsgi_rpm" runs-on: ubuntu-latest @@ -173,7 +192,7 @@ jobs: - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" - - name: "[ PREPARE ] setup environment for alma installation" + - name: "setup environment for alma installation" run: | docker network create acme sudo mkdir -p data @@ -181,11 +200,6 @@ jobs: sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data - - name: "[ PREPARE ] create letsencrypt and lego folder" - run: | - mkdir certbot - mkdir lego - - name: "Retrieve rpms from SBOM repo" run: | git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom @@ -194,7 +208,7 @@ jobs: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "setup a2c with certifier_ca_handler" run: | mkdir -p data/acme_ca sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem @@ -218,37 +232,41 @@ jobs: NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "[ PREPARE ] Almalinux instance" + - name: "Almalinux instance" run: | sudo cp examples/Docker/almalinux-systemd/Dockerfile data sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - - name: "[ RUN ] Execute install scipt" + - name: "Execute install scipt" run: | docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh - name: "Test http://acme-srv/directory is accessible" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ FAIL ] certbot without eab-credentials" + - name: "create letsencrypt folder" + run: | + mkdir certbot + + - name: "Fail - certbot without eab-credentials" id: certbotfail continue-on-error: true run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ CHECK ] certbot result " + - name: "Check certbot result " if: steps.certbotfail.outcome != 'failure' run: | echo "certbot outcome is ${{steps.certbotfail.outcome }}" exit 1 - - name: "[ REGISTER] certbot" + - name: "Register certbot" run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email --eab-kid keyid_02 --eab-hmac-key=bWFjXzAy + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email --eab-kid keyid_02 --eab-hmac-key=dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM - - name: "[ ENROLL ] HTTP-01 single domain certbot" + - name: "Enroll HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo chmod 777 certbot/archive/certbot/chain1.pem @@ -256,47 +274,47 @@ jobs: awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < chain1.pem sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem - - name: "[ PREPARE ] prepare acme.sh container" + - name: "prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ FAIL] acme.sh" + - name: "Fail - acme.sh" id: acmeshfail continue-on-error: true run: | docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 - - name: "[ CHECK ] acme.sh result " + - name: "Check acme.sh result " if: steps.acmeshfail.outcome != 'failure' run: | echo "acmeshfail outcome is ${{steps.acmeshfail.outcome }}" exit 1 - - name: "[ REGISTER] acme.sh" + - name: "Register acme.sh" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key bWFjXzAy --debug 3 + docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM --debug 3 - - name: "[ ENROLL] acme.sh" + - name: "Enroll acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --debug 3 --output-insecure openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ FAIL ] lego" + - name: "Fail - lego" id: legofail continue-on-error: true run: | mkdir lego docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - - name: "[ CHECK ] lego result " + - name: "Check lego result " if: steps.legofail.outcome != 'failure' run: | echo "legofail outcome is ${{steps.legofail.outcome }}" exit 1 - - name: "[ ENROLL ] lego" + - name: "Enroll lego" run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac bWFjXzAy -d lego.acme --http run + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM -d lego.acme --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - name: "[ * ] collecting test logs" @@ -330,7 +348,7 @@ jobs: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] get runner ip" + - name: "get runner ip" run: | echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV @@ -358,7 +376,7 @@ jobs: - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" - - name: "[ PREPARE ] setup environment for alma installation" + - name: "setup environment for alma installation" run: | docker network create acme sudo mkdir -p data/volume @@ -373,7 +391,7 @@ jobs: sudo sed -i "s/\/var\/www\//\/opt\//g" data/acme2certifier/settings.py sudo sed -i "s/USE_I18N = True/USE_I18N = False/g" data/acme2certifier/settings.py - - name: "[ PREPARE ] create lego folder" + - name: "create lego folder" run: | mkdir lego @@ -385,7 +403,7 @@ jobs: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "setup a2c with certifier_ca_handler" run: | mkdir -p data/volume/acme_ca sudo cp test/ca/certsrv_ca_certs.pem data/volume/acme_ca/ca_certs.pem @@ -409,14 +427,14 @@ jobs: NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "[ PREPARE ] Almalinux instance" + - name: "Almalinux instance" run: | sudo cp examples/Docker/almalinux-systemd/Dockerfile data sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme -p 22280:80 --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - - name: "[ RUN ] Execute install scipt" + - name: "Execute install scipt" run: | docker exec acme-srv sh /tmp/acme2certifier/django_tester.sh @@ -426,23 +444,27 @@ jobs: - name: "Test if https://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - name: "[ FAIL ] certbot without eab-credentials" + - name: "create letsencrypt folder" + run: | + mkdir certbot + + - name: "Fail - certbot without eab-credentials" id: certbotfail continue-on-error: true run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ CHECK ] certbot result " + - name: "Check certbot result " if: steps.certbotfail.outcome != 'failure' run: | echo "certbot outcome is ${{steps.certbotfail.outcome }}" exit 1 - - name: "[ REGISTER] certbot" + - name: "Register certbot" run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email --eab-kid keyid_02 --eab-hmac-key=bWFjXzAy + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email --eab-kid keyid_02 --eab-hmac-key=dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM - - name: "[ ENROLL ] HTTP-01 single domain certbot" + - name: "Enroll HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo chmod 777 certbot/archive/certbot/chain1.pem @@ -450,47 +472,47 @@ jobs: awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < chain1.pem sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem - - name: "[ PREPARE ] prepare acme.sh container" + - name: "prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ FAIL] acme.sh" + - name: "Fail - acme.sh" id: acmeshfail continue-on-error: true run: | docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 - - name: "[ CHECK ] acme.sh result " + - name: "Check acme.sh result " if: steps.acmeshfail.outcome != 'failure' run: | echo "acmeshfail outcome is ${{steps.acmeshfail.outcome }}" exit 1 - - name: "[ REGISTER] acme.sh" + - name: "Register acme.sh" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key bWFjXzAy --debug 3 + docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM --debug 3 - - name: "[ ENROLL] acme.sh" + - name: "Enroll acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --debug 3 --output-insecure openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ FAIL ] lego" + - name: "Fail - lego" id: legofail continue-on-error: true run: | mkdir lego docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - - name: "[ CHECK ] lego result " + - name: "Check lego result " if: steps.legofail.outcome != 'failure' run: | echo "legofail outcome is ${{steps.legofail.outcome }}" exit 1 - - name: "[ ENROLL ] lego" + - name: "Enroll lego" run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac bWFjXzAy -d lego.acme --http run + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM -d lego.acme --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - name: "[ * ] collecting test logs" @@ -515,7 +537,4 @@ jobs: if: ${{ failure() }} with: name: eab_django_rpm-rh${{ matrix.rhversion }}.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - - + path: ${{ github.workspace }}/artifact/upload/ \ No newline at end of file diff --git a/.github/workflows/enrollment-timeout.yml b/.github/workflows/enrollment-timeout.yml index 702f8c6e..3bc24f44 100644 --- a/.github/workflows/enrollment-timeout.yml +++ b/.github/workflows/enrollment-timeout.yml @@ -22,7 +22,7 @@ jobs: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + - name: "Build docker-compose (apache2_wsgi)" working-directory: examples/Docker/ run: | sudo mkdir -p data @@ -33,8 +33,12 @@ jobs: - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "setup a2c with certifier_ca_handler" run: | + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem sudo touch examples/Docker/data/acme_srv.cfg sudo chmod 777 examples/Docker/data/acme_srv.cfg @@ -58,51 +62,51 @@ jobs: NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "[ PREPARE ] prepare acme.sh container" + - name: "prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ ENROLL ] acme.sh" + - name: "Enroll acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh//acme-sh.acme/ca.cer openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer - - name: "[ VERIFY ] Check timeout" + - name: "Check timeout" working-directory: examples/Docker/ run: | docker-compose logs | grep "Certificate.enroll_and_store() ended with: None:timeout" sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) - - name: "[ ENROLL ] acme.sh" + - name: "Enroll acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force - - name: "[ VERIFY ] Check certificate reusage" + - name: "Check certificate reusage" working-directory: examples/Docker/ run: | docker-compose logs | grep "Certificate._enroll(): reuse existing certificate" - - name: "[ ENROL] lego" + - name: "Enroll lego" run: | mkdir lego docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --cert.timeout 150 --http run - - name: "[ VERIFY ] Check timeout" + - name: "Check timeout" working-directory: examples/Docker/ run: | docker-compose logs | grep "Certificate.enroll_and_store() ended with: None:timeout" sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) - - name: "[ REGISTER ] certbot" + - name: "Register certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ ENROLL ] certbot" + - name: "Enroll certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - - name: "[ VERIFY ] Check timeout" + - name: "Check timeout" working-directory: examples/Docker/ run: | docker-compose logs | grep "Certificate.enroll_and_store() ended with: None:timeout" @@ -126,119 +130,6 @@ jobs: name: async_enrollment_cert_reusage.tar.gz path: ${{ github.workspace }}/artifact/upload/ - - ap_django_async_enrollment_cert_reusage: - name: ap_django_async_enrollment_cert_reusage - runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "Build docker-compose (apache2_django)" - working-directory: examples/Docker/ - run: | - sed -i "s/wsgi/django/g" .env - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" - run: | - sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem - sudo touch examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg - # sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_host: $NCM_API_HOST" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_user: $NCM_API_USER" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_password: $NCM_API_PASSWORD" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_name: $NCM_CA_NAME" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> examples/Docker/data/acme_srv.cfg - sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\\ncert_reusage_timeframe: 300/g" examples/Docker/data/acme_srv.cfg - sudo cp examples/ca_handler/certifier_ca_handler.py examples/Docker/data/ca_handler.py - sudo sed -i "s/ cert_dic = self._cert_get(csr)/ cert_dic = self._cert_get(csr)\\n time.sleep(30)/g" examples/Docker/data/ca_handler.py - sudo cp .github/django_settings.py examples/Docker/data/settings.py - cd examples/Docker/ - docker-compose restart - docker-compose logs - env: - NCM_API_HOST: ${{ secrets.NCM_API_HOST }} - NCM_API_USER: ${{ secrets.NCM_API_USER }} - NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} - NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} - NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - - name: "[ PREPARE ] prepare acme.sh container" - run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - - name: "[ ENROLL ] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure - awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh//acme-sh.acme/ca.cer - openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer - - - name: "[ VERIFY ] Check timeout" - working-directory: examples/Docker/ - run: | - docker-compose logs | grep "Certificate.enroll_and_store() ended with: None:timeout" - sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) - - - name: "[ ENROLL ] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force - - - name: "[ VERIFY ] Check certificate reusage" - working-directory: examples/Docker/ - run: | - docker-compose logs | grep "Certificate._enroll(): reuse existing certificate" - - - name: "[ ENROL] lego" - run: | - mkdir lego - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --cert.timeout 150 --http run - - - name: "[ VERIFY ] Check timeout" - working-directory: examples/Docker/ - run: | - docker-compose logs | grep "Certificate.enroll_and_store() ended with: None:timeout" - sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) - - - name: "[ REGISTER ] certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - - name: "[ ENROLL ] certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - - - name: "[ VERIFY ] Check timeout" - working-directory: examples/Docker/ - run: | - docker-compose logs | grep "Certificate.enroll_and_store() ended with: None:timeout" - sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) - - - name: "[ * ] collecting test data" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh - - - name: "[ * ] uploading artifacts" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: ap_django_async_enrollment_cert_reusage.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - rpm_wsgi_async_enrollment_cert_reusage: name: "rpm_wsgi_async_enrollment_cert_reusage" runs-on: ubuntu-latest @@ -270,7 +161,7 @@ jobs: - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" - - name: "[ PREPARE ] setup environment for alma installation" + - name: "setup environment for alma installation" run: | docker network create acme sudo mkdir -p data @@ -278,7 +169,7 @@ jobs: sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data - - name: "[ PREPARE ] create lego and certbot folder" + - name: "create lego and certbot folder" run: | mkdir lego mkdir certbot @@ -291,7 +182,7 @@ jobs: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "setup a2c with certifier_ca_handler" run: | mkdir -p data/acme_ca sudo cp test/ca/certsrv_ca_certs.pem data/ca_certs.pem @@ -317,34 +208,34 @@ jobs: NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "[ PREPARE ] Almalinux instance" + - name: "Almalinux instance" run: | sudo cp examples/Docker/almalinux-systemd/Dockerfile data sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - - name: "[ RUN ] Execute install scipt" + - name: "Execute install scipt" run: | docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh - - name: "[ PREPARE ] prepare acme.sh container" + - name: "prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ ENROLL ] acme.sh" + - name: "Enroll acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "[ VERIFY ] Check timeout" + - name: "Check timeout" run: | docker exec acme-srv grep "Certificate.enroll_and_store() ended with: None:timeout" /var/log/messages - - name: "[ ENROLL ] acme.sh" + - name: "Enroll acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force - - name: "[ VERIFY ] Check certificate reusage" + - name: "Check certificate reusage" run: | docker exec acme-srv grep "Certificate._enroll(): reuse existing certificate" /var/log/messages @@ -380,13 +271,13 @@ jobs: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] get runner ip" + - name: "get runner ip" run: | echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV - run: echo "runner IP is ${{ env.RUNNER_IP }}" - - name: "[ PREPARE ] postgres environment" + - name: "postgres environment" run: | docker network create acme sudo mkdir -p examples/Docker/data/pgsql/ @@ -394,28 +285,28 @@ jobs: sudo cp .github/pgpass examples/Docker/data/pgsql/pgpass sudo chmod 600 examples/Docker/data/pgsql/pgpass - - name: "[ PREPARE ] postgres environment" + - name: "postgres environment" run: | sudo cp .github/a2c.psql examples/Docker/data/pgsql/a2c.psql sudo cp .github/pgpass examples/Docker/data/pgsql/pgpass sudo chmod 600 examples/Docker/data/pgsql/pgpass - - name: "[ PREPARE ] install postgres" + - name: "install postgres" working-directory: examples/Docker/ run: | docker run --name postgresdbsrv --network acme -e POSTGRES_PASSWORD=foobar -d postgres - - name: "[ PREPARE ] Sleep for 10s" + - name: "Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: time: 10s - - name: "[ PREPARE ] configure postgres" + - name: "configure postgres" working-directory: examples/Docker/ run: | docker run -v "$(pwd)/data/pgsql/a2c.psql":/tmp/a2c.psql -v "$(pwd)/data/pgsql/pgpass:/root/.pgpass" --rm --network acme postgres psql -U postgres -h postgresdbsrv -f /tmp/a2c.psql - - name: "[ PREPARE ] Sleep for 10s" + - name: "Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -442,7 +333,7 @@ jobs: - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" - - name: "[ PREPARE ] setup environment for alma installation" + - name: "setup environment for alma installation" run: | sudo mkdir -p data/volume sudo mkdir -p data/acme2certifier @@ -463,7 +354,7 @@ jobs: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "setup a2c with certifier_ca_handler" run: | sudo cp test/ca/certsrv_ca_certs.pem data/volume/ca_certs.pem sudo touch data/volume/acme_srv.cfg @@ -489,14 +380,14 @@ jobs: NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "[ PREPARE ] Almalinux instance" + - name: "Almalinux instance" run: | sudo cp examples/Docker/almalinux-systemd/Dockerfile data sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme -p 22280:80 --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - - name: "[ RUN ] Execute install scipt" + - name: "Execute install scipt" run: | docker exec acme-srv sh /tmp/acme2certifier/django_tester.sh @@ -507,33 +398,33 @@ jobs: run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" + - name: "prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ ENROLL ] acme.sh" + - name: "Enroll acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "[ PREPARE ] Sleep for 5s" + - name: "Sleep for 5s" uses: juliangruber/sleep-action@v2.0.3 with: time: 5s - - name: "[ VERIFY ] Check timeout" + - name: "Check timeout" run: | docker exec acme-srv grep "Certificate.enroll_and_store() ended with: None:timeout" /var/log/messages - - name: "[ ENROLL ] acme.sh" + - name: "Enroll acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force - - name: "[ PREPARE ] Sleep for 5s" + - name: "Sleep for 5s" uses: juliangruber/sleep-action@v2.0.3 with: time: 5s - - name: "[ VERIFY ] Check certificate reusage" + - name: "Check certificate reusage" run: | docker exec acme-srv grep "Certificate._enroll(): reuse existing certificate" /var/log/messages diff --git a/.github/workflows/hooks-test.yml b/.github/workflows/hooks-test.yml index 40cf0495..9197438b 100644 --- a/.github/workflows/hooks-test.yml +++ b/.github/workflows/hooks-test.yml @@ -11,24 +11,39 @@ jobs: hooks_test: name: "hooks_test" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] + steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | - sudo mkdir -p data/hooks - sudo chmod -R 777 data/hooks + sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker network create acme docker-compose up -d docker-compose logs + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "setup a2c with certifier_ca_handler" run: | + sudo mkdir -p examples/Docker/data/hooks + sudo chmod -R 777 examples/Docker/data/hooks + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem sudo touch examples/Docker/data/acme_srv.cfg sudo chmod 777 examples/Docker/data/acme_srv.cfg @@ -55,18 +70,26 @@ jobs: NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "Test http://acme-srv/directory is accessable again" + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] create letsencrypt folder" + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "create letsencrypt folder" run: | mkdir certbot - - name: "[ REGISTER] certbot" + - name: "Register certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ ENROLL ] HTTP-01 single domain certbot" + - name: "Enroll HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo chmod 777 certbot/archive/certbot/chain1.pem @@ -74,26 +97,26 @@ jobs: awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < chain1.pem sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem - - name: "[ PREPARE ] prepare acme.sh container" + - name: "prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ REGISTER] acme.sh" + - name: "Register acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 - - name: "[ ENROLL] acme.sh" + - name: "Enroll acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --debug 3 --output-insecure awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ ENROLL ] lego" + - name: "Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - - name: "[ CHECK ] compare checksums to validate hook file content" + - name: "Check compare checksums to validate hook file content" working-directory: examples/Docker/data/hooks run: | sha256sum -c checksums.sha256 @@ -111,7 +134,7 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: hooks.tar.gz + name: hooks-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ hooks_test_rpm: @@ -144,7 +167,7 @@ jobs: - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" - - name: "[ PREPARE ] setup environment for alma installation" + - name: "setup environment for alma installation" run: | docker network create acme sudo mkdir -p data @@ -152,7 +175,7 @@ jobs: sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data - - name: "[ PREPARE ] create letsencrypt and lego folder" + - name: "create letsencrypt and lego folder" run: | mkdir acmme-sh mkdir lego @@ -165,7 +188,7 @@ jobs: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "setup a2c with certifier_ca_handler" run: | mkdir -p data/acme_ca sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem @@ -193,25 +216,25 @@ jobs: NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "[ PREPARE ] Almalinux instance" + - name: "Almalinux instance" run: | sudo cp examples/Docker/almalinux-systemd/Dockerfile data sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - - name: "[ RUN ] Execute install scipt" + - name: "Execute install scipt" run: | docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh - name: "Test http://acme-srv/directory is accessible" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ REGISTER] certbot" + - name: "Register certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ ENROLL ] HTTP-01 single domain certbot" + - name: "Enroll HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo chmod 777 certbot/archive/certbot/chain1.pem @@ -219,25 +242,25 @@ jobs: awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < chain1.pem sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem - - name: "[ PREPARE ] prepare acme.sh container" + - name: "prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ REGISTER] acme.sh" + - name: "Register acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 - - name: "[ ENROLL] acme.sh" + - name: "Enroll acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --debug 3 --output-insecure openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ ENROLL ] lego" + - name: "Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - - name: "[ CHECK ] compare checksums to validate hook file content" + - name: "Check compare checksums to validate hook file content" working-directory: data/acme_ca/hooks run: | sha256sum -c checksums.sha256 @@ -265,24 +288,37 @@ jobs: hooks_exception_handling: name: "hooks_exception_handling" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | - sudo mkdir -p data/hooks - sudo chmod -R 777 data/hooks + sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker network create acme docker-compose up -d docker-compose logs + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "setup a2c with certifier_ca_handler" run: | + sudo mkdir -p examples/Docker/data/hooks + sudo chmod -R 777 examples/Docker/data/hooks + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem sudo touch examples/Docker/data/acme_srv.cfg sudo chmod 777 examples/Docker/data/acme_srv.cfg @@ -310,24 +346,32 @@ jobs: NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "Test http://acme-srv/directory is accessable again" + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ REGISTER] acme.sh" + - name: "Register acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 - - name: "[ ENROLL] acme.sh - *_pre_hook_failure not configured " + - name: "Enroll acme.sh - *_pre_hook_failure not configured " run: | docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --debug 3 --output-insecure awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ PREPARE ] reconfigure hook handler to trigger pre hook exception " + - name: "reconfigure hook handler to trigger pre hook exception " run: | sudo sed -i "s/raise_pre_hook_exception: False/raise_pre_hook_exception: True/g" examples/Docker/data/acme_srv.cfg cd examples/Docker/ @@ -340,25 +384,25 @@ jobs: run: | docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure - - name: "[ CHECK ] result - acme.sh enrollment failed due to pre-hook exception " + - name: "Check result - acme.sh enrollment failed due to pre-hook exception " if: steps.prehookfailure.outcome != 'failure' run: | echo "prehookfailure outcome is ${{steps.prehookfailure.outcome }}" exit 1 - - name: "[ PREPARE ] reconfigure a2c to ignore pre-hook failures " + - name: "reconfigure a2c to ignore pre-hook failures " run: | sudo echo "ignore_pre_hook_failure: True" >> examples/Docker/data/acme_srv.cfg cd examples/Docker/ sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) docker-compose restart - - name: "[ ENROLL] acme.sh - ignore pre_hook_failures " + - name: "Enroll acme.sh - ignore pre_hook_failures " run: | docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ PREPARE ] reconfigure hook handler to trigger success hook exception " + - name: "reconfigure hook handler to trigger success hook exception " run: | sudo sed -i "s/raise_pre_hook_exception: True/raise_pre_hook_exception: False/g" examples/Docker/data/acme_srv.cfg sudo sed -i "s/raise_success_hook_exception: False/raise_success_hook_exception: True/g" examples/Docker/data/acme_srv.cfg @@ -372,25 +416,25 @@ jobs: run: | docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure - - name: "[ CHECK ] result - acme.sh enrollment failed due to success-hook exception " + - name: "Check result - acme.sh enrollment failed due to success-hook exception " if: steps.successhookfailure.outcome != 'failure' run: | echo "successhookfailure outcome is ${{steps.successhookfailure.outcome }}" exit 1 - - name: "[ PREPARE ] reconfigure a2c to ignore success-hook failures " + - name: "reconfigure a2c to ignore success-hook failures " run: | sudo sed -i "s/ignore_pre_hook_failure: True/ignore_success_hook_failure: True/g" examples/Docker/data/acme_srv.cfg cd examples/Docker/ sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) docker-compose restart - - name: "[ ENROLL] acme.sh - ignore sucess_hook_failures " + - name: "Enroll acme.sh - ignore sucess_hook_failures " run: | docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ PREPARE ] reconfigure hook handler to trigger post hook exception " + - name: "reconfigure hook handler to trigger post hook exception " run: | sudo sed -i "s/raise_success_hook_exception: True/raise_success_hook_exception: False/g" examples/Docker/data/acme_srv.cfg sudo sed -i "s/raise_post_hook_exception: False/raise_post_hook_exception: True/g" examples/Docker/data/acme_srv.cfg @@ -398,12 +442,12 @@ jobs: sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' acme2certifier_acme-srv_1) docker-compose restart - - name: "[ ENROLL] acme.sh - ignore post_hook_failures (default behaviour) " + - name: "Enroll acme.sh - ignore post_hook_failures (default behaviour) " run: | docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ PREPARE ] reconfigure a2c to detect success-hook failures " + - name: "reconfigure a2c to detect success-hook failures " run: | sudo sed -i "s/ignore_success_hook_failure: True/ignore_post_hook_failure: False/g" examples/Docker/data/acme_srv.cfg cd examples/Docker/ @@ -416,7 +460,7 @@ jobs: run: | docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure - - name: "[ CHECK ] result - acme.sh enrollment failed due to post-hook exception " + - name: "Check result - acme.sh enrollment failed due to post-hook exception " if: steps.posthookfailure.outcome != 'failure' run: | echo "posthookfailure outcome is ${{steps.posthookfailure.outcome }}" @@ -435,7 +479,7 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: hooks_exception_handling.tar.gz + name: hooks_exception_handling-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ hooks_exception_handling_rpm: @@ -468,7 +512,7 @@ jobs: - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" - - name: "[ PREPARE ] setup environment for alma installation" + - name: "setup environment for alma installation" run: | docker network create acme sudo mkdir -p data @@ -476,7 +520,7 @@ jobs: sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data - - name: "[ PREPARE ] create letsencrypt and lego folder" + - name: "create letsencrypt and lego folder" run: | mkdir acmme-sh mkdir lego @@ -489,7 +533,7 @@ jobs: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "setup a2c with certifier_ca_handler" run: | mkdir -p data/acme_ca sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem @@ -518,14 +562,14 @@ jobs: NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "[ PREPARE ] Almalinux instance" + - name: "Almalinux instance" run: | sudo cp examples/Docker/almalinux-systemd/Dockerfile data sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - - name: "[ RUN ] Execute install scipt" + - name: "Execute install scipt" run: | docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh @@ -533,21 +577,21 @@ jobs: run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" + - name: "prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ REGISTER] acme.sh" + - name: "Register acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 - - name: "[ ENROLL] acme.sh - *_pre_hook_failure not configured " + - name: "Enroll acme.sh - *_pre_hook_failure not configured " run: | docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --debug 3 --output-insecure awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ PREPARE ] reconfigure hook handler to trigger pre hook exception " + - name: "reconfigure hook handler to trigger pre hook exception " run: | sudo sed -i "s/raise_pre_hook_exception: False/raise_pre_hook_exception: True/g" data/acme_srv.cfg docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart @@ -558,23 +602,23 @@ jobs: run: | docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure - - name: "[ CHECK ] result - acme.sh enrollment failed due to pre-hook exception " + - name: "Check result - acme.sh enrollment failed due to pre-hook exception " if: steps.prehookfailure.outcome != 'failure' run: | echo "prehookfailure outcome is ${{steps.prehookfailure.outcome }}" exit 1 - - name: "[ PREPARE ] reconfigure a2c to ignore pre-hook failures " + - name: "reconfigure a2c to ignore pre-hook failures " run: | sudo echo "ignore_pre_hook_failure: True" >> data/acme_srv.cfg docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart - - name: "[ ENROLL] acme.sh - ignore pre_hook_failures " + - name: "Enroll acme.sh - ignore pre_hook_failures " run: | docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ PREPARE ] reconfigure hook handler to trigger success hook exception " + - name: "reconfigure hook handler to trigger success hook exception " run: | sudo sed -i "s/raise_pre_hook_exception: True/raise_pre_hook_exception: False/g" data/acme_srv.cfg sudo sed -i "s/raise_success_hook_exception: False/raise_success_hook_exception: True/g" data/acme_srv.cfg @@ -586,34 +630,34 @@ jobs: run: | docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure - - name: "[ CHECK ] result - acme.sh enrollment failed due to success-hook exception " + - name: "Check result - acme.sh enrollment failed due to success-hook exception " if: steps.successhookfailure.outcome != 'failure' run: | echo "successhookfailure outcome is ${{steps.successhookfailure.outcome }}" exit 1 - - name: "[ PREPARE ] reconfigure a2c to ignore success-hook failures " + - name: "reconfigure a2c to ignore success-hook failures " run: | sudo sed -i "s/ignore_pre_hook_failure: True/ignore_success_hook_failure: True/g" data/acme_srv.cfg docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart - - name: "[ ENROLL] acme.sh - ignore sucess_hook_failures " + - name: "Enroll acme.sh - ignore sucess_hook_failures " run: | docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ PREPARE ] reconfigure hook handler to trigger post hook exception " + - name: "reconfigure hook handler to trigger post hook exception " run: | sudo sed -i "s/raise_success_hook_exception: True/raise_success_hook_exception: False/g" data/acme_srv.cfg sudo sed -i "s/raise_post_hook_exception: False/raise_post_hook_exception: True/g" data/acme_srv.cfg docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart - - name: "[ ENROLL] acme.sh - ignore post_hook_failures (default behaviour) " + - name: "Enroll acme.sh - ignore post_hook_failures (default behaviour) " run: | docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ PREPARE ] reconfigure a2c to detect success-hook failures " + - name: "reconfigure a2c to detect success-hook failures " run: | sudo sed -i "s/ignore_success_hook_failure: True/ignore_post_hook_failure: False/g" data/acme_srv.cfg docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart @@ -624,7 +668,7 @@ jobs: run: | docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --force --debug 3 --output-insecure - - name: "[ CHECK ] result - acme.sh enrollment failed due to post-hook exception " + - name: "Check result - acme.sh enrollment failed due to post-hook exception " if: steps.posthookfailure.outcome != 'failure' run: | echo "posthookfailure outcome is ${{steps.posthookfailure.outcome }}" diff --git a/.github/workflows/ip-address-tests.yml b/.github/workflows/ip-address-tests.yml index 28b2e3b0..0a162bff 100644 --- a/.github/workflows/ip-address-tests.yml +++ b/.github/workflows/ip-address-tests.yml @@ -9,296 +9,44 @@ on: - cron: '0 2 * * 6' jobs: - ip_apache2_wsgi: - name: "ip_apache2_wsgi" + ip_tests: + name: "ip_tests" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] get runner ip" + - name: "get runner ip" run: | echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV - run: echo "runner IP is ${{ env.RUNNER_IP }}" - - name: "Build docker-compose (apache2_wsgi)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker network create acme docker-compose up -d docker-compose logs - - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" - run: | - sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem - sudo touch examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg - sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_host: $NCM_API_HOST" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_user: $NCM_API_USER" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_password: $NCM_API_PASSWORD" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_name: $NCM_CA_NAME" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> examples/Docker/data/acme_srv.cfg - sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem - cd examples/Docker/ - docker-compose restart - docker-compose logs env: - NCM_API_HOST: ${{ secrets.NCM_API_HOST }} - NCM_API_USER: ${{ secrets.NCM_API_USER }} - NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} - NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} - NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - - name: "Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 5s - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "Test if https://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - - name: "create lego folder" - run: | - mkdir lego - - - name: "Enroll HTTP-01 single domain and ip address " - run: | - docker run -i -p 80:80 -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme -d $RUNNER_IP --http run - sudo chmod 777 lego/certificates/lego.acme.issuer.crt - sudo cp lego/certificates/lego.acme.issuer.crt lego.acme.issuer.crt - sudo awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < lego.acme.issuer.crt - sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - sudo openssl x509 -in lego/certificates/lego.acme.crt --text --noout | grep "IP Address" - env: - RUNNER_IP: ${{ env.RUNNER_IP }} - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: ip_apache2_wsgi.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - ip_apache2_django: - name: "ip_apache2_django" - runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] get runner ip" - run: | - echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV - echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV - - run: echo "runner IP is ${{ env.RUNNER_IP }}" - - - name: "Build docker-compose (apache2_django)" - working-directory: examples/Docker/ - run: | - sed -i "s/wsgi/django/g" .env - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "setup a2c with certifier_ca_handler" run: | - sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem - sudo touch examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg - sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_host: $NCM_API_HOST" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_user: $NCM_API_USER" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_password: $NCM_API_PASSWORD" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_name: $NCM_CA_NAME" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> examples/Docker/data/acme_srv.cfg - sudo cp .github/django_settings.py examples/Docker/data/settings.py sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem - cd examples/Docker/ - docker-compose restart - docker-compose logs - env: - NCM_API_HOST: ${{ secrets.NCM_API_HOST }} - NCM_API_USER: ${{ secrets.NCM_API_USER }} - NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} - NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} - NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - - name: "Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 5s - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "Test if https://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - - name: "create lego folder" - run: | - mkdir lego - - - name: "Enroll HTTP-01 single domain and ip address " - run: | - docker run -i -p 80:80 -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme -d $RUNNER_IP --http run - sudo chmod 777 lego/certificates/lego.acme.issuer.crt - sudo cp lego/certificates/lego.acme.issuer.crt lego.acme.issuer.crt - sudo awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < lego.acme.issuer.crt - sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - sudo openssl x509 -in lego/certificates/lego.acme.crt --text --noout | grep "IP Address" - env: - RUNNER_IP: ${{ env.RUNNER_IP }} - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: ip_apache2_django.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - ip_nginx_wsgi: - name: "ip_nginx_wsgi" - runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] get runner ip" - run: | - echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV - echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV - - run: echo "runner IP is ${{ env.RUNNER_IP }}" - - - name: "Build docker-compose (nginx_wsgi)" - working-directory: examples/Docker/ - run: | - sed -i "s/apache2/nginx/g" .env - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" - run: | - sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem - sudo touch examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg - sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_host: $NCM_API_HOST" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_user: $NCM_API_USER" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_password: $NCM_API_PASSWORD" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_name: $NCM_CA_NAME" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> examples/Docker/data/acme_srv.cfg sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem - cd examples/Docker/ - docker-compose restart - docker-compose logs - env: - NCM_API_HOST: ${{ secrets.NCM_API_HOST }} - NCM_API_USER: ${{ secrets.NCM_API_USER }} - NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} - NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} - NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - - name: "Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 5s - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "Test if https://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - - name: "create lego folder" - run: | - mkdir lego - - - name: "Enroll HTTP-01 single domain and ip address " - run: | - docker run -i -p 80:80 -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme -d $RUNNER_IP --http run - sudo chmod 777 lego/certificates/lego.acme.issuer.crt - sudo cp lego/certificates/lego.acme.issuer.crt lego.acme.issuer.crt - sudo awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < lego.acme.issuer.crt - sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - sudo openssl x509 -in lego/certificates/lego.acme.crt --text --noout | grep "IP Address" - env: - RUNNER_IP: ${{ env.RUNNER_IP }} - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: ip_nginx_wsgi.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - ip_nginx_django: - name: "ip_nginx_django" - runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] get runner ip" - run: | - echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV - echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV - - run: echo "runner IP is ${{ env.RUNNER_IP }}" - - - name: "Build docker-compose (nginx_django)" - working-directory: examples/Docker/ - run: | - sed -i "s/wsgi/django/g" .env - sed -i "s/apache2/nginx/g" .env - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" - run: | + sudo cp .github/django_settings.py examples/Docker/data/settings.py sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem sudo touch examples/Docker/data/acme_srv.cfg sudo chmod 777 examples/Docker/data/acme_srv.cfg @@ -309,9 +57,7 @@ jobs: sudo echo "api_password: $NCM_API_PASSWORD" >> examples/Docker/data/acme_srv.cfg sudo echo "ca_name: $NCM_CA_NAME" >> examples/Docker/data/acme_srv.cfg sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> examples/Docker/data/acme_srv.cfg - sudo cp .github/django_settings.py examples/Docker/data/settings.py - sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem - sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem cd examples/Docker/ docker-compose restart docker-compose logs @@ -362,7 +108,7 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: ip_nginx_django.tar.gz + name: ip_tests-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ ip_wsgi_rpm: @@ -376,7 +122,7 @@ jobs: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] get runner ip" + - name: "get runner ip" run: | echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV @@ -401,7 +147,7 @@ jobs: - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" - - name: "[ PREPARE ] setup environment for alma installation" + - name: "setup environment for alma installation" run: | docker network create acme sudo mkdir -p data @@ -409,7 +155,7 @@ jobs: sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data - - name: "[ PREPARE ] create lego folder" + - name: "create lego folder" run: | mkdir lego @@ -421,7 +167,7 @@ jobs: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "setup a2c with certifier_ca_handler" run: | mkdir -p data/acme_ca sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem @@ -442,14 +188,14 @@ jobs: NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "[ PREPARE ] Almalinux instance" + - name: "Almalinux instance" run: | sudo cp examples/Docker/almalinux-systemd/Dockerfile data sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - - name: "[ RUN ] Execute install scipt" + - name: "Execute install scipt" run: | docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh @@ -496,7 +242,7 @@ jobs: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] get runner ip" + - name: "get runner ip" run: | echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV @@ -524,7 +270,7 @@ jobs: - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" - - name: "[ PREPARE ] setup environment for alma installation" + - name: "setup environment for alma installation" run: | docker network create acme sudo mkdir -p data/volume @@ -539,7 +285,7 @@ jobs: sudo sed -i "s/\/var\/www\//\/opt\//g" data/acme2certifier/settings.py sudo sed -i "s/USE_I18N = True/USE_I18N = False/g" data/acme2certifier/settings.py - - name: "[ PREPARE ] create lego folder" + - name: "create lego folder" run: | mkdir lego @@ -551,7 +297,7 @@ jobs: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "setup a2c with certifier_ca_handler" run: | mkdir -p data/volume/acme_ca sudo cp test/ca/certsrv_ca_certs.pem data/volume/acme_ca/ca_certs.pem @@ -572,14 +318,14 @@ jobs: NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "[ PREPARE ] Almalinux instance" + - name: "Almalinux instance" run: | sudo cp examples/Docker/almalinux-systemd/Dockerfile data sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme -p 22280:80 --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - - name: "[ RUN ] Execute install scipt" + - name: "Execute install scipt" run: | docker exec acme-srv sh /tmp/acme2certifier/django_tester.sh diff --git a/.github/workflows/ipv6-test.yml b/.github/workflows/ipv6-test.yml index 6ee37282..c29aa7a2 100644 --- a/.github/workflows/ipv6-test.yml +++ b/.github/workflows/ipv6-test.yml @@ -9,168 +9,36 @@ jobs: ipv6_apache2_wsgi: name: "ipv6_apache2_wsgi" runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" - working-directory: examples/Docker/ - run: | - sudo mkdir -p data - docker network create acme --ipv6 --subnet "fdbb:6445:65b4:0a60::/64" - docker-compose up -d - docker-compose logs - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" - run: | - sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem - sudo touch examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg - sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_host: $NCM_API_HOST" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_user: $NCM_API_USER" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_password: $NCM_API_PASSWORD" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_name: $NCM_CA_NAME" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - docker-compose restart - docker-compose logs - env: - NCM_API_HOST: ${{ secrets.NCM_API_HOST }} - NCM_API_USER: ${{ secrets.NCM_API_USER }} - NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} - NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} - NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - - name: "create acme-sh folder" - run: | - mkdir acme-sh - - - name: "[ PREPARE ] prepare acme.sh container" - run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - - name: "[ ENROLL ] HTTP-01 single domain acme.sh using ipv6" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --listen-v6 --debug 3 --output-insecure - awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer - openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer - - - name: "[ ENROLL ] HTTP-01 single domain acme.sh using ipv6 with ipv4 fallback" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --listen-v4 --debug 3 --output-insecure --force - openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: ipv6_apache2_wsgi.tar.gz - path: ${{ github.workspace }}/artifact/upload/ + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] - ipv6_nginx_wsgi: - name: "ipv6_nginx_wsgi" - runs-on: ubuntu-latest steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (nginx_wsgi)" - working-directory: examples/Docker/ - run: | - sed -i "s/apache2/nginx/g" .env - sudo mkdir -p data - docker network create acme --ipv6 --subnet "fdbb:6445:65b4:0a60::/64" - docker-compose up -d - docker-compose logs - - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" - run: | - sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem - sudo touch examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg - sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_host: $NCM_API_HOST" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_user: $NCM_API_USER" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_password: $NCM_API_PASSWORD" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_name: $NCM_CA_NAME" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - docker-compose restart - docker-compose logs - env: - NCM_API_HOST: ${{ secrets.NCM_API_HOST }} - NCM_API_USER: ${{ secrets.NCM_API_USER }} - NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} - NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} - NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - - name: "create acme-sh folder" - run: | - mkdir acme-sh - - - name: "[ PREPARE ] prepare acme.sh container" - run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - - name: "[ ENROLL ] HTTP-01 single domain acme.sh using ipv6" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --listen-v6 --debug 3 --output-insecure - awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer - openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer - - - name: "[ ENROLL ] HTTP-01 single domain acme.sh using ipv6 with ipv4 fallback" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --listen-v4 --debug 3 --output-insecure --force - openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: ipv6_nginx_wsgi.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - ipv6_apache2_django: - name: "ipv6_apache2_django" - runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (apache2_django)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | - sed -i "s/wsgi/django/g" .env sudo mkdir -p data - docker network create acme --ipv6 --subnet "fdbb:6445:65b4:0a60::/64" + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env + docker network create acme docker-compose up -d docker-compose logs + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "setup a2c with certifier_ca_handler" run: | + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem sudo touch examples/Docker/data/acme_srv.cfg sudo chmod 777 examples/Docker/data/acme_srv.cfg @@ -181,7 +49,6 @@ jobs: sudo echo "api_password: $NCM_API_PASSWORD" >> examples/Docker/data/acme_srv.cfg sudo echo "ca_name: $NCM_CA_NAME" >> examples/Docker/data/acme_srv.cfg sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> examples/Docker/data/acme_srv.cfg - sudo cp .github/django_settings.py examples/Docker/data/settings.py cd examples/Docker/ docker-compose restart docker-compose logs @@ -192,95 +59,32 @@ jobs: NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "create acme-sh folder" - run: | - mkdir acme-sh - - - name: "[ PREPARE ] prepare acme.sh container" - run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - - name: "[ ENROLL ] HTTP-01 single domain acme.sh using ipv6" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --listen-v6 --debug 3 --output-insecure - awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer - openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer - - - name: "[ ENROLL ] HTTP-01 single domain acme.sh using ipv6 with ipv4 fallback" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --listen-v4 --debug 3 --output-insecure --force - openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 with: - name: ipv6_apache2_django.tar.gz - path: ${{ github.workspace }}/artifact/upload/ + time: 10s - ipv6_nginx_django: - name: "ipv6_nginx_django" - runs-on: ubuntu-latest - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (nginx_django)" - working-directory: examples/Docker/ - run: | - sed -i "s/wsgi/django/g" .env - sed -i "s/apache2/nginx/g" .env - sudo mkdir -p data - docker network create acme --ipv6 --subnet "fdbb:6445:65b4:0a60::/64" - docker-compose up -d - docker-compose logs + - name: "Test http://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - name: "create acme-sh folder" run: | mkdir acme-sh - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" - run: | - sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem - sudo touch examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg - sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_host: $NCM_API_HOST" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_user: $NCM_API_USER" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_password: $NCM_API_PASSWORD" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_name: $NCM_CA_NAME" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> examples/Docker/data/acme_srv.cfg - sudo cp .github/django_settings.py examples/Docker/data/settings.py - cd examples/Docker/ - docker-compose restart - docker-compose logs - env: - NCM_API_HOST: ${{ secrets.NCM_API_HOST }} - NCM_API_USER: ${{ secrets.NCM_API_USER }} - NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} - NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} - NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - - name: "[ PREPARE ] prepare acme.sh container" + - name: "prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ ENROLL ] HTTP-01 single domain acme.sh using ipv6" + - name: "Enroll HTTP-01 single domain acme.sh using ipv6" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --listen-v6 --debug 3 --output-insecure awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer - - name: "[ ENROLL ] HTTP-01 single domain acme.sh using ipv6 with ipv4 fallback" + - name: "Enroll HTTP-01 single domain acme.sh using ipv6 with ipv4 fallback" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --listen-v4 --debug 3 --output-insecure --force openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer @@ -299,7 +103,7 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: ipv6_nginx_django.tar.gz + name: ipv6_tests-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ rpm_wsgi_ipv6: @@ -332,7 +136,7 @@ jobs: - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" - - name: "[ PREPARE ] setup environment for alma installation" + - name: "setup environment for alma installation" run: | docker network create acme --ipv6 --subnet "fdbb:6445:65b4:0a60::/64" sudo mkdir -p data @@ -340,7 +144,7 @@ jobs: sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data - - name: "[ PREPARE ] create lego and certbot folder" + - name: "create lego and certbot folder" run: | mkdir lego mkdir certbot @@ -353,7 +157,7 @@ jobs: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "setup a2c with certifier_ca_handler" run: | mkdir -p data/acme_ca sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem @@ -377,22 +181,22 @@ jobs: NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "[ PREPARE ] Almalinux instance" + - name: "Almalinux instance" run: | sudo cp examples/Docker/almalinux-systemd/Dockerfile data sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - - name: "[ RUN ] Execute install scipt" + - name: "Execute install scipt" run: | docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh - - name: "[ PREPARE ] prepare acme.sh container" + - name: "prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ ENROLL ] acme.sh" + - name: "Enroll acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer @@ -402,11 +206,11 @@ jobs: run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --cert.timeout 180 --http run - - name: "[ REGISTER ] certbot" + - name: "Register certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ ENROLL ] certbot" + - name: "Enroll certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot @@ -441,7 +245,7 @@ jobs: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] get runner ip" + - name: "get runner ip" run: | echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV @@ -469,7 +273,7 @@ jobs: - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" - - name: "[ PREPARE ] setup environment for alma installation" + - name: "setup environment for alma installation" run: | docker network create acme --ipv6 --subnet "fdbb:6445:65b4:0a60::/64" sudo mkdir -p data/volume @@ -484,7 +288,7 @@ jobs: sudo sed -i "s/\/var\/www\//\/opt\//g" data/acme2certifier/settings.py sudo sed -i "s/USE_I18N = True/USE_I18N = False/g" data/acme2certifier/settings.py - - name: "[ PREPARE ] create lego folder" + - name: "create lego folder" run: | mkdir lego @@ -496,7 +300,7 @@ jobs: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "setup a2c with certifier_ca_handler" run: | mkdir -p data/volume/acme_ca sudo cp test/ca/certsrv_ca_certs.pem data/volume/acme_ca/ca_certs.pem @@ -519,14 +323,14 @@ jobs: NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "[ PREPARE ] Almalinux instance" + - name: "Almalinux instance" run: | sudo cp examples/Docker/almalinux-systemd/Dockerfile data sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme -p 22280:80 --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - - name: "[ RUN ] Execute install scipt" + - name: "Execute install scipt" run: | docker exec acme-srv sh /tmp/acme2certifier/django_tester.sh @@ -537,11 +341,11 @@ jobs: run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" + - name: "prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ ENROLL ] acme.sh" + - name: "Enroll acme.sh" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --keylength 2048 --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer @@ -551,11 +355,11 @@ jobs: run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --cert.timeout 180 --http run - - name: "[ REGISTER ] certbot" + - name: "Register certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ ENROLL ] certbot" + - name: "Enroll certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot diff --git a/.github/workflows/lego-application-test.yml b/.github/workflows/lego-application-test.yml index 007a9c40..0de6716b 100644 --- a/.github/workflows/lego-application-test.yml +++ b/.github/workflows/lego-application-test.yml @@ -17,229 +17,32 @@ jobs: fail-fast: false matrix: keylength: [rsa2048, rsa4096, ec256] + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker network create acme docker-compose up -d docker-compose logs - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" - run: | - sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem - sudo touch examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg - sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_host: $NCM_API_HOST" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_user: $NCM_API_USER" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_password: $NCM_API_PASSWORD" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_name: $NCM_CA_NAME" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - docker-compose restart - docker-compose logs env: - NCM_API_HOST: ${{ secrets.NCM_API_HOST }} - NCM_API_USER: ${{ secrets.NCM_API_USER }} - NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} - NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} - NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - - name: "create lego folder" - run: | - mkdir lego - - - name: "[ ENROLL ] HTTP-01 single domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme --http run - sudo chmod 777 lego/certificates/lego.acme.issuer.crt - sudo cp lego/certificates/lego.acme.issuer.crt lego.acme.issuer.crt - sudo awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < lego.acme.issuer.crt - sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - - - name: "[ RENEW ] HTTP-01 single domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme --http renew - sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - - - name: "[ REVOKE ] HTTP-01 single domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme revoke - - - name: "[ ENROLL ] HTTP-01 2x domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme -d lego --http run - sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - - - name: "[ RENEW ] HTTP-01 2x domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme -d lego --http renew - sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - - - name: "[ REVOKE ] HTTP-01 2x domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme revoke - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: lego_key-${{ matrix.keylength }}.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - lego_apache2_django: - name: "lego_apache2_django" - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - keylength: [rsa2048, rsa4096, ec256] - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (apache2_django)" - working-directory: examples/Docker/ - run: | - sed -i "s/wsgi/django/g" .env - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "setup a2c with certifier_ca_handler" run: | - sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem - sudo touch examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg - sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_host: $NCM_API_HOST" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_user: $NCM_API_USER" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_password: $NCM_API_PASSWORD" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_name: $NCM_CA_NAME" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> examples/Docker/data/acme_srv.cfg sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem sudo cp .github/django_settings.py examples/Docker/data/settings.py - cd examples/Docker/ - docker-compose restart - docker-compose logs - env: - NCM_API_HOST: ${{ secrets.NCM_API_HOST }} - NCM_API_USER: ${{ secrets.NCM_API_USER }} - NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} - NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} - NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - - name: "create lego folder" - run: | - mkdir lego - - - name: "[ ENROLL ] HTTP-01 single domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme --http run - sudo chmod 777 lego/certificates/lego.acme.issuer.crt - sudo cp lego/certificates/lego.acme.issuer.crt lego.acme.issuer.crt - sudo awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < lego.acme.issuer.crt - sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - - - name: "[ RENEW ] HTTP-01 single domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme --http renew - sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - - - name: "[ REVOKE ] HTTP-01 single domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme revoke - - - name: "[ ENROLL ] HTTP-01 2x domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme -d lego --http run - sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - - - name: "[ RENEW ] HTTP-01 2x domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme -d lego --http renew - sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - - - name: "[ REVOKE ] HTTP-01 2x domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme revoke - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: lego_key-${{ matrix.keylength }}.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - lego_nginx_wsgi: - name: "lego_nginx_wsgi" - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - keylength: [rsa2048, rsa4096, ec256] - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (nginx_django)" - working-directory: examples/Docker/ - run: | - sed -i "s/apache2/nginx/g" .env - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" - run: | sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem sudo touch examples/Docker/data/acme_srv.cfg sudo chmod 777 examples/Docker/data/acme_srv.cfg @@ -264,7 +67,7 @@ jobs: run: | mkdir lego - - name: "[ ENROLL ] HTTP-01 single domain lego" + - name: "Enroll HTTP-01 single domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme --http run sudo chmod 777 lego/certificates/lego.acme.issuer.crt @@ -272,26 +75,26 @@ jobs: sudo awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < lego.acme.issuer.crt sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - - name: "[ RENEW ] HTTP-01 single domain lego" + - name: "Renew HTTP-01 single domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme --http renew sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - - name: "[ REVOKE ] HTTP-01 single domain lego" + - name: "Revoke HTTP-01 single domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme revoke - - name: "[ ENROLL ] HTTP-01 2x domain lego" + - name: "Enroll HTTP-01 2x domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme -d lego --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - - name: "[ RENEW ] HTTP-01 2x domain lego" + - name: "Renew HTTP-01 2x domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme -d lego --http renew sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - - name: "[ REVOKE ] HTTP-01 2x domain lego" + - name: "Revoke HTTP-01 2x domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme revoke @@ -309,109 +112,6 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: lego_key-${{ matrix.keylength }}.tar.gz + name: lego_tests-${{ matrix.keylength }}-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ - lego_nginx_django: - name: "lego_nginx_django" - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - keylength: [rsa2048, rsa4096, ec256] - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: "[ PREPARE ] Build docker-compose (nginx_django)" - working-directory: examples/Docker/ - run: | - sed -i "s/wsgi/django/g" .env - sed -i "s/apache2/nginx/g" .env - sudo mkdir -p data - docker network create acme - docker-compose up -d - docker-compose logs - - - name: "[ WAIT ] Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" - run: | - sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem - sudo touch examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg - sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_host: $NCM_API_HOST" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_user: $NCM_API_USER" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_password: $NCM_API_PASSWORD" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_name: $NCM_CA_NAME" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> examples/Docker/data/acme_srv.cfg - sudo cp .github/django_settings.py examples/Docker/data/settings.py - cd examples/Docker/ - docker-compose restart - docker-compose logs - env: - NCM_API_HOST: ${{ secrets.NCM_API_HOST }} - NCM_API_USER: ${{ secrets.NCM_API_USER }} - NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} - NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} - NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - - name: "create lego folder" - run: | - mkdir lego - - - name: "[ ENROLL ] HTTP-01 single domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme --http run - sudo chmod 777 lego/certificates/lego.acme.issuer.crt - sudo cp lego/certificates/lego.acme.issuer.crt lego.acme.issuer.crt - sudo awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < lego.acme.issuer.crt - sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - - - name: "[ RENEW ] HTTP-01 single domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme --http renew - sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - - - name: "[ REVOKE ] HTTP-01 single domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme revoke - - - name: "[ ENROLL ] HTTP-01 2x domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme -d lego --http run - sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - - - name: "[ RENEW ] HTTP-01 2x domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme -d lego --http renew - sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - - - name: "[ REVOKE ] HTTP-01 2x domain lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --key-type ${{ matrix.keylength }} --email "lego@example.com" -d lego.acme revoke - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: lego_key-${{ matrix.keylength }}.tar.gz - path: ${{ github.workspace }}/artifact/upload/ diff --git a/.github/workflows/proxy-test.yml b/.github/workflows/proxy-test.yml index a4772dd6..983038d8 100644 --- a/.github/workflows/proxy-test.yml +++ b/.github/workflows/proxy-test.yml @@ -12,37 +12,49 @@ jobs: proxy_tests: name: "proxy_tests" runs-on: ubuntu-latest - steps: + strategy: + fail-fast: false + matrix: + websrv: ['apache2'] + dbhandler: ['wsgi', 'django'] + steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] create network" + - name: "create network" run: | docker network create acme - - name: "[ PREPARE ] proxy container" + - name: "proxy container" run: | docker pull mosajjal/pproxy:latest docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & - - name: "[ PREPARE ] Sleep for 10s" + - name: "Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: time: 10s - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker-compose up -d docker-compose logs + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup certifier ca_handler for socks proxy usage" + - name: "setup certifier ca_handler for socks proxy usage" run: | + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py sudo cp examples/ca_handler/certifier_ca_handler.py examples/Docker/data/ca_handler.py sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg sudo chmod 777 examples/Docker/data/acme_srv.cfg @@ -57,27 +69,38 @@ jobs: docker-compose restart docker-compose logs - - name: "[ PREPARE ] prepare acme.sh container" + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Test http://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ ENROLL ] via certifier ca_handler" + - name: "Enroll via certifier ca_handler" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ REVOKE ] via certifier ca_handler" + - name: "Revoke via certifier ca_handler" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "[ CHECK ] proxy logs" + - name: "Check proxy logs" run: | docker logs proxy | grep socks5 | grep -- "->" docker stop proxy docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & - - name: "[ PREPARE ] setup certifier ca_handler for http proxy usage" + - name: "setup certifier ca_handler for http proxy usage" run: | sudo cp examples/ca_handler/certifier_ca_handler.py examples/Docker/data/ca_handler.py sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg @@ -93,23 +116,23 @@ jobs: docker-compose restart docker-compose logs - - name: "[ ENROLL ] via certifier ca_handler" + - name: "Enroll via certifier ca_handler" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ REVOKE ] via certifier ca_handler" + - name: "Revoke via certifier ca_handler" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "[ CHECK ] proxy logs" + - name: "Check proxy logs" run: | docker logs proxy | grep http | grep -- "->" docker stop proxy docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & - - name: "[ PREPARE ] setup nclm ca_handler for socks proxy usage" + - name: "setup nclm ca_handler for socks proxy usage" run: | sudo cp examples/ca_handler/nclm_ca_handler.py examples/Docker/data/ca_handler.py sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg @@ -126,18 +149,18 @@ jobs: docker-compose restart docker-compose logs - - name: "[ ENROLL ] via nclm ca_handler" + - name: "Enroll via nclm ca_handler" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force # openssl verify -CAfile acme.sh/acme-sh.acme/ca.cer acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ CHECK ] proxy logs" + - name: "Check proxy logs" run: | docker logs proxy | grep socks5 | grep -- "->" docker stop proxy docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & - - name: "[ PREPARE ] setup nclm ca_handler for http proxy usage" + - name: "setup nclm ca_handler for http proxy usage" run: | sudo cp examples/ca_handler/nclm_ca_handler.py examples/Docker/data/ca_handler.py sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg @@ -154,12 +177,12 @@ jobs: docker-compose restart docker-compose logs - - name: "[ ENROLL ] via nclm ca_handler" + - name: "Enroll via nclm ca_handler" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force # openssl verify -CAfile acme.sh/acme-sh.acme/ca.cer acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ CHECK ] proxy logs" + - name: "Check proxy logs" run: | docker logs proxy | grep http | grep -- "->" docker stop proxy @@ -182,7 +205,7 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: proxy.tar.gz + name: proxy-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ @@ -217,7 +240,7 @@ jobs: - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" - - name: "[ PREPARE ] setup environment for alma installation" + - name: "setup environment for alma installation" run: | docker network create acme sudo mkdir -p data @@ -234,12 +257,12 @@ jobs: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} - - name: "[ PREPARE ] proxy container" + - name: "proxy container" run: | docker pull mosajjal/pproxy:latest docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & - - name: "[ PREPARE ] Sleep for 10s" + - name: "Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: time: 10s @@ -249,7 +272,7 @@ jobs: echo PROXY_IP=$(docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' proxy) >> $GITHUB_ENV - run: echo "Latest tag is ${{ env.PROXY_IP }}" - - name: "[ PREPARE ] prepare acme_srv.cfg with certifier_ca_handler and socks proxy usage" + - name: "prepare acme_srv.cfg with certifier_ca_handler and socks proxy usage" run: | mkdir -p data/acme_ca sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem @@ -270,58 +293,58 @@ jobs: NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "[ PREPARE ] Almalinux instance" + - name: "Almalinux instance" run: | sudo cp examples/Docker/almalinux-systemd/Dockerfile data sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme -p 22280:80 --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - - name: "[ RUN ] Execute install scipt" + - name: "Execute install scipt" run: | docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh - name: "Test if http://acme-srv/directory is accessible" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" + - name: "prepare acme.sh container" run: | docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - name: "[ ENROLL ] acme.sh - http challenge validation" + - name: "Enroll acme.sh - http challenge validation" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme -d acme-sh. --standalone --debug 3 --output-insecure --force awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ CHECK ] proxy logs" + - name: "Check proxy logs" run: | docker logs proxy | grep socks5 | grep -- "->" docker stop proxy docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & - - name: "[ ENROLL ] acme.sh - alpn challenge validation" + - name: "Enroll acme.sh - alpn challenge validation" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn -d acme-sh. --alpn --standalone --debug 3 --output-insecure --force openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ CHECK ] proxy logs" + - name: "Check proxy logs" run: | docker logs proxy | grep socks5 | grep -- "->" docker stop proxy docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & - - name: "[ REVOKE ] via certifier ca_handler" + - name: "Revoke via certifier ca_handler" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "[ CHECK ] proxy logs" + - name: "Check proxy logs" run: | docker logs proxy | grep socks5 | grep -- "->" docker stop proxy docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & - - name: "[ PREPARE ] prepare acme_srv.cfg with certifier_ca_handler and http proxy usage" + - name: "prepare acme_srv.cfg with certifier_ca_handler and http proxy usage" run: | mkdir -p data/acme_ca sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem @@ -349,43 +372,43 @@ jobs: - name: "Test if http://acme-srv/directory is accessible" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ ENROLL ] acme.sh - http challenge validation" + - name: "Enroll acme.sh - http challenge validation" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme -d acme-sh. --standalone --debug 3 --output-insecure --force awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ CHECK ] proxy logs" + - name: "Check proxy logs" run: | docker logs proxy | grep http | grep -- "->" docker stop proxy docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & - - name: "[ ENROLL ] acme.sh - alpn challenge validation" + - name: "Enroll acme.sh - alpn challenge validation" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn -d acme-sh. --alpn --standalone --debug 3 --output-insecure --force openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ CHECK ] proxy logs" + - name: "Check proxy logs" run: | docker logs proxy | grep http | grep -- "->" docker stop proxy docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & - - name: "[ REVOKE ] via certifier ca_handler" + - name: "Revoke via certifier ca_handler" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "[ CHECK ] proxy logs" + - name: "Check proxy logs" run: | docker logs proxy | grep http | grep -- "->" docker stop proxy docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & - - name: "[ PREPARE ] setup using nclm_ca_handler" + - name: "setup using nclm_ca_handler" run: | - - name: "[ PREPARE ] prepare acme_srv.cfg with nclm_ca_handler and socks proxy usage" + - name: "prepare acme_srv.cfg with nclm_ca_handler and socks proxy usage" run: | mkdir -p data/acme_ca sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem @@ -413,17 +436,17 @@ jobs: run: | docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart - - name: "[ ENROLL ] via nclm_ca_handler" + - name: "Enroll via nclm_ca_handler" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force & - - name: "[ CHECK ] proxy logs" + - name: "Check proxy logs" run: | docker logs proxy | grep socks5 | grep -- "->" docker stop proxy docker run -d -it --name=proxy --network acme --rm -p 8080:8080 mosajjal/pproxy:latest -vv & - - name: "[ PREPARE ] prepare acme_srv.cfg with nclm_ca_handler and http proxy usage" + - name: "prepare acme_srv.cfg with nclm_ca_handler and http proxy usage" run: | mkdir -p data/acme_ca sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem @@ -451,11 +474,11 @@ jobs: run: | docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart - - name: "[ ENROLL ] via nclm_ca_handler" + - name: "Enroll via nclm_ca_handler" run: | docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --debug 3 --output-insecure --force & - - name: "[ CHECK ] proxy logs" + - name: "Check proxy logs" run: | docker logs proxy | grep http | grep -- "->" docker stop proxy diff --git a/.github/workflows/tnauth-test.yml b/.github/workflows/tnauth-test.yml index 56ca4905..17eb3bde 100644 --- a/.github/workflows/tnauth-test.yml +++ b/.github/workflows/tnauth-test.yml @@ -12,11 +12,16 @@ jobs: tnauth_tests: name: "tnauth_tests" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "[ PREPARE ] Build docker-compose (apache2_wsgi)" + - name: "Build docker-compose (apache2_wsgi)" working-directory: examples/Docker/ run: | sudo mkdir -p data @@ -24,11 +29,12 @@ jobs: docker-compose up -d docker-compose logs - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "setup a2c with certifier_ca_handler" run: | + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem sudo touch examples/Docker/data/acme_srv.cfg sudo chmod 777 examples/Docker/data/acme_srv.cfg @@ -50,7 +56,18 @@ jobs: NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "[ CURL ] install curl and socat and test connction" + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Test http://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "install curl and socat and test connction" run: | sudo apt-get install -y curl socat curl -f http://localhost:22280 @@ -79,7 +96,7 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: tnauth.tar.gz + name: tnauth-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ @@ -113,7 +130,7 @@ jobs: - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" - - name: "[ PREPARE ] setup environment for alma installation" + - name: "setup environment for alma installation" run: | docker network create acme sudo mkdir -p data @@ -129,7 +146,7 @@ jobs: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "setup a2c with certifier_ca_handler" run: | mkdir -p data/acme_ca sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem @@ -151,21 +168,21 @@ jobs: NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "[ PREPARE ] Almalinux instance" + - name: "Almalinux instance" run: | sudo cp examples/Docker/almalinux-systemd/Dockerfile data sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme -p 22280:80 --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - - name: "[ RUN ] Execute install scipt" + - name: "Execute install scipt" run: | docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh - name: "Test http://acme-srv/directory is accessible" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ CURL ] install curl and socat and test connction" + - name: "install curl and socat and test connction" run: | sudo apt-get install -y curl socat curl -f http://localhost:22280 diff --git a/.github/workflows/traffic-application-test.yml b/.github/workflows/traffic-application-test.yml index 74fd7bd1..3e5d30d4 100644 --- a/.github/workflows/traffic-application-test.yml +++ b/.github/workflows/traffic-application-test.yml @@ -17,6 +17,9 @@ jobs: fail-fast: false matrix: challenge_type: [tlschallenge=true, httpchallenge.entrypoint=web] + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] + steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -29,19 +32,26 @@ jobs: - run: echo "runner IP is ${{ env.RUNNER_IP }}" - run: echo "runner hostname is ${{ env.RUNNER_HOSTNAME }}" - - name: "Build docker-compose (apache2_wsgi)" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" working-directory: examples/Docker/ run: | sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env docker network create acme docker-compose up -d docker-compose logs + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "setup a2c with certifier_ca_handler" run: | + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem sudo touch examples/Docker/data/acme_srv.cfg sudo chmod 777 examples/Docker/data/acme_srv.cfg @@ -62,6 +72,17 @@ jobs: NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Test http://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + - name: "setup and instanciate traefik" run: | mkdir traefik @@ -97,6 +118,6 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: traffic-${{ matrix.challenge_type }}.tar.gz + name: traffic-${{ matrix.challenge_type }}-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ From 3e76b2615cb3ea6040fba0df2387e5740d254a72 Mon Sep 17 00:00:00 2001 From: grindsa Date: Fri, 29 Mar 2024 08:17:34 +0100 Subject: [PATCH 151/460] [wf] fix hmac in eab-workflow --- .github/workflows/eab-test.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/eab-test.yml b/.github/workflows/eab-test.yml index de3aac1e..4747d2c0 100644 --- a/.github/workflows/eab-test.yml +++ b/.github/workflows/eab-test.yml @@ -73,7 +73,7 @@ jobs: - name: "[ REGISTER] certbot" run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email --eab-kid keyid_02 --eab-hmac-key=bWFjXzAy + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email --eab-kid keyid_02 --eab-hmac-key=dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM - name: "[ ENROLL ] HTTP-01 single domain certbot" run: | @@ -101,7 +101,7 @@ jobs: - name: "[ REGISTER] acme.sh" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key bWFjXzAy --debug 3 + docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM --debug 3 - name: "[ ENROLL] acme.sh" run: | @@ -123,7 +123,7 @@ jobs: - name: "[ ENROLL ] lego" run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac bWFjXzAy -d lego.acme --http run + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM -d lego.acme --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - name: "[ * ] collecting test logs" @@ -246,7 +246,7 @@ jobs: - name: "[ REGISTER] certbot" run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email --eab-kid keyid_02 --eab-hmac-key=bWFjXzAy + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email --eab-kid keyid_02 --eab-hmac-key=dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM - name: "[ ENROLL ] HTTP-01 single domain certbot" run: | @@ -274,7 +274,7 @@ jobs: - name: "[ REGISTER] acme.sh" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key bWFjXzAy --debug 3 + docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM --debug 3 - name: "[ ENROLL] acme.sh" run: | @@ -296,7 +296,7 @@ jobs: - name: "[ ENROLL ] lego" run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac bWFjXzAy -d lego.acme --http run + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM -d lego.acme --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - name: "[ * ] collecting test logs" @@ -440,7 +440,7 @@ jobs: - name: "[ REGISTER] certbot" run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email --eab-kid keyid_02 --eab-hmac-key=bWFjXzAy + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email --eab-kid keyid_02 --eab-hmac-key=dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM - name: "[ ENROLL ] HTTP-01 single domain certbot" run: | @@ -468,7 +468,7 @@ jobs: - name: "[ REGISTER] acme.sh" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key bWFjXzAy --debug 3 + docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM --debug 3 - name: "[ ENROLL] acme.sh" run: | @@ -490,7 +490,7 @@ jobs: - name: "[ ENROLL ] lego" run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac bWFjXzAy -d lego.acme --http run + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM -d lego.acme --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - name: "[ * ] collecting test logs" From 2dc332802635b40118171b5efcf8d06d87c10911 Mon Sep 17 00:00:00 2001 From: grindsa Date: Fri, 29 Mar 2024 08:40:26 +0100 Subject: [PATCH 152/460] [feat] kid_profile_handler.py --- examples/eab_handler/kid_profile_handler.py | 51 +++++++++ examples/eab_handler/kid_profiles.json | 28 +++++ test/test_eabkid_profile_handler.py | 121 ++++++++++++++++++++ 3 files changed, 200 insertions(+) create mode 100644 examples/eab_handler/kid_profile_handler.py create mode 100644 examples/eab_handler/kid_profiles.json create mode 100644 test/test_eabkid_profile_handler.py diff --git a/examples/eab_handler/kid_profile_handler.py b/examples/eab_handler/kid_profile_handler.py new file mode 100644 index 00000000..8f5800b7 --- /dev/null +++ b/examples/eab_handler/kid_profile_handler.py @@ -0,0 +1,51 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +""" eab json handler """ +from __future__ import print_function +import json +# pylint: disable=C0209, E0401 +from acme_srv.helper import load_config + + +class EABhandler(object): + """ EAB file handler """ + + def __init__(self, logger: object = None): + self.logger = logger + self.key_file = None + + def __enter__(self): + """ Makes EABhandler a Context Manager """ + if not self.key_file: + self._config_load() + return self + + def __exit__(self, *args): + """ cose the connection at the end of the context """ + + def _config_load(self): + """" load config from file """ + self.logger.debug('EABhandler._config_load()') + + config_dic = load_config(self.logger, 'EABhandler') + if 'EABhandler' in config_dic and 'key_file' in config_dic['EABhandler']: + self.key_file = config_dic['EABhandler']['key_file'] + + self.logger.debug('EABhandler._config_load() ended') + + def mac_key_get(self, kid: str = None) -> str: + """ check external account binding """ + self.logger.debug('EABhandler.mac_key_get({})'.format(kid)) + + mac_key = None + try: + if self.key_file and kid: + with open(self.key_file, encoding='utf8') as json_file: + data_dic = json.load(json_file) + if kid in data_dic and 'hmac' in data_dic[kid]: + mac_key = data_dic[kid]['hmac'] + except Exception as err: + self.logger.error('EABhandler.mac_key_get() error: {0}'.format(err)) + + self.logger.debug('EABhandler.mac_key_get() ended with: {0}'.format(bool(mac_key))) + return mac_key diff --git a/examples/eab_handler/kid_profiles.json b/examples/eab_handler/kid_profiles.json new file mode 100644 index 00000000..f44d5c40 --- /dev/null +++ b/examples/eab_handler/kid_profiles.json @@ -0,0 +1,28 @@ +{ + "keyid_00": { + "hmac": "V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw", + "cahandler": { + "profile_id": ["profile_1", "profile_2", "profile_3"], + "allowed_domains": ["www.example.com", "www.example.org", "*.example.fi"], + "ca_name": "example_ca", + "api_user": "api_user", + "api_password": "api_password" + } + }, + "keyid_01": { + "hmac": "YW5vdXRoZXJfdmVyeV9sb25nX2htYWNfZm9yX2tleWlkXzAxX3doaWNoIHdpbGxfYmUgdXNlZF9kdXJpbmcgcmVncmVzc2lvbg", + "cahandler": { + "profile_id": "profile_2", + "allowed_domains": ["*.example.fi"], + "ca_name": "example_ca_2", + "api_user": "api_user_2", + "api_password": "api_password_2" + } + }, + "keyid_02": { + "hmac": "dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM" + }, + "keyid_03": { + "hmac": "YW5kX2ZpbmFsbHlfdGhlX2xhc3RfaG1hY19rZXlfd2hpY2hfaXNfbG9uZ2VyX3RoYW5fMjU2X2JpdHNfYW5kX3Nob3VsZF93b3Jr" + } +} diff --git a/test/test_eabkid_profile_handler.py b/test/test_eabkid_profile_handler.py new file mode 100644 index 00000000..355f1c1c --- /dev/null +++ b/test/test_eabkid_profile_handler.py @@ -0,0 +1,121 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +""" unittests for acme2certifier """ +# pylint: disable= C0415, W0212 +import unittest +import sys +import os +from OpenSSL import crypto +from unittest.mock import patch, Mock, MagicMock, mock_open +import requests + +sys.path.insert(0, '.') +sys.path.insert(1, '..') + + +class TestACMEHandler(unittest.TestCase): + """ test class for cgi_handler """ + + def setUp(self): + """ setup unittest """ + import logging + logging.basicConfig(level=logging.CRITICAL) + self.logger = logging.getLogger('test_a2c') + from examples.eab_handler.kid_profile_handler import EABhandler + self.eabhandler = EABhandler(self.logger) + self.dir_path = os.path.dirname(os.path.realpath(__file__)) + + def test_001_default(self): + """ default test which always passes """ + self.assertEqual('foo', 'foo') + + @patch('examples.eab_handler.kid_profile_handler.EABhandler._config_load') + def test_002__enter__(self, mock_cfg): + """ test enter called """ + mock_cfg.return_value = True + self.eabhandler.__enter__() + self.assertTrue(mock_cfg.called) + + @patch('examples.eab_handler.kid_profile_handler.load_config') + def test_003_config_load(self, mock_load_cfg): + """ test _config_load - empty dictionary """ + mock_load_cfg.return_value = {} + self.eabhandler._config_load() + self.assertFalse(self.eabhandler.key_file) + + @patch('examples.eab_handler.kid_profile_handler.load_config') + def test_004_config_load(self, mock_load_cfg): + """ test _config_load - bogus values """ + mock_load_cfg.return_value = {'foo': 'bar'} + self.eabhandler._config_load() + self.assertFalse(self.eabhandler.key_file) + + @patch('examples.eab_handler.kid_profile_handler.load_config') + def test_005_config_load(self, mock_load_cfg): + """ test _config_load - bogus values """ + mock_load_cfg.return_value = {'EABhandler': {'foo': 'bar'}} + self.eabhandler._config_load() + self.assertFalse(self.eabhandler.key_file) + + @patch('examples.eab_handler.kid_profile_handler.load_config') + def test_006_config_load(self, mock_load_cfg): + """ test _config_load - bogus values """ + mock_load_cfg.return_value = {'EABhandler': {'key_file': 'key_file'}} + self.eabhandler._config_load() + self.assertEqual('key_file', self.eabhandler.key_file) + + def test_007_mac_key_get(self): + """ test mac_key_get without file specified """ + self.assertFalse(self.eabhandler.mac_key_get(None)) + + @patch("builtins.open", mock_open(read_data='foo'), create=True) + def test_008_mac_key_get(self): + """ test mac_key_get with file but no kid """ + self.eabhandler.key_file = 'file' + self.assertFalse(self.eabhandler.mac_key_get(None)) + + @patch('json.load') + @patch("builtins.open", mock_open(read_data='foo'), create=True) + def test_009_mac_key_get(self, mock_json): + """ test mac_key_get json reader return bogus values """ + self.eabhandler.key_file = 'file' + mock_json.return_value = {'foo', 'bar'} + self.assertFalse(self.eabhandler.mac_key_get('kid')) + + @patch('json.load') + @patch("builtins.open", mock_open(read_data='foo'), create=True) + def test_010_mac_key_get(self, mock_json): + """ test mac_key_get json match """ + self.eabhandler.key_file = 'file' + mock_json.return_value = {'kid': {'hmac': 'mac', 'foo': 'bar'}} + self.assertEqual('mac', self.eabhandler.mac_key_get('kid')) + + @patch('json.load') + @patch("builtins.open", mock_open(read_data='foo'), create=True) + def test_011_mac_key_get(self, mock_json): + """ test mac_key_get json no match """ + self.eabhandler.key_file = 'file' + mock_json.return_value = {'kid1': 'mac'} + self.assertFalse(self.eabhandler.mac_key_get('kid')) + + @patch('json.load') + @patch("builtins.open", mock_open(read_data='foo'), create=True) + def test_012_mac_key_get(self, mock_json): + """ test mac_key_get json load exception """ + self.eabhandler.key_file = 'file' + mock_json.side_effect = Exception('ex_json_load') + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.eabhandler.mac_key_get('kid')) + self.assertIn('ERROR:test_a2c:EABhandler.mac_key_get() error: ex_json_load', lcm.output) + + @patch('json.load') + @patch("builtins.open", mock_open(read_data='foo'), create=True) + def test_013_mac_key_get(self, mock_json): + """ test mac_key_get json match """ + self.eabhandler.key_file = 'file' + mock_json.return_value = {'kid': {'foo': 'bar'}} + self.assertFalse(self.eabhandler.mac_key_get('kid')) + +if __name__ == '__main__': + + unittest.main() From ee97ca5652bac9b1cddfb9ff0bc2a606d7afadff Mon Sep 17 00:00:00 2001 From: grindsa Date: Mon, 1 Apr 2024 08:26:58 +0200 Subject: [PATCH 153/460] [fix] account profile support --- acme_srv/helper.py | 44 ++ examples/ca_handler/certifier_ca_handler.py | 144 ++++-- examples/db_handler/wsgi_handler.py | 3 +- examples/eab_handler/kid_profile_handler.py | 161 ++++++- test/test_certifier_handler.py | 464 ++++++++++++++++---- test/test_eabkid_profile_handler.py | 234 ++++++++++ test/test_helper.py | 85 +++- 7 files changed, 1015 insertions(+), 120 deletions(-) diff --git a/acme_srv/helper.py b/acme_srv/helper.py index 46048d22..6bac64c7 100644 --- a/acme_srv/helper.py +++ b/acme_srv/helper.py @@ -674,6 +674,50 @@ def get_url(environ: Dict[str, str], include_path: bool = False) -> str: return result +def header_info_field_validate(logger, csr: str, header_info_field: str, value: str, value_list: List[str]) -> Tuple[str, str]: + """ select value from list""" + logger.debug('header_info_field_validate(%s)', value) + + value_to_set = None + error = None + # get header info + header_info_value = header_info_lookup(logger, csr, header_info_field, value) + if header_info_value: + if header_info_value in value_list: + value_to_set = header_info_value + else: + error = f'{value} "{header_info_value}" is not allowed' + else: + # header not set, use first value from list + value_to_set = value_list[0] + + logger.debug('header_info_field_validate(%s) ended with %s/%s', value, value_to_set, error) + return value_to_set, error + + +def header_info_lookup(logger, csr: str, header_info_field, key: str) -> str: + """ lookup header info """ + logger.debug('header_info_lookup(%s)', key) + + result = None + header_info = header_info_get(logger, csr=csr) + if header_info: + try: + header_info_dic = json.loads(header_info[-1]['header_info']) + if header_info_field in header_info_dic: + for ele in header_info_dic[header_info_field].split(' '): + if key in ele.lower(): + result = ele.split('=', 1)[1] + break + else: + logger.error('header_info_lookup() header_info_field not found: %s', header_info_field) + except Exception as err: + logger.error('header_info_lookup() could not parse header_info_field: %s', err) + + logger.debug('header_info_lookup(%s) ended with: %s', key, result) + return result + + def header_info_get(logger: logging.Logger, csr: str, vlist: List[str] = ('id', 'name', 'header_info')) -> List[str]: """ lookup header information """ logger.debug('header_info_get()') diff --git a/examples/ca_handler/certifier_ca_handler.py b/examples/ca_handler/certifier_ca_handler.py index 95a24d28..da7ccf10 100644 --- a/examples/ca_handler/certifier_ca_handler.py +++ b/examples/ca_handler/certifier_ca_handler.py @@ -10,7 +10,7 @@ import requests from requests.auth import HTTPBasicAuth # pylint: disable=e0401 -from acme_srv.helper import load_config, cert_serial_get, uts_now, uts_to_date_utc, b64_decode, b64_encode, cert_pem2der, parse_url, proxy_check, error_dic_get, header_info_get +from acme_srv.helper import load_config, cert_serial_get, uts_now, uts_to_date_utc, b64_decode, b64_encode, cert_pem2der, parse_url, proxy_check, error_dic_get, header_info_field_validate, eab_handler_load, header_info_lookup class CAhandler(object): @@ -30,6 +30,8 @@ def __init__(self, debug: bool = False, logger: object = None): self.profile_id = None self.proxy = None self.header_info_field = False + self.eab_handler = None + self.eab_profiling = False def __enter__(self): """ Makes ACMEHandler a Context Manager """ @@ -134,10 +136,6 @@ def _cert_get(self, csr: str) -> Dict[str, str]: ca_dic = self._ca_get_properties('name', self.ca_name) cert_dic = {} - if self.header_info_field: - # parse profileid from http_header - self.profile_id = self._profile_id_get(csr=csr) - if 'href' in ca_dic: data = {'ca': ca_dic['href'], 'pkcs10': csr} @@ -301,6 +299,30 @@ def _config_headerinfo_get(self, config_dic: Dict[str, str]): self.logger.debug('_config_header_info() ended') + def _config_eab_profile_load(self, config_dic: Dict[str, str]): + """ load parameters """ + self.logger.debug('_config_eab_profile_load()') + + try: + self.eab_profiling = config_dic.getboolean('CAhandler', 'eab_profiling', fallback=False) + except Exception as err: + self.logger.warning('CAhandler._config_eab_profile_load() failed with error: %s', err) + self.eab_profiling = False + + if self.eab_profiling: + if 'EABhandler' in config_dic and 'eab_handler_file' in config_dic['EABhandler']: + # load eab_handler according to configuration + eab_handler_module = eab_handler_load(self.logger, config_dic) + if eab_handler_module: + # store handler in variable + self.eab_handler = eab_handler_module.EABhandler + else: + self.logger.critical('CAhandler._config_load(): EABHandler could not get loaded') + else: + self.logger.critical('CAhandler._config_load(): EABHandler configuration incomplete') + + self.logger.debug('_config_profile_load() ended') + def _config_load(self): """" load config from file """ # pylint: disable=R0912, R0915 @@ -320,12 +342,70 @@ def _config_load(self): self._config_parameter_load(config_dic) # load headerinfo self._config_headerinfo_get(config_dic) + # load profiling + self._config_eab_profile_load(config_dic) # load proxy configuration self._config_proxy_load(config_dic) - self.logger.debug('CAhandler._config_load() ended') + def _eab_profile_string_check(self, key, value): + self.logger.debug('CAhandler._eab_profile_string_check(): string: key: %s, value: %s', key, value) + + if hasattr(self, key): + self.logger.debug('CAhandler._eab_profile_string_check(): setting attribute: %s to %s', key, value) + setattr(self, key, value) + else: + self.logger.error('CAhandler._eab_profile_string_check(): ignore string attribute: key: %s value: %s', key, value) + + self.logger.debug('CAhandler._eab_profile_string_check() ended') + + def _eab_profile_list_check(self, eab_handler, csr, key, value): + self.logger.debug('CAhandler._eab_profile_list_check(): list: key: %s, value: %s', key, value) + + result = None + if hasattr(self, key): + new_value, error = header_info_field_validate(self.logger, csr, self.header_info_field, key, value) + if new_value: + self.logger.debug('CAhandler._eab_profile_list_check(): setting attribute: %s to %s', key, new_value) + setattr(self, key, new_value) + else: + result = error + elif key == 'allowed_domainlist': + # check if csr contains allowed domains + error = eab_handler.allowed_domains_check(csr, value) + if error: + result = error + else: + self.logger.error('CAhandler._eab_profile_list_check(): ignore list attribute: key: %s value: %s', key, value) + + self.logger.debug('CAhandler._eab_profile_list_check() ended with: %s', result) + return result + + def _eab_profile_check(self, csr: str) -> str: + """ check eab profile""" + self.logger.debug('CAhandler._eab_profile_check()') + + result = None + with self.eab_handler(self.logger) as eab_handler: + eab_profile_dic = eab_handler.eab_profile_get(csr) + for key, value in eab_profile_dic.items(): + if isinstance(value, str): + self._eab_profile_string_check(key, value) + elif isinstance(value, list): + result = self._eab_profile_list_check(eab_handler, csr, key, value) + if result: + break + + # we need to cover cases where profiling is enabled but no profile_id is defined in json + if self.header_info_field and "profile_id" not in eab_profile_dic: + hil_profile_id = header_info_lookup(self.logger, csr, self.header_info_field, 'profile_id') + if hil_profile_id: + self.profile_id = hil_profile_id + + self.logger.debug('CAhandler._eab_profile_check() ended with: %s', result) + return result + def _poll_cert_get(self, request_dic: Dict[str, str], poll_identifier: str, error: str) -> Tuple[str, str, str, str, bool]: """ get certificate via poll request """ self.logger.debug('CAhandler._poll_cert_get()') @@ -447,27 +527,6 @@ def _pem_cert_chain_generate(self, cert_dic: str) -> str: self.logger.debug('CAhandler._pem_cert_chain_generate() ended') return pem_file - def _profile_id_get(self, csr: str) -> str: - """ get profile id from csr """ - self.logger.debug('CAhandler._profile_id_get(%s)', csr) - profile_id = None - - # parse profileid from http_header - header_info = header_info_get(self.logger, csr=csr) - if header_info: - try: - header_info_dic = json.loads(header_info[-1]['header_info']) - if self.header_info_field in header_info_dic: - for ele in header_info_dic[self.header_info_field].split(' '): - if 'profileid' in ele.lower(): - profile_id = ele.split('=')[1] - break - except Exception as err: - self.logger.error('CAhandler._profile_id_get() could not parse profile_id: %s', err) - - self.logger.debug('CAhandler._profile_id_get() ended with: %s', profile_id) - return profile_id - def _request_poll(self, request_url: str) -> Tuple[str, str, str, str, bool]: """ poll request """ self.logger.debug('CAhandler._request_poll(%s)', request_url) @@ -521,15 +580,36 @@ def _trigger_bundle_build(self, cert_raw: str, ca_dic: Dict[str, str]) -> Tuple[ self.logger.debug('CAhandler._trigger_bundle_build() ended with: %s', error) return (error, cert_bundle) + def _profile_check(self, csr: str) -> str: + """ check profile """ + self.logger.debug('CAhandler._profile_check()') + error = None + + if self.eab_profiling: + error = self._eab_profile_check(csr) + # we need to cover cases where profiling is enabled but no profile_id is defined in json + elif self.header_info_field: + # no profiling - parse profileid from http_header + self.profile_id = header_info_lookup(self.logger, csr, self.header_info_field, 'profile_id') + + self.logger.debug('CAhandler._profile_check() ended with %s', error) + return error + def enroll(self, csr: str) -> Tuple[str, str, str, str]: """ enroll certificate """ self.logger.debug('Certificate.enroll()') cert_bundle = None - error = None cert_raw = None poll_identifier = None - cert_dic = self._cert_get(csr) + # check for eab profiling and header_info + error = self._profile_check(csr) + + # enrollment starts here + if not error: + cert_dic = self._cert_get(csr) + else: + cert_dic = None if cert_dic: if 'status' in cert_dic: @@ -537,7 +617,7 @@ def enroll(self, csr: str) -> Tuple[str, str, str, str]: if 'message' in cert_dic: error = cert_dic['message'] else: - error = 'unknown errror' + error = 'unknown error' elif 'certificateBase64' in cert_dic: # this is a valid cert generate the bundle cert_bundle = self._pem_cert_chain_generate(cert_dic) @@ -548,7 +628,9 @@ def enroll(self, csr: str) -> Tuple[str, str, str, str]: else: error = 'no certificate information found' else: - error = 'internal error' + if not error: + error = 'internal error' + self.logger.debug('Certificate.enroll() ended') return (error, cert_bundle, cert_raw, poll_identifier) diff --git a/examples/db_handler/wsgi_handler.py b/examples/db_handler/wsgi_handler.py index b0eef3e0..1e721609 100644 --- a/examples/db_handler/wsgi_handler.py +++ b/examples/db_handler/wsgi_handler.py @@ -175,7 +175,8 @@ def _certificate_search(self, column: str, string: str) -> Dict[str, str]: orders.id as order__id, orders.name as order__name, orders.status_id as order__status_id, - account.name as order__account__name + account.name as order__account__name, + account.eab_kid as order__account__eab_kid from certificate INNER JOIN orders on orders.id = certificate.order_id INNER JOIN account on account.id = orders.account_id diff --git a/examples/eab_handler/kid_profile_handler.py b/examples/eab_handler/kid_profile_handler.py index 8f5800b7..c5f84f9a 100644 --- a/examples/eab_handler/kid_profile_handler.py +++ b/examples/eab_handler/kid_profile_handler.py @@ -3,9 +3,10 @@ """ eab json handler """ from __future__ import print_function import json +import re # pylint: disable=C0209, E0401 -from acme_srv.helper import load_config - +from acme_srv.helper import load_config, csr_cn_get, csr_san_get +from typing import List, Tuple, Dict class EABhandler(object): """ EAB file handler """ @@ -33,6 +34,162 @@ def _config_load(self): self.logger.debug('EABhandler._config_load() ended') + def _chk_san_lists_get(self, csr: str) -> Tuple[List[str], List[bool]]: + """ check lists """ + self.logger.debug('EABhandler._chk_san_lists_get()') + + # get sans and build a list + _san_list = csr_san_get(self.logger, csr) + + check_list = [] + san_list = [] + + if _san_list: + for san in _san_list: + try: + # SAN list must be modified/filtered) + (_san_type, san_value) = san.lower().split(':') + san_list.append(san_value) + except Exception: + # force check to fail as something went wrong during parsing + check_list.append(False) + self.logger.info('EABhandler._csr_check(): san_list parsing failed at entry: {0}'.format(san)) + + self.logger.debug('EABhandler._chk_san_lists_get() ended') + return (san_list, check_list) + + def _cn_add(self, csr: str, san_list: List[str]) -> Tuple[List[str], str]: + """ add CN if required """ + self.logger.debug('EABhandler._cn_add()') + + # get common name and attach it to san_list + cn_ = csr_cn_get(self.logger, csr) + + if cn_: + cn_ = cn_.lower() + if cn_ not in san_list: + # append cn to san_list + self.logger.debug('EABhandler._csr_check(): append cn to san_list') + san_list.append(cn_) + + self.logger.debug('EABhandler._cn_add() ended') + return (san_list) + + def _profiles_load(self): + """ load profiles from key_file """ + self.logger.debug('EABhandler._profiles_load()') + + if self.key_file: + try: + with open(self.key_file, encoding='utf8') as json_file: + profiles_dic = json.load(json_file) + except Exception as err: + self.logger.error('EABhandler._profiles_load() error: {0}'.format(err)) + profiles_dic = {} + else: + self.logger.error('EABhandler._profiles_load() no key_file specified') + profiles_dic = {} + + self.logger.debug('EABhandler._profiles_load() ended with %s', bool(profiles_dic)) + return profiles_dic + + def _list_regex_check(self, entry: str, list_: List[str]) -> bool: + """ check entry against regex """ + self.logger.debug('EABhandler._list_regex_check()') + + check_result = False + for regex in list_: + if regex.startswith('*.'): + regex = regex.replace('*.', '.') + regex_compiled = re.compile(regex) + if bool(regex_compiled.search(entry)): + # parameter is in set flag accordingly and stop loop + check_result = True + + self.logger.debug('EABhandler._list_regex_check() ended with: {0}'.format(check_result)) + return check_result + + def _wllist_check(self, entry: str, list_: List[str], toggle: bool = False) -> bool: + """ check string against list """ + self.logger.debug('EABhandler._wllist_check({0}:{1})'.format(entry, toggle)) + self.logger.debug('check against list: {0}'.format(list_)) + + # default setting + check_result = False + + if entry: + if list_: + check_result = self._list_regex_check(entry, list_) + else: + # empty list, flip parameter to make the check successful + check_result = True + + if toggle: + # toggle result if this is a blocked_domainlist + check_result = not check_result + + self.logger.debug('EABhandler._wllist_check() ended with: {0}'.format(check_result)) + return check_result + + def allowed_domains_check(self, csr: str, domain_list: List[str]) -> str: + """ check allowed domains """ + self.logger.debug('EABhandler.allowed_domains_check()') + + (san_list, check_list) = self._chk_san_lists_get(csr) + (san_list) = self._cn_add(csr, san_list) + + # go over the san list and check each entry + for san in san_list: + check_list.append(self._wllist_check(san, domain_list)) + + if check_list: + # cover a cornercase with empty checklist (no san, no cn) + if False in check_list: + result = "allowed_domainlist checking failed" + else: + result = False + + self.logger.debug('EABhandler.allowed_domains_check() ended with: %s', result) + return result + + def eab_kid_get(self, csr: str) -> str: + """ get eab kid from datbases based on csr""" + self.logger.debug('EABhandler.eab_kid_get()') + try: + # look up eab_kid from database based on csr + from acme_srv.db_handler import DBstore # pylint: disable=c0415 + dbstore = DBstore(False, self.logger) + result_dic = dbstore.certificate_lookup('csr', csr, vlist=['name', 'order__name', 'order__account__name', 'order__account__eab_kid']) + if result_dic and 'order__account__eab_kid' in result_dic: + eab_kid = result_dic['order__account__eab_kid'] + else: + eab_kid = None + except Exception as err: + self.logger.error('EABhandler._eab_profile_get() database error: {0}'.format(err)) + eab_kid = None + + self.logger.debug('EABhandler.eab_kid_get() ended with: %s', eab_kid) + return eab_kid + + def eab_profile_get(self, csr: str) -> str: + """ get eab profile """ + self.logger.debug('EABhandler._eab_profile_get()') + + # load profiles from key_file + profiles_dic = self._profiles_load() + + # get eab_kid from database + eab_kid = self.eab_kid_get(csr) + + # get profile from profiles_dic + if profiles_dic and eab_kid and eab_kid in profiles_dic and 'cahandler' in profiles_dic[eab_kid]: + profile_dic = profiles_dic[eab_kid]['cahandler'] + else: + profile_dic = {} + + self.logger.debug('EABhandler._eab_profile_get() ended with: %s', bool(profile_dic)) + return profile_dic + def mac_key_get(self, kid: str = None) -> str: """ check external account binding """ self.logger.debug('EABhandler.mac_key_get({})'.format(kid)) diff --git a/test/test_certifier_handler.py b/test/test_certifier_handler.py index 73523349..6ee68369 100644 --- a/test/test_certifier_handler.py +++ b/test/test_certifier_handler.py @@ -5,8 +5,9 @@ import unittest import sys import os -from unittest.mock import patch, Mock +from unittest.mock import patch, Mock, MagicMock import requests +import configparser sys.path.insert(0, '.') sys.path.insert(1, '..') @@ -502,23 +503,20 @@ def test_047__cert_get(self, mock_caget, mock_post): mock_post.return_value = {'mock': 'post'} self.assertEqual({'mock': 'post'}, self.cahandler._cert_get('csr')) - @patch('examples.ca_handler.certifier_ca_handler.CAhandler._profile_id_get') @patch('examples.ca_handler.certifier_ca_handler.CAhandler._api_post') @patch('examples.ca_handler.certifier_ca_handler.CAhandler._ca_get_properties') - def test_048__cert_get(self, mock_caget, mock_post, mock_profile): + def test_048__cert_get(self, mock_caget, mock_post): """ CAhandler._ca_get_properties() _ca_get_properties does returns "href" key """ self.cahandler.api_host = 'api_host' self.cahandler.profile_id = 100 self.cahandler.header_info_field = 'header_info_field' - mock_profile.return_value = '101' mock_caget.return_value = {'href': 'href'} mock_post.return_value = {'mock': 'post'} self.assertEqual({'mock': 'post'}, self.cahandler._cert_get('csr')) - self.assertTrue(mock_profile.called) - self.assertEqual('101', self.cahandler.profile_id, ) + self.assertEqual(100, self.cahandler.profile_id) @patch('requests.get') - def test_048__cert_get_properties(self, mock_req): + def test_049__cert_get_properties(self, mock_req): """ CAhandler._cert_get_properties() all good """ self.cahandler.api_host = 'api_host' self.cahandler.auth = 'auth' @@ -528,7 +526,7 @@ def test_048__cert_get_properties(self, mock_req): self.assertEqual({'foo': 'bar'}, self.cahandler._cert_get_properties('serial', 'link')) @patch('requests.get') - def test_049__cert_get_properties(self, mock_get): + def test_050__cert_get_properties(self, mock_get): """ CAhandler._cert_get_properties() all good """ self.cahandler.api_host = 'api_host' self.cahandler.auth = 'auth' @@ -537,24 +535,24 @@ def test_049__cert_get_properties(self, mock_get): self.assertEqual({'status': 500, 'message': 'exc_api_get', 'statusMessage': 'Internal Server Error'}, self.cahandler._cert_get_properties('serial', 'link')) self.assertIn('ERROR:test_a2c:CAhandler._cert_get_properties() returned error: exc_api_get', lcm.output) - def test_050_poll(self): + def test_051_poll(self): """ CAhandler.poll() poll_identifier is none """ self.assertEqual((None, None, None, None, False), self.cahandler.poll('cert_name', None, 'csr')) @patch('examples.ca_handler.certifier_ca_handler.CAhandler._request_poll') - def test_051_poll(self, mock_poll): + def test_052_poll(self, mock_poll): """ CAhandler.poll() poll_identifier is none """ mock_poll.return_value = ('error', 'cert_bundle', 'cert_raw', 'poll_identifier', 'rejected') self.assertEqual(('error', 'cert_bundle', 'cert_raw', 'poll_identifier', 'rejected'), self.cahandler.poll('cert_name', 'poll_identifier', 'csr')) - def test_052__loop_poll(self): + def test_053__loop_poll(self): """ CAhandler._loop_poll() - no request url""" request_url = None self.assertEqual((None, None, None, None), self.cahandler._loop_poll(request_url)) @patch('time.sleep') @patch('requests.get') - def test_053__loop_poll(self, mock_get, mock_sleep): + def test_054__loop_poll(self, mock_get, mock_sleep): """ CAhandler._loop_poll() - nothing come back from request get""" self.cahandler.polling_timeout = 5 self.cahandler.timeout = 0 @@ -567,7 +565,7 @@ def test_053__loop_poll(self, mock_get, mock_sleep): @patch('time.sleep') @patch('requests.get') - def test_054__loop_poll(self, mock_get, mock_sleep): + def test_055__loop_poll(self, mock_get, mock_sleep): """ CAhandler._loop_poll() - no status returned from request get""" self.cahandler.polling_timeout = 5 self.cahandler.timeout = 0 @@ -579,7 +577,7 @@ def test_054__loop_poll(self, mock_get, mock_sleep): self.assertEqual((None, None, None, 'request_url'), self.cahandler._loop_poll(request_url)) @patch('requests.get') - def test_055__loop_poll(self, mock_get): + def test_056__loop_poll(self, mock_get): """ CAhandler._loop_poll() - status "rejected" returned from request get""" self.cahandler.polling_timeout = 6 self.cahandler.timeout = 0 @@ -591,7 +589,7 @@ def test_055__loop_poll(self, mock_get): @patch('time.sleep') @patch('requests.get') - def test_056__loop_poll(self, mock_get, mock_sleep): + def test_057__loop_poll(self, mock_get, mock_sleep): """ CAhandler._loop_poll() - status "accepted" returned from request get but no certificate in""" self.cahandler.polling_timeout = 6 self.cahandler.timeout = 0 @@ -604,7 +602,7 @@ def test_056__loop_poll(self, mock_get, mock_sleep): @patch('time.sleep') @patch('requests.get') - def test_057__loop_poll(self, mock_get, mock_sleep): + def test_058__loop_poll(self, mock_get, mock_sleep): """ CAhandler._loop_poll() - status "accepted" returned from request "certifiate" in but no "certificateBase64" in 2dn request """ self.cahandler.polling_timeout = 6 self.cahandler.timeout = 0 @@ -617,7 +615,7 @@ def test_057__loop_poll(self, mock_get, mock_sleep): @patch('examples.ca_handler.certifier_ca_handler.CAhandler._pem_cert_chain_generate') @patch('requests.get') - def test_058__loop_poll(self, mock_get, mock_chain): + def test_059__loop_poll(self, mock_get, mock_chain): """ CAhandler._loop_poll() - status "accepted" returned from request "certifiate" in but no "certificateBase64" in 2dn request """ self.cahandler.polling_timeout = 6 self.cahandler.timeout = 0 @@ -629,32 +627,32 @@ def test_058__loop_poll(self, mock_get, mock_chain): self.assertEqual((None, 'foo', 'certificateBase64', None), self.cahandler._loop_poll(request_url)) @patch('examples.ca_handler.certifier_ca_handler.CAhandler._cert_get') - def test_059_enroll(self, mock_certget): + def test_060_enroll(self, mock_certget): """ CAhandler.enroll() _cert_get returns None """ mock_certget.return_value = {} self.assertEqual(('internal error', None, None, None), self.cahandler.enroll('csr')) @patch('examples.ca_handler.certifier_ca_handler.CAhandler._cert_get') - def test_060_enroll(self, mock_certget): + def test_061_enroll(self, mock_certget): """ CAhandler.enroll() _cert_get returns wrong information """ mock_certget.return_value = {'foo': 'bar'} self.assertEqual(('no certificate information found', None, None, None), self.cahandler.enroll('csr')) @patch('examples.ca_handler.certifier_ca_handler.CAhandler._cert_get') - def test_061_enroll(self, mock_certget): + def test_062_enroll(self, mock_certget): """ CAhandler.enroll() _cert_get returns status without error message """ mock_certget.return_value = {'foo': 'bar', 'status': 'foo'} - self.assertEqual(('unknown errror', None, None, None), self.cahandler.enroll('csr')) + self.assertEqual(('unknown error', None, None, None), self.cahandler.enroll('csr')) @patch('examples.ca_handler.certifier_ca_handler.CAhandler._cert_get') - def test_062_enroll(self, mock_certget): + def test_063_enroll(self, mock_certget): """ CAhandler.enroll() _cert_get returns status with error message """ mock_certget.return_value = {'foo': 'bar', 'status': 'foo', 'message': 'message'} self.assertEqual(('message', None, None, None), self.cahandler.enroll('csr')) @patch('examples.ca_handler.certifier_ca_handler.CAhandler._pem_cert_chain_generate') @patch('examples.ca_handler.certifier_ca_handler.CAhandler._cert_get') - def test_063_enroll(self, mock_certget, mock_chain): + def test_064_enroll(self, mock_certget, mock_chain): """ CAhandler.enroll() _cert_get returns certb64 """ mock_certget.return_value = {'foo': 'bar', 'certificateBase64': 'certificateBase64'} mock_chain.return_value = 'mock_chain' @@ -662,27 +660,102 @@ def test_063_enroll(self, mock_certget, mock_chain): @patch('examples.ca_handler.certifier_ca_handler.CAhandler._loop_poll') @patch('examples.ca_handler.certifier_ca_handler.CAhandler._cert_get') - def test_064_enroll(self, mock_certget, mock_loop): + def test_065_enroll(self, mock_certget, mock_loop): + """ CAhandler.enroll() _cert_get returns certb64 """ + mock_certget.return_value = {'foo': 'bar', 'href': 'href'} + mock_loop.return_value = ('error', 'cert_bundle', 'cert_raw', 'poll_identifier') + self.assertEqual(('error', 'cert_bundle', 'cert_raw', 'poll_identifier'), self.cahandler.enroll('csr')) + + @patch('examples.ca_handler.certifier_ca_handler.header_info_lookup') + @patch('examples.ca_handler.certifier_ca_handler.CAhandler._eab_profile_check') + @patch('examples.ca_handler.certifier_ca_handler.CAhandler._loop_poll') + @patch('examples.ca_handler.certifier_ca_handler.CAhandler._cert_get') + def test_066_enroll(self, mock_certget, mock_loop, mock_prof, mock_lookup): """ CAhandler.enroll() _cert_get returns certb64 """ mock_certget.return_value = {'foo': 'bar', 'href': 'href'} mock_loop.return_value = ('error', 'cert_bundle', 'cert_raw', 'poll_identifier') self.assertEqual(('error', 'cert_bundle', 'cert_raw', 'poll_identifier'), self.cahandler.enroll('csr')) + self.assertFalse(mock_prof.called) + self.assertFalse(mock_lookup.called) + + @patch('examples.ca_handler.certifier_ca_handler.header_info_lookup') + @patch('examples.ca_handler.certifier_ca_handler.CAhandler._eab_profile_check') + @patch('examples.ca_handler.certifier_ca_handler.CAhandler._loop_poll') + @patch('examples.ca_handler.certifier_ca_handler.CAhandler._cert_get') + def test_067_enroll(self, mock_certget, mock_loop, mock_prof, mock_lookup): + """ CAhandler.enroll() _cert_get returns certb64 """ + mock_certget.return_value = {'foo': 'bar', 'href': 'href'} + mock_loop.return_value = ('error', 'cert_bundle', 'cert_raw', 'poll_identifier') + self.cahandler.eab_profiling = True + mock_prof.return_value = None + self.assertEqual(('error', 'cert_bundle', 'cert_raw', 'poll_identifier'), self.cahandler.enroll('csr')) + self.assertTrue(mock_prof.called) + self.assertFalse(mock_lookup.called) + + @patch('examples.ca_handler.certifier_ca_handler.header_info_lookup') + @patch('examples.ca_handler.certifier_ca_handler.CAhandler._eab_profile_check') + @patch('examples.ca_handler.certifier_ca_handler.CAhandler._loop_poll') + @patch('examples.ca_handler.certifier_ca_handler.CAhandler._cert_get') + def test_068_enroll(self, mock_certget, mock_loop, mock_prof, mock_lookup): + """ CAhandler.enroll() _cert_get returns certb64 """ + mock_certget.return_value = {'foo': 'bar', 'href': 'href'} + mock_loop.return_value = ('error', 'cert_bundle', 'cert_raw', 'poll_identifier') + self.cahandler.eab_profiling = True + self.cahandler.header_info_field = 'header_info_field' + mock_prof.return_value = None + self.assertEqual(('error', 'cert_bundle', 'cert_raw', 'poll_identifier'), self.cahandler.enroll('csr')) + self.assertTrue(mock_prof.called) + self.assertFalse(mock_lookup.called) + + @patch('examples.ca_handler.certifier_ca_handler.header_info_lookup') + @patch('examples.ca_handler.certifier_ca_handler.CAhandler._eab_profile_check') + @patch('examples.ca_handler.certifier_ca_handler.CAhandler._loop_poll') + @patch('examples.ca_handler.certifier_ca_handler.CAhandler._cert_get') + def test_069_enroll(self, mock_certget, mock_loop, mock_prof, mock_lookup): + """ CAhandler.enroll() _cert_get returns certb64 """ + mock_certget.return_value = {'foo': 'bar', 'href': 'href'} + mock_loop.return_value = ('error', 'cert_bundle', 'cert_raw', 'poll_identifier') + self.cahandler.eab_profiling = True + self.cahandler.header_info_field = 'header_info_field' + mock_prof.return_value = 'prof_error' + self.assertEqual(('prof_error', None, None, None), self.cahandler.enroll('csr')) + self.assertTrue(mock_prof.called) + self.assertFalse(mock_lookup.called) + self.assertFalse(mock_certget.called) + + @patch('examples.ca_handler.certifier_ca_handler.header_info_lookup') + @patch('examples.ca_handler.certifier_ca_handler.CAhandler._eab_profile_check') + @patch('examples.ca_handler.certifier_ca_handler.CAhandler._loop_poll') + @patch('examples.ca_handler.certifier_ca_handler.CAhandler._cert_get') + def test_070_enroll(self, mock_certget, mock_loop, mock_prof, mock_lookup): + """ CAhandler.enroll() _cert_get returns certb64 """ + mock_certget.return_value = {'foo': 'bar', 'href': 'href'} + mock_loop.return_value = ('error', 'cert_bundle', 'cert_raw', 'poll_identifier') + self.cahandler.eab_profiling = False + self.cahandler.header_info_field = 'header_info_field' + mock_prof.return_value = 'prof_error' + mock_lookup.return_value = 'mock_lookup' + self.assertEqual(('error', 'cert_bundle', 'cert_raw', 'poll_identifier'), self.cahandler.enroll('csr')) + self.assertFalse(mock_prof.called) + self.assertTrue(mock_lookup.called) + self.assertTrue(mock_certget.called) + self.assertEqual(self.cahandler.profile_id, 'mock_lookup') @patch('examples.ca_handler.certifier_ca_handler.CAhandler._ca_get_properties') - def test_065_revoke(self, mock_getca): + def test_071_revoke(self, mock_getca): """ CAhandler.revoke() _ca_get_properties returns nothing """ mock_getca.return_value = {} self.assertEqual((404, 'urn:ietf:params:acme:error:serverInternal', 'CA could not be found'), self.cahandler.revoke('cert')) @patch('examples.ca_handler.certifier_ca_handler.CAhandler._ca_get_properties') - def test_066_revoke(self, mock_getca): + def test_072_revoke(self, mock_getca): """ CAhandler.revoke() _ca_get_properties returns wrong information """ mock_getca.return_value = {'foo': 'bar'} self.assertEqual((404, 'urn:ietf:params:acme:error:serverInternal', 'CA could not be found'), self.cahandler.revoke('cert')) @patch('examples.ca_handler.certifier_ca_handler.cert_serial_get') @patch('examples.ca_handler.certifier_ca_handler.CAhandler._ca_get_properties') - def test_067_revoke(self, mock_getca, mock_serial): + def test_073_revoke(self, mock_getca, mock_serial): """ CAhandler.revoke() _ca_get_properties cert_serial_get failed """ mock_getca.return_value = {'foo': 'bar', 'href': 'href'} mock_serial.return_value = None @@ -691,7 +764,7 @@ def test_067_revoke(self, mock_getca, mock_serial): @patch('examples.ca_handler.certifier_ca_handler.CAhandler._cert_get_properties') @patch('examples.ca_handler.certifier_ca_handler.cert_serial_get') @patch('examples.ca_handler.certifier_ca_handler.CAhandler._ca_get_properties') - def test_068_revoke(self, mock_getca, mock_serial, mock_getcert): + def test_074_revoke(self, mock_getca, mock_serial, mock_getcert): """ CAhandler.revoke() _ca_get_properties get_cert_properties failed """ mock_getca.return_value = {'foo': 'bar', 'href': 'href'} mock_serial.return_value = 123 @@ -701,7 +774,7 @@ def test_068_revoke(self, mock_getca, mock_serial, mock_getcert): @patch('examples.ca_handler.certifier_ca_handler.CAhandler._cert_get_properties') @patch('examples.ca_handler.certifier_ca_handler.cert_serial_get') @patch('examples.ca_handler.certifier_ca_handler.CAhandler._ca_get_properties') - def test_069_revoke(self, mock_getca, mock_serial, mock_getcert): + def test_075_revoke(self, mock_getca, mock_serial, mock_getcert): """ CAhandler.revoke() _ca_get_properties get_cert_properties returns wrong information """ mock_getca.return_value = {'foo': 'bar', 'href': 'href'} mock_serial.return_value = 123 @@ -711,7 +784,7 @@ def test_069_revoke(self, mock_getca, mock_serial, mock_getcert): @patch('examples.ca_handler.certifier_ca_handler.CAhandler._cert_get_properties') @patch('examples.ca_handler.certifier_ca_handler.cert_serial_get') @patch('examples.ca_handler.certifier_ca_handler.CAhandler._ca_get_properties') - def test_070_revoke(self, mock_getca, mock_serial, mock_getcert): + def test_076_revoke(self, mock_getca, mock_serial, mock_getcert): """ CAhandler.revoke() _ca_get_properties get_cert_properties empty cert_list """ mock_getca.return_value = {'foo': 'bar', 'href': 'href'} mock_serial.return_value = 123 @@ -721,7 +794,7 @@ def test_070_revoke(self, mock_getca, mock_serial, mock_getcert): @patch('examples.ca_handler.certifier_ca_handler.CAhandler._cert_get_properties') @patch('examples.ca_handler.certifier_ca_handler.cert_serial_get') @patch('examples.ca_handler.certifier_ca_handler.CAhandler._ca_get_properties') - def test_071_revoke(self, mock_getca, mock_serial, mock_getcert): + def test_077_revoke(self, mock_getca, mock_serial, mock_getcert): """ CAhandler.revoke() _ca_get_properties get_cert_properties returns cert_list with wrong information """ mock_getca.return_value = {'foo': 'bar', 'href': 'href'} mock_serial.return_value = 123 @@ -732,7 +805,7 @@ def test_071_revoke(self, mock_getca, mock_serial, mock_getcert): @patch('examples.ca_handler.certifier_ca_handler.CAhandler._cert_get_properties') @patch('examples.ca_handler.certifier_ca_handler.cert_serial_get') @patch('examples.ca_handler.certifier_ca_handler.CAhandler._ca_get_properties') - def test_072_revoke(self, mock_getca, mock_serial, mock_getcert, mock_post): + def test_078_revoke(self, mock_getca, mock_serial, mock_getcert, mock_post): """ CAhandler.revoke() _ca_get_properties get_cert_properties returns cert_list revocation successful """ mock_getca.return_value = {'foo': 'bar', 'href': 'href'} mock_serial.return_value = 123 @@ -744,7 +817,7 @@ def test_072_revoke(self, mock_getca, mock_serial, mock_getcert, mock_post): @patch('examples.ca_handler.certifier_ca_handler.CAhandler._cert_get_properties') @patch('examples.ca_handler.certifier_ca_handler.cert_serial_get') @patch('examples.ca_handler.certifier_ca_handler.CAhandler._ca_get_properties') - def test_073_revoke(self, mock_getca, mock_serial, mock_getcert, mock_post): + def test_079_revoke(self, mock_getca, mock_serial, mock_getcert, mock_post): """ CAhandler.revoke() _ca_get_properties get_cert_properties returns href. revocation returns status without message """ mock_getca.return_value = {'foo': 'bar', 'href': 'href'} mock_serial.return_value = 123 @@ -756,7 +829,7 @@ def test_073_revoke(self, mock_getca, mock_serial, mock_getcert, mock_post): @patch('examples.ca_handler.certifier_ca_handler.CAhandler._cert_get_properties') @patch('examples.ca_handler.certifier_ca_handler.cert_serial_get') @patch('examples.ca_handler.certifier_ca_handler.CAhandler._ca_get_properties') - def test_074_revoke(self, mock_getca, mock_serial, mock_getcert, mock_post): + def test_080_revoke(self, mock_getca, mock_serial, mock_getcert, mock_post): """ CAhandler.revoke() _ca_get_properties get_cert_properties returns href. revocation returns status with message """ mock_getca.return_value = {'foo': 'bar', 'href': 'href'} mock_serial.return_value = 123 @@ -764,7 +837,7 @@ def test_074_revoke(self, mock_getca, mock_serial, mock_getcert, mock_post): mock_post.return_value = {'foo': 'bar', 'status': 'status', 'message': 'message'} self.assertEqual((400, 'urn:ietf:params:acme:error:alreadyRevoked', 'message'), self.cahandler.revoke('cert')) - def test_075_trigger(self): + def test_081_trigger(self): """ CAhandler.trigger() - no payload given """ payload = None self.assertEqual(('No payload given', None, None), self.cahandler.trigger(payload)) @@ -773,7 +846,7 @@ def test_075_trigger(self): @patch('examples.ca_handler.certifier_ca_handler.cert_pem2der') @patch('examples.ca_handler.certifier_ca_handler.b64_decode') @patch('examples.ca_handler.certifier_ca_handler.b64_encode') - def test_076_trigger(self, mock_b64dec, mock_b64enc, mock_p2d, mock_caprop): + def test_082_trigger(self, mock_b64dec, mock_b64enc, mock_p2d, mock_caprop): """ CAhandler.trigger() - payload but ca_lookup failed""" payload = 'foo' mock_b64dec.return_value = 'foodecode' @@ -786,7 +859,7 @@ def test_076_trigger(self, mock_b64dec, mock_b64enc, mock_p2d, mock_caprop): @patch('examples.ca_handler.certifier_ca_handler.cert_pem2der') @patch('examples.ca_handler.certifier_ca_handler.b64_decode') @patch('examples.ca_handler.certifier_ca_handler.b64_encode') - def test_077_trigger(self, mock_b64dec, mock_b64enc, mock_p2d, mock_caprop, mock_serial): + def test_083_trigger(self, mock_b64dec, mock_b64enc, mock_p2d, mock_caprop, mock_serial): """ CAhandler.trigger() - payload serial number lookup failed""" payload = 'foo' mock_b64dec.return_value = 'foodecode' @@ -801,7 +874,7 @@ def test_077_trigger(self, mock_b64dec, mock_b64enc, mock_p2d, mock_caprop, mock @patch('examples.ca_handler.certifier_ca_handler.cert_pem2der') @patch('examples.ca_handler.certifier_ca_handler.b64_decode') @patch('examples.ca_handler.certifier_ca_handler.b64_encode') - def test_078_trigger(self, mock_b64dec, mock_b64enc, mock_p2d, mock_caprop, mock_serial, mock_certprop): + def test_084_trigger(self, mock_b64dec, mock_b64enc, mock_p2d, mock_caprop, mock_serial, mock_certprop): """ CAhandler.trigger() - payload serial number lookup failed""" payload = 'foo' mock_b64dec.return_value = 'foodecode' @@ -818,7 +891,7 @@ def test_078_trigger(self, mock_b64dec, mock_b64enc, mock_p2d, mock_caprop, mock @patch('examples.ca_handler.certifier_ca_handler.cert_pem2der') @patch('examples.ca_handler.certifier_ca_handler.b64_decode') @patch('examples.ca_handler.certifier_ca_handler.b64_encode') - def test_079_trigger(self, mock_b64dec, mock_b64enc, mock_p2d, mock_caprop, mock_serial, mock_certprop, mock_chain): + def test_085_trigger(self, mock_b64dec, mock_b64enc, mock_p2d, mock_caprop, mock_serial, mock_certprop, mock_chain): """ CAhandler.trigger() - payload serial number lookup failed""" payload = 'foo' mock_b64dec.return_value = 'foodecode' @@ -836,7 +909,7 @@ def test_079_trigger(self, mock_b64dec, mock_b64enc, mock_p2d, mock_caprop, mock @patch('examples.ca_handler.certifier_ca_handler.cert_pem2der') @patch('examples.ca_handler.certifier_ca_handler.b64_decode') @patch('examples.ca_handler.certifier_ca_handler.b64_encode') - def test_080_trigger(self, mock_b64dec, mock_b64enc, mock_p2d, mock_caprop, mock_serial, mock_certprop, mock_chain): + def test_086_trigger(self, mock_b64dec, mock_b64enc, mock_p2d, mock_caprop, mock_serial, mock_certprop, mock_chain): """ CAhandler.trigger() - payload serial number lookup failed""" payload = 'foo' mock_b64dec.return_value = 'foodecode' @@ -847,23 +920,23 @@ def test_080_trigger(self, mock_b64dec, mock_b64enc, mock_p2d, mock_caprop, mock mock_chain.return_value = 'chain' self.assertEqual((None, 'chain', 'foodecode'), self.cahandler.trigger(payload)) - def test_081__pem_cert_chain_generate(self): + def test_087__pem_cert_chain_generate(self): """ _pem_cert_chain_generate - empty cert_dic """ cert_dic = {} self.assertFalse(self.cahandler._pem_cert_chain_generate(cert_dic)) - def test_082__pem_cert_chain_generate(self): + def test_088__pem_cert_chain_generate(self): """ _pem_cert_chain_generate - wrong dic """ cert_dic = {'foo': 'bar'} self.assertFalse(self.cahandler._pem_cert_chain_generate(cert_dic)) - def test_083__pem_cert_chain_generate(self): + def test_089__pem_cert_chain_generate(self): """ _pem_cert_chain_generate - certificateBase64 in dict """ cert_dic = {'certificateBase64': 'certificateBase64'} self.assertEqual('-----BEGIN CERTIFICATE-----\ncertificateBase64\n-----END CERTIFICATE-----\n', self.cahandler._pem_cert_chain_generate(cert_dic)) @patch('requests.get') - def test_084__pem_cert_chain_generate(self, mock_get): + def test_090__pem_cert_chain_generate(self, mock_get): """ _pem_cert_chain_generate - issuer in dict without certificateBase64 """ cert_dic = {'issuer': 'issuer'} mockresponse = Mock() @@ -872,7 +945,7 @@ def test_084__pem_cert_chain_generate(self, mock_get): self.assertFalse(self.cahandler._pem_cert_chain_generate(cert_dic)) @patch('requests.get') - def test_085__pem_cert_chain_generate(self, mock_get): + def test_091__pem_cert_chain_generate(self, mock_get): """ _pem_cert_chain_generate - request returns "certificates" but no active """ cert_dic = {'issuer': 'issuer', 'certificateBase64': 'certificateBase641'} mockresponse1 = Mock() @@ -883,7 +956,7 @@ def test_085__pem_cert_chain_generate(self, mock_get): self.assertEqual('-----BEGIN CERTIFICATE-----\ncertificateBase641\n-----END CERTIFICATE-----\n', self.cahandler._pem_cert_chain_generate(cert_dic)) @patch('requests.get') - def test_086__pem_cert_chain_generate(self, mock_get): + def test_092__pem_cert_chain_generate(self, mock_get): """ _pem_cert_chain_generate - request returns certificate and active, 2nd request is bogus """ cert_dic = {'issuer': 'issuer', 'certificateBase64': 'certificateBase641'} mockresponse1 = Mock() @@ -894,7 +967,7 @@ def test_086__pem_cert_chain_generate(self, mock_get): self.assertEqual('-----BEGIN CERTIFICATE-----\ncertificateBase641\n-----END CERTIFICATE-----\n', self.cahandler._pem_cert_chain_generate(cert_dic)) @patch('requests.get') - def test_087__pem_cert_chain_generate(self, mock_get): + def test_093__pem_cert_chain_generate(self, mock_get): """ _pem_cert_chain_generate - request returns certificate two certs """ cert_dic = {'issuer': 'issuer', 'certificateBase64': 'certificateBase641'} mockresponse1 = Mock() @@ -907,7 +980,7 @@ def test_087__pem_cert_chain_generate(self, mock_get): self.assertEqual('-----BEGIN CERTIFICATE-----\ncertificateBase641\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\ncertificateBase642\n-----END CERTIFICATE-----\n', self.cahandler._pem_cert_chain_generate(cert_dic)) @patch('requests.get') - def test_088__pem_cert_chain_generate(self, mock_get): + def test_094__pem_cert_chain_generate(self, mock_get): """ _pem_cert_chain_generate - request returns certificate three certs """ cert_dic = {'issuer': 'issuer', 'certificateBase64': 'certificateBase641'} mockresponse1 = Mock() @@ -924,7 +997,7 @@ def test_088__pem_cert_chain_generate(self, mock_get): self.assertEqual('-----BEGIN CERTIFICATE-----\ncertificateBase641\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\ncertificateBase642\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\ncertificateBase643\n-----END CERTIFICATE-----\n', self.cahandler._pem_cert_chain_generate(cert_dic)) @patch('requests.get') - def test_089__pem_cert_chain_generate(self, mock_get): + def test_095__pem_cert_chain_generate(self, mock_get): """ _pem_cert_chain_generate - issuerCa in """ cert_dic = {'issuerCa': 'issuerCa', 'certificateBase64': 'certificateBase641'} mockresponse1 = Mock() @@ -934,12 +1007,12 @@ def test_089__pem_cert_chain_generate(self, mock_get): mock_get.side_effect = [mockresponse1, mockresponse2] self.assertEqual('-----BEGIN CERTIFICATE-----\ncertificateBase641\n-----END CERTIFICATE-----\n', self.cahandler._pem_cert_chain_generate(cert_dic)) - def test_090__enter__(self): + def test_096__enter__(self): """ test __enter__ """ self.cahandler.__enter__() @patch('requests.get') - def test_091_request_poll(self, mock_get): + def test_097_request_poll(self, mock_get): """ test request poll request returned exception """ mock_get.side_effect = Exception('exc_api_get') result = ('"status" field not found in response.', None, None, 'url', False) @@ -948,7 +1021,7 @@ def test_091_request_poll(self, mock_get): self.assertIn('ERROR:test_a2c:CAhandler._request.poll() returned: exc_api_get', lcm.output) @patch('requests.get') - def test_092_request_poll(self, mock_get): + def test_098_request_poll(self, mock_get): """ test request poll request returned unknown status """ mockresponse = Mock() mockresponse.json = lambda: {'status': 'unknown'} @@ -957,7 +1030,7 @@ def test_092_request_poll(self, mock_get): self.assertEqual(result, self.cahandler._request_poll('url')) @patch('requests.get') - def test_093_request_poll(self, mock_get): + def test_099_request_poll(self, mock_get): """ test request poll request returned status rejected """ mockresponse = Mock() mockresponse.json = lambda: {'status': 'rejected'} @@ -966,7 +1039,7 @@ def test_093_request_poll(self, mock_get): self.assertEqual(result, self.cahandler._request_poll('url')) @patch('requests.get') - def test_094_request_poll(self, mock_get): + def test_100_request_poll(self, mock_get): """ test request poll request returned status accepted but no certinformation in """ mockresponse = Mock() mockresponse.json = lambda: {'status': 'accepted', 'foo': 'bar'} @@ -975,7 +1048,7 @@ def test_094_request_poll(self, mock_get): self.assertEqual(result, self.cahandler._request_poll('url')) @patch('requests.get') - def test_095_request_poll(self, mock_get): + def test_101_request_poll(self, mock_get): """ test request poll request returned status accepted but no certinformation in """ mockresponse = Mock() mockresponse.json = lambda: {'status': 'accepted', 'certificate': 'certificate'} @@ -985,7 +1058,7 @@ def test_095_request_poll(self, mock_get): @patch('examples.ca_handler.certifier_ca_handler.CAhandler._pem_cert_chain_generate') @patch('requests.get') - def test_096_request_poll(self, mock_get, mock_pemgen): + def test_102_request_poll(self, mock_get, mock_pemgen): """ test request poll request returned status accepted but no certinformation in """ mockresponse = Mock() mockresponse.json = lambda: {'status': 'accepted', 'certificate': 'certificate', 'certificateBase64': 'certificateBase64'} @@ -994,35 +1067,19 @@ def test_096_request_poll(self, mock_get, mock_pemgen): result = (None, 'bundle', 'certificateBase64', 'url', False) self.assertEqual(result, self.cahandler._request_poll('url')) - @patch('examples.ca_handler.certifier_ca_handler.header_info_get') - def test_096_profile_id_get(self, mock_header): - """ test _profile_id_get()""" - mock_header.return_value = [{'header_info': '{"header_field": "profileID=101 lego-cli/4.14.2 xenolf-acme/4.14.2 (release; linux; amd64)"}'}] - self.cahandler.header_info_field = 'header_field' - self.assertEqual('101', self.cahandler._profile_id_get('csr')) - - @patch('examples.ca_handler.certifier_ca_handler.header_info_get') - def test_097_profile_id_get(self, mock_header): - """ test _profile_id_get()""" - mock_header.return_value = [{'header_info': 'header_info'}] - self.cahandler.header_info_field = 'header_field' - with self.assertLogs('test_a2c', level='INFO') as lcm: - self.assertFalse(self.cahandler._profile_id_get('csr')) - self.assertIn('ERROR:test_a2c:CAhandler._profile_id_get() could not parse profile_id: Expecting value: line 1 column 1 (char 0)', lcm.output) - - def test_098_config_headerinfo_get(self): + def test_103_config_headerinfo_get(self): """ test config_headerinfo_get()""" config_dic = {'Order': {'header_info_list': '["foo", "bar", "foobar"]'}} self.cahandler._config_headerinfo_get(config_dic) self.assertEqual( 'foo', self.cahandler.header_info_field) - def test_099_config_headerinfo_get(self): + def test_104_config_headerinfo_get(self): """ test config_headerinfo_get()""" config_dic = {'Order': {'header_info_list': '["foo"]'}} self.cahandler._config_headerinfo_get(config_dic) self.assertEqual( 'foo', self.cahandler.header_info_field) - def test_100_config_headerinfo_get(self): + def test_105_config_headerinfo_get(self): """ test config_headerinfo_get()""" config_dic = {'Order': {'header_info_list': 'foo'}} with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -1030,6 +1087,263 @@ def test_100_config_headerinfo_get(self): self.assertFalse(self.cahandler.header_info_field) self.assertIn('WARNING:test_a2c:Order._config_orderconfig_load() header_info_list failed with error: Expecting value: line 1 column 1 (char 0)', lcm.output) + @patch('examples.ca_handler.certifier_ca_handler.eab_handler_load') + def test_106_config_eab_profile_load(self, mock_eabload): + """ test config_eab_profiling()""" + config_dic = configparser.ConfigParser() + config_dic['CAhandler'] = {'eab_profiling': True} + config_dic['EABhandler'] = {'eab_handler_file': 'eab_handler_file'} + self.cahandler._config_eab_profile_load(config_dic) + self.assertTrue(mock_eabload.called) + self.assertTrue(self.cahandler.eab_profiling) + + @patch('examples.ca_handler.certifier_ca_handler.eab_handler_load') + def test_107_config_eab_profile_load(self, mock_eabload): + """ test config_eab_profiling()""" + config_dic = configparser.ConfigParser() + config_dic['CAhandler'] = {'eab_profiling': True} + # ['EABhandler'] = {'eab_handler_file': 'eab_handler_file'} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.cahandler._config_eab_profile_load(config_dic) + self.assertFalse(mock_eabload.called) + self.assertIn('CRITICAL:test_a2c:CAhandler._config_load(): EABHandler configuration incomplete', lcm.output) + self.assertTrue(self.cahandler.eab_profiling) + + @patch('examples.ca_handler.certifier_ca_handler.eab_handler_load') + def test_108_config_eab_profile_load(self, mock_eabload): + """ test config_eab_profiling()""" + config_dic = configparser.ConfigParser() + config_dic['CAhandler'] = {'eab_profiling': True} + config_dic['EABhandler'] = {'eab_handler_file': 'eab_handler_file'} + mock_eabload.return_value = None + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.cahandler._config_eab_profile_load(config_dic) + self.assertTrue(mock_eabload.called) + self.assertIn('CRITICAL:test_a2c:CAhandler._config_load(): EABHandler could not get loaded', lcm.output) + self.assertTrue(self.cahandler.eab_profiling) + + @patch('examples.ca_handler.certifier_ca_handler.eab_handler_load') + def test_109_config_eab_profile_load(self, mock_eabload): + """ test config_eab_profiling()""" + config_dic = configparser.ConfigParser() + config_dic['CAhandler'] = {'eab_profiling': False} + config_dic['EABhandler'] = {'eab_handler_file': 'eab_handler_file'} + self.cahandler._config_eab_profile_load(config_dic) + self.assertFalse(mock_eabload.called) + self.assertFalse(self.cahandler.eab_profiling) + + @patch('examples.ca_handler.certifier_ca_handler.eab_handler_load') + def test_110_config_eab_profile_load(self, mock_eabload): + """ test config_eab_profiling()""" + config_dic = configparser.ConfigParser() + config_dic['CAhandler'] = {'eab_profiling': 'aa'} + config_dic['EABhandler'] = {'eab_handler_file': 'eab_handler_file'} + self.cahandler._config_eab_profile_load(config_dic) + self.assertFalse(mock_eabload.called) + self.assertFalse(self.cahandler.eab_profiling) + + @patch('examples.ca_handler.certifier_ca_handler.header_info_field_validate') + def test_111__eab_profile_check(self, mock_hil): + """ test eab_profile_check """ + self.cahandler.eab_handler = MagicMock() + self.cahandler.api_host = 'api_host' + self.cahandler.api_user = 'api_user' + self.cahandler.api_password = 'api_password' + self.cahandler.profile_id = 'profile_id' + self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar'} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.cahandler._eab_profile_check('csr')) + self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) + self.assertEqual('api_host', self.cahandler.api_host) + self.assertEqual('api_user', self.cahandler.api_user) + self.assertEqual('api_password', self.cahandler.api_password) + self.assertEqual('profile_id', self.cahandler.profile_id) + self.assertFalse(mock_hil.called) + + @patch('examples.ca_handler.certifier_ca_handler.header_info_lookup') + def test_112__eab_profile_check(self, mock_hil): + """ test eab_profile_check """ + self.cahandler.eab_handler = MagicMock() + self.cahandler.api_host = 'api_host' + self.cahandler.api_user = 'api_user' + self.cahandler.api_password = 'api_password' + self.cahandler.profile_id = 'profile_id' + self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'api_host': 'new_host', 'api_user': 'new_user', 'api_password': 'new_password', 'profile_id': 'new_profile'} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.cahandler._eab_profile_check('csr')) + self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) + self.assertEqual('new_host', self.cahandler.api_host) + self.assertEqual('new_user', self.cahandler.api_user) + self.assertEqual('new_password', self.cahandler.api_password) + self.assertEqual('new_profile', self.cahandler.profile_id) + self.assertFalse(mock_hil.called) + + def test_113__eab_profile_check(self): + """ test eab_profile_check default value from list """ + self.cahandler.eab_handler = MagicMock() + self.cahandler.api_host = 'api_host' + self.cahandler.api_user = 'api_user' + self.cahandler.api_password = 'api_password' + self.cahandler.profile_id = 'profile_id' + self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'profile_id': ['profile_1', 'profile_2', 'profile_3']} + # mock_hil.return_value = ('None', None) + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.cahandler._eab_profile_check('csr')) + self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) + self.assertEqual('api_host', self.cahandler.api_host) + self.assertEqual('api_user', self.cahandler.api_user) + self.assertEqual('api_password', self.cahandler.api_password) + self.assertEqual('profile_1', self.cahandler.profile_id) + + @patch('examples.ca_handler.certifier_ca_handler.header_info_field_validate') + def test_114__eab_profile_check(self, mock_hil): + """ test eab_profile_check default value from list header info validate returns a value """ + self.cahandler.eab_handler = MagicMock() + self.cahandler.api_host = 'api_host' + self.cahandler.api_user = 'api_user' + self.cahandler.api_password = 'api_password' + self.cahandler.profile_id = 'profile_id' + mock_hil.return_value = ('profile_2', None) + self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'profile_id': ['profile_1', 'profile_2', 'profile_3']} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.cahandler._eab_profile_check('csr')) + self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) + self.assertEqual('api_host', self.cahandler.api_host) + self.assertEqual('api_user', self.cahandler.api_user) + self.assertEqual('api_password', self.cahandler.api_password) + self.assertEqual('profile_2', self.cahandler.profile_id) + self.assertTrue(mock_hil.called) + + @patch('examples.ca_handler.certifier_ca_handler.header_info_field_validate') + def test_114__eab_profile_check(self, mock_hil): + """ test eab_profile_check default value from list headerinfo_lookup returns an error """ + self.cahandler.eab_handler = MagicMock() + self.cahandler.api_host = 'api_host' + self.cahandler.api_user = 'api_user' + self.cahandler.api_password = 'api_password' + self.cahandler.profile_id = 'profile_id' + mock_hil.return_value = (None, 'error') + self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'profile_id': ['profile_1', 'profile_2', 'profile_3']} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertEqual('error', self.cahandler._eab_profile_check('csr')) + self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) + self.assertEqual('api_host', self.cahandler.api_host) + self.assertEqual('api_user', self.cahandler.api_user) + self.assertEqual('api_password', self.cahandler.api_password) + self.assertEqual('profile_id', self.cahandler.profile_id) + self.assertTrue(mock_hil.called) + + @patch('examples.ca_handler.certifier_ca_handler.header_info_field_validate') + def test_115__eab_profile_check(self, mock_hil): + """ test eab_profile_check """ + self.cahandler.eab_handler = MagicMock() + self.cahandler.api_host = 'api_host' + self.cahandler.api_user = 'api_user' + self.cahandler.api_password = 'api_password' + self.cahandler.profile_id = 'profile_id' + mock_hil.return_value = ('hil_value', None) + self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'allowed_domainlist': ['foo.bar', 'bar.foo']} + self.cahandler.eab_handler.return_value.__enter__.return_value.allowed_domains_check.return_value = 'domain_chk_error' + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertEqual('domain_chk_error', self.cahandler._eab_profile_check('csr')) + self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) + self.assertEqual('api_host', self.cahandler.api_host) + self.assertEqual('api_user', self.cahandler.api_user) + self.assertEqual('api_password', self.cahandler.api_password) + self.assertEqual('profile_id', self.cahandler.profile_id) + self.assertFalse(mock_hil.called) + + @patch('examples.ca_handler.certifier_ca_handler.header_info_field_validate') + def test_116__eab_profile_check(self, mock_hil): + """ test eab_profile_check """ + self.cahandler.eab_handler = MagicMock() + self.cahandler.api_host = 'api_host' + self.cahandler.api_user = 'api_user' + self.cahandler.api_password = 'api_password' + self.cahandler.profile_id = 'profile_id' + mock_hil.return_value = ('hil_value', None) + self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'allowed_domainlist': ['foo.bar', 'bar.foo']} + self.cahandler.eab_handler.return_value.__enter__.return_value.allowed_domains_check.return_value = None + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.cahandler._eab_profile_check('csr')) + self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) + self.assertEqual('api_host', self.cahandler.api_host) + self.assertEqual('api_user', self.cahandler.api_user) + self.assertEqual('api_password', self.cahandler.api_password) + self.assertEqual('profile_id', self.cahandler.profile_id) + self.assertFalse(mock_hil.called) + + @patch('examples.ca_handler.certifier_ca_handler.header_info_field_validate') + def test_117__eab_profile_check(self, mock_hil): + """ test eab_profile_check """ + self.cahandler.eab_handler = MagicMock() + self.cahandler.api_host = 'api_host' + self.cahandler.api_user = 'api_user' + self.cahandler.api_password = 'api_password' + self.cahandler.profile_id = 'profile_id' + mock_hil.return_value = ('hil_value', None) + self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'unknown': ['foobar', 'barfoo']} + self.cahandler.eab_handler.return_value.__enter__.return_value.allowed_domains_check.return_value = None + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.cahandler._eab_profile_check('csr')) + self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) + self.assertIn("ERROR:test_a2c:CAhandler._eab_profile_list_check(): ignore list attribute: key: unknown value: ['foobar', 'barfoo']", lcm.output) + self.assertEqual('api_host', self.cahandler.api_host) + self.assertEqual('api_user', self.cahandler.api_user) + self.assertEqual('api_password', self.cahandler.api_password) + self.assertEqual('profile_id', self.cahandler.profile_id) + self.assertFalse(mock_hil.called) + + @patch('examples.ca_handler.certifier_ca_handler.header_info_lookup') + @patch('examples.ca_handler.certifier_ca_handler.header_info_field_validate') + def test_118__eab_profile_check(self, mock_hiv, mock_hil): + """ test eab_profile_check """ + self.cahandler.eab_handler = MagicMock() + self.cahandler.api_host = 'api_host' + self.cahandler.api_user = 'api_user' + self.cahandler.api_password = 'api_password' + self.cahandler.profile_id = 'profile_id' + self.cahandler.header_info_field = 'header_info_field' + mock_hiv.return_value = ('hil_value', None) + mock_hil.return_value = 'mock_hil' + self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'unknown': ['foobar', 'barfoo']} + self.cahandler.eab_handler.return_value.__enter__.return_value.allowed_domains_check.return_value = None + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.cahandler._eab_profile_check('csr')) + self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) + self.assertIn("ERROR:test_a2c:CAhandler._eab_profile_list_check(): ignore list attribute: key: unknown value: ['foobar', 'barfoo']", lcm.output) + self.assertEqual('api_host', self.cahandler.api_host) + self.assertEqual('api_user', self.cahandler.api_user) + self.assertEqual('api_password', self.cahandler.api_password) + self.assertEqual('mock_hil', self.cahandler.profile_id) + self.assertFalse(mock_hiv.called) + self.assertTrue(mock_hil.called) + + @patch('examples.ca_handler.certifier_ca_handler.header_info_lookup') + @patch('examples.ca_handler.certifier_ca_handler.header_info_field_validate') + def test_119__eab_profile_check(self, mock_hiv, mock_hil): + """ test eab_profile_check """ + self.cahandler.eab_handler = MagicMock() + self.cahandler.api_host = 'api_host' + self.cahandler.api_user = 'api_user' + self.cahandler.api_password = 'api_password' + self.cahandler.profile_id = 'profile_id' + self.cahandler.header_info_field = 'header_info_field' + mock_hiv.return_value = ('hil_value', None) + mock_hil.return_value = None + self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'unknown': ['foobar', 'barfoo']} + self.cahandler.eab_handler.return_value.__enter__.return_value.allowed_domains_check.return_value = None + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.cahandler._eab_profile_check('csr')) + self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) + self.assertIn("ERROR:test_a2c:CAhandler._eab_profile_list_check(): ignore list attribute: key: unknown value: ['foobar', 'barfoo']", lcm.output) + self.assertEqual('api_host', self.cahandler.api_host) + self.assertEqual('api_user', self.cahandler.api_user) + self.assertEqual('api_password', self.cahandler.api_password) + self.assertEqual('profile_id', self.cahandler.profile_id) + self.assertFalse(mock_hiv.called) + self.assertTrue(mock_hil.called) + if __name__ == '__main__': if os.path.exists('acme_test.db'): diff --git a/test/test_eabkid_profile_handler.py b/test/test_eabkid_profile_handler.py index 355f1c1c..73c5aeca 100644 --- a/test/test_eabkid_profile_handler.py +++ b/test/test_eabkid_profile_handler.py @@ -116,6 +116,240 @@ def test_013_mac_key_get(self, mock_json): mock_json.return_value = {'kid': {'foo': 'bar'}} self.assertFalse(self.eabhandler.mac_key_get('kid')) + def test_014_wllist_check(self): + """ CAhandler._wllist_check failed check as empty entry""" + list_ = ['bar.foo$', 'foo.bar$'] + entry = None + self.assertFalse(self.eabhandler._wllist_check(entry, list_)) + + def test_015_wllist_check(self): + """ CAhandler._wllist_check check against empty list""" + list_ = [] + entry = 'host.bar.foo' + self.assertTrue(self.eabhandler._wllist_check(entry, list_)) + + def test_016_wllist_check(self): + """ CAhandler._wllist_check successful check against 1st element of a list""" + list_ = ['bar.foo$', 'foo.bar$'] + entry = 'host.bar.foo' + self.assertTrue(self.eabhandler._wllist_check(entry, list_)) + + def test_017_wllist_check(self): + """ CAhandler._wllist_check unsuccessful as endcheck failed""" + list_ = ['bar.foo$', 'foo.bar$'] + entry = 'host.bar.foo.bar_' + self.assertFalse(self.eabhandler._wllist_check(entry, list_)) + + def test_018_wllist_check(self): + """ CAhandler._wllist_check successful without $""" + list_ = ['bar.foo', 'foo.bar$'] + entry = 'host.bar.foo.bar_' + self.assertTrue(self.eabhandler._wllist_check(entry, list_)) + + def test_019_wllist_check(self): + """ CAhandler._wllist_check wildcard check""" + list_ = ['bar.foo$', 'foo.bar$'] + entry = '*.bar.foo' + self.assertTrue(self.eabhandler._wllist_check(entry, list_)) + + def test_020_wllist_check(self): + """ CAhandler._wllist_check failed wildcard check""" + list_ = ['bar.foo$', 'foo.bar$'] + entry = '*.bar.foo_' + self.assertFalse(self.eabhandler._wllist_check(entry, list_)) + + def test_021_wllist_check(self): + """ CAhandler._wllist_check not end check""" + list_ = ['bar.foo$', 'foo.bar$'] + entry = 'bar.foo gna' + self.assertFalse(self.eabhandler._wllist_check(entry, list_)) + + def test_022_wllist_check(self): + """ CAhandler._wllist_check $ at the end""" + list_ = ['bar.foo$', 'foo.bar$'] + entry = 'bar.foo$' + self.assertFalse(self.eabhandler._wllist_check(entry, list_)) + + def test_023_wllist_check(self): + """ CAhandler._wllist_check check against empty list flip""" + list_ = [] + entry = 'host.bar.foo' + self.assertFalse(self.eabhandler._wllist_check(entry, list_, True)) + + def test_024_wllist_check(self): + """ CAhandler._wllist_check flip successful check """ + list_ = ['bar.foo$', 'foo.bar$'] + entry = 'host.bar.foo' + self.assertFalse(self.eabhandler._wllist_check(entry, list_, True)) + + def test_025_wllist_check(self): + """ CAhandler._wllist_check flip unsuccessful check""" + list_ = ['bar.foo$', 'foo.bar$'] + entry = 'host.bar.foo' + self.assertFalse(self.eabhandler._wllist_check(entry, list_, True)) + + def test_026_wllist_check(self): + """ CAhandler._wllist_check unsuccessful whildcard check""" + list_ = ['foo.bar$', r'\*.bar.foo'] + entry = 'host.bar.foo' + self.assertFalse(self.eabhandler._wllist_check(entry, list_)) + + def test_027_wllist_check(self): + """ CAhandler._wllist_check successful whildcard check""" + list_ = ['foo.bar$', r'\*.bar.foo'] + entry = '*.bar.foo' + self.assertTrue(self.eabhandler._wllist_check(entry, list_)) + + def test_028_wllist_check(self): + """ CAhandler._wllist_check successful whildcard in list but not in string """ + list_ = ['foo.bar$', '*.bar.foo'] + entry = 'foo.bar.foo' + self.assertTrue(self.eabhandler._wllist_check(entry, list_)) + + @patch('examples.eab_handler.kid_profile_handler.csr_san_get') + def test_029_chk_san_lists_get(self, mock_san): + """ CAhandler._chk_san_lists_get() """ + csr = 'csr' + mock_san.return_value = ['dns:foo.bar', 'dns:bar.foo'] + self.assertEqual((['foo.bar', 'bar.foo'], []), self.eabhandler._chk_san_lists_get(csr)) + + @patch('examples.eab_handler.kid_profile_handler.csr_san_get') + def test_030_chk_san_lists_get(self, mock_san): + """ CAhandler._chk_san_lists_get() """ + csr = 'csr' + mock_san.return_value = ['dns:foo.bar', 'bar.foo'] + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertEqual((['foo.bar'], [False]), self.eabhandler._chk_san_lists_get(csr)) + self.assertIn('INFO:test_a2c:EABhandler._csr_check(): san_list parsing failed at entry: bar.foo', lcm.output) + + @patch('examples.eab_handler.kid_profile_handler.csr_san_get') + def test_031_chk_san_lists_get(self, mock_san): + """ CAhandler._chk_san_lists_get() """ + csr = 'csr' + mock_san.return_value = None + self.assertEqual(([], []), self.eabhandler._chk_san_lists_get(csr)) + + @patch('examples.eab_handler.kid_profile_handler.csr_cn_get') + def test_032_cn_add(self, mock_cnget): + """ CAhandler._cn_add() """ + csr = 'csr' + san_list = ['foo.bar', 'bar.foo'] + mock_cnget.return_value = 'foobar.bar' + self.assertEqual(['foo.bar', 'bar.foo', 'foobar.bar'], self.eabhandler._cn_add(csr, san_list)) + + @patch('examples.eab_handler.kid_profile_handler.csr_cn_get') + def test_033_cn_add(self, mock_cnget): + """ CAhandler._cn_add() """ + csr = 'csr' + san_list = ['foo.bar', 'bar.foo'] + mock_cnget.return_value = 'bar.foo' + self.assertEqual(['foo.bar', 'bar.foo'], self.eabhandler._cn_add(csr, san_list)) + + @patch("builtins.open", mock_open(read_data='{"foo": "bar"}'), create=True) + def test_034_profiles_load(self): + """ CAhandler._cn_add() """ + self.eabhandler.key_file = 'file' + self.assertEqual({'foo': 'bar'}, self.eabhandler._profiles_load()) + + @patch("builtins.open", mock_open(read_data='foobar'), create=True) + def test_035_profiles_load(self): + """ CAhandler._cn_add() """ + self.eabhandler.key_file = 'file' + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.eabhandler._profiles_load()) + self.assertIn('ERROR:test_a2c:EABhandler._profiles_load() error: Expecting value: line 1 column 1 (char 0)', lcm.output) + + @patch("builtins.open", mock_open(read_data='{"foo": "bar"}'), create=True) + def test_036_profiles_load(self): + """ CAhandler._cn_add() """ + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.eabhandler._profiles_load()) + self.assertIn('ERROR:test_a2c:EABhandler._profiles_load() no key_file specified', lcm.output) + + @patch('examples.eab_handler.kid_profile_handler.EABhandler._wllist_check') + @patch('examples.eab_handler.kid_profile_handler.EABhandler._cn_add') + @patch('examples.eab_handler.kid_profile_handler.EABhandler._chk_san_lists_get') + def test_037_allowed_domains_check(self, mock_san, mock_cn, mock_wlc): + """ test EABhanlder._allowed_domains_check() """ + mock_san.return_value = (['foo'], []) + mock_cn.return_value = ['foo', 'bar'] + mock_wlc.side_effect = [True, True] + self.assertFalse(self.eabhandler.allowed_domains_check('csr', ['domain', 'list'])) + + @patch('examples.eab_handler.kid_profile_handler.EABhandler._wllist_check') + @patch('examples.eab_handler.kid_profile_handler.EABhandler._cn_add') + @patch('examples.eab_handler.kid_profile_handler.EABhandler._chk_san_lists_get') + def test_038_allowed_domains_check(self, mock_san, mock_cn, mock_wlc): + """ test EABhanlder._allowed_domains_check() """ + mock_san.return_value = (['foo'], [False]) + mock_cn.return_value = ['foo', 'bar'] + mock_wlc.side_effect = [True, True] + self.assertEqual('allowed_domainlist checking failed', self.eabhandler.allowed_domains_check('csr', ['domain', 'list'])) + + @patch('examples.eab_handler.kid_profile_handler.EABhandler._wllist_check') + @patch('examples.eab_handler.kid_profile_handler.EABhandler._cn_add') + @patch('examples.eab_handler.kid_profile_handler.EABhandler._chk_san_lists_get') + def test_039_allowed_domains_check(self, mock_san, mock_cn, mock_wlc): + """ test EABhanlder._allowed_domains_check() """ + mock_san.return_value = (['foo'], []) + mock_cn.return_value = ['foo', 'bar'] + mock_wlc.side_effect = [False, True] + self.assertEqual('allowed_domainlist checking failed', self.eabhandler.allowed_domains_check('csr', ['domain', 'list'])) + + @patch('examples.eab_handler.kid_profile_handler.EABhandler._profiles_load') + def test_040_eab_profile_get(self, mock_prof): + """ test EABhandler._eab_profile_get() """ + mock_prof.return_value = {'eab_kid': {'cahandler': {'foo_parameter': 'bar_parameter'}}} + models_mock = MagicMock() + models_mock.DBstore().certificate_lookup.return_value = {'foo': 'bar', 'order__account__eab_kid': 'eab_kid'} + modules = {'acme_srv.db_handler': models_mock} + patch.dict('sys.modules', modules).start() + self.assertEqual({'foo_parameter': 'bar_parameter'}, self.eabhandler.eab_profile_get('csr')) + + + @patch('examples.eab_handler.kid_profile_handler.EABhandler._profiles_load') + def test_041_eab_profile_get(self, mock_prof): + """ test EABhandler._eab_profile_get() """ + mock_prof.return_value = {'eab_kid': {'cahandler1': {'foo_parameter': 'bar_parameter'}}} + models_mock = MagicMock() + models_mock.DBstore().certificate_lookup.return_value = {'foo': 'bar', 'order__account__eab_kid': 'eab_kid'} + modules = {'acme_srv.db_handler': models_mock} + patch.dict('sys.modules', modules).start() + self.assertFalse(self.eabhandler.eab_profile_get('csr')) + + @patch('examples.eab_handler.kid_profile_handler.EABhandler._profiles_load') + def test_042_eab_profile_get(self, mock_prof): + """ test EABhandler._eab_profile_get() """ + mock_prof.return_value = {'eab_kid': {'cahandler': {'foo_parameter': 'bar_parameter'}}} + models_mock = MagicMock() + models_mock.DBstore().certificate_lookup.return_value = {'foo': 'bar', '1order__account__eab_kid': 'eab_kid'} + modules = {'acme_srv.db_handler': models_mock} + patch.dict('sys.modules', modules).start() + self.assertFalse(self.eabhandler.eab_profile_get('csr')) + + @patch('examples.eab_handler.kid_profile_handler.EABhandler._profiles_load') + def test_043_eab_profile_get(self, mock_prof): + """ test EABhandler._eab_profile_get() """ + mock_prof.return_value = {'eab_kid': {'cahandler': {'foo_parameter': 'bar_parameter'}}} + models_mock = MagicMock() + models_mock.DBstore().certificate_lookup.return_value = {'foo': 'bar', 'order__account__eab_kid': 'eab_kid1'} + modules = {'acme_srv.db_handler': models_mock} + patch.dict('sys.modules', modules).start() + self.assertFalse(self.eabhandler.eab_profile_get('csr')) + + @patch('examples.eab_handler.kid_profile_handler.EABhandler._profiles_load') + def test_044_eab_profile_get(self, mock_prof): + """ test EABhandler._eab_profile_get() """ + mock_prof.return_value = {'eab_kid': {'cahandler': {'foo_parameter': 'bar_parameter'}}} + models_mock = MagicMock() + models_mock.DBstore().certificate_lookup.side_effect = Exception('ex_db_lookup') + modules = {'acme_srv.db_handler': models_mock} + patch.dict('sys.modules', modules).start() + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.eabhandler.eab_profile_get('csr')) + self.assertIn('ERROR:test_a2c:EABhandler._eab_profile_get() database error: ex_db_lookup', lcm.output) + + if __name__ == '__main__': unittest.main() diff --git a/test/test_helper.py b/test/test_helper.py index 85adb9a1..1e2f2f16 100644 --- a/test/test_helper.py +++ b/test/test_helper.py @@ -26,7 +26,7 @@ def setUp(self): """ setup unittest """ import logging logging.basicConfig(level=logging.CRITICAL) - from acme_srv.helper import b64decode_pad, b64_decode, b64_encode, b64_url_encode, b64_url_recode, convert_string_to_byte, convert_byte_to_string, decode_message, decode_deserialize, get_url, generate_random_string, signature_check, validate_email, uts_to_date_utc, date_to_uts_utc, load_config, cert_serial_get, cert_san_get, cert_san_pyopenssl_get, cert_dates_get, build_pem_file, date_to_datestr, datestr_to_date, dkeys_lower, csr_cn_get, cert_pubkey_get, csr_pubkey_get, url_get, url_get_with_own_dns, dns_server_list_load, csr_san_get, csr_san_byte_get, csr_extensions_get, fqdn_resolve, fqdn_in_san_check, sha256_hash, sha256_hash_hex, cert_der2pem, cert_pem2der, cert_extensions_get, csr_dn_get, logger_setup, logger_info, print_debug, jwk_thumbprint_get, allowed_gai_family, patched_create_connection, validate_csr, servercert_get, txt_get, proxystring_convert, proxy_check, handle_exception, ca_handler_load, eab_handler_load, hooks_load, error_dic_get, _logger_nonce_modify, _logger_certificate_modify, _logger_token_modify, _logger_challenges_modify, config_check, cert_issuer_get, cert_cn_get, string_sanitize, pembundle_to_list, certid_asn1_get, certid_check, certid_hex_get, v6_adjust, ipv6_chk, ip_validate, header_info_get, encode_url, uts_now, cert_ski_get, cert_ski_pyopenssl_get, cert_aki_get, cert_aki_pyopenssl_get, validate_fqdn, validate_ip, validate_identifier + from acme_srv.helper import b64decode_pad, b64_decode, b64_encode, b64_url_encode, b64_url_recode, convert_string_to_byte, convert_byte_to_string, decode_message, decode_deserialize, get_url, generate_random_string, signature_check, validate_email, uts_to_date_utc, date_to_uts_utc, load_config, cert_serial_get, cert_san_get, cert_san_pyopenssl_get, cert_dates_get, build_pem_file, date_to_datestr, datestr_to_date, dkeys_lower, csr_cn_get, cert_pubkey_get, csr_pubkey_get, url_get, url_get_with_own_dns, dns_server_list_load, csr_san_get, csr_san_byte_get, csr_extensions_get, fqdn_resolve, fqdn_in_san_check, sha256_hash, sha256_hash_hex, cert_der2pem, cert_pem2der, cert_extensions_get, csr_dn_get, logger_setup, logger_info, print_debug, jwk_thumbprint_get, allowed_gai_family, patched_create_connection, validate_csr, servercert_get, txt_get, proxystring_convert, proxy_check, handle_exception, ca_handler_load, eab_handler_load, hooks_load, error_dic_get, _logger_nonce_modify, _logger_certificate_modify, _logger_token_modify, _logger_challenges_modify, config_check, cert_issuer_get, cert_cn_get, string_sanitize, pembundle_to_list, certid_asn1_get, certid_check, certid_hex_get, v6_adjust, ipv6_chk, ip_validate, header_info_get, encode_url, uts_now, cert_ski_get, cert_ski_pyopenssl_get, cert_aki_get, cert_aki_pyopenssl_get, validate_fqdn, validate_ip, validate_identifier, header_info_field_validate, header_info_lookup self.logger = logging.getLogger('test_a2c') self.allowed_gai_family = allowed_gai_family self.b64_decode = b64_decode @@ -74,6 +74,8 @@ def setUp(self): self.fqdn_in_san_check = fqdn_in_san_check self.generate_random_string = generate_random_string self.get_url = get_url + self.header_info_field_validate = header_info_field_validate + self.header_info_lookup = header_info_lookup self.hooks_load = hooks_load self.ipv6_chk = ipv6_chk self.jwk_thumbprint_get = jwk_thumbprint_get @@ -2230,29 +2232,29 @@ def test_294_validate_fqdn(self): """ test validate_fqdn() """ self.assertTrue(self.validate_fqdn(self.logger, '*.bar.local')) - def test_294_validate_ip(self): + def test_295_validate_ip(self): """ test validate_ip() """ self.assertTrue(self.validate_ip(self.logger, '10.0.0.1')) - def test_295_validate_ip(self): + def test_296_validate_ip(self): """ test validate_ip() """ self.assertTrue(self.validate_ip(self.logger, '2a01:c22:b0cf:600:74be:80a7:4feb:bfe8')) - def test_296_validate_ip(self): + def test_297_validate_ip(self): """ test validate_ip() """ self.assertFalse(self.validate_ip(self.logger, 'foo.bar.local')) - def test_297_validate_ip(self): + def test_298_validate_ip(self): """ test validate_ip() """ self.assertFalse(self.validate_ip(self.logger, 'foo@bar.local')) - def test_298_validate_ip(self): + def test_299_validate_ip(self): """ test validate_ip() """ self.assertFalse(self.validate_ip(self.logger, '301.0.0.1')) @patch('acme_srv.helper.validate_fqdn') @patch('acme_srv.helper.validate_ip') - def test_299_validate_identifier(self, mock_ip, mock_fqdn): + def test_300_validate_identifier(self, mock_ip, mock_fqdn): """ test validate_identifier """ mock_fqdn.return_value = 'dns' mock_ip.return_value = 'ip' @@ -2262,7 +2264,7 @@ def test_299_validate_identifier(self, mock_ip, mock_fqdn): @patch('acme_srv.helper.validate_fqdn') @patch('acme_srv.helper.validate_ip') - def test_300_validate_identifier(self, mock_ip, mock_fqdn): + def test_301_validate_identifier(self, mock_ip, mock_fqdn): """ test validate_identifier """ mock_fqdn.return_value = 'dns' mock_ip.return_value = 'ip' @@ -2272,7 +2274,7 @@ def test_300_validate_identifier(self, mock_ip, mock_fqdn): @patch('acme_srv.helper.validate_fqdn') @patch('acme_srv.helper.validate_ip') - def test_301_validate_identifier(self, mock_ip, mock_fqdn): + def test_302_validate_identifier(self, mock_ip, mock_fqdn): """ test validate_identifier """ mock_fqdn.return_value = 'dns' mock_ip.return_value = 'ip' @@ -2282,7 +2284,7 @@ def test_301_validate_identifier(self, mock_ip, mock_fqdn): @patch('acme_srv.helper.validate_fqdn') @patch('acme_srv.helper.validate_ip') - def test_302_validate_identifier(self, mock_ip, mock_fqdn): + def test_303_validate_identifier(self, mock_ip, mock_fqdn): """ test validate_identifier """ mock_fqdn.return_value = 'dns' mock_ip.return_value = 'ip' @@ -2292,7 +2294,7 @@ def test_302_validate_identifier(self, mock_ip, mock_fqdn): @patch('acme_srv.helper.validate_fqdn') @patch('acme_srv.helper.validate_ip') - def test_303_validate_identifier(self, mock_ip, mock_fqdn): + def test_304_validate_identifier(self, mock_ip, mock_fqdn): """ test validate_identifier """ mock_fqdn.return_value = 'dns' mock_ip.return_value = 'ip' @@ -2300,5 +2302,66 @@ def test_303_validate_identifier(self, mock_ip, mock_fqdn): self.assertFalse(mock_fqdn.called) self.assertFalse(mock_ip.called) + @patch('acme_srv.helper.header_info_lookup') + def test_305_header_info_field_validate(self, mock_lookup): + """ test header_info_field_validate """ + mock_lookup.return_value = 'value2' + self.assertEqual(('value2', None), self.header_info_field_validate(self.logger, 'csr', 'header_info_field', 'key', ['value0', 'value2'])) + + @patch('acme_srv.helper.header_info_lookup') + def test_306_header_info_field_validate(self, mock_lookup): + """ test header_info_field_validate """ + mock_lookup.return_value = 'unk_value' + self.assertEqual((None, 'parameter "unk_value" is not allowed'), self.header_info_field_validate(self.logger, 'csr', 'header_info_field', 'parameter', ['value0', 'value2'])) + + @patch('acme_srv.helper.header_info_lookup') + def test_307_header_info_field_validate(self, mock_lookup): + """ test header_info_field_validate """ + mock_lookup.return_value = None + self.assertEqual(('value0', None), self.header_info_field_validate(self.logger, 'csr', 'header_info_field', 'parameter', ['value0', 'value2'])) + + @patch('acme_srv.helper.header_info_get') + def test_308_header_info_lookup(self, mock_info): + """ test header_info_lookup """ + mock_info.return_value = [{'header_info': '{"header_info_field": "foo1=value1 foo2=value2"}'}] + self.assertEqual('value1', self.header_info_lookup(self.logger, 'csr', 'header_info_field', 'foo1')) + + @patch('acme_srv.helper.header_info_get') + def test_309_header_info_lookup(self, mock_info): + """ test header_info_lookup """ + mock_info.return_value = [{'header_info': '{"header_info_field": "foo1=value1=foo foo2=value2=foo"}'}] + self.assertEqual('value1=foo', self.header_info_lookup(self.logger, 'csr', 'header_info_field', 'foo1')) + + @patch('acme_srv.helper.header_info_get') + def test_310_header_info_lookup(self, mock_info): + """ test header_info_lookup """ + mock_info.return_value = None + self.assertFalse(self.header_info_lookup(self.logger, 'csr', 'header_info_field', 'foo1')) + + @patch('acme_srv.helper.header_info_get') + def test_311_header_info_lookup(self, mock_info): + """ test header_info_lookup """ + mock_info.return_value = [{'foo': '{"header_info_field": "foo1=value1 foo2=value2"}'}] + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.header_info_lookup(self.logger, 'csr', 'header_info_field', 'foo1')) + self.assertIn("ERROR:test_a2c:header_info_lookup() could not parse header_info_field: 'header_info'", lcm.output) + + @patch('acme_srv.helper.header_info_get') + def test_312_header_info_lookup(self, mock_info): + """ test header_info_lookup """ + mock_info.return_value = [{'header_info': '{"foo": "foo1=value1 foo2=value2"}'}] + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.header_info_lookup(self.logger, 'csr', 'header_info_field', 'foo1')) + self.assertIn('ERROR:test_a2c:header_info_lookup() header_info_field not found: header_info_field', lcm.output) + + @patch('acme_srv.helper.header_info_get') + def test_313_header_info_lookup(self, mock_info): + """ test header_info_lookup """ + mock_info.return_value = 'bump' + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.header_info_lookup(self.logger, 'csr', 'header_info_field', 'foo1')) + self.assertIn("ERROR:test_a2c:header_info_lookup() could not parse header_info_field: string indices must be integers, not 'str'", lcm.output) + + if __name__ == '__main__': unittest.main() From 67cf26192ee53b7c65e03a8dbef78ab1ac7dadb7 Mon Sep 17 00:00:00 2001 From: grindsa Date: Mon, 1 Apr 2024 15:33:19 +0200 Subject: [PATCH 154/460] [doc] basic documentation of accont profiling feature --- CHANGES.md | 3 ++- docs/account-profiling.md | 55 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 docs/account-profiling.md diff --git a/CHANGES.md b/CHANGES.md index a339f2bc..48ead986 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -9,6 +9,7 @@ and pick the appropriate release branch. **Features and Improvements**: +- [Account profiling](docs/account-profiling.md) - [#144](https://github.com/grindsa/acme2certifier/issues/144) configuration option to supress product name - [#143](https://github.com/grindsa/acme2certifier/issues/143) template name as part of the user-agent field in wcce/wes handler - configuration option to limit the number of identifiers in a single order request @@ -18,7 +19,7 @@ and pick the appropriate release branch. **Bugfixes**: -- #147(https://github.com/grindsa/acme2certifier/pull/147) correct content-type for problem+json message +- [#147](https://github.com/grindsa/acme2certifier/pull/147) correct content-type for problem+json message - updated [eab-example files](https://github.com/grindsa/acme2certifier/tree/master/examples/eab_handler) as hmac must be longer than 256bits - identifier sanitizing diff --git a/docs/account-profiling.md b/docs/account-profiling.md new file mode 100644 index 00000000..95627943 --- /dev/null +++ b/docs/account-profiling.md @@ -0,0 +1,55 @@ + + +# Pass information from acme client to CA-handler + +Starting with version 0.34 acme2certifier supports the configuration of account specific enrollment configuration. Depending on the handler to be used the feature allows the definition of individual authentication credentials, enrollment profiles or certificate authoritzies. + +Currently the following ca-handlers had been modified and do support this feature: + +- [Insta certifier/NetGuard Certificate manager](certifier.md) +- [Insta ActiveCMS](asa.md) +- [XCA](xca.md) + +In case you need support for a different ca-handler feel free to raise an [issue](https://github.com/grindsa/acme2certifier/issues/new). + +## Configuration + +This feature requires [external account binding](eab.md) to be enabled and a specific EAB-handler to be configured. + +```cfg +[EABhandler] +eab_handler_file: examples/eab_handler/kid_profile_handler.py +key_file: volume/kid_profiles.json +``` + +The `key_file` allows the specification enrollmenmt parameters per (extenral) acme count. Main identifier is the key_id to be used during account registration. Any parameter used in the [CAhandler] configuration section of a handler can be customized. Below an example configuration to be used for [Insta Certifier](certifier.md) with some explaination: + +```json +{ + "keyid_00": { + "hmac": "V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw", + "cahandler": { + "profile_id": "profile_1", + "allowed_domainlist": ["*.example.com", "*.example.org", "*.example.fi"], + "ca_name": "non_default_ca", + "api_user": "non_default_api_user", + "api_password": "api_password" + } + }, + "keyid_01": { + "hmac": "YW5vdXRoZXJfdmVyeV9sb25nX2htYWNfZm9yX2tleWlkXzAxX3doaWNoIHdpbGxfYmUgdXNlZF9kdXJpbmcgcmVncmVzc2lvbg", + "cahandler": { + "profile_id": ["profile_1", "profile_2", "profile_3"], + "allowed_domainlist": ["*.example.fi", "*.acme"], + } + }, + }, + "keyid_02": { + "hmac": "YW5kX2ZpbmFsbHlfdGhlX2xhc3RfaG1hY19rZXlfd2hpY2hfaXNfbG9uZ2VyX3RoYW5fMjU2X2JpdHNfYW5kX3Nob3VsZF93b3Jr" + } +} +``` + +- Acme-accounts created with keyid "keyid_00" will always use profile-id "profile_1" and specific api-user credentials for enrollment from certificate authority "non_default_ca". Further, the SAN/Common names to be used in enrollment requests are restricted to the domains "example.com", "example.org" and "example.fi". +- Acme-accounts created with keyid "keyid_01" and can specify 3 different profile_ids by using the [header_info feature](header_info.md). Enrollment requests having other profile_ids will be rejected. In case no profile_id get specified the first profile_id in the list ("profile_1") will be used. SAN/CNs to be used are restricted to "example.fi" and ".local" All other enrollment paramters will be taken from acme_srv.cfg +- Acme-accounts created with keyid "keyid_02" do not have any restriction. Enrolment parameters will be taken from the [CAhandler] section in ´acme_srv.cfg` From 30e5deea620c2e6f34131ab5f042f6d74fb93b7c Mon Sep 17 00:00:00 2001 From: grindsa Date: Mon, 1 Apr 2024 16:37:39 +0200 Subject: [PATCH 155/460] [fix] header_info without account profiling --- examples/ca_handler/certifier_ca_handler.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/ca_handler/certifier_ca_handler.py b/examples/ca_handler/certifier_ca_handler.py index da7ccf10..d8ed5271 100644 --- a/examples/ca_handler/certifier_ca_handler.py +++ b/examples/ca_handler/certifier_ca_handler.py @@ -590,7 +590,9 @@ def _profile_check(self, csr: str) -> str: # we need to cover cases where profiling is enabled but no profile_id is defined in json elif self.header_info_field: # no profiling - parse profileid from http_header - self.profile_id = header_info_lookup(self.logger, csr, self.header_info_field, 'profile_id') + hil_profile_id = header_info_lookup(self.logger, csr, self.header_info_field, 'profile_id') + if hil_profile_id: + self.profile_id = hil_profile_id self.logger.debug('CAhandler._profile_check() ended with %s', error) return error From b72b63bcd2d3b92ad17f74dbd571d6b78cfbe61c Mon Sep 17 00:00:00 2001 From: grindsa Date: Mon, 1 Apr 2024 16:55:50 +0200 Subject: [PATCH 156/460] [fix] header_info_feature for certifier --- .github/workflows/ca_handler_tests_certifier.yml | 16 ++++++++-------- docs/certifier.md | 4 ++-- examples/ca_handler/certifier_ca_handler.py | 1 + 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ca_handler_tests_certifier.yml b/.github/workflows/ca_handler_tests_certifier.yml index f5e47000..c1077a13 100644 --- a/.github/workflows/ca_handler_tests_certifier.yml +++ b/.github/workflows/ca_handler_tests_certifier.yml @@ -495,28 +495,28 @@ jobs: run: | docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 - - name: "Enroll acme.sh with profileID 101" + - name: "Enroll acme.sh with profile_id 101" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --useragent profileID=101 --debug 3 --output-insecure + docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --useragent profile_id=101 --debug 3 --output-insecure awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Client" - - name: "Enroll lego with profileID 101" + - name: "Enroll lego with profile_id 101" run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent profileID=101 -d lego.acme --http run + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent profile_id=101 -d lego.acme --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Client" - - name: "Enroll acme.sh with profileID 102" + - name: "Enroll acme.sh with profile_id 102" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --renew --force -d acme-sh.acme --standalone --useragent profileID=102 --debug 3 --output-insecure + docker exec -i acme-sh acme.sh --server http://acme-srv --renew --force -d acme-sh.acme --standalone --useragent profile_id=102 --debug 3 --output-insecure openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Server" - - name: "Enroll lego with profileID 102" + - name: "Enroll lego with profile_id 102" run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent profileID=102 -d lego.acme --http run + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent profile_id=102 -d lego.acme --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Server" diff --git a/docs/certifier.md b/docs/certifier.md index fab9d67a..e30a5ac8 100644 --- a/docs/certifier.md +++ b/docs/certifier.md @@ -87,13 +87,13 @@ The acme-client can then specify the profileID as part of its user-agent string. Example for acme.sh: ```bash -docker exec -i acme-sh acme.sh --server http:// --issue -d --standalone --useragent profileID=101 --debug 3 --output-insecure +docker exec -i acme-sh acme.sh --server http:// --issue -d --standalone --useragent profile_id=101 --debug 3 --output-insecure ``` Example for lego: ```bash -docker run -i -v $PWD/lego:/.lego/ --rm --name lego goacme/lego -s http:// -a --email "lego@example.com" --user-agent profileID=101 -d --http run +docker run -i -v $PWD/lego:/.lego/ --rm --name lego goacme/lego -s http:// -a --email "lego@example.com" --user-agent profile_id=101 -d --http run ``` ## CA policy configuration diff --git a/examples/ca_handler/certifier_ca_handler.py b/examples/ca_handler/certifier_ca_handler.py index d8ed5271..57ac5a75 100644 --- a/examples/ca_handler/certifier_ca_handler.py +++ b/examples/ca_handler/certifier_ca_handler.py @@ -592,6 +592,7 @@ def _profile_check(self, csr: str) -> str: # no profiling - parse profileid from http_header hil_profile_id = header_info_lookup(self.logger, csr, self.header_info_field, 'profile_id') if hil_profile_id: + self.logger.debug('CAhandler._profile_check(): setting profile_id to %s', hil_profile_id) self.profile_id = hil_profile_id self.logger.debug('CAhandler._profile_check() ended with %s', error) From c8832b8e54797e08444faa76fd6d8a851a8d495b Mon Sep 17 00:00:00 2001 From: grindsa Date: Mon, 1 Apr 2024 18:02:01 +0200 Subject: [PATCH 157/460] [fix] backwards compatiblility with older header_info_feature --- .github/workflows/ca_handler_tests_certifier.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ca_handler_tests_certifier.yml b/.github/workflows/ca_handler_tests_certifier.yml index c1077a13..94b5bb2c 100644 --- a/.github/workflows/ca_handler_tests_certifier.yml +++ b/.github/workflows/ca_handler_tests_certifier.yml @@ -504,6 +504,7 @@ jobs: - name: "Enroll lego with profile_id 101" run: | + sudo rm -rf lego/* docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent profile_id=101 -d lego.acme --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Client" @@ -516,6 +517,7 @@ jobs: - name: "Enroll lego with profile_id 102" run: | + sudo rm -rf lego/* docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent profile_id=102 -d lego.acme --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Server" From 84e9f9ce31ae5dc767866add101e6f998de83487 Mon Sep 17 00:00:00 2001 From: grindsa Date: Mon, 1 Apr 2024 18:13:08 +0200 Subject: [PATCH 158/460] [wf] limit parallel jobs in certifier_ca_handler.py to 2 --- .github/workflows/ca_handler_tests_certifier.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ca_handler_tests_certifier.yml b/.github/workflows/ca_handler_tests_certifier.yml index 94b5bb2c..1772072f 100644 --- a/.github/workflows/ca_handler_tests_certifier.yml +++ b/.github/workflows/ca_handler_tests_certifier.yml @@ -13,6 +13,7 @@ jobs: name: "certifier_handler_tests" runs-on: ubuntu-latest strategy: + max-parallel: 2 fail-fast: false matrix: websrv: ['apache2', 'nginx'] @@ -423,6 +424,7 @@ jobs: runs-on: ubuntu-latest strategy: fail-fast: false + max-parallel: 2 matrix: websrv: ['apache2', 'nginx'] dbhandler: ['wsgi', 'django'] From e5b4d8642ff1106cac022bb5def79e2151bbec66 Mon Sep 17 00:00:00 2001 From: grindsa Date: Mon, 1 Apr 2024 18:53:47 +0200 Subject: [PATCH 159/460] [fix] linting and better error handling in header_info_lookup() --- acme_srv/helper.py | 43 ++++++++++++++------- examples/eab_handler/kid_profile_handler.py | 1 + test/test_helper.py | 13 ++++++- 3 files changed, 40 insertions(+), 17 deletions(-) diff --git a/acme_srv/helper.py b/acme_srv/helper.py index 6bac64c7..b9587e60 100644 --- a/acme_srv/helper.py +++ b/acme_srv/helper.py @@ -695,24 +695,37 @@ def header_info_field_validate(logger, csr: str, header_info_field: str, value: return value_to_set, error +def header_info_jsonify(logger: logging.Logger, header_info: str) -> Dict[str, str]: + """ jsonify header info""" + logger.debug('header_info_json_parse()') + + header_info_dic = {} + try: + if isinstance(header_info, list) and 'header_info' in header_info[-1]: + header_info_dic = json.loads(header_info[-1]['header_info']) + except Exception as err: + logger.error('header_info_lookup() could not parse header_info_field: %s', err) + + logger.debug('header_info_json_parse() ended with: %s', bool(header_info_dic)) + return header_info_dic + + def header_info_lookup(logger, csr: str, header_info_field, key: str) -> str: """ lookup header info """ logger.debug('header_info_lookup(%s)', key) result = None header_info = header_info_get(logger, csr=csr) + if header_info: - try: - header_info_dic = json.loads(header_info[-1]['header_info']) - if header_info_field in header_info_dic: - for ele in header_info_dic[header_info_field].split(' '): - if key in ele.lower(): - result = ele.split('=', 1)[1] - break - else: - logger.error('header_info_lookup() header_info_field not found: %s', header_info_field) - except Exception as err: - logger.error('header_info_lookup() could not parse header_info_field: %s', err) + header_info_dic = header_info_jsonify(logger, header_info) + if header_info_field in header_info_dic: + for ele in header_info_dic[header_info_field].split(' '): + if key in ele.lower(): + result = ele.split('=', 1)[1] + break + else: + logger.error('header_info_lookup() header_info_field not found: %s', header_info_field) logger.debug('header_info_lookup(%s) ended with: %s', key, result) return result @@ -1306,17 +1319,17 @@ def validate_email(logger: logging.Logger, contact_list: List[str]) -> bool: return result -def validate_identifier(logger: logging.Logger, type: str, identifier: str, tnauthlist_support: bool = False) -> bool: +def validate_identifier(logger: logging.Logger, id_type: str, identifier: str, tnauthlist_support: bool = False) -> bool: """ validate identifier """ logger.debug('validate_identifier()') result = False if identifier: - if type == 'dns': + if id_type == 'dns': result = validate_fqdn(logger, identifier) - elif type == 'ip': + elif id_type == 'ip': result = validate_ip(logger, identifier) - elif type == 'tnauthlist' and tnauthlist_support: + elif id_type == 'tnauthlist' and tnauthlist_support: result = True logger.debug('validate_identifier() ended with: %s', result) diff --git a/examples/eab_handler/kid_profile_handler.py b/examples/eab_handler/kid_profile_handler.py index c5f84f9a..de19791b 100644 --- a/examples/eab_handler/kid_profile_handler.py +++ b/examples/eab_handler/kid_profile_handler.py @@ -8,6 +8,7 @@ from acme_srv.helper import load_config, csr_cn_get, csr_san_get from typing import List, Tuple, Dict + class EABhandler(object): """ EAB file handler """ diff --git a/test/test_helper.py b/test/test_helper.py index 1e2f2f16..1ee9d775 100644 --- a/test/test_helper.py +++ b/test/test_helper.py @@ -2344,7 +2344,7 @@ def test_311_header_info_lookup(self, mock_info): mock_info.return_value = [{'foo': '{"header_info_field": "foo1=value1 foo2=value2"}'}] with self.assertLogs('test_a2c', level='INFO') as lcm: self.assertFalse(self.header_info_lookup(self.logger, 'csr', 'header_info_field', 'foo1')) - self.assertIn("ERROR:test_a2c:header_info_lookup() could not parse header_info_field: 'header_info'", lcm.output) + self.assertIn('ERROR:test_a2c:header_info_lookup() header_info_field not found: header_info_field', lcm.output) @patch('acme_srv.helper.header_info_get') def test_312_header_info_lookup(self, mock_info): @@ -2360,8 +2360,17 @@ def test_313_header_info_lookup(self, mock_info): mock_info.return_value = 'bump' with self.assertLogs('test_a2c', level='INFO') as lcm: self.assertFalse(self.header_info_lookup(self.logger, 'csr', 'header_info_field', 'foo1')) - self.assertIn("ERROR:test_a2c:header_info_lookup() could not parse header_info_field: string indices must be integers, not 'str'", lcm.output) + self.assertIn('ERROR:test_a2c:header_info_lookup() header_info_field not found: header_info_field', lcm.output) + @patch('acme_srv.helper.json.loads') + @patch('acme_srv.helper.header_info_get') + def test_314_header_info_lookup(self, mock_info, mock_json): + """ test header_info_lookup """ + mock_info.return_value = [{'header_info': 'foo1=value1 foo2=value2'}] + mock_json.side_effect = Exception('mock_json') + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.header_info_lookup(self.logger, 'csr', 'header_info_field', 'foo1')) + self.assertIn('ERROR:test_a2c:header_info_lookup() could not parse header_info_field: mock_json', lcm.output) if __name__ == '__main__': unittest.main() From f28259c64ce2f91f53048468357465c20eabcb7b Mon Sep 17 00:00:00 2001 From: grindsa Date: Sun, 7 Apr 2024 07:19:04 +0200 Subject: [PATCH 160/460] [feat] eab profiling in xca_handler --- acme_srv/helper.py | 43 +++ examples/ca_handler/certifier_ca_handler.py | 181 +++++------ examples/ca_handler/xca_ca_handler.py | 98 +++++- test/test_certifier_handler.py | 299 +++++++++--------- test/test_helper.py | 77 ++++- test/test_xca_ca_handler.py | 333 +++++++++++++++++--- 6 files changed, 721 insertions(+), 310 deletions(-) diff --git a/acme_srv/helper.py b/acme_srv/helper.py index b9587e60..5ca8fc38 100644 --- a/acme_srv/helper.py +++ b/acme_srv/helper.py @@ -139,6 +139,49 @@ def config_check(logger: logging.Logger, config_dic: Dict): logger.warning('config_check(): section %s option: %s contains " characters. Check if this is really needed!', section, key) +def config_eab_profile_load(logger: logging.Logger, config_dic: Dict[str, str]): + """ load parameters """ + logger.debug('_config_eab_profile_load()') + + eab_profiling = False + eab_handler = None + + try: + eab_profiling = config_dic.getboolean('CAhandler', 'eab_profiling', fallback=False) + except Exception as err: + logger.warning('CAhandler._config_eab_profile_load() failed with error: %s', err) + eab_profiling = False + + if eab_profiling: + if 'EABhandler' in config_dic and 'eab_handler_file' in config_dic['EABhandler']: + # load eab_handler according to configuration + eab_handler_module = eab_handler_load(logger, config_dic) + if not eab_handler_module: + logger.critical('CAhandler._config_load(): EABHandler could not get loaded') + else: + eab_handler = eab_handler_module.EABhandler + else: + logger.critical('CAhandler._config_load(): EABHandler configuration incomplete') + + logger.debug('_config_profile_load() ended') + return eab_profiling, eab_handler + + +def config_headerinfo_get(logger: logging.Logger, config_dic: Dict[str, str]): + """ load parameters """ + logger.debug('config_headerinfo_get()') + + header_info_field = None + if 'Order' in config_dic and 'header_info_list' in config_dic['Order'] and config_dic['Order']['header_info_list']: + try: + header_info_field = json.loads(config_dic['Order']['header_info_list'])[0] + except Exception as err_: + logger.warning('Helper.config_headerinfo_get() header_info_list failed with error: %s', err_) + + logger.debug('config_headerinfo_get() ended') + return header_info_field + + def eab_handler_load(logger: logging.Logger, config_dic: Dict) -> importlib.import_module: """ load and return eab_handler """ logger.debug('Helper.eab_handler_load()') diff --git a/examples/ca_handler/certifier_ca_handler.py b/examples/ca_handler/certifier_ca_handler.py index 57ac5a75..2f955447 100644 --- a/examples/ca_handler/certifier_ca_handler.py +++ b/examples/ca_handler/certifier_ca_handler.py @@ -10,7 +10,7 @@ import requests from requests.auth import HTTPBasicAuth # pylint: disable=e0401 -from acme_srv.helper import load_config, cert_serial_get, uts_now, uts_to_date_utc, b64_decode, b64_encode, cert_pem2der, parse_url, proxy_check, error_dic_get, header_info_field_validate, eab_handler_load, header_info_lookup +from acme_srv.helper import load_config, cert_serial_get, uts_now, uts_to_date_utc, b64_decode, b64_encode, cert_pem2der, parse_url, proxy_check, error_dic_get, header_info_field_validate, header_info_lookup, config_eab_profile_load, config_headerinfo_get class CAhandler(object): @@ -287,42 +287,6 @@ def _config_proxy_load(self, config_dic: Dict[str, str]): self.logger.debug('_config_proxy_load() ended') - def _config_headerinfo_get(self, config_dic: Dict[str, str]): - """ load parameters """ - self.logger.debug('_config_header_info()') - - if 'Order' in config_dic and 'header_info_list' in config_dic['Order'] and config_dic['Order']['header_info_list']: - try: - self.header_info_field = json.loads(config_dic['Order']['header_info_list'])[0] - except Exception as err_: - self.logger.warning('Order._config_orderconfig_load() header_info_list failed with error: %s', err_) - - self.logger.debug('_config_header_info() ended') - - def _config_eab_profile_load(self, config_dic: Dict[str, str]): - """ load parameters """ - self.logger.debug('_config_eab_profile_load()') - - try: - self.eab_profiling = config_dic.getboolean('CAhandler', 'eab_profiling', fallback=False) - except Exception as err: - self.logger.warning('CAhandler._config_eab_profile_load() failed with error: %s', err) - self.eab_profiling = False - - if self.eab_profiling: - if 'EABhandler' in config_dic and 'eab_handler_file' in config_dic['EABhandler']: - # load eab_handler according to configuration - eab_handler_module = eab_handler_load(self.logger, config_dic) - if eab_handler_module: - # store handler in variable - self.eab_handler = eab_handler_module.EABhandler - else: - self.logger.critical('CAhandler._config_load(): EABHandler could not get loaded') - else: - self.logger.critical('CAhandler._config_load(): EABHandler configuration incomplete') - - self.logger.debug('_config_profile_load() ended') - def _config_load(self): """" load config from file """ # pylint: disable=R0912, R0915 @@ -340,72 +304,15 @@ def _config_load(self): self._config_password_load(config_dic) # load parameters from config self._config_parameter_load(config_dic) - # load headerinfo - self._config_headerinfo_get(config_dic) # load profiling - self._config_eab_profile_load(config_dic) + self.eab_profiling, self.eab_handler = config_eab_profile_load(self.logger, config_dic) + # load header info + self.header_info_field = config_headerinfo_get(self.logger, config_dic) # load proxy configuration self._config_proxy_load(config_dic) self.logger.debug('CAhandler._config_load() ended') - def _eab_profile_string_check(self, key, value): - self.logger.debug('CAhandler._eab_profile_string_check(): string: key: %s, value: %s', key, value) - - if hasattr(self, key): - self.logger.debug('CAhandler._eab_profile_string_check(): setting attribute: %s to %s', key, value) - setattr(self, key, value) - else: - self.logger.error('CAhandler._eab_profile_string_check(): ignore string attribute: key: %s value: %s', key, value) - - self.logger.debug('CAhandler._eab_profile_string_check() ended') - - def _eab_profile_list_check(self, eab_handler, csr, key, value): - self.logger.debug('CAhandler._eab_profile_list_check(): list: key: %s, value: %s', key, value) - - result = None - if hasattr(self, key): - new_value, error = header_info_field_validate(self.logger, csr, self.header_info_field, key, value) - if new_value: - self.logger.debug('CAhandler._eab_profile_list_check(): setting attribute: %s to %s', key, new_value) - setattr(self, key, new_value) - else: - result = error - elif key == 'allowed_domainlist': - # check if csr contains allowed domains - error = eab_handler.allowed_domains_check(csr, value) - if error: - result = error - else: - self.logger.error('CAhandler._eab_profile_list_check(): ignore list attribute: key: %s value: %s', key, value) - - self.logger.debug('CAhandler._eab_profile_list_check() ended with: %s', result) - return result - - def _eab_profile_check(self, csr: str) -> str: - """ check eab profile""" - self.logger.debug('CAhandler._eab_profile_check()') - - result = None - with self.eab_handler(self.logger) as eab_handler: - eab_profile_dic = eab_handler.eab_profile_get(csr) - for key, value in eab_profile_dic.items(): - if isinstance(value, str): - self._eab_profile_string_check(key, value) - elif isinstance(value, list): - result = self._eab_profile_list_check(eab_handler, csr, key, value) - if result: - break - - # we need to cover cases where profiling is enabled but no profile_id is defined in json - if self.header_info_field and "profile_id" not in eab_profile_dic: - hil_profile_id = header_info_lookup(self.logger, csr, self.header_info_field, 'profile_id') - if hil_profile_id: - self.profile_id = hil_profile_id - - self.logger.debug('CAhandler._eab_profile_check() ended with: %s', result) - return result - def _poll_cert_get(self, request_dic: Dict[str, str], poll_identifier: str, error: str) -> Tuple[str, str, str, str, bool]: """ get certificate via poll request """ self.logger.debug('CAhandler._poll_cert_get()') @@ -580,20 +487,84 @@ def _trigger_bundle_build(self, cert_raw: str, ca_dic: Dict[str, str]) -> Tuple[ self.logger.debug('CAhandler._trigger_bundle_build() ended with: %s', error) return (error, cert_bundle) + def _eab_profile_string_check(self, key, value): + self.logger.debug('CAhandler._eab_profile_string_check(): string: key: %s, value: %s', key, value) + + if hasattr(self, key): + self.logger.debug('CAhandler._eab_profile_string_check(): setting attribute: %s to %s', key, value) + setattr(self, key, value) + else: + self.logger.error('CAhandler._eab_profile_string_check(): ignore string attribute: key: %s value: %s', key, value) + + self.logger.debug('CAhandler._eab_profile_string_check() ended') + + def _eab_profile_list_check(self, eab_handler, csr, key, value): + self.logger.debug('CAhandler._eab_profile_list_check(): list: key: %s, value: %s', key, value) + + result = None + if hasattr(self, key): + new_value, error = header_info_field_validate(self.logger, csr, self.header_info_field, key, value) + if new_value: + self.logger.debug('CAhandler._eab_profile_list_check(): setting attribute: %s to %s', key, new_value) + setattr(self, key, new_value) + else: + result = error + elif key == 'allowed_domainlist': + # check if csr contains allowed domains + error = eab_handler.allowed_domains_check(csr, value) + if error: + result = error + else: + self.logger.error('CAhandler._eab_profile_list_check(): ignore list attribute: key: %s value: %s', key, value) + + self.logger.debug('CAhandler._eab_profile_list_check() ended with: %s', result) + return result + + def _eab_profile_check(self, csr: str, handler_hifield: str) -> str: + """ check eab profile""" + self.logger.debug('CAhandler._eab_profile_check()') + + result = None + with self.eab_handler(self.logger) as eab_handler: + eab_profile_dic = eab_handler.eab_profile_get(csr) + for key, value in eab_profile_dic.items(): + if isinstance(value, str): + self._eab_profile_string_check(key, value) + elif isinstance(value, list): + result = self._eab_profile_list_check(eab_handler, csr, key, value) + if result: + break + + # we need to cover cases where profiling is enabled but no profile_id is defined in json + if self.header_info_field and handler_hifield not in eab_profile_dic: + hil_value = header_info_lookup(self.logger, csr, self.header_info_field, handler_hifield) + if hil_value: + setattr(self, handler_hifield, hil_value) + + self.logger.debug('CAhandler._eab_profile_check() ended with: %s', result) + return result + def _profile_check(self, csr: str) -> str: """ check profile """ self.logger.debug('CAhandler._profile_check()') error = None + # handler specific header info field + handler_hifield = "profile_id" + if self.eab_profiling: - error = self._eab_profile_check(csr) - # we need to cover cases where profiling is enabled but no profile_id is defined in json - elif self.header_info_field: - # no profiling - parse profileid from http_header - hil_profile_id = header_info_lookup(self.logger, csr, self.header_info_field, 'profile_id') - if hil_profile_id: - self.logger.debug('CAhandler._profile_check(): setting profile_id to %s', hil_profile_id) - self.profile_id = hil_profile_id + if self.eab_handler: + error = self._eab_profile_check(csr, handler_hifield) + # we need to cover cases where handler_value is enabled but nothing is defined in json + elif self.header_info_field: + # no profiling - parse profileid from http_header + hil_value = header_info_lookup(self.logger, csr, self.header_info_field, handler_hifield) + if hil_value: + self.logger.debug('CAhandler._profile_check(): setting %s to %s', handler_hifield, hil_value) + self.profile_id = hil_value + setattr(self, handler_hifield, hil_value) + else: + self.logger.error('CAhandler._profile_check(): eab_profiling enabled but no handler defined') self.logger.debug('CAhandler._profile_check() ended with %s', error) return error diff --git a/examples/ca_handler/xca_ca_handler.py b/examples/ca_handler/xca_ca_handler.py index 1cea337a..84756083 100644 --- a/examples/ca_handler/xca_ca_handler.py +++ b/examples/ca_handler/xca_ca_handler.py @@ -14,7 +14,7 @@ from cryptography.x509.oid import ExtendedKeyUsageOID from OpenSSL import crypto as pyossslcrypto # pylint: disable=e0401 -from acme_srv.helper import load_config, build_pem_file, uts_now, uts_to_date_utc, b64_encode, b64_decode, b64_url_recode, cert_serial_get, convert_string_to_byte, convert_byte_to_string, csr_cn_get, csr_san_get, error_dic_get, header_info_get +from acme_srv.helper import load_config, build_pem_file, uts_now, uts_to_date_utc, b64_encode, b64_decode, b64_url_recode, cert_serial_get, convert_string_to_byte, convert_byte_to_string, csr_cn_get, csr_san_get, error_dic_get, header_info_lookup, header_info_field_validate, config_headerinfo_get, config_eab_profile_load DEFAULT_DATE_FORMAT = '%Y%m%d%H%M%SZ' @@ -38,6 +38,9 @@ def __init__(self, debug: bool = False, logger: object = None): self.cert_validity_days = 365 self.ca_cert_chain_list = [] self.template_name = None + self.header_info_field = None + self.eab_handler = None + self.eab_profiling = False def __enter__(self): """ Makes ACMEHandler a Context Manager """ @@ -352,6 +355,11 @@ def _config_load(self): if 'template_name' in config_dic['CAhandler']: self.template_name = config_dic['CAhandler']['template_name'] + # load profiling + self.eab_profiling, self.eab_handler = config_eab_profile_load(self.logger, config_dic) + # load header info + self.header_info_field = config_headerinfo_get(self.logger, config_dic) + def _csr_import(self, csr, request_name): """ check existance of csr and load into db """ self.logger.debug('CAhandler._csr_import()') @@ -903,6 +911,88 @@ def _xca_template_process(self, template_dic: Dict[str, str], csr_extensions_dic return extension_list + def _eab_profile_string_check(self, key, value): + self.logger.debug('CAhandler._eab_profile_string_check(): string: key: %s, value: %s', key, value) + + if hasattr(self, key): + self.logger.debug('CAhandler._eab_profile_string_check(): setting attribute: %s to %s', key, value) + setattr(self, key, value) + else: + self.logger.error('CAhandler._eab_profile_string_check(): ignore string attribute: key: %s value: %s', key, value) + + self.logger.debug('CAhandler._eab_profile_string_check() ended') + + def _eab_profile_list_check(self, eab_handler, csr, key, value): + self.logger.debug('CAhandler._eab_profile_list_check(): list: key: %s, value: %s', key, value) + + result = None + if hasattr(self, key): + new_value, error = header_info_field_validate(self.logger, csr, self.header_info_field, key, value) + if new_value: + self.logger.debug('CAhandler._eab_profile_list_check(): setting attribute: %s to %s', key, new_value) + setattr(self, key, new_value) + else: + result = error + elif key == 'allowed_domainlist': + # check if csr contains allowed domains + error = eab_handler.allowed_domains_check(csr, value) + if error: + result = error + else: + self.logger.error('CAhandler._eab_profile_list_check(): ignore list attribute: key: %s value: %s', key, value) + + self.logger.debug('CAhandler._eab_profile_list_check() ended with: %s', result) + return result + + def _eab_profile_check(self, csr: str, handler_hifield: str) -> str: + """ check eab profile""" + self.logger.debug('CAhandler._eab_profile_check()') + + result = None + with self.eab_handler(self.logger) as eab_handler: + eab_profile_dic = eab_handler.eab_profile_get(csr) + for key, value in eab_profile_dic.items(): + if isinstance(value, str): + self._eab_profile_string_check(key, value) + elif isinstance(value, list): + result = self._eab_profile_list_check(eab_handler, csr, key, value) + if result: + break + + # we need to cover cases where profiling is enabled but no profile_id is defined in json + if self.header_info_field and handler_hifield not in eab_profile_dic: + hil_value = header_info_lookup(self.logger, csr, self.header_info_field, handler_hifield) + if hil_value: + setattr(self, handler_hifield, hil_value) + + self.logger.debug('CAhandler._eab_profile_check() ended with: %s', result) + return result + + def _profile_check(self, csr: str) -> str: + """ check profile """ + self.logger.debug('CAhandler._profile_check()') + error = None + + # handler specific header info field + handler_hifield = "template_name" + + if self.eab_profiling: + if self.eab_handler: + error = self._eab_profile_check(csr, handler_hifield) + # we need to cover cases where handler_value is enabled but nothing is defined in json + elif self.header_info_field: + # no profiling - parse profileid from http_header + hil_value = header_info_lookup(self.logger, csr, self.header_info_field, handler_hifield) + if hil_value: + self.logger.debug('CAhandler._profile_check(): setting %s to %s', handler_hifield, hil_value) + # self.template_name = hil_value + setattr(self, handler_hifield, hil_value) + else: + self.logger.error('CAhandler._profile_check(): eab_profiling enabled but no handler defined') + + self.logger.debug('CAhandler._profile_check() ended with %s', error) + return error + def enroll(self, csr: str = None) -> Tuple[str, str, str, str]: """ enroll certificate """ # pylint: disable=R0914, R0915 @@ -912,10 +1002,8 @@ def enroll(self, csr: str = None) -> Tuple[str, str, str, str]: cert_raw = None error = self._config_check() - # lookup http header information from request - qset = header_info_get(self.logger, csr=csr) - if qset: - self.logger.info('header_info: %s', qset[-1]['header_info']) + if not error: + error = self._profile_check(csr) if not error: request_name = self._requestname_get(csr) diff --git a/test/test_certifier_handler.py b/test/test_certifier_handler.py index 6ee68369..109afedb 100644 --- a/test/test_certifier_handler.py +++ b/test/test_certifier_handler.py @@ -678,40 +678,23 @@ def test_066_enroll(self, mock_certget, mock_loop, mock_prof, mock_lookup): self.assertFalse(mock_prof.called) self.assertFalse(mock_lookup.called) - @patch('examples.ca_handler.certifier_ca_handler.header_info_lookup') - @patch('examples.ca_handler.certifier_ca_handler.CAhandler._eab_profile_check') + @patch('examples.ca_handler.certifier_ca_handler.CAhandler._profile_check') @patch('examples.ca_handler.certifier_ca_handler.CAhandler._loop_poll') @patch('examples.ca_handler.certifier_ca_handler.CAhandler._cert_get') - def test_067_enroll(self, mock_certget, mock_loop, mock_prof, mock_lookup): + def test_067_enroll(self, mock_certget, mock_loop, mock_prof): """ CAhandler.enroll() _cert_get returns certb64 """ mock_certget.return_value = {'foo': 'bar', 'href': 'href'} mock_loop.return_value = ('error', 'cert_bundle', 'cert_raw', 'poll_identifier') - self.cahandler.eab_profiling = True mock_prof.return_value = None - self.assertEqual(('error', 'cert_bundle', 'cert_raw', 'poll_identifier'), self.cahandler.enroll('csr')) - self.assertTrue(mock_prof.called) - self.assertFalse(mock_lookup.called) - - @patch('examples.ca_handler.certifier_ca_handler.header_info_lookup') - @patch('examples.ca_handler.certifier_ca_handler.CAhandler._eab_profile_check') - @patch('examples.ca_handler.certifier_ca_handler.CAhandler._loop_poll') - @patch('examples.ca_handler.certifier_ca_handler.CAhandler._cert_get') - def test_068_enroll(self, mock_certget, mock_loop, mock_prof, mock_lookup): - """ CAhandler.enroll() _cert_get returns certb64 """ - mock_certget.return_value = {'foo': 'bar', 'href': 'href'} - mock_loop.return_value = ('error', 'cert_bundle', 'cert_raw', 'poll_identifier') self.cahandler.eab_profiling = True self.cahandler.header_info_field = 'header_info_field' - mock_prof.return_value = None self.assertEqual(('error', 'cert_bundle', 'cert_raw', 'poll_identifier'), self.cahandler.enroll('csr')) self.assertTrue(mock_prof.called) - self.assertFalse(mock_lookup.called) - @patch('examples.ca_handler.certifier_ca_handler.header_info_lookup') - @patch('examples.ca_handler.certifier_ca_handler.CAhandler._eab_profile_check') + @patch('examples.ca_handler.certifier_ca_handler.CAhandler._profile_check') @patch('examples.ca_handler.certifier_ca_handler.CAhandler._loop_poll') @patch('examples.ca_handler.certifier_ca_handler.CAhandler._cert_get') - def test_069_enroll(self, mock_certget, mock_loop, mock_prof, mock_lookup): + def test_068_enroll(self, mock_certget, mock_loop, mock_prof): """ CAhandler.enroll() _cert_get returns certb64 """ mock_certget.return_value = {'foo': 'bar', 'href': 'href'} mock_loop.return_value = ('error', 'cert_bundle', 'cert_raw', 'poll_identifier') @@ -720,42 +703,38 @@ def test_069_enroll(self, mock_certget, mock_loop, mock_prof, mock_lookup): mock_prof.return_value = 'prof_error' self.assertEqual(('prof_error', None, None, None), self.cahandler.enroll('csr')) self.assertTrue(mock_prof.called) - self.assertFalse(mock_lookup.called) self.assertFalse(mock_certget.called) - @patch('examples.ca_handler.certifier_ca_handler.header_info_lookup') - @patch('examples.ca_handler.certifier_ca_handler.CAhandler._eab_profile_check') + @patch('examples.ca_handler.certifier_ca_handler.CAhandler._profile_check') @patch('examples.ca_handler.certifier_ca_handler.CAhandler._loop_poll') @patch('examples.ca_handler.certifier_ca_handler.CAhandler._cert_get') - def test_070_enroll(self, mock_certget, mock_loop, mock_prof, mock_lookup): + def test_069_enroll(self, mock_certget, mock_loop, mock_prof): """ CAhandler.enroll() _cert_get returns certb64 """ mock_certget.return_value = {'foo': 'bar', 'href': 'href'} mock_loop.return_value = ('error', 'cert_bundle', 'cert_raw', 'poll_identifier') self.cahandler.eab_profiling = False self.cahandler.header_info_field = 'header_info_field' - mock_prof.return_value = 'prof_error' - mock_lookup.return_value = 'mock_lookup' + mock_prof.return_value = None self.assertEqual(('error', 'cert_bundle', 'cert_raw', 'poll_identifier'), self.cahandler.enroll('csr')) - self.assertFalse(mock_prof.called) - self.assertTrue(mock_lookup.called) + self.assertTrue(mock_prof.called) self.assertTrue(mock_certget.called) - self.assertEqual(self.cahandler.profile_id, 'mock_lookup') + self.assertEqual(self.cahandler.profile_id, None) @patch('examples.ca_handler.certifier_ca_handler.CAhandler._ca_get_properties') - def test_071_revoke(self, mock_getca): + def test_070_revoke(self, mock_getca): """ CAhandler.revoke() _ca_get_properties returns nothing """ mock_getca.return_value = {} self.assertEqual((404, 'urn:ietf:params:acme:error:serverInternal', 'CA could not be found'), self.cahandler.revoke('cert')) @patch('examples.ca_handler.certifier_ca_handler.CAhandler._ca_get_properties') - def test_072_revoke(self, mock_getca): + def test_071_revoke(self, mock_getca): """ CAhandler.revoke() _ca_get_properties returns wrong information """ mock_getca.return_value = {'foo': 'bar'} self.assertEqual((404, 'urn:ietf:params:acme:error:serverInternal', 'CA could not be found'), self.cahandler.revoke('cert')) @patch('examples.ca_handler.certifier_ca_handler.cert_serial_get') @patch('examples.ca_handler.certifier_ca_handler.CAhandler._ca_get_properties') - def test_073_revoke(self, mock_getca, mock_serial): + def test_072_revoke(self, mock_getca, mock_serial): """ CAhandler.revoke() _ca_get_properties cert_serial_get failed """ mock_getca.return_value = {'foo': 'bar', 'href': 'href'} mock_serial.return_value = None @@ -764,7 +743,7 @@ def test_073_revoke(self, mock_getca, mock_serial): @patch('examples.ca_handler.certifier_ca_handler.CAhandler._cert_get_properties') @patch('examples.ca_handler.certifier_ca_handler.cert_serial_get') @patch('examples.ca_handler.certifier_ca_handler.CAhandler._ca_get_properties') - def test_074_revoke(self, mock_getca, mock_serial, mock_getcert): + def test_073_revoke(self, mock_getca, mock_serial, mock_getcert): """ CAhandler.revoke() _ca_get_properties get_cert_properties failed """ mock_getca.return_value = {'foo': 'bar', 'href': 'href'} mock_serial.return_value = 123 @@ -774,7 +753,7 @@ def test_074_revoke(self, mock_getca, mock_serial, mock_getcert): @patch('examples.ca_handler.certifier_ca_handler.CAhandler._cert_get_properties') @patch('examples.ca_handler.certifier_ca_handler.cert_serial_get') @patch('examples.ca_handler.certifier_ca_handler.CAhandler._ca_get_properties') - def test_075_revoke(self, mock_getca, mock_serial, mock_getcert): + def test_074_revoke(self, mock_getca, mock_serial, mock_getcert): """ CAhandler.revoke() _ca_get_properties get_cert_properties returns wrong information """ mock_getca.return_value = {'foo': 'bar', 'href': 'href'} mock_serial.return_value = 123 @@ -784,7 +763,7 @@ def test_075_revoke(self, mock_getca, mock_serial, mock_getcert): @patch('examples.ca_handler.certifier_ca_handler.CAhandler._cert_get_properties') @patch('examples.ca_handler.certifier_ca_handler.cert_serial_get') @patch('examples.ca_handler.certifier_ca_handler.CAhandler._ca_get_properties') - def test_076_revoke(self, mock_getca, mock_serial, mock_getcert): + def test_075_revoke(self, mock_getca, mock_serial, mock_getcert): """ CAhandler.revoke() _ca_get_properties get_cert_properties empty cert_list """ mock_getca.return_value = {'foo': 'bar', 'href': 'href'} mock_serial.return_value = 123 @@ -794,7 +773,7 @@ def test_076_revoke(self, mock_getca, mock_serial, mock_getcert): @patch('examples.ca_handler.certifier_ca_handler.CAhandler._cert_get_properties') @patch('examples.ca_handler.certifier_ca_handler.cert_serial_get') @patch('examples.ca_handler.certifier_ca_handler.CAhandler._ca_get_properties') - def test_077_revoke(self, mock_getca, mock_serial, mock_getcert): + def test_076_revoke(self, mock_getca, mock_serial, mock_getcert): """ CAhandler.revoke() _ca_get_properties get_cert_properties returns cert_list with wrong information """ mock_getca.return_value = {'foo': 'bar', 'href': 'href'} mock_serial.return_value = 123 @@ -805,7 +784,7 @@ def test_077_revoke(self, mock_getca, mock_serial, mock_getcert): @patch('examples.ca_handler.certifier_ca_handler.CAhandler._cert_get_properties') @patch('examples.ca_handler.certifier_ca_handler.cert_serial_get') @patch('examples.ca_handler.certifier_ca_handler.CAhandler._ca_get_properties') - def test_078_revoke(self, mock_getca, mock_serial, mock_getcert, mock_post): + def test_077_revoke(self, mock_getca, mock_serial, mock_getcert, mock_post): """ CAhandler.revoke() _ca_get_properties get_cert_properties returns cert_list revocation successful """ mock_getca.return_value = {'foo': 'bar', 'href': 'href'} mock_serial.return_value = 123 @@ -817,7 +796,7 @@ def test_078_revoke(self, mock_getca, mock_serial, mock_getcert, mock_post): @patch('examples.ca_handler.certifier_ca_handler.CAhandler._cert_get_properties') @patch('examples.ca_handler.certifier_ca_handler.cert_serial_get') @patch('examples.ca_handler.certifier_ca_handler.CAhandler._ca_get_properties') - def test_079_revoke(self, mock_getca, mock_serial, mock_getcert, mock_post): + def test_078_revoke(self, mock_getca, mock_serial, mock_getcert, mock_post): """ CAhandler.revoke() _ca_get_properties get_cert_properties returns href. revocation returns status without message """ mock_getca.return_value = {'foo': 'bar', 'href': 'href'} mock_serial.return_value = 123 @@ -829,7 +808,7 @@ def test_079_revoke(self, mock_getca, mock_serial, mock_getcert, mock_post): @patch('examples.ca_handler.certifier_ca_handler.CAhandler._cert_get_properties') @patch('examples.ca_handler.certifier_ca_handler.cert_serial_get') @patch('examples.ca_handler.certifier_ca_handler.CAhandler._ca_get_properties') - def test_080_revoke(self, mock_getca, mock_serial, mock_getcert, mock_post): + def test_079_revoke(self, mock_getca, mock_serial, mock_getcert, mock_post): """ CAhandler.revoke() _ca_get_properties get_cert_properties returns href. revocation returns status with message """ mock_getca.return_value = {'foo': 'bar', 'href': 'href'} mock_serial.return_value = 123 @@ -837,7 +816,7 @@ def test_080_revoke(self, mock_getca, mock_serial, mock_getcert, mock_post): mock_post.return_value = {'foo': 'bar', 'status': 'status', 'message': 'message'} self.assertEqual((400, 'urn:ietf:params:acme:error:alreadyRevoked', 'message'), self.cahandler.revoke('cert')) - def test_081_trigger(self): + def test_080_trigger(self): """ CAhandler.trigger() - no payload given """ payload = None self.assertEqual(('No payload given', None, None), self.cahandler.trigger(payload)) @@ -846,7 +825,7 @@ def test_081_trigger(self): @patch('examples.ca_handler.certifier_ca_handler.cert_pem2der') @patch('examples.ca_handler.certifier_ca_handler.b64_decode') @patch('examples.ca_handler.certifier_ca_handler.b64_encode') - def test_082_trigger(self, mock_b64dec, mock_b64enc, mock_p2d, mock_caprop): + def test_081_trigger(self, mock_b64dec, mock_b64enc, mock_p2d, mock_caprop): """ CAhandler.trigger() - payload but ca_lookup failed""" payload = 'foo' mock_b64dec.return_value = 'foodecode' @@ -859,7 +838,7 @@ def test_082_trigger(self, mock_b64dec, mock_b64enc, mock_p2d, mock_caprop): @patch('examples.ca_handler.certifier_ca_handler.cert_pem2der') @patch('examples.ca_handler.certifier_ca_handler.b64_decode') @patch('examples.ca_handler.certifier_ca_handler.b64_encode') - def test_083_trigger(self, mock_b64dec, mock_b64enc, mock_p2d, mock_caprop, mock_serial): + def test_082_trigger(self, mock_b64dec, mock_b64enc, mock_p2d, mock_caprop, mock_serial): """ CAhandler.trigger() - payload serial number lookup failed""" payload = 'foo' mock_b64dec.return_value = 'foodecode' @@ -874,7 +853,7 @@ def test_083_trigger(self, mock_b64dec, mock_b64enc, mock_p2d, mock_caprop, mock @patch('examples.ca_handler.certifier_ca_handler.cert_pem2der') @patch('examples.ca_handler.certifier_ca_handler.b64_decode') @patch('examples.ca_handler.certifier_ca_handler.b64_encode') - def test_084_trigger(self, mock_b64dec, mock_b64enc, mock_p2d, mock_caprop, mock_serial, mock_certprop): + def test_083_trigger(self, mock_b64dec, mock_b64enc, mock_p2d, mock_caprop, mock_serial, mock_certprop): """ CAhandler.trigger() - payload serial number lookup failed""" payload = 'foo' mock_b64dec.return_value = 'foodecode' @@ -891,7 +870,7 @@ def test_084_trigger(self, mock_b64dec, mock_b64enc, mock_p2d, mock_caprop, mock @patch('examples.ca_handler.certifier_ca_handler.cert_pem2der') @patch('examples.ca_handler.certifier_ca_handler.b64_decode') @patch('examples.ca_handler.certifier_ca_handler.b64_encode') - def test_085_trigger(self, mock_b64dec, mock_b64enc, mock_p2d, mock_caprop, mock_serial, mock_certprop, mock_chain): + def test_084_trigger(self, mock_b64dec, mock_b64enc, mock_p2d, mock_caprop, mock_serial, mock_certprop, mock_chain): """ CAhandler.trigger() - payload serial number lookup failed""" payload = 'foo' mock_b64dec.return_value = 'foodecode' @@ -909,7 +888,7 @@ def test_085_trigger(self, mock_b64dec, mock_b64enc, mock_p2d, mock_caprop, mock @patch('examples.ca_handler.certifier_ca_handler.cert_pem2der') @patch('examples.ca_handler.certifier_ca_handler.b64_decode') @patch('examples.ca_handler.certifier_ca_handler.b64_encode') - def test_086_trigger(self, mock_b64dec, mock_b64enc, mock_p2d, mock_caprop, mock_serial, mock_certprop, mock_chain): + def test_085_trigger(self, mock_b64dec, mock_b64enc, mock_p2d, mock_caprop, mock_serial, mock_certprop, mock_chain): """ CAhandler.trigger() - payload serial number lookup failed""" payload = 'foo' mock_b64dec.return_value = 'foodecode' @@ -920,23 +899,23 @@ def test_086_trigger(self, mock_b64dec, mock_b64enc, mock_p2d, mock_caprop, mock mock_chain.return_value = 'chain' self.assertEqual((None, 'chain', 'foodecode'), self.cahandler.trigger(payload)) - def test_087__pem_cert_chain_generate(self): + def test_086__pem_cert_chain_generate(self): """ _pem_cert_chain_generate - empty cert_dic """ cert_dic = {} self.assertFalse(self.cahandler._pem_cert_chain_generate(cert_dic)) - def test_088__pem_cert_chain_generate(self): + def test_087__pem_cert_chain_generate(self): """ _pem_cert_chain_generate - wrong dic """ cert_dic = {'foo': 'bar'} self.assertFalse(self.cahandler._pem_cert_chain_generate(cert_dic)) - def test_089__pem_cert_chain_generate(self): + def test_088__pem_cert_chain_generate(self): """ _pem_cert_chain_generate - certificateBase64 in dict """ cert_dic = {'certificateBase64': 'certificateBase64'} self.assertEqual('-----BEGIN CERTIFICATE-----\ncertificateBase64\n-----END CERTIFICATE-----\n', self.cahandler._pem_cert_chain_generate(cert_dic)) @patch('requests.get') - def test_090__pem_cert_chain_generate(self, mock_get): + def test_089__pem_cert_chain_generate(self, mock_get): """ _pem_cert_chain_generate - issuer in dict without certificateBase64 """ cert_dic = {'issuer': 'issuer'} mockresponse = Mock() @@ -945,7 +924,7 @@ def test_090__pem_cert_chain_generate(self, mock_get): self.assertFalse(self.cahandler._pem_cert_chain_generate(cert_dic)) @patch('requests.get') - def test_091__pem_cert_chain_generate(self, mock_get): + def test_090__pem_cert_chain_generate(self, mock_get): """ _pem_cert_chain_generate - request returns "certificates" but no active """ cert_dic = {'issuer': 'issuer', 'certificateBase64': 'certificateBase641'} mockresponse1 = Mock() @@ -956,7 +935,7 @@ def test_091__pem_cert_chain_generate(self, mock_get): self.assertEqual('-----BEGIN CERTIFICATE-----\ncertificateBase641\n-----END CERTIFICATE-----\n', self.cahandler._pem_cert_chain_generate(cert_dic)) @patch('requests.get') - def test_092__pem_cert_chain_generate(self, mock_get): + def test_091__pem_cert_chain_generate(self, mock_get): """ _pem_cert_chain_generate - request returns certificate and active, 2nd request is bogus """ cert_dic = {'issuer': 'issuer', 'certificateBase64': 'certificateBase641'} mockresponse1 = Mock() @@ -967,7 +946,7 @@ def test_092__pem_cert_chain_generate(self, mock_get): self.assertEqual('-----BEGIN CERTIFICATE-----\ncertificateBase641\n-----END CERTIFICATE-----\n', self.cahandler._pem_cert_chain_generate(cert_dic)) @patch('requests.get') - def test_093__pem_cert_chain_generate(self, mock_get): + def test_092__pem_cert_chain_generate(self, mock_get): """ _pem_cert_chain_generate - request returns certificate two certs """ cert_dic = {'issuer': 'issuer', 'certificateBase64': 'certificateBase641'} mockresponse1 = Mock() @@ -980,7 +959,7 @@ def test_093__pem_cert_chain_generate(self, mock_get): self.assertEqual('-----BEGIN CERTIFICATE-----\ncertificateBase641\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\ncertificateBase642\n-----END CERTIFICATE-----\n', self.cahandler._pem_cert_chain_generate(cert_dic)) @patch('requests.get') - def test_094__pem_cert_chain_generate(self, mock_get): + def test_093__pem_cert_chain_generate(self, mock_get): """ _pem_cert_chain_generate - request returns certificate three certs """ cert_dic = {'issuer': 'issuer', 'certificateBase64': 'certificateBase641'} mockresponse1 = Mock() @@ -997,7 +976,7 @@ def test_094__pem_cert_chain_generate(self, mock_get): self.assertEqual('-----BEGIN CERTIFICATE-----\ncertificateBase641\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\ncertificateBase642\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\ncertificateBase643\n-----END CERTIFICATE-----\n', self.cahandler._pem_cert_chain_generate(cert_dic)) @patch('requests.get') - def test_095__pem_cert_chain_generate(self, mock_get): + def test_094__pem_cert_chain_generate(self, mock_get): """ _pem_cert_chain_generate - issuerCa in """ cert_dic = {'issuerCa': 'issuerCa', 'certificateBase64': 'certificateBase641'} mockresponse1 = Mock() @@ -1007,12 +986,12 @@ def test_095__pem_cert_chain_generate(self, mock_get): mock_get.side_effect = [mockresponse1, mockresponse2] self.assertEqual('-----BEGIN CERTIFICATE-----\ncertificateBase641\n-----END CERTIFICATE-----\n', self.cahandler._pem_cert_chain_generate(cert_dic)) - def test_096__enter__(self): + def test_095__enter__(self): """ test __enter__ """ self.cahandler.__enter__() @patch('requests.get') - def test_097_request_poll(self, mock_get): + def test_096_request_poll(self, mock_get): """ test request poll request returned exception """ mock_get.side_effect = Exception('exc_api_get') result = ('"status" field not found in response.', None, None, 'url', False) @@ -1021,7 +1000,7 @@ def test_097_request_poll(self, mock_get): self.assertIn('ERROR:test_a2c:CAhandler._request.poll() returned: exc_api_get', lcm.output) @patch('requests.get') - def test_098_request_poll(self, mock_get): + def test_097_request_poll(self, mock_get): """ test request poll request returned unknown status """ mockresponse = Mock() mockresponse.json = lambda: {'status': 'unknown'} @@ -1030,7 +1009,7 @@ def test_098_request_poll(self, mock_get): self.assertEqual(result, self.cahandler._request_poll('url')) @patch('requests.get') - def test_099_request_poll(self, mock_get): + def test_098_request_poll(self, mock_get): """ test request poll request returned status rejected """ mockresponse = Mock() mockresponse.json = lambda: {'status': 'rejected'} @@ -1039,7 +1018,7 @@ def test_099_request_poll(self, mock_get): self.assertEqual(result, self.cahandler._request_poll('url')) @patch('requests.get') - def test_100_request_poll(self, mock_get): + def test_099_request_poll(self, mock_get): """ test request poll request returned status accepted but no certinformation in """ mockresponse = Mock() mockresponse.json = lambda: {'status': 'accepted', 'foo': 'bar'} @@ -1048,7 +1027,7 @@ def test_100_request_poll(self, mock_get): self.assertEqual(result, self.cahandler._request_poll('url')) @patch('requests.get') - def test_101_request_poll(self, mock_get): + def test_100_request_poll(self, mock_get): """ test request poll request returned status accepted but no certinformation in """ mockresponse = Mock() mockresponse.json = lambda: {'status': 'accepted', 'certificate': 'certificate'} @@ -1058,7 +1037,7 @@ def test_101_request_poll(self, mock_get): @patch('examples.ca_handler.certifier_ca_handler.CAhandler._pem_cert_chain_generate') @patch('requests.get') - def test_102_request_poll(self, mock_get, mock_pemgen): + def test_101_request_poll(self, mock_get, mock_pemgen): """ test request poll request returned status accepted but no certinformation in """ mockresponse = Mock() mockresponse.json = lambda: {'status': 'accepted', 'certificate': 'certificate', 'certificateBase64': 'certificateBase64'} @@ -1067,83 +1046,8 @@ def test_102_request_poll(self, mock_get, mock_pemgen): result = (None, 'bundle', 'certificateBase64', 'url', False) self.assertEqual(result, self.cahandler._request_poll('url')) - def test_103_config_headerinfo_get(self): - """ test config_headerinfo_get()""" - config_dic = {'Order': {'header_info_list': '["foo", "bar", "foobar"]'}} - self.cahandler._config_headerinfo_get(config_dic) - self.assertEqual( 'foo', self.cahandler.header_info_field) - - def test_104_config_headerinfo_get(self): - """ test config_headerinfo_get()""" - config_dic = {'Order': {'header_info_list': '["foo"]'}} - self.cahandler._config_headerinfo_get(config_dic) - self.assertEqual( 'foo', self.cahandler.header_info_field) - - def test_105_config_headerinfo_get(self): - """ test config_headerinfo_get()""" - config_dic = {'Order': {'header_info_list': 'foo'}} - with self.assertLogs('test_a2c', level='INFO') as lcm: - self.cahandler._config_headerinfo_get(config_dic) - self.assertFalse(self.cahandler.header_info_field) - self.assertIn('WARNING:test_a2c:Order._config_orderconfig_load() header_info_list failed with error: Expecting value: line 1 column 1 (char 0)', lcm.output) - - @patch('examples.ca_handler.certifier_ca_handler.eab_handler_load') - def test_106_config_eab_profile_load(self, mock_eabload): - """ test config_eab_profiling()""" - config_dic = configparser.ConfigParser() - config_dic['CAhandler'] = {'eab_profiling': True} - config_dic['EABhandler'] = {'eab_handler_file': 'eab_handler_file'} - self.cahandler._config_eab_profile_load(config_dic) - self.assertTrue(mock_eabload.called) - self.assertTrue(self.cahandler.eab_profiling) - - @patch('examples.ca_handler.certifier_ca_handler.eab_handler_load') - def test_107_config_eab_profile_load(self, mock_eabload): - """ test config_eab_profiling()""" - config_dic = configparser.ConfigParser() - config_dic['CAhandler'] = {'eab_profiling': True} - # ['EABhandler'] = {'eab_handler_file': 'eab_handler_file'} - with self.assertLogs('test_a2c', level='INFO') as lcm: - self.cahandler._config_eab_profile_load(config_dic) - self.assertFalse(mock_eabload.called) - self.assertIn('CRITICAL:test_a2c:CAhandler._config_load(): EABHandler configuration incomplete', lcm.output) - self.assertTrue(self.cahandler.eab_profiling) - - @patch('examples.ca_handler.certifier_ca_handler.eab_handler_load') - def test_108_config_eab_profile_load(self, mock_eabload): - """ test config_eab_profiling()""" - config_dic = configparser.ConfigParser() - config_dic['CAhandler'] = {'eab_profiling': True} - config_dic['EABhandler'] = {'eab_handler_file': 'eab_handler_file'} - mock_eabload.return_value = None - with self.assertLogs('test_a2c', level='INFO') as lcm: - self.cahandler._config_eab_profile_load(config_dic) - self.assertTrue(mock_eabload.called) - self.assertIn('CRITICAL:test_a2c:CAhandler._config_load(): EABHandler could not get loaded', lcm.output) - self.assertTrue(self.cahandler.eab_profiling) - - @patch('examples.ca_handler.certifier_ca_handler.eab_handler_load') - def test_109_config_eab_profile_load(self, mock_eabload): - """ test config_eab_profiling()""" - config_dic = configparser.ConfigParser() - config_dic['CAhandler'] = {'eab_profiling': False} - config_dic['EABhandler'] = {'eab_handler_file': 'eab_handler_file'} - self.cahandler._config_eab_profile_load(config_dic) - self.assertFalse(mock_eabload.called) - self.assertFalse(self.cahandler.eab_profiling) - - @patch('examples.ca_handler.certifier_ca_handler.eab_handler_load') - def test_110_config_eab_profile_load(self, mock_eabload): - """ test config_eab_profiling()""" - config_dic = configparser.ConfigParser() - config_dic['CAhandler'] = {'eab_profiling': 'aa'} - config_dic['EABhandler'] = {'eab_handler_file': 'eab_handler_file'} - self.cahandler._config_eab_profile_load(config_dic) - self.assertFalse(mock_eabload.called) - self.assertFalse(self.cahandler.eab_profiling) - @patch('examples.ca_handler.certifier_ca_handler.header_info_field_validate') - def test_111__eab_profile_check(self, mock_hil): + def test_102__eab_profile_check(self, mock_hil): """ test eab_profile_check """ self.cahandler.eab_handler = MagicMock() self.cahandler.api_host = 'api_host' @@ -1152,7 +1056,7 @@ def test_111__eab_profile_check(self, mock_hil): self.cahandler.profile_id = 'profile_id' self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar'} with self.assertLogs('test_a2c', level='INFO') as lcm: - self.assertFalse(self.cahandler._eab_profile_check('csr')) + self.assertFalse(self.cahandler._eab_profile_check('csr', 'handler_hifield')) self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) self.assertEqual('api_host', self.cahandler.api_host) self.assertEqual('api_user', self.cahandler.api_user) @@ -1161,7 +1065,7 @@ def test_111__eab_profile_check(self, mock_hil): self.assertFalse(mock_hil.called) @patch('examples.ca_handler.certifier_ca_handler.header_info_lookup') - def test_112__eab_profile_check(self, mock_hil): + def test_103__eab_profile_check(self, mock_hil): """ test eab_profile_check """ self.cahandler.eab_handler = MagicMock() self.cahandler.api_host = 'api_host' @@ -1170,7 +1074,7 @@ def test_112__eab_profile_check(self, mock_hil): self.cahandler.profile_id = 'profile_id' self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'api_host': 'new_host', 'api_user': 'new_user', 'api_password': 'new_password', 'profile_id': 'new_profile'} with self.assertLogs('test_a2c', level='INFO') as lcm: - self.assertFalse(self.cahandler._eab_profile_check('csr')) + self.assertFalse(self.cahandler._eab_profile_check('csr', 'handler_hifield')) self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) self.assertEqual('new_host', self.cahandler.api_host) self.assertEqual('new_user', self.cahandler.api_user) @@ -1178,7 +1082,7 @@ def test_112__eab_profile_check(self, mock_hil): self.assertEqual('new_profile', self.cahandler.profile_id) self.assertFalse(mock_hil.called) - def test_113__eab_profile_check(self): + def test_104__eab_profile_check(self): """ test eab_profile_check default value from list """ self.cahandler.eab_handler = MagicMock() self.cahandler.api_host = 'api_host' @@ -1188,7 +1092,7 @@ def test_113__eab_profile_check(self): self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'profile_id': ['profile_1', 'profile_2', 'profile_3']} # mock_hil.return_value = ('None', None) with self.assertLogs('test_a2c', level='INFO') as lcm: - self.assertFalse(self.cahandler._eab_profile_check('csr')) + self.assertFalse(self.cahandler._eab_profile_check('csr', 'handler_hifield')) self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) self.assertEqual('api_host', self.cahandler.api_host) self.assertEqual('api_user', self.cahandler.api_user) @@ -1196,7 +1100,7 @@ def test_113__eab_profile_check(self): self.assertEqual('profile_1', self.cahandler.profile_id) @patch('examples.ca_handler.certifier_ca_handler.header_info_field_validate') - def test_114__eab_profile_check(self, mock_hil): + def test_105__eab_profile_check(self, mock_hil): """ test eab_profile_check default value from list header info validate returns a value """ self.cahandler.eab_handler = MagicMock() self.cahandler.api_host = 'api_host' @@ -1206,7 +1110,7 @@ def test_114__eab_profile_check(self, mock_hil): mock_hil.return_value = ('profile_2', None) self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'profile_id': ['profile_1', 'profile_2', 'profile_3']} with self.assertLogs('test_a2c', level='INFO') as lcm: - self.assertFalse(self.cahandler._eab_profile_check('csr')) + self.assertFalse(self.cahandler._eab_profile_check('csr', 'handler_hifield')) self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) self.assertEqual('api_host', self.cahandler.api_host) self.assertEqual('api_user', self.cahandler.api_user) @@ -1215,7 +1119,7 @@ def test_114__eab_profile_check(self, mock_hil): self.assertTrue(mock_hil.called) @patch('examples.ca_handler.certifier_ca_handler.header_info_field_validate') - def test_114__eab_profile_check(self, mock_hil): + def test_106__eab_profile_check(self, mock_hil): """ test eab_profile_check default value from list headerinfo_lookup returns an error """ self.cahandler.eab_handler = MagicMock() self.cahandler.api_host = 'api_host' @@ -1225,7 +1129,7 @@ def test_114__eab_profile_check(self, mock_hil): mock_hil.return_value = (None, 'error') self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'profile_id': ['profile_1', 'profile_2', 'profile_3']} with self.assertLogs('test_a2c', level='INFO') as lcm: - self.assertEqual('error', self.cahandler._eab_profile_check('csr')) + self.assertEqual('error', self.cahandler._eab_profile_check('csr', 'handler_hifield')) self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) self.assertEqual('api_host', self.cahandler.api_host) self.assertEqual('api_user', self.cahandler.api_user) @@ -1234,7 +1138,7 @@ def test_114__eab_profile_check(self, mock_hil): self.assertTrue(mock_hil.called) @patch('examples.ca_handler.certifier_ca_handler.header_info_field_validate') - def test_115__eab_profile_check(self, mock_hil): + def test_107__eab_profile_check(self, mock_hil): """ test eab_profile_check """ self.cahandler.eab_handler = MagicMock() self.cahandler.api_host = 'api_host' @@ -1245,7 +1149,7 @@ def test_115__eab_profile_check(self, mock_hil): self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'allowed_domainlist': ['foo.bar', 'bar.foo']} self.cahandler.eab_handler.return_value.__enter__.return_value.allowed_domains_check.return_value = 'domain_chk_error' with self.assertLogs('test_a2c', level='INFO') as lcm: - self.assertEqual('domain_chk_error', self.cahandler._eab_profile_check('csr')) + self.assertEqual('domain_chk_error', self.cahandler._eab_profile_check('csr', 'handler_hifield')) self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) self.assertEqual('api_host', self.cahandler.api_host) self.assertEqual('api_user', self.cahandler.api_user) @@ -1254,7 +1158,7 @@ def test_115__eab_profile_check(self, mock_hil): self.assertFalse(mock_hil.called) @patch('examples.ca_handler.certifier_ca_handler.header_info_field_validate') - def test_116__eab_profile_check(self, mock_hil): + def test_108__eab_profile_check(self, mock_hil): """ test eab_profile_check """ self.cahandler.eab_handler = MagicMock() self.cahandler.api_host = 'api_host' @@ -1265,7 +1169,7 @@ def test_116__eab_profile_check(self, mock_hil): self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'allowed_domainlist': ['foo.bar', 'bar.foo']} self.cahandler.eab_handler.return_value.__enter__.return_value.allowed_domains_check.return_value = None with self.assertLogs('test_a2c', level='INFO') as lcm: - self.assertFalse(self.cahandler._eab_profile_check('csr')) + self.assertFalse(self.cahandler._eab_profile_check('csr', 'handler_hifield')) self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) self.assertEqual('api_host', self.cahandler.api_host) self.assertEqual('api_user', self.cahandler.api_user) @@ -1274,7 +1178,7 @@ def test_116__eab_profile_check(self, mock_hil): self.assertFalse(mock_hil.called) @patch('examples.ca_handler.certifier_ca_handler.header_info_field_validate') - def test_117__eab_profile_check(self, mock_hil): + def test_109__eab_profile_check(self, mock_hil): """ test eab_profile_check """ self.cahandler.eab_handler = MagicMock() self.cahandler.api_host = 'api_host' @@ -1285,7 +1189,7 @@ def test_117__eab_profile_check(self, mock_hil): self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'unknown': ['foobar', 'barfoo']} self.cahandler.eab_handler.return_value.__enter__.return_value.allowed_domains_check.return_value = None with self.assertLogs('test_a2c', level='INFO') as lcm: - self.assertFalse(self.cahandler._eab_profile_check('csr')) + self.assertFalse(self.cahandler._eab_profile_check('csr', 'handler_hifield')) self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) self.assertIn("ERROR:test_a2c:CAhandler._eab_profile_list_check(): ignore list attribute: key: unknown value: ['foobar', 'barfoo']", lcm.output) self.assertEqual('api_host', self.cahandler.api_host) @@ -1296,7 +1200,7 @@ def test_117__eab_profile_check(self, mock_hil): @patch('examples.ca_handler.certifier_ca_handler.header_info_lookup') @patch('examples.ca_handler.certifier_ca_handler.header_info_field_validate') - def test_118__eab_profile_check(self, mock_hiv, mock_hil): + def test_110__eab_profile_check(self, mock_hiv, mock_hil): """ test eab_profile_check """ self.cahandler.eab_handler = MagicMock() self.cahandler.api_host = 'api_host' @@ -1309,19 +1213,19 @@ def test_118__eab_profile_check(self, mock_hiv, mock_hil): self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'unknown': ['foobar', 'barfoo']} self.cahandler.eab_handler.return_value.__enter__.return_value.allowed_domains_check.return_value = None with self.assertLogs('test_a2c', level='INFO') as lcm: - self.assertFalse(self.cahandler._eab_profile_check('csr')) + self.assertFalse(self.cahandler._eab_profile_check('csr', 'profile_id')) self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) self.assertIn("ERROR:test_a2c:CAhandler._eab_profile_list_check(): ignore list attribute: key: unknown value: ['foobar', 'barfoo']", lcm.output) self.assertEqual('api_host', self.cahandler.api_host) self.assertEqual('api_user', self.cahandler.api_user) self.assertEqual('api_password', self.cahandler.api_password) - self.assertEqual('mock_hil', self.cahandler.profile_id) self.assertFalse(mock_hiv.called) self.assertTrue(mock_hil.called) + self.assertEqual('mock_hil', self.cahandler.profile_id) @patch('examples.ca_handler.certifier_ca_handler.header_info_lookup') @patch('examples.ca_handler.certifier_ca_handler.header_info_field_validate') - def test_119__eab_profile_check(self, mock_hiv, mock_hil): + def test_111__eab_profile_check(self, mock_hiv, mock_hil): """ test eab_profile_check """ self.cahandler.eab_handler = MagicMock() self.cahandler.api_host = 'api_host' @@ -1334,7 +1238,7 @@ def test_119__eab_profile_check(self, mock_hiv, mock_hil): self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'unknown': ['foobar', 'barfoo']} self.cahandler.eab_handler.return_value.__enter__.return_value.allowed_domains_check.return_value = None with self.assertLogs('test_a2c', level='INFO') as lcm: - self.assertFalse(self.cahandler._eab_profile_check('csr')) + self.assertFalse(self.cahandler._eab_profile_check('csr', 'handler_hifield')) self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) self.assertIn("ERROR:test_a2c:CAhandler._eab_profile_list_check(): ignore list attribute: key: unknown value: ['foobar', 'barfoo']", lcm.output) self.assertEqual('api_host', self.cahandler.api_host) @@ -1344,6 +1248,85 @@ def test_119__eab_profile_check(self, mock_hiv, mock_hil): self.assertFalse(mock_hiv.called) self.assertTrue(mock_hil.called) + @patch('examples.ca_handler.certifier_ca_handler.header_info_lookup') + @patch('examples.ca_handler.certifier_ca_handler.CAhandler._eab_profile_check') + def test_112__profile_check(self, mock_eab, mock_hil): + """ test eab_profile_string_check """ + self.assertFalse(self.cahandler._profile_check('csr')) + self.assertFalse(mock_eab.called) + self.assertFalse(mock_hil.called) + + @patch('examples.ca_handler.certifier_ca_handler.header_info_lookup') + @patch('examples.ca_handler.certifier_ca_handler.CAhandler._eab_profile_check') + def test_113__profile_check(self, mock_eab, mock_hil): + """ test eab_profile_string_check """ + self.cahandler.eab_profiling = False + self.assertFalse(self.cahandler._profile_check('csr')) + self.assertFalse(mock_eab.called) + self.assertFalse(mock_hil.called) + + @patch('examples.ca_handler.certifier_ca_handler.header_info_lookup') + @patch('examples.ca_handler.certifier_ca_handler.CAhandler._eab_profile_check') + def test_114__eab_profile_string_check(self, mock_eab, mock_hil): + """ test eab_profile_string_check """ + self.cahandler.eab_profiling = True + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.cahandler._profile_check('csr')) + self.assertIn('ERROR:test_a2c:CAhandler._profile_check(): eab_profiling enabled but no handler defined', lcm.output) + self.assertFalse(mock_eab.called) + self.assertFalse(mock_hil.called) + + @patch('examples.ca_handler.certifier_ca_handler.header_info_lookup') + @patch('examples.ca_handler.certifier_ca_handler.CAhandler._eab_profile_check') + def test_115__eab_profile_string_check(self, mock_eab, mock_hil): + """ test eab_profile_string_check """ + self.cahandler.eab_profiling = True + self.cahandler.eab_handler = MagicMock() + mock_eab.return_value = 'mock_eab' + self.assertEqual('mock_eab', self.cahandler._profile_check('csr')) + self.assertTrue(mock_eab.called) + self.assertFalse(mock_hil.called) + + @patch('examples.ca_handler.certifier_ca_handler.header_info_lookup') + @patch('examples.ca_handler.certifier_ca_handler.CAhandler._eab_profile_check') + def test_116__eab_profile_string_check(self, mock_eab, mock_hil): + """ test eab_profile_string_check """ + self.cahandler.eab_profiling = True + self.cahandler.header_info_field = 'header_info_field' + self.cahandler.eab_handler = MagicMock() + mock_eab.return_value = 'mock_eab' + self.assertEqual('mock_eab', self.cahandler._profile_check('csr')) + self.assertTrue(mock_eab.called) + self.assertFalse(mock_hil.called) + + @patch('examples.ca_handler.certifier_ca_handler.header_info_lookup') + @patch('examples.ca_handler.certifier_ca_handler.CAhandler._eab_profile_check') + def test_117__eab_profile_string_check(self, mock_eab, mock_hil): + """ test eab_profile_string_check """ + self.cahandler.eab_profiling = True + self.cahandler.eab_handler = None + self.cahandler.header_info_field = 'profile_id' + self.cahandler.profile_id = 'profile_id' + mock_hil.return_value = 'mock_hil' + self.assertFalse(self.cahandler._profile_check('csr')) + self.assertFalse(mock_eab.called) + self.assertTrue(mock_hil.called) + self.assertEqual('mock_hil', self.cahandler.profile_id) + + @patch('examples.ca_handler.certifier_ca_handler.header_info_lookup') + @patch('examples.ca_handler.certifier_ca_handler.CAhandler._eab_profile_check') + def test_118__eab_profile_string_check(self, mock_eab, mock_hil): + """ test eab_profile_string_check """ + self.cahandler.eab_profiling = True + self.cahandler.eab_handler = None + self.cahandler.header_info_field = 'profile_id' + self.cahandler.profile_id = 'profile_id' + mock_hil.return_value = None + self.assertFalse(self.cahandler._profile_check('csr')) + self.assertFalse(mock_eab.called) + self.assertTrue(mock_hil.called) + self.assertEqual('profile_id', self.cahandler.profile_id) + if __name__ == '__main__': if os.path.exists('acme_test.db'): diff --git a/test/test_helper.py b/test/test_helper.py index 1ee9d775..9fd0c39d 100644 --- a/test/test_helper.py +++ b/test/test_helper.py @@ -26,7 +26,7 @@ def setUp(self): """ setup unittest """ import logging logging.basicConfig(level=logging.CRITICAL) - from acme_srv.helper import b64decode_pad, b64_decode, b64_encode, b64_url_encode, b64_url_recode, convert_string_to_byte, convert_byte_to_string, decode_message, decode_deserialize, get_url, generate_random_string, signature_check, validate_email, uts_to_date_utc, date_to_uts_utc, load_config, cert_serial_get, cert_san_get, cert_san_pyopenssl_get, cert_dates_get, build_pem_file, date_to_datestr, datestr_to_date, dkeys_lower, csr_cn_get, cert_pubkey_get, csr_pubkey_get, url_get, url_get_with_own_dns, dns_server_list_load, csr_san_get, csr_san_byte_get, csr_extensions_get, fqdn_resolve, fqdn_in_san_check, sha256_hash, sha256_hash_hex, cert_der2pem, cert_pem2der, cert_extensions_get, csr_dn_get, logger_setup, logger_info, print_debug, jwk_thumbprint_get, allowed_gai_family, patched_create_connection, validate_csr, servercert_get, txt_get, proxystring_convert, proxy_check, handle_exception, ca_handler_load, eab_handler_load, hooks_load, error_dic_get, _logger_nonce_modify, _logger_certificate_modify, _logger_token_modify, _logger_challenges_modify, config_check, cert_issuer_get, cert_cn_get, string_sanitize, pembundle_to_list, certid_asn1_get, certid_check, certid_hex_get, v6_adjust, ipv6_chk, ip_validate, header_info_get, encode_url, uts_now, cert_ski_get, cert_ski_pyopenssl_get, cert_aki_get, cert_aki_pyopenssl_get, validate_fqdn, validate_ip, validate_identifier, header_info_field_validate, header_info_lookup + from acme_srv.helper import b64decode_pad, b64_decode, b64_encode, b64_url_encode, b64_url_recode, convert_string_to_byte, convert_byte_to_string, decode_message, decode_deserialize, get_url, generate_random_string, signature_check, validate_email, uts_to_date_utc, date_to_uts_utc, load_config, cert_serial_get, cert_san_get, cert_san_pyopenssl_get, cert_dates_get, build_pem_file, date_to_datestr, datestr_to_date, dkeys_lower, csr_cn_get, cert_pubkey_get, csr_pubkey_get, url_get, url_get_with_own_dns, dns_server_list_load, csr_san_get, csr_san_byte_get, csr_extensions_get, fqdn_resolve, fqdn_in_san_check, sha256_hash, sha256_hash_hex, cert_der2pem, cert_pem2der, cert_extensions_get, csr_dn_get, logger_setup, logger_info, print_debug, jwk_thumbprint_get, allowed_gai_family, patched_create_connection, validate_csr, servercert_get, txt_get, proxystring_convert, proxy_check, handle_exception, ca_handler_load, eab_handler_load, hooks_load, error_dic_get, _logger_nonce_modify, _logger_certificate_modify, _logger_token_modify, _logger_challenges_modify, config_check, cert_issuer_get, cert_cn_get, string_sanitize, pembundle_to_list, certid_asn1_get, certid_check, certid_hex_get, v6_adjust, ipv6_chk, ip_validate, header_info_get, encode_url, uts_now, cert_ski_get, cert_ski_pyopenssl_get, cert_aki_get, cert_aki_pyopenssl_get, validate_fqdn, validate_ip, validate_identifier, header_info_field_validate, header_info_lookup, config_eab_profile_load, config_headerinfo_get self.logger = logging.getLogger('test_a2c') self.allowed_gai_family = allowed_gai_family self.b64_decode = b64_decode @@ -112,6 +112,8 @@ def setUp(self): self.encode_url = encode_url self.uts_now = uts_now self.ip_validate = ip_validate + self.config_headerinfo_get = config_headerinfo_get + self.config_eab_profile_load = config_eab_profile_load def test_001_helper_b64decode_pad(self): """ test b64decode_pad() method with a regular base64 encoded string """ @@ -2372,5 +2374,78 @@ def test_314_header_info_lookup(self, mock_info, mock_json): self.assertFalse(self.header_info_lookup(self.logger, 'csr', 'header_info_field', 'foo1')) self.assertIn('ERROR:test_a2c:header_info_lookup() could not parse header_info_field: mock_json', lcm.output) + def test_315_config_headerinfo_get(self): + """ test config_headerinfo_get()""" + config_dic = {'Order': {'header_info_list': '["foo", "bar", "foobar"]'}} + self.assertEqual('foo', self.config_headerinfo_get(self.logger, config_dic)) + + def test_316_config_headerinfo_get(self): + """ test config_headerinfo_get()""" + config_dic = {'Order': {'header_info_list': '["foo"]'}} + self.assertEqual('foo', self.config_headerinfo_get(self.logger, config_dic)) + + def test_317_config_headerinfo_get(self): + """ test config_headerinfo_get()""" + config_dic = {'Order': {'header_info_list': 'foo'}} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.config_headerinfo_get(self.logger, config_dic)) + self.assertIn('WARNING:test_a2c:Helper.config_headerinfo_get() header_info_list failed with error: Expecting value: line 1 column 1 (char 0)', lcm.output) + + @patch('acme_srv.helper.eab_handler_load') + def test_318_config_eab_profile_load(self, mock_eabload): + """ test config_eab_profiling()""" + config_dic = configparser.ConfigParser() + config_dic['CAhandler'] = {'eab_profiling': True} + config_dic['EABhandler'] = {'eab_handler_file': 'eab_handler_file'} + eabl = Mock() + eabl.EABhandler = 'bar' + mock_eabload.return_value = eabl + self.assertEqual((True, 'bar'), self.config_eab_profile_load(self.logger, config_dic)) + self.assertTrue(mock_eabload.called) + + @patch('acme_srv.helper.eab_handler_load') + def test_319_config_eab_profile_load(self, mock_eabload): + """ test config_eab_profiling()""" + config_dic = configparser.ConfigParser() + config_dic['CAhandler'] = {'eab_profiling': True} + eabl = Mock() + eabl.EABhandler = 'bar' + mock_eabload.return_value = eabl + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertEqual((True, None), self.config_eab_profile_load(self.logger, config_dic)) + self.assertFalse(mock_eabload.called) + self.assertIn('CRITICAL:test_a2c:CAhandler._config_load(): EABHandler configuration incomplete', lcm.output) + self.assertFalse(mock_eabload.called) + + @patch('acme_srv.helper.eab_handler_load') + def test_320_config_eab_profile_load(self, mock_eabload): + """ test config_eab_profiling()""" + config_dic = configparser.ConfigParser() + config_dic['CAhandler'] = {'eab_profiling': True} + config_dic['EABhandler'] = {'eab_handler_file': 'eab_handler_file'} + mock_eabload.return_value = None + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertEqual((True, None), self.config_eab_profile_load(self.logger, config_dic)) + self.assertTrue(mock_eabload.called) + self.assertIn('CRITICAL:test_a2c:CAhandler._config_load(): EABHandler could not get loaded', lcm.output) + + @patch('acme_srv.helper.eab_handler_load') + def test_321_config_eab_profile_load(self, mock_eabload): + """ test config_eab_profiling()""" + config_dic = configparser.ConfigParser() + config_dic['CAhandler'] = {'eab_profiling': False} + config_dic['EABhandler'] = {'eab_handler_file': 'eab_handler_file'} + self.assertEqual((False, None), self.config_eab_profile_load(self.logger, config_dic)) + self.assertFalse(mock_eabload.called) + + @patch('acme_srv.helper.eab_handler_load') + def test_322_config_eab_profile_load(self, mock_eabload): + """ test config_eab_profiling()""" + config_dic = configparser.ConfigParser() + config_dic['CAhandler'] = {'eab_profiling': 'aa'} + config_dic['EABhandler'] = {'eab_handler_file': 'eab_handler_file'} + self.assertEqual((False, None), self.config_eab_profile_load(self.logger, config_dic)) + self.assertFalse(mock_eabload.called) + if __name__ == '__main__': unittest.main() diff --git a/test/test_xca_ca_handler.py b/test/test_xca_ca_handler.py index 7ea5d753..4c3db17b 100644 --- a/test/test_xca_ca_handler.py +++ b/test/test_xca_ca_handler.py @@ -1465,177 +1465,194 @@ def test_177__subject_modify(self, mock_addr, mock_name): self.assertEqual('mock_name', self.cahandler._subject_modify('subject', dn_dic)) self.assertIn('INFO:test_a2c:rewrite C to countryName', lcm.output) + @patch('examples.ca_handler.xca_ca_handler.CAhandler._profile_check') @patch('examples.ca_handler.xca_ca_handler.CAhandler._cert_sign') @patch('examples.ca_handler.xca_ca_handler.CAhandler._ca_load') @patch('examples.ca_handler.xca_ca_handler.build_pem_file') @patch('examples.ca_handler.xca_ca_handler.b64_url_recode') @patch('examples.ca_handler.xca_ca_handler.CAhandler._csr_import') @patch('examples.ca_handler.xca_ca_handler.CAhandler._requestname_get') - @patch('examples.ca_handler.xca_ca_handler.header_info_get') @patch('examples.ca_handler.xca_ca_handler.CAhandler._config_check') - def test_179_enroll(self, mock_chk, mock_info, mock_reqname, mock_csr, mock_b64, mock_build, mock_ca, mock_sign): + def test_179_enroll(self, mock_chk, mock_reqname, mock_csr, mock_b64, mock_build, mock_ca, mock_sign, mock_prof): """ test enroll() """ mock_chk.return_value = 'error' + mock_prof.return_value = None self.assertEqual(('error', None, None, None), self.cahandler.enroll('csr')) self.assertTrue(mock_chk.called) - self.assertTrue(mock_info.called) self.assertFalse(mock_reqname.called) self.assertFalse(mock_csr.called) self.assertFalse(mock_b64.called) self.assertFalse(mock_build.called) self.assertFalse(mock_ca.called) self.assertFalse(mock_sign.called) + self.assertFalse(mock_prof.called) + @patch('examples.ca_handler.xca_ca_handler.CAhandler._profile_check') @patch('examples.ca_handler.xca_ca_handler.CAhandler._cert_sign') @patch('examples.ca_handler.xca_ca_handler.CAhandler._ca_load') @patch('examples.ca_handler.xca_ca_handler.build_pem_file') @patch('examples.ca_handler.xca_ca_handler.b64_url_recode') @patch('examples.ca_handler.xca_ca_handler.CAhandler._csr_import') @patch('examples.ca_handler.xca_ca_handler.CAhandler._requestname_get') - @patch('examples.ca_handler.xca_ca_handler.header_info_get') @patch('examples.ca_handler.xca_ca_handler.CAhandler._config_check') - def test_180_enroll(self, mock_chk, mock_info, mock_reqname, mock_csr, mock_b64, mock_build, mock_ca, mock_sign): + def test_180_enroll(self, mock_chk, mock_reqname, mock_csr, mock_b64, mock_build, mock_ca, mock_sign, mock_prof): """ test enroll() """ mock_chk.return_value = 'error' + mock_prof.return_value = None self.assertEqual(('error', None, None, None), self.cahandler.enroll('csr')) self.assertTrue(mock_chk.called) - self.assertTrue(mock_info.called) self.assertFalse(mock_reqname.called) self.assertFalse(mock_csr.called) self.assertFalse(mock_b64.called) self.assertFalse(mock_build.called) self.assertFalse(mock_ca.called) self.assertFalse(mock_sign.called) + self.assertFalse(mock_prof.called) + @patch('examples.ca_handler.xca_ca_handler.CAhandler._profile_check') @patch('examples.ca_handler.xca_ca_handler.CAhandler._cert_sign') @patch('examples.ca_handler.xca_ca_handler.CAhandler._ca_load') @patch('examples.ca_handler.xca_ca_handler.build_pem_file') @patch('examples.ca_handler.xca_ca_handler.b64_url_recode') @patch('examples.ca_handler.xca_ca_handler.CAhandler._csr_import') @patch('examples.ca_handler.xca_ca_handler.CAhandler._requestname_get') - @patch('examples.ca_handler.xca_ca_handler.header_info_get') @patch('examples.ca_handler.xca_ca_handler.CAhandler._config_check') - def test_181_enroll(self, mock_chk, mock_info, mock_reqname, mock_csr, mock_b64, mock_build, mock_ca, mock_sign): + def test_181_enroll(self, mock_chk, mock_reqname, mock_csr, mock_b64, mock_build, mock_ca, mock_sign, mock_prof): """ test enroll() """ mock_chk.return_value = None - mock_info.return_value = [{'header_info': 'header_info'}] mock_reqname.return_value = None - with self.assertLogs('test_a2c', level='INFO') as lcm: - self.assertEqual(('request_name lookup failed', None, None, None), self.cahandler.enroll('csr')) + mock_prof.return_value = None + self.assertEqual(('request_name lookup failed', None, None, None), self.cahandler.enroll('csr')) self.assertTrue(mock_chk.called) - self.assertTrue(mock_info.called) self.assertTrue(mock_reqname.called) self.assertFalse(mock_csr.called) self.assertFalse(mock_b64.called) self.assertFalse(mock_build.called) self.assertFalse(mock_ca.called) self.assertFalse(mock_sign.called) - self.assertIn('INFO:test_a2c:header_info: header_info', lcm.output) + self.assertTrue(mock_prof.called) + @patch('examples.ca_handler.xca_ca_handler.CAhandler._profile_check') @patch('examples.ca_handler.xca_ca_handler.CAhandler._cert_sign') @patch('examples.ca_handler.xca_ca_handler.CAhandler._ca_load') @patch('examples.ca_handler.xca_ca_handler.build_pem_file') @patch('examples.ca_handler.xca_ca_handler.b64_url_recode') @patch('examples.ca_handler.xca_ca_handler.CAhandler._csr_import') @patch('examples.ca_handler.xca_ca_handler.CAhandler._requestname_get') - @patch('examples.ca_handler.xca_ca_handler.header_info_get') @patch('examples.ca_handler.xca_ca_handler.CAhandler._config_check') - def test_182_enroll(self, mock_chk, mock_info, mock_reqname, mock_csr, mock_b64, mock_build, mock_ca, mock_sign): + def test_182_enroll(self, mock_chk, mock_reqname, mock_csr, mock_b64, mock_build, mock_ca, mock_sign, mock_prof): """ test enroll() """ mock_chk.return_value = None - mock_info.return_value = [{'header_info': 'header_info'}] mock_reqname.return_value = 'request_name' mock_ca.return_value = [None, 'cert', 'id'] - with self.assertLogs('test_a2c', level='INFO') as lcm: - self.assertEqual(('ca lookup failed', None, None, None), self.cahandler.enroll('csr')) + mock_prof.return_value = None + self.assertEqual(('ca lookup failed', None, None, None), self.cahandler.enroll('csr')) self.assertTrue(mock_chk.called) - self.assertTrue(mock_info.called) self.assertTrue(mock_reqname.called) self.assertTrue(mock_csr.called) self.assertTrue(mock_b64.called) self.assertTrue(mock_build.called) self.assertTrue(mock_ca.called) self.assertFalse(mock_sign.called) - self.assertIn('INFO:test_a2c:header_info: header_info', lcm.output) + self.assertTrue(mock_prof.called) + @patch('examples.ca_handler.xca_ca_handler.CAhandler._profile_check') @patch('examples.ca_handler.xca_ca_handler.CAhandler._cert_sign') @patch('examples.ca_handler.xca_ca_handler.CAhandler._ca_load') @patch('examples.ca_handler.xca_ca_handler.build_pem_file') @patch('examples.ca_handler.xca_ca_handler.b64_url_recode') @patch('examples.ca_handler.xca_ca_handler.CAhandler._csr_import') @patch('examples.ca_handler.xca_ca_handler.CAhandler._requestname_get') - @patch('examples.ca_handler.xca_ca_handler.header_info_get') @patch('examples.ca_handler.xca_ca_handler.CAhandler._config_check') - def test_183_enroll(self, mock_chk, mock_info, mock_reqname, mock_csr, mock_b64, mock_build, mock_ca, mock_sign): + def test_183_enroll(self, mock_chk, mock_reqname, mock_csr, mock_b64, mock_build, mock_ca, mock_sign, mock_prof): """ test enroll() """ mock_chk.return_value = None - mock_info.return_value = [{'header_info': 'header_info'}] mock_reqname.return_value = 'request_name' mock_ca.return_value = ['key', None, 'id'] - with self.assertLogs('test_a2c', level='INFO') as lcm: - self.assertEqual(('ca lookup failed', None, None, None), self.cahandler.enroll('csr')) + mock_prof.return_value = None + self.assertEqual(('ca lookup failed', None, None, None), self.cahandler.enroll('csr')) self.assertTrue(mock_chk.called) - self.assertTrue(mock_info.called) self.assertTrue(mock_reqname.called) self.assertTrue(mock_csr.called) self.assertTrue(mock_b64.called) self.assertTrue(mock_build.called) self.assertTrue(mock_ca.called) self.assertFalse(mock_sign.called) - self.assertIn('INFO:test_a2c:header_info: header_info', lcm.output) + self.assertTrue(mock_prof.called) + @patch('examples.ca_handler.xca_ca_handler.CAhandler._profile_check') @patch('examples.ca_handler.xca_ca_handler.CAhandler._cert_sign') @patch('examples.ca_handler.xca_ca_handler.CAhandler._ca_load') @patch('examples.ca_handler.xca_ca_handler.build_pem_file') @patch('examples.ca_handler.xca_ca_handler.b64_url_recode') @patch('examples.ca_handler.xca_ca_handler.CAhandler._csr_import') @patch('examples.ca_handler.xca_ca_handler.CAhandler._requestname_get') - @patch('examples.ca_handler.xca_ca_handler.header_info_get') @patch('examples.ca_handler.xca_ca_handler.CAhandler._config_check') - def test_184_enroll(self, mock_chk, mock_info, mock_reqname, mock_csr, mock_b64, mock_build, mock_ca, mock_sign): + def test_184_enroll(self, mock_chk, mock_reqname, mock_csr, mock_b64, mock_build, mock_ca, mock_sign, mock_prof): """ test enroll() """ mock_chk.return_value = None - mock_info.return_value = [{'header_info': 'header_info'}] mock_reqname.return_value = 'request_name' mock_ca.return_value = ['key', 'cert', None] - with self.assertLogs('test_a2c', level='INFO') as lcm: - self.assertEqual(('ca lookup failed', None, None, None), self.cahandler.enroll('csr')) + mock_prof.return_value = None + self.assertEqual(('ca lookup failed', None, None, None), self.cahandler.enroll('csr')) self.assertTrue(mock_chk.called) - self.assertTrue(mock_info.called) self.assertTrue(mock_reqname.called) self.assertTrue(mock_csr.called) self.assertTrue(mock_b64.called) self.assertTrue(mock_build.called) self.assertTrue(mock_ca.called) self.assertFalse(mock_sign.called) - self.assertIn('INFO:test_a2c:header_info: header_info', lcm.output) + self.assertTrue(mock_prof.called) + @patch('examples.ca_handler.xca_ca_handler.CAhandler._profile_check') @patch('examples.ca_handler.xca_ca_handler.CAhandler._cert_sign') @patch('examples.ca_handler.xca_ca_handler.CAhandler._ca_load') @patch('examples.ca_handler.xca_ca_handler.build_pem_file') @patch('examples.ca_handler.xca_ca_handler.b64_url_recode') @patch('examples.ca_handler.xca_ca_handler.CAhandler._csr_import') @patch('examples.ca_handler.xca_ca_handler.CAhandler._requestname_get') - @patch('examples.ca_handler.xca_ca_handler.header_info_get') @patch('examples.ca_handler.xca_ca_handler.CAhandler._config_check') - def test_185_enroll(self, mock_chk, mock_info, mock_reqname, mock_csr, mock_b64, mock_build, mock_ca, mock_sign): + def test_185_enroll(self, mock_chk, mock_reqname, mock_csr, mock_b64, mock_build, mock_ca, mock_sign, mock_prof): """ test enroll() """ mock_chk.return_value = None - mock_info.return_value = [{'header_info': 'header_info'}] mock_reqname.return_value = 'request_name' mock_ca.return_value = ['key', 'cert', 'caid'] mock_sign.return_value = ['bundle', 'raw'] - with self.assertLogs('test_a2c', level='INFO') as lcm: - self.assertEqual((None, 'bundle', 'raw', None), self.cahandler.enroll('csr')) + mock_prof.return_value = None + self.assertEqual((None, 'bundle', 'raw', None), self.cahandler.enroll('csr')) self.assertTrue(mock_chk.called) - self.assertTrue(mock_info.called) self.assertTrue(mock_reqname.called) self.assertTrue(mock_csr.called) self.assertTrue(mock_b64.called) self.assertTrue(mock_build.called) self.assertTrue(mock_ca.called) self.assertTrue(mock_sign.called) - self.assertIn('INFO:test_a2c:header_info: header_info', lcm.output) + self.assertTrue(mock_prof.called) + + @patch('examples.ca_handler.xca_ca_handler.CAhandler._profile_check') + @patch('examples.ca_handler.xca_ca_handler.CAhandler._cert_sign') + @patch('examples.ca_handler.xca_ca_handler.CAhandler._ca_load') + @patch('examples.ca_handler.xca_ca_handler.build_pem_file') + @patch('examples.ca_handler.xca_ca_handler.b64_url_recode') + @patch('examples.ca_handler.xca_ca_handler.CAhandler._csr_import') + @patch('examples.ca_handler.xca_ca_handler.CAhandler._requestname_get') + @patch('examples.ca_handler.xca_ca_handler.CAhandler._config_check') + def test_186_enroll(self, mock_chk, mock_reqname, mock_csr, mock_b64, mock_build, mock_ca, mock_sign, mock_prof): + """ test enroll() """ + mock_chk.return_value = None + mock_reqname.return_value = 'request_name' + mock_ca.return_value = ['key', 'cert', 'caid'] + mock_sign.return_value = ['bundle', 'raw'] + mock_prof.return_value = "prof_error" + self.assertEqual(('prof_error', None, None, None), self.cahandler.enroll('csr')) + self.assertTrue(mock_chk.called) + self.assertFalse(mock_reqname.called) + self.assertFalse(mock_csr.called) + self.assertFalse(mock_b64.called) + self.assertFalse(mock_build.called) + self.assertFalse(mock_ca.called) + self.assertFalse(mock_sign.called) + self.assertTrue(mock_prof.called) @patch('examples.ca_handler.xca_ca_handler.x509.CertificateBuilder') @patch('examples.ca_handler.xca_ca_handler.b64_encode') @@ -1993,6 +2010,240 @@ def test_195_xca_template_process(self, mock_ski, mock_aki, mock_ku, mock_eku, m self.assertTrue(mock_bc.called) self.assertFalse(mock_cdp.called) + @patch('examples.ca_handler.xca_ca_handler.header_info_lookup') + @patch('examples.ca_handler.xca_ca_handler.CAhandler._eab_profile_check') + def test_112__profile_check(self, mock_eab, mock_hil): + """ test eab_profile_string_check """ + self.assertFalse(self.cahandler._profile_check('csr')) + self.assertFalse(mock_eab.called) + self.assertFalse(mock_hil.called) + + @patch('examples.ca_handler.xca_ca_handler.header_info_lookup') + @patch('examples.ca_handler.xca_ca_handler.CAhandler._eab_profile_check') + def test_113__profile_check(self, mock_eab, mock_hil): + """ test eab_profile_string_check """ + self.cahandler.eab_profiling = False + self.assertFalse(self.cahandler._profile_check('csr')) + self.assertFalse(mock_eab.called) + self.assertFalse(mock_hil.called) + + @patch('examples.ca_handler.xca_ca_handler.header_info_lookup') + @patch('examples.ca_handler.xca_ca_handler.CAhandler._eab_profile_check') + def test_114__profile_check(self, mock_eab, mock_hil): + """ test eab_profile_string_check """ + self.cahandler.eab_profiling = True + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.cahandler._profile_check('csr')) + self.assertIn('ERROR:test_a2c:CAhandler._profile_check(): eab_profiling enabled but no handler defined', lcm.output) + self.assertFalse(mock_eab.called) + self.assertFalse(mock_hil.called) + + @patch('examples.ca_handler.xca_ca_handler.header_info_lookup') + @patch('examples.ca_handler.xca_ca_handler.CAhandler._eab_profile_check') + def test_115__profile_check(self, mock_eab, mock_hil): + """ test eab_profile_string_check """ + self.cahandler.eab_profiling = True + self.cahandler.eab_handler = MagicMock() + mock_eab.return_value = 'mock_eab' + self.assertEqual('mock_eab', self.cahandler._profile_check('csr')) + self.assertTrue(mock_eab.called) + self.assertFalse(mock_hil.called) + + @patch('examples.ca_handler.xca_ca_handler.header_info_lookup') + @patch('examples.ca_handler.xca_ca_handler.CAhandler._eab_profile_check') + def test_116__profile_check(self, mock_eab, mock_hil): + """ test eab_profile_string_check """ + self.cahandler.eab_profiling = True + self.cahandler.header_info_field = 'header_info_field' + self.cahandler.eab_handler = MagicMock() + mock_eab.return_value = 'mock_eab' + self.assertEqual('mock_eab', self.cahandler._profile_check('csr')) + self.assertTrue(mock_eab.called) + self.assertFalse(mock_hil.called) + + @patch('examples.ca_handler.xca_ca_handler.header_info_lookup') + @patch('examples.ca_handler.xca_ca_handler.CAhandler._eab_profile_check') + def test_117__profile_check(self, mock_eab, mock_hil): + """ test eab_profile_string_check """ + self.cahandler.eab_profiling = True + self.cahandler.eab_handler = None + self.cahandler.header_info_field = 'template_name' + self.cahandler.template_name = 'template_name' + mock_hil.return_value = 'mock_hil' + self.assertFalse(self.cahandler._profile_check('csr')) + self.assertFalse(mock_eab.called) + self.assertTrue(mock_hil.called) + self.assertEqual('mock_hil', self.cahandler.template_name) + + @patch('examples.ca_handler.xca_ca_handler.header_info_lookup') + @patch('examples.ca_handler.xca_ca_handler.CAhandler._eab_profile_check') + def test_118__profile_check(self, mock_eab, mock_hil): + """ test eab_profile_string_check """ + self.cahandler.eab_profiling = True + self.cahandler.eab_handler = None + self.cahandler.header_info_field = 'template_name' + self.cahandler.template_name = 'template_name' + mock_hil.return_value = None + self.assertFalse(self.cahandler._profile_check('csr')) + self.assertFalse(mock_eab.called) + self.assertTrue(mock_hil.called) + self.assertEqual('template_name', self.cahandler.template_name) + + @patch('examples.ca_handler.xca_ca_handler.header_info_field_validate') + def test_150__eab_profile_check(self, mock_hil): + """ test eab_profile_check """ + self.cahandler.eab_handler = MagicMock() + self.cahandler.template_name = 'template_name' + self.cahandler.issuing_ca_key = 'issuing_ca_key' + self.cahandler.issuing_ca_name = 'issuing_ca_name' + self.cahandler.passphrase = 'passphrase' + self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar'} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.cahandler._eab_profile_check('csr', 'handler_hifield')) + self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) + self.assertEqual('template_name', self.cahandler.template_name) + self.assertEqual('issuing_ca_key', self.cahandler.issuing_ca_key) + self.assertEqual('issuing_ca_name', self.cahandler.issuing_ca_name) + self.assertEqual('passphrase', self.cahandler.passphrase) + self.assertFalse(mock_hil.called) + + @patch('examples.ca_handler.xca_ca_handler.header_info_field_validate') + def test_151__eab_profile_check(self, mock_hil): + """ test eab_profile_check """ + self.cahandler.eab_handler = MagicMock() + self.cahandler.template_name = 'template_name' + self.cahandler.issuing_ca_key = 'issuing_ca_key' + self.cahandler.issuing_ca_name = 'issuing_ca_name' + self.cahandler.passphrase = 'passphrase' + self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'template_name': 'new_template_name'} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.cahandler._eab_profile_check('csr', 'handler_hifield')) + self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) + self.assertEqual('new_template_name', self.cahandler.template_name) + self.assertEqual('issuing_ca_key', self.cahandler.issuing_ca_key) + self.assertEqual('issuing_ca_name', self.cahandler.issuing_ca_name) + self.assertEqual('passphrase', self.cahandler.passphrase) + self.assertFalse(mock_hil.called) + + @patch('examples.ca_handler.xca_ca_handler.header_info_field_validate') + def test_152__eab_profile_check(self, mock_hil): + """ test eab_profile_check """ + self.cahandler.eab_handler = MagicMock() + self.cahandler.template_name = 'template_name' + self.cahandler.issuing_ca_key = 'issuing_ca_key' + self.cahandler.issuing_ca_name = 'issuing_ca_name' + self.cahandler.passphrase = 'passphrase' + mock_hil.return_value = ('new_template_name2', None) + self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'template_name': ["new_template_name1", "new_template_name2", "new_template_name3"]} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.cahandler._eab_profile_check('csr', 'handler_hifield')) + self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) + self.assertEqual('new_template_name2', self.cahandler.template_name) + self.assertEqual('issuing_ca_key', self.cahandler.issuing_ca_key) + self.assertEqual('issuing_ca_name', self.cahandler.issuing_ca_name) + self.assertEqual('passphrase', self.cahandler.passphrase) + self.assertTrue(mock_hil.called) + + @patch('examples.ca_handler.xca_ca_handler.header_info_field_validate') + def test_153__eab_profile_check(self, mock_hil): + """ test eab_profile_check """ + self.cahandler.eab_handler = MagicMock() + self.cahandler.template_name = 'template_name' + self.cahandler.issuing_ca_key = 'issuing_ca_key' + self.cahandler.issuing_ca_name = 'issuing_ca_name' + self.cahandler.passphrase = 'passphrase' + mock_hil.return_value = (None, 'hil_error') + self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'template_name': ["new_template_name1", "new_template_name2", "new_template_name3"]} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertEqual('hil_error', self.cahandler._eab_profile_check('csr', 'handler_hifield')) + self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) + self.assertEqual('template_name', self.cahandler.template_name) + self.assertEqual('issuing_ca_key', self.cahandler.issuing_ca_key) + self.assertEqual('issuing_ca_name', self.cahandler.issuing_ca_name) + self.assertEqual('passphrase', self.cahandler.passphrase) + self.assertTrue(mock_hil.called) + + @patch('examples.ca_handler.xca_ca_handler.header_info_field_validate') + def test_154__eab_profile_check(self, mock_hil): + """ test eab_profile_check """ + self.cahandler.eab_handler = MagicMock() + self.cahandler.template_name = 'template_name' + self.cahandler.issuing_ca_key = 'issuing_ca_key' + self.cahandler.issuing_ca_name = 'issuing_ca_name' + self.cahandler.passphrase = 'passphrase' + self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'template_name': 'new_template_name', 'issuing_ca_key': 'new_issuing_ca_key', 'issuing_ca_name': 'new_issuing_ca_name', 'passphrase': 'new_passphrase'} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.cahandler._eab_profile_check('csr', 'handler_hifield')) + self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) + self.assertEqual('new_template_name', self.cahandler.template_name) + self.assertEqual('new_issuing_ca_key', self.cahandler.issuing_ca_key) + self.assertEqual('new_issuing_ca_name', self.cahandler.issuing_ca_name) + self.assertEqual('new_passphrase', self.cahandler.passphrase) + self.assertFalse(mock_hil.called) + + @patch('examples.ca_handler.xca_ca_handler.header_info_field_validate') + def test_155__eab_profile_check(self, mock_hil): + """ test eab_profile_check """ + self.cahandler.eab_handler = MagicMock() + self.cahandler.template_name = 'template_name' + self.cahandler.issuing_ca_key = 'issuing_ca_key' + self.cahandler.issuing_ca_name = 'issuing_ca_name' + self.cahandler.passphrase = 'passphrase' + self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'template_name': 'new_template_name', 'allowed_domainlist': ['domain1', 'domain2', 'domain3']} + self.cahandler.eab_handler.return_value.__enter__.return_value.allowed_domains_check.return_value = 'domain_chk_error' + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertEqual('domain_chk_error', self.cahandler._eab_profile_check('csr', 'handler_hifield')) + self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) + self.assertEqual('new_template_name', self.cahandler.template_name) + self.assertEqual('issuing_ca_key', self.cahandler.issuing_ca_key) + self.assertEqual('issuing_ca_name', self.cahandler.issuing_ca_name) + self.assertEqual('passphrase', self.cahandler.passphrase) + self.assertFalse(mock_hil.called) + + @patch('examples.ca_handler.xca_ca_handler.header_info_field_validate') + def test_156__eab_profile_check(self, mock_hil): + """ test eab_profile_check """ + self.cahandler.eab_handler = MagicMock() + self.cahandler.template_name = 'template_name' + self.cahandler.issuing_ca_key = 'issuing_ca_key' + self.cahandler.issuing_ca_name = 'issuing_ca_name' + self.cahandler.passphrase = 'passphrase' + self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'template_name': 'new_template_name', 'unknown': ['foobar', 'barfoo']} + self.cahandler.eab_handler.return_value.__enter__.return_value.allowed_domains_check.return_value = 'domain_chk_error' + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.cahandler._eab_profile_check('csr', 'handler_hifield')) + self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) + self.assertIn("ERROR:test_a2c:CAhandler._eab_profile_list_check(): ignore list attribute: key: unknown value: ['foobar', 'barfoo']", lcm.output) + self.assertEqual('new_template_name', self.cahandler.template_name) + self.assertEqual('issuing_ca_key', self.cahandler.issuing_ca_key) + self.assertEqual('issuing_ca_name', self.cahandler.issuing_ca_name) + self.assertEqual('passphrase', self.cahandler.passphrase) + self.assertFalse(mock_hil.called) + + + @patch('examples.ca_handler.xca_ca_handler.header_info_lookup') + @patch('examples.ca_handler.xca_ca_handler.header_info_field_validate') + def test_150__eab_profile_check(self, mock_hil, mock_lookup): + """ test eab_profile_check """ + self.cahandler.eab_handler = MagicMock() + self.cahandler.template_name = 'template_name' + self.cahandler.issuing_ca_key = 'issuing_ca_key' + self.cahandler.issuing_ca_name = 'issuing_ca_name' + self.cahandler.passphrase = 'passphrase' + self.cahandler.header_info_field = 'template_name' + self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar'} + mock_lookup.return_value = 'mock_lookup' + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.cahandler._eab_profile_check('csr', 'template_name')) + self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) + self.assertEqual('mock_lookup', self.cahandler.template_name) + self.assertEqual('issuing_ca_key', self.cahandler.issuing_ca_key) + self.assertEqual('issuing_ca_name', self.cahandler.issuing_ca_name) + self.assertEqual('passphrase', self.cahandler.passphrase) + self.assertFalse(mock_hil.called) + + + if __name__ == '__main__': unittest.main() From 39b9459e5eaa1bcfd510d6a6106d211e479b376c Mon Sep 17 00:00:00 2001 From: grindsa Date: Mon, 8 Apr 2024 06:33:38 +0200 Subject: [PATCH 161/460] [wf] xca_handler.test --- .github/workflows/ca_handler_tests_xca.yml | 601 +++++++++++++-------- examples/ca_handler/xca_ca_handler.py | 13 +- examples/eab_handler/kid_profiles.json | 9 +- test/test_xca_ca_handler.py | 102 ++-- 4 files changed, 437 insertions(+), 288 deletions(-) diff --git a/.github/workflows/ca_handler_tests_xca.yml b/.github/workflows/ca_handler_tests_xca.yml index 3b877382..8991a68d 100644 --- a/.github/workflows/ca_handler_tests_xca.yml +++ b/.github/workflows/ca_handler_tests_xca.yml @@ -9,8 +9,8 @@ on: - cron: '0 2 * * 6' jobs: - xca_handler_tests: - name: "xca_handler_tests" + xca_handler_tests_profiling: + name: "xca_handler_tests_profiling" runs-on: ubuntu-latest strategy: fail-fast: false @@ -35,13 +35,12 @@ jobs: WEB_SRV: ${{ matrix.websrv }} DB_HANDLER: ${{ matrix.dbhandler }} - - name: "Create letsencrypt and lego folder" + - name: "Create acme-sh and lego folder" run: | mkdir acme-sh - mkdir certbot mkdir lego - - name: "Setup a2c with xca_ca_handler - no template" + - name: "Setup a2c with xca_ca_handler - headerinfo-only" run: | sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem @@ -60,7 +59,8 @@ jobs: sudo echo "issuing_ca_name: $XCA_ISSUING_CA" >> examples/Docker/data/acme_srv.cfg sudo echo "passphrase: $XCA_PASSPHRASE" >> examples/Docker/data/acme_srv.cfg sudo echo "ca_cert_chain_list: [\"root-ca\"]" >> examples/Docker/data/acme_srv.cfg - # sudo echo "template_name: $XCA_TEMPLATE" >> examples/Docker/data/acme_srv.cfg + sudo echo "template_name: $XCA_TEMPLATE" >> examples/Docker/data/acme_srv.cfg + sudo sed -i "s/tnauthlist_support: False/tnauthlist_support: False\nheader_info_list: [\"HTTP_USER_AGENT\"]/g" examples/Docker/data/acme_srv.cfg cd examples/Docker/ docker-compose restart docker-compose logs @@ -81,55 +81,52 @@ jobs: - name: "Test if https://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - name: "Prepare acme.sh container" - run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - - name: "Acme.sh" + - name: "01 - Enroll acme.sh without template_name" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + sudo rm -rf acme-sh/* + # docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' -d acme-sh.acme --standalone --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout - openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout | grep "Basic Constraints: critical" - openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout | grep "Digital Signature, Key Encipherment" - openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout | grep "TLS Web Server Authentication" + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Server Authentication, TLS Web Client Authentication" - - name: "Revoke via acme.sh" + - name: "01 - Enroll lego without template_name" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure - - - name: "Register certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - - name: "Enroll certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem - sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout - sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "Basic Constraints: critical" - sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "Digital Signature, Key Encipherment" - sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "TLS Web Server Authentication" + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext keyUsage | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Server Authentication, TLS Web Client Authentication" - - name: "Revoke certbot" + - name: "02 - Enroll acme.sh with template_name template" run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot + sudo rm -rf acme-sh/* + # docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' --useragent template_name=template -d acme-sh.acme --standalone --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature, Non Repudiation" + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Server Authentication, Code Signing" - - name: "Enroll lego" + - name: "02 - Enroll lego with template_name template" run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent template_name=template -d lego.acme --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout - sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout | grep "Basic Constraints: critical" - sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout | grep "Digital Signature, Key Encipherment" - sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout | grep "TLS Web Server Authentication" - - - name: "Revoke lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext keyUsage | grep "Digital Signature, Non Repudiation" + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Server Authentication, Code Signing" - - name: "Setup a2c with xca_ca_handler - with template" + - name: "Setup a2c with xca_ca_handler - profiling" run: | + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py sudo mkdir -p examples/Docker/data/xca sudo chmod -R 777 examples/Docker/data/xca sudo cp test/ca/acme2certifier-clean.xdb examples/Docker/data/xca/$XCA_DB_NAME @@ -137,13 +134,29 @@ jobs: sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ sudo touch examples/Docker/data/acme_srv.cfg sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_choosen_handler.cfg > examples/Docker/data/acme_srv.cfg sudo echo "handler_file: /var/www/acme2certifier/examples/ca_handler/xca_ca_handler.py" >> examples/Docker/data/acme_srv.cfg sudo echo "xdb_file: volume/xca/$XCA_DB_NAME" >> examples/Docker/data/acme_srv.cfg sudo echo "issuing_ca_name: $XCA_ISSUING_CA" >> examples/Docker/data/acme_srv.cfg sudo echo "passphrase: $XCA_PASSPHRASE" >> examples/Docker/data/acme_srv.cfg sudo echo "ca_cert_chain_list: [\"root-ca\"]" >> examples/Docker/data/acme_srv.cfg sudo echo "template_name: $XCA_TEMPLATE" >> examples/Docker/data/acme_srv.cfg + sudo echo "eab_profiling: True" >> examples/Docker/data/acme_srv.cfg + sudo sed -i "s/tnauthlist_support: False/tnauthlist_support: False\nheader_info_list: [\"HTTP_USER_AGENT\"]/g" examples/Docker/data/acme_srv.cfg + sudo echo -e "\n\n[EABhandler]" >> examples/Docker/data/acme_srv.cfg + sudo echo "eab_handler_file: /var/www/acme2certifier/examples/eab_handler/kid_profile_handler.py" >> examples/Docker/data/acme_srv.cfg + sudo echo "key_file: volume/kid_profiles.json" >> examples/Docker/data/acme_srv.cfg + + sudo cp examples/eab_handler/kid_profiles.json examples/Docker/data/kid_profiles.json + sudo chmod 777 examples/eab_handler/kid_profiles.json + sudo sed -i "s/\"profile_id\"\: \[\"profile_1\", \"profile_2\", \"profile_3\"\]/\"template_name\"\: \[\"template\", \"acme\"\]/g" examples/Docker/data/kid_profiles.json + sudo sed -i "s/\"profile_id\"\: \"profile_2\"/\"template_name\"\: \"template\"/g" examples/Docker/data/kid_profiles.json + sudo sed -i "s/\"ca_name\": \"example_ca_2\",/\"issuing_ca_name\": \"root-ca\",\n \"issuing_ca_key\": \"root-ca\"/g" examples/Docker/data/kid_profiles.json + sudo sed -i "s/\"ca_name\": \"example_ca\",/\"unknown_key\": \"unknown_value\"/g" examples/Docker/data/kid_profiles.json + sudo sed -i "s/example.net/acme/g" examples/Docker/data/kid_profiles.json + sudo sed -i '19,20d' examples/Docker/data/kid_profiles.json + sudo sed -i '8,9d' examples/Docker/data/kid_profiles.json + cd examples/Docker/ docker-compose restart docker-compose logs @@ -164,46 +177,147 @@ jobs: - name: "Test if https://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - name: "Enroll acme.sh" + - name: "01 - Enroll acme with a template_name taken from list in kid.json" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force - openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_00 --eab-hmac-key V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout - openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" - openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout | grep "TLS Web Server Authentication, TLS Web Client Authentication" + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature, Non Repudiation" + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Server Authentication, Code Signing" - - name: "Revoke via acme.sh" + - name: "01 - Enroll lego with a template_name taken from list in kid.json" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw -d lego.acme --http run + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -issuer --noout + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext keyUsage | grep "Digital Signature, Non Repudiation" + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Server Authentication, Code Signing" - - name: "Register certbot" + - name: "02a - Enroll acme with a template_name taken from header_info NOT included in kid.json (to fail)" + id: acmefail01 + continue-on-error: true run: | - sudo rm -rf certbot/* - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_00 --eab-hmac-key V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --useragent template_name=unknown -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "Enroll certbot" + - name: "02a - check result " + if: steps.acmefail01.outcome != 'failure' run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem - sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout - sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" - sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "TLS Web Server Authentication, TLS Web Client Authentication" + echo "acmefail outcome is ${{steps.acmefail01.outcome }}" + exit 1 - - name: "Revoke certbot" + - name: "02b - Enroll acme with a template_name taken from header_info included in kid.json" run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_00 --eab-hmac-key V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --useragent template_name=acme -d acme-sh.acme --standalone --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Server Authentication, TLS Web Client Authentication" - - name: "Enroll lego" + - name: "02a - Enroll lego with a template_name taken from header_info NOT included in kid.json (to fail)" + id: legofail01 + continue-on-error: true run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --user-agent template_name=unknown -d lego.acme --http run + + - name: "02a - check result " + if: steps.legofail01.outcome != 'failure' + run: | + echo "legofail outcome is ${{steps.legofail01.outcome }}" + exit 1 + + - name: "02b - Enroll lego with a template_name taken from header_info included in kid.json" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --user-agent template_name=acme -d lego.acme --http run + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -issuer --noout + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext keyUsage | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Server Authentication, TLS Web Client Authentication" + + - name: "03 - Enroll acme with a template_name/ca_name taken from kid.json" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_01 --eab-hmac-key YW5vdXRoZXJfdmVyeV9sb25nX2htYWNfZm9yX2tleWlkXzAxX3doaWNoIHdpbGxfYmUgdXNlZF9kdXJpbmcgcmVncmVzc2lvbg --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature, Non Repudiation" + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Server Authentication, Code Signing" + + - name: "03 - Enroll lego with a template_name/ca_name taken from kid.json" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_01 --hmac YW5vdXRoZXJfdmVyeV9sb25nX2htYWNfZm9yX2tleWlkXzAxX3doaWNoIHdpbGxfYmUgdXNlZF9kdXJpbmcgcmVncmVzc2lvbg -d lego.acme --http run + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -issuer --noout + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout - sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" - sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout | grep "TLS Web Server Authentication, TLS Web Client Authentication" + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext keyUsage | grep "Digital Signature, Non Repudiation" + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Server Authentication, Code Signing" + + - name: "04 - Enroll acme with a not allowed fqdn in kid.json (to fail)" + id: acmefail02 + continue-on-error: true + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure + + - name: "04 - check result " + if: steps.acmefail02.outcome != 'failure' + run: | + echo "acmefail outcome is ${{steps.acmefail02.outcome }}" + exit 1 + + - name: "04 - Enroll lego with a not allowed fqdn in kid.json (to fail)" + id: legofail02 + continue-on-error: true + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM -d lego.acme --http run - - name: "Revoke lego" + - name: "04a - check result " + if: steps.legofail02.outcome != 'failure' run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke + echo "legofail outcome is ${{steps.legofail02.outcome }}" + exit 1 + + - name: "05 - Enroll acme with default values from acme.cfg" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_03 --eab-hmac-key YW5kX2ZpbmFsbHlfdGhlX2xhc3RfaG1hY19rZXlfd2hpY2hfaXNfbG9uZ2VyX3RoYW5fMjU2X2JpdHNfYW5kX3Nob3VsZF93b3Jr --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Server Authentication, TLS Web Client Authentication" + + - name: "05 - Enroll lego with default values from acme.cfg" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_03 --hmac YW5kX2ZpbmFsbHlfdGhlX2xhc3RfaG1hY19rZXlfd2hpY2hfaXNfbG9uZ2VyX3RoYW5fMjU2X2JpdHNfYW5kX3Nob3VsZF93b3Jr -d lego.acme --http run + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -issuer --noout + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext keyUsage | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Server Authentication, TLS Web Client Authentication" - name: "[ * ] collecting test logs" if: ${{ failure() }} @@ -211,21 +325,20 @@ jobs: mkdir -p ${{ github.workspace }}/artifact/upload sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ - sudo cp -rp certbot/ ${{ github.workspace }}/artifact/certbot/ sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ cd examples/Docker docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh certbot lego + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh lego - name: "[ * ] uploading artificates" uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: xca_handler-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz + name: xca_handler_tests_profiling-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ - xca_handler_no_tmpl_tests_rpm: - name: "xca_handler_no_tmpl_tests_rpm" + xca_handler_tests_profiling_rpm: + name: "xca_handler_tests_profiling_rpm" runs-on: ubuntu-latest strategy: fail-fast: false @@ -254,7 +367,7 @@ jobs: - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" - - name: "[ PREPARE ] setup environment for alma installation" + - name: "Setup environment for alma installation" run: | docker network create acme sudo mkdir -p data @@ -262,7 +375,7 @@ jobs: sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data - - name: "[ PREPARE ] create letsencrypt and lego folder" + - name: "Create letsencrypt and lego folder" run: | mkdir certbot mkdir lego @@ -275,7 +388,7 @@ jobs: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} - - name: "[ PREPARE ] prepare acme_srv.cfg with xca_ca_handler" + - name: "Setup a2c with xca_ca_handler - headerinfo-only" run: | mkdir -p data/acme_ca sudo cp test/ca/acme2certifier-clean.xdb data/acme_ca/$XCA_DB_NAME @@ -289,147 +402,71 @@ jobs: sudo echo "issuing_ca_name: $XCA_ISSUING_CA" >> data/acme_srv.cfg sudo echo "passphrase: $XCA_PASSPHRASE" >> data/acme_srv.cfg sudo echo "ca_cert_chain_list: [\"root-ca\"]" >> data/acme_srv.cfg - # sudo echo "template_name: $XCA_TEMPLATE" >> data/acme_srv.cfg + sudo echo "template_name: $XCA_TEMPLATE" >> data/acme_srv.cfg + sudo sed -i "s/tnauthlist_support: False/tnauthlist_support: False\nheader_info_list: [\"HTTP_USER_AGENT\"]/g" data/acme_srv.cfg + sudo echo "eab_handler_file: /opt/acme2certifier/examples/eab_handler/kid_profile_handler.py" >> data/acme_srv.cfg + sudo echo "key_file: /opt/acme2certifier/volume/acme_ca/kid_profiles.json" >> data/acme_srv.cfg env: XCA_PASSPHRASE: ${{ secrets.XCA_PASSPHRASE }} XCA_ISSUING_CA: ${{ secrets.XCA_ISSUING_CA }} XCA_TEMPLATE: ${{ secrets.XCA_TEMPLATE }} XCA_DB_NAME: ${{ secrets.XCA_DB_NAME }} - - name: "[ PREPARE ] Almalinux instance" + - name: "Prepare Almalinux instance" run: | sudo cp examples/Docker/almalinux-systemd/Dockerfile data sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - - name: "[ RUN ] Execute install scipt" + - name: "Execute install scipt" run: | docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh - name: "Test http://acme-srv/directory is accessible" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" - run: | - sudo mkdir acme-sh - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - - name: "[ ENROLL ] acme.sh" + - name: "01 - Enroll acme.sh without template_name" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force - openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + sudo rm -rf acme-sh/* + # docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' -d acme-sh.acme --standalone --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout - openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout | grep "Basic Constraints: critical" - openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout | grep "Digital Signature, Key Encipherment" - openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout | grep "TLS Web Server Authentication" + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Server Authentication, TLS Web Client Authentication" - - name: "revoke via acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure - - - name: "[ REGISTER] certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - - name: "[ ENROLL ] HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - sudo openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem - sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout - sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "Basic Constraints: critical" - sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "Digital Signature, Key Encipherment" - sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "TLS Web Server Authentication" - - - name: "revoke HTTP-01 single domain certbot" - run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - - - name: "[ ENROLL ] lego" + - name: "01 - Enroll lego without template_name" run: | + sudo rm -rf lego/* docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - sudo openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout - sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout | grep "Basic Constraints: critical" - sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout | grep "Digital Signature, Key Encipherment" - sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout | grep "TLS Web Server Authentication" + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext keyUsage | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Server Authentication, TLS Web Client Authentication" - - name: "revoke HTTP-01 single domain lego" + - name: "02 - Enroll acme.sh with template_name template" run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke - - - name: "[ * ] collecting test logs" - if: ${{ failure() }} - run: | - mkdir -p ${{ github.workspace }}/artifact/upload - docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier - sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ - sudo rm ${{ github.workspace }}/artifact/data/*.rpm - docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig - docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf - docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh - - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: xca_handler_no_tmpl_tests_rpm-rh${{ matrix.rhversion }}.tar.gz - path: ${{ github.workspace }}/artifact/upload/ - - xca_handler_tmpl_tests_rpm: - name: "xca_handler_tmpl_tests_rpm" - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - rhversion: [8, 9] - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 - - - name: Retrieve Version from version.py - run: | - echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV - - run: echo "Latest tag is ${{ env.TAG_NAME }}" - - - name: update version number in spec file - run: | - # sudo sed -i "s/Source0:.*/Source0: %{name}-%{version}.tar.gz/g" examples/install_scripts/rpm/acme2certifier.spec - sudo sed -i "s/__version__/${{ env.TAG_NAME }}/g" examples/install_scripts/rpm/acme2certifier.spec - cat examples/install_scripts/rpm/acme2certifier.spec - - - name: build RPM package - id: rpm - uses: grindsa/rpmbuild@alma9 - with: - spec_file: "examples/install_scripts/rpm/acme2certifier.spec" - - - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" - - - name: "[ PREPARE ] setup environment for alma installation" - run: | - docker network create acme - sudo mkdir -p data - sudo chmod -R 777 data - sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data - sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data - - - name: "[ PREPARE ] create letsencrypt and lego folder" - run: | - mkdir certbot - mkdir lego + sudo rm -rf acme-sh/* + # docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' --useragent template_name=template -d acme-sh.acme --standalone --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature, Non Repudiation" + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Server Authentication, Code Signing" - - name: "Retrieve rpms from SBOM repo" + - name: "02 - Enroll lego with template_name template" run: | - git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom - cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data - env: - GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} - GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent template_name=template -d lego.acme --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext keyUsage | grep "Digital Signature, Non Repudiation" + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Server Authentication, Code Signing" - - name: "[ PREPARE ] prepare acme_srv.cfg with xca_ca_handler" + - name: "Setup a2c with xca_ca_handler - profiling" run: | mkdir -p data/acme_ca sudo cp test/ca/acme2certifier-clean.xdb data/acme_ca/$XCA_DB_NAME @@ -444,70 +481,180 @@ jobs: sudo echo "passphrase: $XCA_PASSPHRASE" >> data/acme_srv.cfg sudo echo "ca_cert_chain_list: [\"root-ca\"]" >> data/acme_srv.cfg sudo echo "template_name: $XCA_TEMPLATE" >> data/acme_srv.cfg + sudo echo "eab_profiling: True" >> data/acme_srv.cfg + sudo sed -i "s/tnauthlist_support: False/tnauthlist_support: False\nheader_info_list: [\"HTTP_USER_AGENT\"]/g" data/acme_srv.cfg + sudo echo -e "\n\n[EABhandler]" >> data/acme_srv.cfg + sudo echo "eab_handler_file: /opt/acme2certifier/examples/eab_handler/kid_profile_handler.py" >> data/acme_srv.cfg + sudo echo "key_file: /opt/acme2certifier/volume/acme_ca/kid_profiles.json" >> data/acme_srv.cfg + sudo cp examples/eab_handler/kid_profiles.json data/acme_ca/kid_profiles.json + sudo chmod 777 data/acme_ca/kid_profiles.json + sudo sed -i "s/\"profile_id\"\: \[\"profile_1\", \"profile_2\", \"profile_3\"\]/\"template_name\"\: \[\"template\", \"acme\"\]/g" data/acme_ca/kid_profiles.json + sudo sed -i "s/\"profile_id\"\: \"profile_2\"/\"template_name\"\: \"template\"/g" data/acme_ca/kid_profiles.json + sudo sed -i "s/\"ca_name\": \"example_ca_2\",/\"issuing_ca_name\": \"root-ca\",\n \"issuing_ca_key\": \"root-ca\"/g" data/acme_ca/kid_profiles.json + sudo sed -i "s/\"ca_name\": \"example_ca\",/\"unknown_key\": \"unknown_value\"/g" data/acme_ca/kid_profiles.json + sudo sed -i "s/example.net/acme/g" data/acme_ca/kid_profiles.json + sudo sed -i '19,20d' data/acme_ca/kid_profiles.json + sudo sed -i '8,9d' data/acme_ca/kid_profiles.json env: XCA_PASSPHRASE: ${{ secrets.XCA_PASSPHRASE }} XCA_ISSUING_CA: ${{ secrets.XCA_ISSUING_CA }} XCA_TEMPLATE: ${{ secrets.XCA_TEMPLATE }} XCA_DB_NAME: ${{ secrets.XCA_DB_NAME }} - - name: "[ PREPARE ] Almalinux instance" + - name: "Reconfigure a2c " run: | - sudo cp examples/Docker/almalinux-systemd/Dockerfile data - sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile - cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache - docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd + docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart - - name: "[ RUN ] Execute install scipt" - run: | - docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh + - name: "Sleep for 5s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 5s - - name: "Test http://acme-srv/directory is accessible" + - name: "Test http://acme-srv/directory is accessable " run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" + - name: "01 - Enroll acme with a template_name taken from list in kid.json" run: | - sudo mkdir acme-sh - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_00 --eab-hmac-key V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature, Non Repudiation" + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Server Authentication, Code Signing" - - name: "[ ENROLL ] acme.sh" + - name: "01 - Enroll lego with a template_name taken from list in kid.json" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force - openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw -d lego.acme --http run + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -issuer --noout + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext keyUsage | grep "Digital Signature, Non Repudiation" + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Server Authentication, Code Signing" + + - name: "02a - Enroll acme with a template_name taken from header_info NOT included in kid.json (to fail)" + id: acmefail01 + continue-on-error: true + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_00 --eab-hmac-key V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --useragent template_name=unknown -d acme-sh.acme --standalone --debug 3 --output-insecure + + - name: "02a - check result " + if: steps.acmefail01.outcome != 'failure' + run: | + echo "acmefail outcome is ${{steps.acmefail01.outcome }}" + exit 1 + + - name: "02b - Enroll acme with a template_name taken from header_info included in kid.json" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_00 --eab-hmac-key V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --useragent template_name=acme -d acme-sh.acme --standalone --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout - openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" - openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout | grep "TLS Web Server Authentication, TLS Web Client Authentication" + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Server Authentication, TLS Web Client Authentication" - - name: "revoke via acme.sh" + - name: "02a - Enroll lego with a template_name taken from header_info NOT included in kid.json (to fail)" + id: legofail01 + continue-on-error: true run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --user-agent template_name=unknown -d lego.acme --http run - - name: "[ REGISTER] certbot" + - name: "02a - check result " + if: steps.legofail01.outcome != 'failure' run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email + echo "legofail outcome is ${{steps.legofail01.outcome }}" + exit 1 - - name: "[ ENROLL ] HTTP-01 single domain certbot" + - name: "02b - Enroll lego with a template_name taken from header_info included in kid.json" run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - sudo openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem - sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout - sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" - sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "TLS Web Server Authentication, TLS Web Client Authentication" + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --user-agent template_name=acme -d lego.acme --http run + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -issuer --noout + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext keyUsage | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Server Authentication, TLS Web Client Authentication" - - name: "revoke HTTP-01 single domain certbot" + - name: "03 - Enroll acme with a template_name/ca_name taken from kid.json" run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_01 --eab-hmac-key YW5vdXRoZXJfdmVyeV9sb25nX2htYWNfZm9yX2tleWlkXzAxX3doaWNoIHdpbGxfYmUgdXNlZF9kdXJpbmcgcmVncmVzc2lvbg --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature, Non Repudiation" + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Server Authentication, Code Signing" - - name: "[ ENROLL ] lego" + - name: "03 - Enroll lego with a template_name/ca_name taken from kid.json" run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - sudo openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_01 --hmac YW5vdXRoZXJfdmVyeV9sb25nX2htYWNfZm9yX2tleWlkXzAxX3doaWNoIHdpbGxfYmUgdXNlZF9kdXJpbmcgcmVncmVzc2lvbg -d lego.acme --http run + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -issuer --noout + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout - sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" - sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout | grep "TLS Web Server Authentication, TLS Web Client Authentication" + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext keyUsage | grep "Digital Signature, Non Repudiation" + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Server Authentication, Code Signing" + + - name: "04 - Enroll acme with a not allowed fqdn in kid.json (to fail)" + id: acmefail02 + continue-on-error: true + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure + + - name: "04 - check result " + if: steps.acmefail02.outcome != 'failure' + run: | + echo "acmefail outcome is ${{steps.acmefail02.outcome }}" + exit 1 - - name: "revoke HTTP-01 single domain lego" + - name: "04 - Enroll lego with a not allowed fqdn in kid.json (to fail)" + id: legofail02 + continue-on-error: true run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM -d lego.acme --http run + + - name: "04a - check result " + if: steps.legofail02.outcome != 'failure' + run: | + echo "legofail outcome is ${{steps.legofail02.outcome }}" + exit 1 + + - name: "05 - Enroll acme with default values from acme.cfg" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_03 --eab-hmac-key YW5kX2ZpbmFsbHlfdGhlX2xhc3RfaG1hY19rZXlfd2hpY2hfaXNfbG9uZ2VyX3RoYW5fMjU2X2JpdHNfYW5kX3Nob3VsZF93b3Jr --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Server Authentication, TLS Web Client Authentication" + + - name: "05 - Enroll lego with default values from acme.cfg" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_03 --hmac YW5kX2ZpbmFsbHlfdGhlX2xhc3RfaG1hY19rZXlfd2hpY2hfaXNfbG9uZ2VyX3RoYW5fMjU2X2JpdHNfYW5kX3Nob3VsZF93b3Jr -d lego.acme --http run + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -issuer --noout + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext keyUsage | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Server Authentication, TLS Web Client Authentication" + - name: "[ * ] collecting test logs" if: ${{ failure() }} @@ -526,5 +673,5 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: xca_handler_tmpl_tests_rpm-rh${{ matrix.rhversion }}.tar.gz + name: xca_handler_tests_profiling_rpm-rh${{ matrix.rhversion }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ diff --git a/examples/ca_handler/xca_ca_handler.py b/examples/ca_handler/xca_ca_handler.py index 84756083..7d557065 100644 --- a/examples/ca_handler/xca_ca_handler.py +++ b/examples/ca_handler/xca_ca_handler.py @@ -980,15 +980,14 @@ def _profile_check(self, csr: str) -> str: if self.eab_handler: error = self._eab_profile_check(csr, handler_hifield) # we need to cover cases where handler_value is enabled but nothing is defined in json - elif self.header_info_field: - # no profiling - parse profileid from http_header - hil_value = header_info_lookup(self.logger, csr, self.header_info_field, handler_hifield) - if hil_value: - self.logger.debug('CAhandler._profile_check(): setting %s to %s', handler_hifield, hil_value) - # self.template_name = hil_value - setattr(self, handler_hifield, hil_value) else: self.logger.error('CAhandler._profile_check(): eab_profiling enabled but no handler defined') + elif self.header_info_field: + # no profiling - parse profileid from http_header + hil_value = header_info_lookup(self.logger, csr, self.header_info_field, handler_hifield) + if hil_value: + self.logger.debug('CAhandler._profile_check(): setting %s to %s', handler_hifield, hil_value) + setattr(self, handler_hifield, hil_value) self.logger.debug('CAhandler._profile_check() ended with %s', error) return error diff --git a/examples/eab_handler/kid_profiles.json b/examples/eab_handler/kid_profiles.json index f44d5c40..f2fff84f 100644 --- a/examples/eab_handler/kid_profiles.json +++ b/examples/eab_handler/kid_profiles.json @@ -3,7 +3,7 @@ "hmac": "V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw", "cahandler": { "profile_id": ["profile_1", "profile_2", "profile_3"], - "allowed_domains": ["www.example.com", "www.example.org", "*.example.fi"], + "allowed_domainlist": ["www.example.com", "www.example.org", "*.example.net"], "ca_name": "example_ca", "api_user": "api_user", "api_password": "api_password" @@ -13,14 +13,17 @@ "hmac": "YW5vdXRoZXJfdmVyeV9sb25nX2htYWNfZm9yX2tleWlkXzAxX3doaWNoIHdpbGxfYmUgdXNlZF9kdXJpbmcgcmVncmVzc2lvbg", "cahandler": { "profile_id": "profile_2", - "allowed_domains": ["*.example.fi"], + "allowed_domainlist": ["www.example.com", "www.example.org", "*.example.net"], "ca_name": "example_ca_2", "api_user": "api_user_2", "api_password": "api_password_2" } }, "keyid_02": { - "hmac": "dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM" + "hmac": "dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM", + "cahandler": { + "allowed_domainlist": ["www.example.com", "www.example.org"] + } }, "keyid_03": { "hmac": "YW5kX2ZpbmFsbHlfdGhlX2xhc3RfaG1hY19rZXlfd2hpY2hfaXNfbG9uZ2VyX3RoYW5fMjU2X2JpdHNfYW5kX3Nob3VsZF93b3Jr" diff --git a/test/test_xca_ca_handler.py b/test/test_xca_ca_handler.py index 4c3db17b..cc0b3bbd 100644 --- a/test/test_xca_ca_handler.py +++ b/test/test_xca_ca_handler.py @@ -1263,7 +1263,7 @@ def test_165__cert_subject_generate(self, mock_submod, mock_name): @patch('cryptography.x509.Name') @patch('examples.ca_handler.xca_ca_handler.CAhandler._subject_modify') - def test_165__cert_subject_generate(self, mock_submod, mock_name): + def test_166__cert_subject_generate(self, mock_submod, mock_name): """ _cert_subject_generate() """ req = Mock() req.subject = None @@ -1280,7 +1280,7 @@ def test_165__cert_subject_generate(self, mock_submod, mock_name): @patch('examples.ca_handler.xca_ca_handler.SubjectKeyIdentifier') @patch('examples.ca_handler.xca_ca_handler.KeyUsage') @patch('examples.ca_handler.xca_ca_handler.BasicConstraints') - def test_166__extension_list_default(self, mock_bc, mock_ku, mock_ski, mock_aki, mock_eku): + def test_167__extension_list_default(self, mock_bc, mock_ku, mock_ski, mock_aki, mock_eku): """ _extension_list_default() """ cert = Mock() mock_bc.return_value = 'mock_bc' @@ -1296,7 +1296,7 @@ def test_166__extension_list_default(self, mock_bc, mock_ku, mock_ski, mock_aki, @patch('examples.ca_handler.xca_ca_handler.SubjectKeyIdentifier') @patch('examples.ca_handler.xca_ca_handler.KeyUsage') @patch('examples.ca_handler.xca_ca_handler.BasicConstraints') - def test_167__extension_list_default(self, mock_bc, mock_ku, mock_ski, mock_aki, mock_eku): + def test_168__extension_list_default(self, mock_bc, mock_ku, mock_ski, mock_aki, mock_eku): """ _extension_list_default() """ cert = Mock() mock_bc.return_value = 'mock_bc' @@ -1312,7 +1312,7 @@ def test_167__extension_list_default(self, mock_bc, mock_ku, mock_ski, mock_aki, @patch('examples.ca_handler.xca_ca_handler.SubjectKeyIdentifier') @patch('examples.ca_handler.xca_ca_handler.KeyUsage') @patch('examples.ca_handler.xca_ca_handler.BasicConstraints') - def test_168__extension_list_default(self, mock_bc, mock_ku, mock_ski, mock_aki, mock_eku): + def test_169__extension_list_default(self, mock_bc, mock_ku, mock_ski, mock_aki, mock_eku): """ _extension_list_default() """ cert = Mock() mock_bc.return_value = 'mock_bc' @@ -1326,7 +1326,7 @@ def test_168__extension_list_default(self, mock_bc, mock_ku, mock_ski, mock_aki, @patch('examples.ca_handler.xca_ca_handler.convert_byte_to_string') @patch('examples.ca_handler.xca_ca_handler.CAhandler._extension_list_default') @patch('examples.ca_handler.xca_ca_handler.CAhandler._xca_template_process') - def test_169__extension_list_generate(self, mock_template, mock_extlist, mock_convert): + def test_170__extension_list_generate(self, mock_template, mock_extlist, mock_convert): """ _extension_list_generate() """ cert = Mock() mock_extlist.return_value = 'mock_extlist' @@ -1342,7 +1342,7 @@ def test_169__extension_list_generate(self, mock_template, mock_extlist, mock_co @patch('examples.ca_handler.xca_ca_handler.convert_byte_to_string') @patch('examples.ca_handler.xca_ca_handler.CAhandler._extension_list_default') @patch('examples.ca_handler.xca_ca_handler.CAhandler._xca_template_process') - def test_170__extension_list_generate(self, mock_template, mock_extlist, mock_convert): + def test_171__extension_list_generate(self, mock_template, mock_extlist, mock_convert): """ _extension_list_generate() """ cert = Mock() mock_extlist.return_value = 'mock_extlist' @@ -1359,7 +1359,7 @@ def test_170__extension_list_generate(self, mock_template, mock_extlist, mock_co @patch('examples.ca_handler.xca_ca_handler.convert_byte_to_string') @patch('examples.ca_handler.xca_ca_handler.CAhandler._extension_list_default') @patch('examples.ca_handler.xca_ca_handler.CAhandler._xca_template_process') - def test_171__extension_list_generate(self, mock_template, mock_extlist, mock_convert): + def test_172__extension_list_generate(self, mock_template, mock_extlist, mock_convert): """ _extension_list_generate() """ cert = Mock() mock_extlist.return_value = 'mock_extlist' @@ -1377,7 +1377,7 @@ def test_171__extension_list_generate(self, mock_template, mock_extlist, mock_co @patch('examples.ca_handler.xca_ca_handler.convert_byte_to_string') @patch('examples.ca_handler.xca_ca_handler.CAhandler._extension_list_default') @patch('examples.ca_handler.xca_ca_handler.CAhandler._xca_template_process') - def test_172__extension_list_generate(self, mock_template, mock_extlist, mock_convert, mock_san): + def test_173__extension_list_generate(self, mock_template, mock_extlist, mock_convert, mock_san): """ _extension_list_generate() """ cert = Mock() mock_extlist.return_value = ['mock_extlist'] @@ -1393,7 +1393,7 @@ def test_172__extension_list_generate(self, mock_template, mock_extlist, mock_co self.assertTrue(mock_convert.called) @patch('OpenSSL.crypto.X509.from_cryptography') - def test_173__subject_name_hash_get(self, mock_x509): + def test_174__subject_name_hash_get(self, mock_x509): """ _subject_name_hash_get() """ # mock_x509 = Mock() obj = Mock() @@ -1402,7 +1402,7 @@ def test_173__subject_name_hash_get(self, mock_x509): self.assertEqual(73429447, self.cahandler._subject_name_hash_get('cert')) @patch('OpenSSL.crypto.X509.from_cryptography') - def test_172__subject_name_hash_get(self, mock_x509): + def test_175__subject_name_hash_get(self, mock_x509): """ _subject_name_hash_get() """ # mock_x509 = Mock() obj = Mock() @@ -1412,7 +1412,7 @@ def test_172__subject_name_hash_get(self, mock_x509): @patch('examples.ca_handler.xca_ca_handler.x509.Name') @patch('examples.ca_handler.xca_ca_handler.x509.NameAttribute') - def test_173__subject_modify(self, mock_addr, mock_name): + def test_176__subject_modify(self, mock_addr, mock_name): """ _subject_modify() """ mock_name.return_value = 'mock_name' mock_addr.return_value = 'mock_addr' @@ -1423,7 +1423,7 @@ def test_173__subject_modify(self, mock_addr, mock_name): @patch('examples.ca_handler.xca_ca_handler.x509.Name') @patch('examples.ca_handler.xca_ca_handler.x509.NameAttribute') - def test_174__subject_modify(self, mock_addr, mock_name): + def test_177__subject_modify(self, mock_addr, mock_name): """ _subject_modify() """ mock_name.return_value = 'mock_name' mock_addr.return_value = 'mock_addr' @@ -1434,7 +1434,7 @@ def test_174__subject_modify(self, mock_addr, mock_name): @patch('examples.ca_handler.xca_ca_handler.x509.Name') @patch('examples.ca_handler.xca_ca_handler.x509.NameAttribute') - def test_175__subject_modify(self, mock_addr, mock_name): + def test_178__subject_modify(self, mock_addr, mock_name): """ _subject_modify() """ mock_name.return_value = 'mock_name' mock_addr.return_value = 'mock_addr' @@ -1445,7 +1445,7 @@ def test_175__subject_modify(self, mock_addr, mock_name): @patch('examples.ca_handler.xca_ca_handler.x509.Name') @patch('examples.ca_handler.xca_ca_handler.x509.NameAttribute') - def test_176__subject_modify(self, mock_addr, mock_name): + def test_179__subject_modify(self, mock_addr, mock_name): """ _subject_modify() """ mock_name.return_value = 'mock_name' mock_addr.return_value = 'mock_addr' @@ -1456,7 +1456,7 @@ def test_176__subject_modify(self, mock_addr, mock_name): @patch('examples.ca_handler.xca_ca_handler.x509.Name') @patch('examples.ca_handler.xca_ca_handler.x509.NameAttribute') - def test_177__subject_modify(self, mock_addr, mock_name): + def test_180__subject_modify(self, mock_addr, mock_name): """ _subject_modify() """ mock_name.return_value = 'mock_name' mock_addr.return_value = 'mock_addr' @@ -1473,7 +1473,7 @@ def test_177__subject_modify(self, mock_addr, mock_name): @patch('examples.ca_handler.xca_ca_handler.CAhandler._csr_import') @patch('examples.ca_handler.xca_ca_handler.CAhandler._requestname_get') @patch('examples.ca_handler.xca_ca_handler.CAhandler._config_check') - def test_179_enroll(self, mock_chk, mock_reqname, mock_csr, mock_b64, mock_build, mock_ca, mock_sign, mock_prof): + def test_181_enroll(self, mock_chk, mock_reqname, mock_csr, mock_b64, mock_build, mock_ca, mock_sign, mock_prof): """ test enroll() """ mock_chk.return_value = 'error' mock_prof.return_value = None @@ -1495,7 +1495,7 @@ def test_179_enroll(self, mock_chk, mock_reqname, mock_csr, mock_b64, mock_build @patch('examples.ca_handler.xca_ca_handler.CAhandler._csr_import') @patch('examples.ca_handler.xca_ca_handler.CAhandler._requestname_get') @patch('examples.ca_handler.xca_ca_handler.CAhandler._config_check') - def test_180_enroll(self, mock_chk, mock_reqname, mock_csr, mock_b64, mock_build, mock_ca, mock_sign, mock_prof): + def test_182_enroll(self, mock_chk, mock_reqname, mock_csr, mock_b64, mock_build, mock_ca, mock_sign, mock_prof): """ test enroll() """ mock_chk.return_value = 'error' mock_prof.return_value = None @@ -1517,7 +1517,7 @@ def test_180_enroll(self, mock_chk, mock_reqname, mock_csr, mock_b64, mock_build @patch('examples.ca_handler.xca_ca_handler.CAhandler._csr_import') @patch('examples.ca_handler.xca_ca_handler.CAhandler._requestname_get') @patch('examples.ca_handler.xca_ca_handler.CAhandler._config_check') - def test_181_enroll(self, mock_chk, mock_reqname, mock_csr, mock_b64, mock_build, mock_ca, mock_sign, mock_prof): + def test_183_enroll(self, mock_chk, mock_reqname, mock_csr, mock_b64, mock_build, mock_ca, mock_sign, mock_prof): """ test enroll() """ mock_chk.return_value = None mock_reqname.return_value = None @@ -1540,7 +1540,7 @@ def test_181_enroll(self, mock_chk, mock_reqname, mock_csr, mock_b64, mock_build @patch('examples.ca_handler.xca_ca_handler.CAhandler._csr_import') @patch('examples.ca_handler.xca_ca_handler.CAhandler._requestname_get') @patch('examples.ca_handler.xca_ca_handler.CAhandler._config_check') - def test_182_enroll(self, mock_chk, mock_reqname, mock_csr, mock_b64, mock_build, mock_ca, mock_sign, mock_prof): + def test_184_enroll(self, mock_chk, mock_reqname, mock_csr, mock_b64, mock_build, mock_ca, mock_sign, mock_prof): """ test enroll() """ mock_chk.return_value = None mock_reqname.return_value = 'request_name' @@ -1564,7 +1564,7 @@ def test_182_enroll(self, mock_chk, mock_reqname, mock_csr, mock_b64, mock_build @patch('examples.ca_handler.xca_ca_handler.CAhandler._csr_import') @patch('examples.ca_handler.xca_ca_handler.CAhandler._requestname_get') @patch('examples.ca_handler.xca_ca_handler.CAhandler._config_check') - def test_183_enroll(self, mock_chk, mock_reqname, mock_csr, mock_b64, mock_build, mock_ca, mock_sign, mock_prof): + def test_185_enroll(self, mock_chk, mock_reqname, mock_csr, mock_b64, mock_build, mock_ca, mock_sign, mock_prof): """ test enroll() """ mock_chk.return_value = None mock_reqname.return_value = 'request_name' @@ -1588,7 +1588,7 @@ def test_183_enroll(self, mock_chk, mock_reqname, mock_csr, mock_b64, mock_build @patch('examples.ca_handler.xca_ca_handler.CAhandler._csr_import') @patch('examples.ca_handler.xca_ca_handler.CAhandler._requestname_get') @patch('examples.ca_handler.xca_ca_handler.CAhandler._config_check') - def test_184_enroll(self, mock_chk, mock_reqname, mock_csr, mock_b64, mock_build, mock_ca, mock_sign, mock_prof): + def test_186_enroll(self, mock_chk, mock_reqname, mock_csr, mock_b64, mock_build, mock_ca, mock_sign, mock_prof): """ test enroll() """ mock_chk.return_value = None mock_reqname.return_value = 'request_name' @@ -1612,7 +1612,7 @@ def test_184_enroll(self, mock_chk, mock_reqname, mock_csr, mock_b64, mock_build @patch('examples.ca_handler.xca_ca_handler.CAhandler._csr_import') @patch('examples.ca_handler.xca_ca_handler.CAhandler._requestname_get') @patch('examples.ca_handler.xca_ca_handler.CAhandler._config_check') - def test_185_enroll(self, mock_chk, mock_reqname, mock_csr, mock_b64, mock_build, mock_ca, mock_sign, mock_prof): + def test_187_enroll(self, mock_chk, mock_reqname, mock_csr, mock_b64, mock_build, mock_ca, mock_sign, mock_prof): """ test enroll() """ mock_chk.return_value = None mock_reqname.return_value = 'request_name' @@ -1637,7 +1637,7 @@ def test_185_enroll(self, mock_chk, mock_reqname, mock_csr, mock_b64, mock_build @patch('examples.ca_handler.xca_ca_handler.CAhandler._csr_import') @patch('examples.ca_handler.xca_ca_handler.CAhandler._requestname_get') @patch('examples.ca_handler.xca_ca_handler.CAhandler._config_check') - def test_186_enroll(self, mock_chk, mock_reqname, mock_csr, mock_b64, mock_build, mock_ca, mock_sign, mock_prof): + def test_188_enroll(self, mock_chk, mock_reqname, mock_csr, mock_b64, mock_build, mock_ca, mock_sign, mock_prof): """ test enroll() """ mock_chk.return_value = None mock_reqname.return_value = 'request_name' @@ -1664,7 +1664,7 @@ def test_186_enroll(self, mock_chk, mock_reqname, mock_csr, mock_b64, mock_build @patch('examples.ca_handler.xca_ca_handler.x509.load_pem_x509_csr') @patch('examples.ca_handler.xca_ca_handler.convert_string_to_byte') @patch('examples.ca_handler.xca_ca_handler.CAhandler._template_load') - def test_186_cert_sign(self, mock_teml_load, mock_str2byte, mock_load, mock_extlist, mock_hash, mock_store, mock_chain, mock_cvt, mock_b64, mock_builder): + def test_189_cert_sign(self, mock_teml_load, mock_str2byte, mock_load, mock_extlist, mock_hash, mock_store, mock_chain, mock_cvt, mock_b64, mock_builder): """ test cert sign """ ca_cert = Mock() ca_cert.subject = 'subject' @@ -1694,7 +1694,7 @@ def test_186_cert_sign(self, mock_teml_load, mock_str2byte, mock_load, mock_extl @patch('examples.ca_handler.xca_ca_handler.x509.load_pem_x509_csr') @patch('examples.ca_handler.xca_ca_handler.convert_string_to_byte') @patch('examples.ca_handler.xca_ca_handler.CAhandler._template_load') - def test_187_cert_sign(self, mock_teml_load, mock_str2byte, mock_load, mock_extlist, mock_hash, mock_store, mock_chain, mock_cvt, mock_b64, mock_builder): + def test_190_cert_sign(self, mock_teml_load, mock_str2byte, mock_load, mock_extlist, mock_hash, mock_store, mock_chain, mock_cvt, mock_b64, mock_builder): """ test cert sign """ ca_cert = Mock() ca_cert.subject = 'subject' @@ -1726,7 +1726,7 @@ def test_187_cert_sign(self, mock_teml_load, mock_str2byte, mock_load, mock_extl @patch('examples.ca_handler.xca_ca_handler.x509.load_pem_x509_csr') @patch('examples.ca_handler.xca_ca_handler.convert_string_to_byte') @patch('examples.ca_handler.xca_ca_handler.CAhandler._template_load') - def test_187_cert_sign(self, mock_teml_load, mock_str2byte, mock_load, mock_extlist, mock_hash, mock_store, mock_chain, mock_cvt, mock_b64, mock_builder): + def test_191_cert_sign(self, mock_teml_load, mock_str2byte, mock_load, mock_extlist, mock_hash, mock_store, mock_chain, mock_cvt, mock_b64, mock_builder): """ test cert sign """ ca_cert = Mock() ca_cert.subject = 'subject' @@ -1757,7 +1757,7 @@ def test_187_cert_sign(self, mock_teml_load, mock_str2byte, mock_load, mock_extl @patch('examples.ca_handler.xca_ca_handler.KeyUsage') @patch('examples.ca_handler.xca_ca_handler.AuthorityKeyIdentifier') @patch('examples.ca_handler.xca_ca_handler.SubjectKeyIdentifier') - def test_188_xca_template_process(self, mock_ski, mock_aki, mock_ku, mock_eku, mock_crl, mock_bc, mock_kug, mock_cdp, mock_ekug): + def test_192_xca_template_process(self, mock_ski, mock_aki, mock_ku, mock_eku, mock_crl, mock_bc, mock_kug, mock_cdp, mock_ekug): """ test _xca_template_process() """ csr_extensions_dic = {} template_dic = {'foo': 'bar'} @@ -1789,7 +1789,7 @@ def test_188_xca_template_process(self, mock_ski, mock_aki, mock_ku, mock_eku, m @patch('examples.ca_handler.xca_ca_handler.KeyUsage') @patch('examples.ca_handler.xca_ca_handler.AuthorityKeyIdentifier') @patch('examples.ca_handler.xca_ca_handler.SubjectKeyIdentifier') - def test_189_xca_template_process(self, mock_ski, mock_aki, mock_ku, mock_eku, mock_crl, mock_bc, mock_kug, mock_cdp, mock_ekug): + def test_193_xca_template_process(self, mock_ski, mock_aki, mock_ku, mock_eku, mock_crl, mock_bc, mock_kug, mock_cdp, mock_ekug): """ test _xca_template_process() """ csr_extensions_dic = {} template_dic = {'foo': 'bar'} @@ -1821,7 +1821,7 @@ def test_189_xca_template_process(self, mock_ski, mock_aki, mock_ku, mock_eku, m @patch('examples.ca_handler.xca_ca_handler.KeyUsage') @patch('examples.ca_handler.xca_ca_handler.AuthorityKeyIdentifier') @patch('examples.ca_handler.xca_ca_handler.SubjectKeyIdentifier') - def test_190_xca_template_process(self, mock_ski, mock_aki, mock_ku, mock_eku, mock_crl, mock_bc, mock_kug, mock_cdp, mock_ekug): + def test_194_xca_template_process(self, mock_ski, mock_aki, mock_ku, mock_eku, mock_crl, mock_bc, mock_kug, mock_cdp, mock_ekug): """ test _xca_template_process() """ csr_extensions_dic = {} template_dic = {'crlDist': 'crlDist'} @@ -1854,7 +1854,7 @@ def test_190_xca_template_process(self, mock_ski, mock_aki, mock_ku, mock_eku, m @patch('examples.ca_handler.xca_ca_handler.KeyUsage') @patch('examples.ca_handler.xca_ca_handler.AuthorityKeyIdentifier') @patch('examples.ca_handler.xca_ca_handler.SubjectKeyIdentifier') - def test_191_xca_template_process(self, mock_ski, mock_aki, mock_ku, mock_eku, mock_crl, mock_bc, mock_kug, mock_cdp, mock_ekug): + def test_195_xca_template_process(self, mock_ski, mock_aki, mock_ku, mock_eku, mock_crl, mock_bc, mock_kug, mock_cdp, mock_ekug): """ test _xca_template_process() """ csr_extensions_dic = {} template_dic = {'ca': '1', 'bcCritical': True} @@ -1887,7 +1887,7 @@ def test_191_xca_template_process(self, mock_ski, mock_aki, mock_ku, mock_eku, m @patch('examples.ca_handler.xca_ca_handler.KeyUsage') @patch('examples.ca_handler.xca_ca_handler.AuthorityKeyIdentifier') @patch('examples.ca_handler.xca_ca_handler.SubjectKeyIdentifier') - def test_192_xca_template_process(self, mock_ski, mock_aki, mock_ku, mock_eku, mock_crl, mock_bc, mock_kug, mock_cdp, mock_ekug): + def test_196_xca_template_process(self, mock_ski, mock_aki, mock_ku, mock_eku, mock_crl, mock_bc, mock_kug, mock_cdp, mock_ekug): """ test _xca_template_process() """ csr_extensions_dic = {} template_dic = {'ca': '1', 'bcCritical': False} @@ -1920,7 +1920,7 @@ def test_192_xca_template_process(self, mock_ski, mock_aki, mock_ku, mock_eku, m @patch('examples.ca_handler.xca_ca_handler.KeyUsage') @patch('examples.ca_handler.xca_ca_handler.AuthorityKeyIdentifier') @patch('examples.ca_handler.xca_ca_handler.SubjectKeyIdentifier') - def test_193_xca_template_process(self, mock_ski, mock_aki, mock_ku, mock_eku, mock_crl, mock_bc, mock_kug, mock_cdp, mock_ekug): + def test_197_xca_template_process(self, mock_ski, mock_aki, mock_ku, mock_eku, mock_crl, mock_bc, mock_kug, mock_cdp, mock_ekug): """ test _xca_template_process() """ csr_extensions_dic = {} template_dic = {'ca': '1', 'bcCritical': 'aa'} @@ -1953,7 +1953,7 @@ def test_193_xca_template_process(self, mock_ski, mock_aki, mock_ku, mock_eku, m @patch('examples.ca_handler.xca_ca_handler.KeyUsage') @patch('examples.ca_handler.xca_ca_handler.AuthorityKeyIdentifier') @patch('examples.ca_handler.xca_ca_handler.SubjectKeyIdentifier') - def test_194_xca_template_process(self, mock_ski, mock_aki, mock_ku, mock_eku, mock_crl, mock_bc, mock_kug, mock_cdp, mock_ekug): + def test_198_xca_template_process(self, mock_ski, mock_aki, mock_ku, mock_eku, mock_crl, mock_bc, mock_kug, mock_cdp, mock_ekug): """ test _xca_template_process() """ csr_extensions_dic = {} template_dic = {'ca': '2', 'bcCritical': 'aa'} @@ -1986,7 +1986,7 @@ def test_194_xca_template_process(self, mock_ski, mock_aki, mock_ku, mock_eku, m @patch('examples.ca_handler.xca_ca_handler.KeyUsage') @patch('examples.ca_handler.xca_ca_handler.AuthorityKeyIdentifier') @patch('examples.ca_handler.xca_ca_handler.SubjectKeyIdentifier') - def test_195_xca_template_process(self, mock_ski, mock_aki, mock_ku, mock_eku, mock_crl, mock_bc, mock_kug, mock_cdp, mock_ekug): + def test_199_xca_template_process(self, mock_ski, mock_aki, mock_ku, mock_eku, mock_crl, mock_bc, mock_kug, mock_cdp, mock_ekug): """ test _xca_template_process() """ csr_extensions_dic = {} template_dic = {'ca': '1'} @@ -2012,7 +2012,7 @@ def test_195_xca_template_process(self, mock_ski, mock_aki, mock_ku, mock_eku, m @patch('examples.ca_handler.xca_ca_handler.header_info_lookup') @patch('examples.ca_handler.xca_ca_handler.CAhandler._eab_profile_check') - def test_112__profile_check(self, mock_eab, mock_hil): + def test_200__profile_check(self, mock_eab, mock_hil): """ test eab_profile_string_check """ self.assertFalse(self.cahandler._profile_check('csr')) self.assertFalse(mock_eab.called) @@ -2020,7 +2020,7 @@ def test_112__profile_check(self, mock_eab, mock_hil): @patch('examples.ca_handler.xca_ca_handler.header_info_lookup') @patch('examples.ca_handler.xca_ca_handler.CAhandler._eab_profile_check') - def test_113__profile_check(self, mock_eab, mock_hil): + def test_201__profile_check(self, mock_eab, mock_hil): """ test eab_profile_string_check """ self.cahandler.eab_profiling = False self.assertFalse(self.cahandler._profile_check('csr')) @@ -2029,7 +2029,7 @@ def test_113__profile_check(self, mock_eab, mock_hil): @patch('examples.ca_handler.xca_ca_handler.header_info_lookup') @patch('examples.ca_handler.xca_ca_handler.CAhandler._eab_profile_check') - def test_114__profile_check(self, mock_eab, mock_hil): + def test_202__profile_check(self, mock_eab, mock_hil): """ test eab_profile_string_check """ self.cahandler.eab_profiling = True with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -2040,7 +2040,7 @@ def test_114__profile_check(self, mock_eab, mock_hil): @patch('examples.ca_handler.xca_ca_handler.header_info_lookup') @patch('examples.ca_handler.xca_ca_handler.CAhandler._eab_profile_check') - def test_115__profile_check(self, mock_eab, mock_hil): + def test_203__profile_check(self, mock_eab, mock_hil): """ test eab_profile_string_check """ self.cahandler.eab_profiling = True self.cahandler.eab_handler = MagicMock() @@ -2051,7 +2051,7 @@ def test_115__profile_check(self, mock_eab, mock_hil): @patch('examples.ca_handler.xca_ca_handler.header_info_lookup') @patch('examples.ca_handler.xca_ca_handler.CAhandler._eab_profile_check') - def test_116__profile_check(self, mock_eab, mock_hil): + def test_204__profile_check(self, mock_eab, mock_hil): """ test eab_profile_string_check """ self.cahandler.eab_profiling = True self.cahandler.header_info_field = 'header_info_field' @@ -2063,9 +2063,9 @@ def test_116__profile_check(self, mock_eab, mock_hil): @patch('examples.ca_handler.xca_ca_handler.header_info_lookup') @patch('examples.ca_handler.xca_ca_handler.CAhandler._eab_profile_check') - def test_117__profile_check(self, mock_eab, mock_hil): + def test_205__profile_check(self, mock_eab, mock_hil): """ test eab_profile_string_check """ - self.cahandler.eab_profiling = True + self.cahandler.eab_profiling = False self.cahandler.eab_handler = None self.cahandler.header_info_field = 'template_name' self.cahandler.template_name = 'template_name' @@ -2077,9 +2077,9 @@ def test_117__profile_check(self, mock_eab, mock_hil): @patch('examples.ca_handler.xca_ca_handler.header_info_lookup') @patch('examples.ca_handler.xca_ca_handler.CAhandler._eab_profile_check') - def test_118__profile_check(self, mock_eab, mock_hil): + def test_206__profile_check(self, mock_eab, mock_hil): """ test eab_profile_string_check """ - self.cahandler.eab_profiling = True + self.cahandler.eab_profiling = False self.cahandler.eab_handler = None self.cahandler.header_info_field = 'template_name' self.cahandler.template_name = 'template_name' @@ -2090,7 +2090,7 @@ def test_118__profile_check(self, mock_eab, mock_hil): self.assertEqual('template_name', self.cahandler.template_name) @patch('examples.ca_handler.xca_ca_handler.header_info_field_validate') - def test_150__eab_profile_check(self, mock_hil): + def test_207__eab_profile_check(self, mock_hil): """ test eab_profile_check """ self.cahandler.eab_handler = MagicMock() self.cahandler.template_name = 'template_name' @@ -2108,7 +2108,7 @@ def test_150__eab_profile_check(self, mock_hil): self.assertFalse(mock_hil.called) @patch('examples.ca_handler.xca_ca_handler.header_info_field_validate') - def test_151__eab_profile_check(self, mock_hil): + def test_208__eab_profile_check(self, mock_hil): """ test eab_profile_check """ self.cahandler.eab_handler = MagicMock() self.cahandler.template_name = 'template_name' @@ -2126,7 +2126,7 @@ def test_151__eab_profile_check(self, mock_hil): self.assertFalse(mock_hil.called) @patch('examples.ca_handler.xca_ca_handler.header_info_field_validate') - def test_152__eab_profile_check(self, mock_hil): + def test_209__eab_profile_check(self, mock_hil): """ test eab_profile_check """ self.cahandler.eab_handler = MagicMock() self.cahandler.template_name = 'template_name' @@ -2145,7 +2145,7 @@ def test_152__eab_profile_check(self, mock_hil): self.assertTrue(mock_hil.called) @patch('examples.ca_handler.xca_ca_handler.header_info_field_validate') - def test_153__eab_profile_check(self, mock_hil): + def test_210__eab_profile_check(self, mock_hil): """ test eab_profile_check """ self.cahandler.eab_handler = MagicMock() self.cahandler.template_name = 'template_name' @@ -2164,7 +2164,7 @@ def test_153__eab_profile_check(self, mock_hil): self.assertTrue(mock_hil.called) @patch('examples.ca_handler.xca_ca_handler.header_info_field_validate') - def test_154__eab_profile_check(self, mock_hil): + def test_211__eab_profile_check(self, mock_hil): """ test eab_profile_check """ self.cahandler.eab_handler = MagicMock() self.cahandler.template_name = 'template_name' @@ -2182,7 +2182,7 @@ def test_154__eab_profile_check(self, mock_hil): self.assertFalse(mock_hil.called) @patch('examples.ca_handler.xca_ca_handler.header_info_field_validate') - def test_155__eab_profile_check(self, mock_hil): + def test_212__eab_profile_check(self, mock_hil): """ test eab_profile_check """ self.cahandler.eab_handler = MagicMock() self.cahandler.template_name = 'template_name' @@ -2201,7 +2201,7 @@ def test_155__eab_profile_check(self, mock_hil): self.assertFalse(mock_hil.called) @patch('examples.ca_handler.xca_ca_handler.header_info_field_validate') - def test_156__eab_profile_check(self, mock_hil): + def test_213__eab_profile_check(self, mock_hil): """ test eab_profile_check """ self.cahandler.eab_handler = MagicMock() self.cahandler.template_name = 'template_name' @@ -2223,7 +2223,7 @@ def test_156__eab_profile_check(self, mock_hil): @patch('examples.ca_handler.xca_ca_handler.header_info_lookup') @patch('examples.ca_handler.xca_ca_handler.header_info_field_validate') - def test_150__eab_profile_check(self, mock_hil, mock_lookup): + def test_214__eab_profile_check(self, mock_hil, mock_lookup): """ test eab_profile_check """ self.cahandler.eab_handler = MagicMock() self.cahandler.template_name = 'template_name' From 41937ee103d1eb01f0ed40375a61b97a301951af Mon Sep 17 00:00:00 2001 From: grindsa Date: Mon, 8 Apr 2024 07:00:30 +0200 Subject: [PATCH 162/460] [wf] extended XCA-workflow --- .github/workflows/ca_handler_tests_xca.yml | 336 ++++++++++++++++++++- 1 file changed, 325 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ca_handler_tests_xca.yml b/.github/workflows/ca_handler_tests_xca.yml index 8991a68d..ed41935d 100644 --- a/.github/workflows/ca_handler_tests_xca.yml +++ b/.github/workflows/ca_handler_tests_xca.yml @@ -9,8 +9,8 @@ on: - cron: '0 2 * * 6' jobs: - xca_handler_tests_profiling: - name: "xca_handler_tests_profiling" + xca_handler_tests: + name: "xca_handler_tests" runs-on: ubuntu-latest strategy: fail-fast: false @@ -38,8 +38,171 @@ jobs: - name: "Create acme-sh and lego folder" run: | mkdir acme-sh + mkdir certbot mkdir lego + - name: "Setup a2c with xca_ca_handler - no template" + run: | + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py + sudo mkdir -p examples/Docker/data/xca + sudo chmod -R 777 examples/Docker/data/xca + sudo cp test/ca/acme2certifier-clean.xdb examples/Docker/data/xca/$XCA_DB_NAME + sudo mkdir -p examples/Docker/data/acme_ca/certs + sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ + sudo touch examples/Docker/data/acme_srv.cfg + sudo chmod 777 examples/Docker/data/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg + sudo echo "handler_file: /var/www/acme2certifier/examples/ca_handler/xca_ca_handler.py" >> examples/Docker/data/acme_srv.cfg + sudo echo "xdb_file: volume/xca/$XCA_DB_NAME" >> examples/Docker/data/acme_srv.cfg + sudo echo "issuing_ca_name: $XCA_ISSUING_CA" >> examples/Docker/data/acme_srv.cfg + sudo echo "passphrase: $XCA_PASSPHRASE" >> examples/Docker/data/acme_srv.cfg + sudo echo "ca_cert_chain_list: [\"root-ca\"]" >> examples/Docker/data/acme_srv.cfg + # sudo echo "template_name: $XCA_TEMPLATE" >> examples/Docker/data/acme_srv.cfg + cd examples/Docker/ + docker-compose restart + docker-compose logs + env: + XCA_PASSPHRASE: ${{ secrets.XCA_PASSPHRASE }} + XCA_ISSUING_CA: ${{ secrets.XCA_ISSUING_CA }} + XCA_TEMPLATE: ${{ secrets.XCA_TEMPLATE }} + XCA_DB_NAME: ${{ secrets.XCA_DB_NAME }} + + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Test http://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "Acme.sh" + run: | + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure + openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout | grep "Basic Constraints: critical" + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout | grep "Digital Signature, Key Encipherment" + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout | grep "TLS Web Server Authentication" + + - name: "Revoke via acme.sh" + run: | + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure + + - name: "Register certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email + + - name: "Enroll certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot + sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem + sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout + sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "Basic Constraints: critical" + sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "Digital Signature, Key Encipherment" + sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "TLS Web Server Authentication" + + - name: "Revoke certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot + + - name: "Enroll lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout | grep "Basic Constraints: critical" + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout | grep "Digital Signature, Key Encipherment" + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout | grep "TLS Web Server Authentication" + + - name: "Revoke lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke + + - name: "Setup a2c with xca_ca_handler - with template" + run: | + sudo mkdir -p examples/Docker/data/xca + sudo chmod -R 777 examples/Docker/data/xca + sudo cp test/ca/acme2certifier-clean.xdb examples/Docker/data/xca/$XCA_DB_NAME + sudo mkdir -p examples/Docker/data/acme_ca/certs + sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem examples/Docker/data/acme_ca/ + sudo touch examples/Docker/data/acme_srv.cfg + sudo chmod 777 examples/Docker/data/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg + sudo echo "handler_file: /var/www/acme2certifier/examples/ca_handler/xca_ca_handler.py" >> examples/Docker/data/acme_srv.cfg + sudo echo "xdb_file: volume/xca/$XCA_DB_NAME" >> examples/Docker/data/acme_srv.cfg + sudo echo "issuing_ca_name: $XCA_ISSUING_CA" >> examples/Docker/data/acme_srv.cfg + sudo echo "passphrase: $XCA_PASSPHRASE" >> examples/Docker/data/acme_srv.cfg + sudo echo "ca_cert_chain_list: [\"root-ca\"]" >> examples/Docker/data/acme_srv.cfg + sudo echo "template_name: $XCA_TEMPLATE" >> examples/Docker/data/acme_srv.cfg + cd examples/Docker/ + docker-compose restart + docker-compose logs + env: + XCA_PASSPHRASE: ${{ secrets.XCA_PASSPHRASE }} + XCA_ISSUING_CA: ${{ secrets.XCA_ISSUING_CA }} + XCA_TEMPLATE: ${{ secrets.XCA_TEMPLATE }} + XCA_DB_NAME: ${{ secrets.XCA_DB_NAME }} + + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Test http://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "Enroll acme.sh" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure + openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout | grep "TLS Web Server Authentication, TLS Web Client Authentication" + + - name: "Revoke via acme.sh" + run: | + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --revoke --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure + + - name: "Register certbot" + run: | + sudo rm -rf certbot/* + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email + + - name: "Enroll certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot + sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem + sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout + sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" + sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "TLS Web Server Authentication, TLS Web Client Authentication" + + - name: "Revoke certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot + + - name: "Enroll lego" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout | grep "TLS Web Server Authentication, TLS Web Client Authentication" + + - name: "Revoke lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke + - name: "Setup a2c with xca_ca_handler - headerinfo-only" run: | sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem @@ -84,7 +247,6 @@ jobs: - name: "01 - Enroll acme.sh without template_name" run: | sudo rm -rf acme-sh/* - # docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --debug 3 docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' -d acme-sh.acme --standalone --debug 3 --output-insecure awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer @@ -334,7 +496,7 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: xca_handler_tests_profiling-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz + name: xca_handler-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ xca_handler_tests_profiling_rpm: @@ -379,6 +541,7 @@ jobs: run: | mkdir certbot mkdir lego + mkdir achme-sh - name: "Retrieve rpms from SBOM repo" run: | @@ -388,7 +551,7 @@ jobs: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} - - name: "Setup a2c with xca_ca_handler - headerinfo-only" + - name: "[ PREPARE ] prepare acme_srv.cfg with xca_ca_handler" run: | mkdir -p data/acme_ca sudo cp test/ca/acme2certifier-clean.xdb data/acme_ca/$XCA_DB_NAME @@ -402,30 +565,181 @@ jobs: sudo echo "issuing_ca_name: $XCA_ISSUING_CA" >> data/acme_srv.cfg sudo echo "passphrase: $XCA_PASSPHRASE" >> data/acme_srv.cfg sudo echo "ca_cert_chain_list: [\"root-ca\"]" >> data/acme_srv.cfg - sudo echo "template_name: $XCA_TEMPLATE" >> data/acme_srv.cfg - sudo sed -i "s/tnauthlist_support: False/tnauthlist_support: False\nheader_info_list: [\"HTTP_USER_AGENT\"]/g" data/acme_srv.cfg - sudo echo "eab_handler_file: /opt/acme2certifier/examples/eab_handler/kid_profile_handler.py" >> data/acme_srv.cfg - sudo echo "key_file: /opt/acme2certifier/volume/acme_ca/kid_profiles.json" >> data/acme_srv.cfg + # sudo echo "template_name: $XCA_TEMPLATE" >> data/acme_srv.cfg env: XCA_PASSPHRASE: ${{ secrets.XCA_PASSPHRASE }} XCA_ISSUING_CA: ${{ secrets.XCA_ISSUING_CA }} XCA_TEMPLATE: ${{ secrets.XCA_TEMPLATE }} XCA_DB_NAME: ${{ secrets.XCA_DB_NAME }} - - name: "Prepare Almalinux instance" + - name: "[ PREPARE ] Almalinux instance" run: | sudo cp examples/Docker/almalinux-systemd/Dockerfile data sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - - name: "Execute install scipt" + - name: "[ RUN ] Execute install scipt" run: | docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh - name: "Test http://acme-srv/directory is accessible" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + - name: "[ ENROLL ] acme.sh" + run: | + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure + openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout | grep "Basic Constraints: critical" + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout | grep "Digital Signature, Key Encipherment" + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout | grep "TLS Web Server Authentication" + + - name: "revoke via acme.sh" + run: | + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure + + - name: "[ REGISTER] certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email + + - name: "[ ENROLL ] HTTP-01 single domain certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot + sudo openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem + sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout + sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "Basic Constraints: critical" + sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "Digital Signature, Key Encipherment" + sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "TLS Web Server Authentication" + + - name: "revoke HTTP-01 single domain certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot + + - name: "[ ENROLL ] lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + sudo openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout | grep "Basic Constraints: critical" + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout | grep "Digital Signature, Key Encipherment" + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout | grep "TLS Web Server Authentication" + + - name: "revoke HTTP-01 single domain lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke + + - name: "[ PREPARE ] prepare acme_srv.cfg with xca_ca_handler" + run: | + mkdir -p data/acme_ca + sudo cp test/ca/acme2certifier-clean.xdb data/acme_ca/$XCA_DB_NAME + sudo mkdir -p examples/Docker/data/acme_ca/certs + sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem data/acme_ca/ + sudo touch data/acme_srv.cfg + sudo chmod 777 data/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/acme_srv.cfg + sudo echo "handler_file: /opt/acme2certifier/examples/ca_handler/xca_ca_handler.py" >> data/acme_srv.cfg + sudo echo "xdb_file: volume/acme_ca/$XCA_DB_NAME" >> data/acme_srv.cfg + sudo echo "issuing_ca_name: $XCA_ISSUING_CA" >> data/acme_srv.cfg + sudo echo "passphrase: $XCA_PASSPHRASE" >> data/acme_srv.cfg + sudo echo "ca_cert_chain_list: [\"root-ca\"]" >> data/acme_srv.cfg + sudo echo "template_name: $XCA_TEMPLATE" >> data/acme_srv.cfg + env: + XCA_PASSPHRASE: ${{ secrets.XCA_PASSPHRASE }} + XCA_ISSUING_CA: ${{ secrets.XCA_ISSUING_CA }} + XCA_TEMPLATE: ${{ secrets.XCA_TEMPLATE }} + XCA_DB_NAME: ${{ secrets.XCA_DB_NAME }} + + - name: "Reconfigure a2c " + run: | + docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart + + - name: "Sleep for 5s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 5s + + - name: "Test http://acme-srv/directory is accessable " + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "Enroll acme.sh" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure + openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout | grep "TLS Web Server Authentication, TLS Web Client Authentication" + + - name: "Revoke via acme.sh" + run: | + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --revoke --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure + + - name: "Register certbot" + run: | + sudo rm -rf certbot/* + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email + + - name: "Enroll HTTP-01 single domain certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot + sudo openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem + sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout + sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" + sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "TLS Web Server Authentication, TLS Web Client Authentication" + + - name: "Revoke HTTP-01 single domain certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot + + - name: "Enroll lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + sudo openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout | grep "TLS Web Server Authentication, TLS Web Client Authentication" + + - name: "Revoke HTTP-01 single domain lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke + + - name: "Setup a2c with xca_ca_handler - headerinfo-only" + run: | + mkdir -p data/acme_ca + sudo cp test/ca/acme2certifier-clean.xdb data/acme_ca/$XCA_DB_NAME + sudo mkdir -p examples/Docker/data/acme_ca/certs + sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem data/acme_ca/ + sudo touch data/acme_srv.cfg + sudo chmod 777 data/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/acme_srv.cfg + sudo echo "handler_file: /opt/acme2certifier/examples/ca_handler/xca_ca_handler.py" >> data/acme_srv.cfg + sudo echo "xdb_file: volume/acme_ca/$XCA_DB_NAME" >> data/acme_srv.cfg + sudo echo "issuing_ca_name: $XCA_ISSUING_CA" >> data/acme_srv.cfg + sudo echo "passphrase: $XCA_PASSPHRASE" >> data/acme_srv.cfg + sudo echo "ca_cert_chain_list: [\"root-ca\"]" >> data/acme_srv.cfg + sudo echo "template_name: $XCA_TEMPLATE" >> data/acme_srv.cfg + sudo sed -i "s/tnauthlist_support: False/tnauthlist_support: False\nheader_info_list: [\"HTTP_USER_AGENT\"]/g" data/acme_srv.cfg + sudo echo "eab_handler_file: /opt/acme2certifier/examples/eab_handler/kid_profile_handler.py" >> data/acme_srv.cfg + sudo echo "key_file: /opt/acme2certifier/volume/acme_ca/kid_profiles.json" >> data/acme_srv.cfg + env: + XCA_PASSPHRASE: ${{ secrets.XCA_PASSPHRASE }} + XCA_ISSUING_CA: ${{ secrets.XCA_ISSUING_CA }} + XCA_TEMPLATE: ${{ secrets.XCA_TEMPLATE }} + XCA_DB_NAME: ${{ secrets.XCA_DB_NAME }} + + - name: "Reconfigure a2c " + run: | + docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart + + - name: "Sleep for 5s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 5s + + - name: "Test http://acme-srv/directory is accessable " + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + - name: "01 - Enroll acme.sh without template_name" run: | sudo rm -rf acme-sh/* From 79e7bef6a4a25c91c8d2b0740e4ee879f2872238 Mon Sep 17 00:00:00 2001 From: grindsa Date: Tue, 9 Apr 2024 18:32:48 +0200 Subject: [PATCH 163/460] [wf] certifier_ca_handler --- .../workflows/ca_handler_tests_certifier.yml | 804 ++++++++++++++---- .github/workflows/ca_handler_tests_xca.yml | 203 +++-- examples/ca_handler/certifier_ca_handler.py | 13 +- 3 files changed, 760 insertions(+), 260 deletions(-) diff --git a/.github/workflows/ca_handler_tests_certifier.yml b/.github/workflows/ca_handler_tests_certifier.yml index 1772072f..8c617ac4 100644 --- a/.github/workflows/ca_handler_tests_certifier.yml +++ b/.github/workflows/ca_handler_tests_certifier.yml @@ -42,7 +42,7 @@ jobs: WEB_SRV: ${{ matrix.websrv }} DB_HANDLER: ${{ matrix.dbhandler }} - - name: "Setup a2c with certifier_ca_handler" + - name: "No profile - Setup a2c with certifier_ca_handler" run: | sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem @@ -68,54 +68,50 @@ jobs: NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "Sleep for 10s" + - name: "No profile - Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: time: 10s - - name: "Test http://acme-srv/directory is accessable" + - name: "No profile - Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "Test if https://acme-srv/directory is accessable" + - name: "No profile - Test if https://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - name: "Prepare acme.sh container" - run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - - name: "Enroll acme.sh" + - name: "No profile - Enroll acme.sh" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "Revoke via acme.sh" + - name: "No profile - Revoke via acme.sh" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --revoke --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "Register certbot" + - name: "No profile - Register certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "Enroll HTTP-01 single domain certbot" + - name: "No profile - Enroll HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem - - name: "Revoke HTTP-01 single domain certbot" + - name: "No profile - Revoke HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - - name: "Enroll lego" + - name: "No profile - Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - - name: "Revoke HTTP-01 single domain lego" + - name: "No profile - Revoke HTTP-01 single domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke - - name: "Setup a2c with certifier_ca_handler with profile 101" + - name: "Profile 101 - Setup a2c with certifier_ca_handler with profile 101" run: | sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem sudo touch examples/Docker/data/acme_srv.cfg @@ -139,53 +135,54 @@ jobs: NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} PROFILE: ${{ secrets.PROFILE }} - - name: "Sleep for 10s" + - name: "Profile 101 - Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: time: 10s - - name: "Test http://acme-srv/directory is accessable" + - name: "Profile 101 - Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "Test if https://acme-srv/directory is accessable" + - name: "Profile 101 - Test if https://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - name: "Enroll acme.sh" + - name: "Profile 101 - Enroll acme.sh" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "Revoke via acme.sh" + - name: "Profile 101 - Revoke via acme.sh" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --revoke --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "Register certbot" + - name: "Profile 101 - Register certbot" run: | sudo rm -rf certbot/* docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "Enroll HTTP-01 single domain certbot" + - name: "Profile 101 - Enroll HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem sudo openssl x509 -in certbot/live/certbot/cert.pem -ext extendedKeyUsage -noout | grep -i "TLS Web Client" - - name: "Revoke HTTP-01 single domain certbot" + - name: "Profile 101 - Revoke HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - - name: "Enroll lego" + - name: "Profile 101 - Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Client" - - name: "Revoke HTTP-01 single domain lego" + - name: "Profile 101 - Revoke HTTP-01 single domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke - - name: "Setup a2c with certifier_ca_handler with Profile 102" + - name: "Profile 102 - Setup a2c with certifier_ca_handler with Profile 102" run: | sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem sudo touch examples/Docker/data/acme_srv.cfg @@ -208,52 +205,306 @@ jobs: NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "Sleep for 10s" + - name: "Profile 102 - Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: time: 10s - - name: "Test http://acme-srv/directory is accessable" + - name: "Profile 102 - Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "Test if https://acme-srv/directory is accessable" + - name: "Profile 102 - Test if https://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - name: "Enroll acme.sh" + - name: "Profile 102 - Enroll acme.sh" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "Revoke via acme.sh" + - name: "Profile 102 - Revoke via acme.sh" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --revoke --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "Register certbot" + - name: "Profile 102 - Register certbot" run: | sudo rm -rf certbot/* docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "Enroll HTTP-01 single domain certbot" + - name: "Profile 102 - Enroll HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem sudo openssl x509 -in certbot/live/certbot/cert.pem -ext extendedKeyUsage -noout | grep -i "TLS Web Server" - - name: "Revoke HTTP-01 single domain certbot" + - name: "Profile 102 - Revoke HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - - name: "Enroll lego" + - name: "Profile 102 - Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Server" - - name: "Revoke HTTP-01 single domain lego" + - name: "Profile 102 - Revoke HTTP-01 single domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke + - name: "Header-info - Setup a2c with certifier_ca_handler with header-info" + run: | + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py + sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg + sudo chmod 777 examples/Docker/data/acme_srv.cfg + sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg + sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> examples/Docker/data/acme_srv.cfg + sudo echo "api_host: $NCM_API_HOST" >> examples/Docker/data/acme_srv.cfg + sudo echo "api_user: $NCM_API_USER" >> examples/Docker/data/acme_srv.cfg + sudo echo "api_password: $NCM_API_PASSWORD" >> examples/Docker/data/acme_srv.cfg + sudo echo "ca_name: $NCM_CA_NAME" >> examples/Docker/data/acme_srv.cfg + sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> examples/Docker/data/acme_srv.cfg + sudo sed -i "s/tnauthlist_support: False/tnauthlist_support: False\nheader_info_list: [\"HTTP_USER_AGENT\"]/g" examples/Docker/data/acme_srv.cfg + cd examples/Docker/ + docker-compose restart + docker-compose logs + env: + NCM_API_HOST: ${{ secrets.NCM_API_HOST }} + NCM_API_USER: ${{ secrets.NCM_API_USER }} + NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} + NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} + NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} + + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Header-info - Test http://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "Header-info - Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "Header-info - 01 - Enroll acme.sh with profile_id 101" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' --useragent profile_id=101 -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Client" + + - name: "Header-info - 01 - Enroll lego with profile_id 101" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent profile_id=101 -d lego.acme --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Client" + + - name: "Header-info - 02 - Enroll acme.sh with profile_id 102" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' --useragent profile_id=102 -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Server" + + - name: "Header-info - 02 - Enroll lego with profile_id 102" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent profile_id=102 -d lego.acme --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Server" + + - name: "EAB - Setup a2c with certifier_ca_handler" + run: | + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py + sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg + sudo chmod 777 examples/Docker/data/acme_srv.cfg + sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg + sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> examples/Docker/data/acme_srv.cfg + sudo echo "api_host: $NCM_API_HOST" >> examples/Docker/data/acme_srv.cfg + sudo echo "api_user: $NCM_API_USER" >> examples/Docker/data/acme_srv.cfg + sudo echo "api_password: $NCM_API_PASSWORD" >> examples/Docker/data/acme_srv.cfg + sudo echo "ca_name: $NCM_CA_NAME" >> examples/Docker/data/acme_srv.cfg + sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> examples/Docker/data/acme_srv.cfg + sudo echo "profile_id: 100" >> examples/Docker/data/acme_srv.cfg + sudo echo "eab_profiling: True" >> examples/Docker/data/acme_srv.cfg + sudo sed -i "s/tnauthlist_support: False/tnauthlist_support: False\nheader_info_list: [\"HTTP_USER_AGENT\"]/g" examples/Docker/data/acme_srv.cfg + sudo echo -e "\n[EABhandler]" >> examples/Docker/data/acme_srv.cfg + sudo echo "eab_handler_file: /var/www/acme2certifier/examples/eab_handler/kid_profile_handler.py" >> examples/Docker/data/acme_srv.cfg + sudo echo "key_file: volume/kid_profiles.json" >> examples/Docker/data/acme_srv.cfg + + sudo cp examples/eab_handler/kid_profiles.json examples/Docker/data/kid_profiles.json + sudo chmod 777 examples/eab_handler/kid_profiles.json + sudo sed -i "s/\"profile_id\"\: \[\"profile_1\", \"profile_2\", \"profile_3\"\]/\"profile_id\"\: \[\"102\", \"101\"\, \"100\"]/g" examples/Docker/data/kid_profiles.json + sudo sed -i "s/\"profile_id\"\: \"profile_2\"/\"profile_id\"\: \"102\"/g" examples/Docker/data/kid_profiles.json + sudo sed -i "s/\"ca_name\": \"example_ca_2\",/\"ca_name\": \"SubCA2\"/" examples/Docker/data/kid_profiles.json + sudo sed -i "s/\"ca_name\": \"example_ca\",/\"unknown_key\": \"unknown_value\"/g" examples/Docker/data/kid_profiles.json + sudo sed -i "s/example.net/acme/g" examples/Docker/data/kid_profiles.json + sudo sed -i '18,19d' examples/Docker/data/kid_profiles.json + sudo sed -i '8,9d' examples/Docker/data/kid_profiles.json + + cd examples/Docker/ + docker-compose restart + docker-compose logs + env: + NCM_API_HOST: ${{ secrets.NCM_API_HOST }} + NCM_API_USER: ${{ secrets.NCM_API_USER }} + NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} + NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} + NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} + + - name: "EAB - Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "EAB - Test http://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "EAB - Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "EAB - 01 - Enroll acme.sh without profile_id" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_00 --eab-hmac-key V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Server Authentication" + + - name: "EAB - 01 - Enroll lego without profile_id" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw -d lego.acme --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Server Authentication" + + - name: "EAB - 02a - Enroll acme with a template_name taken from header_info NOT included in kid.json (to fail)" + id: acmefail01 + continue-on-error: true + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_00 --eab-hmac-key V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --useragent profile_id=unknown -d acme-sh.acme --standalone --debug 3 --output-insecure + + - name: "EAB - 02a - check result " + if: steps.acmefail01.outcome != 'failure' + run: | + echo "acmefail outcome is ${{steps.acmefail01.outcome }}" + exit 1 + + - name: "EAB - 02b - Enroll acme with a template_name taken from header_info included in kid.json" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_00 --eab-hmac-key V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --useragent profile_id=101 -d acme-sh.acme --standalone --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Client Authentication" + + - name: "EAB - 02a - Enroll lego with a template_name taken from header_info NOT included in kid.json (to fail)" + id: legofail01 + continue-on-error: true + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --user-agent profile_id=unknown -d lego.acme --http run + + - name: "EAB - 02a - check result " + if: steps.legofail01.outcome != 'failure' + run: | + echo "legofail outcome is ${{steps.legofail01.outcome }}" + exit 1 + + - name: "EAB - 02b - Enroll lego with a template_name taken from header_info included in kid.json" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --user-agent profile_id=101 -d lego.acme --http run + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -issuer --noout + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Client Authentication" + + - name: "EAB - 03 - Enroll acme with a template_name/ca_name taken from kid.json" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_01 --eab-hmac-key YW5vdXRoZXJfdmVyeV9sb25nX2htYWNfZm9yX2tleWlkXzAxX3doaWNoIHdpbGxfYmUgdXNlZF9kdXJpbmcgcmVncmVzc2lvbg --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Server Authentication" + + - name: "EAB - 03 - Enroll lego with a template_name/ca_name taken from kid.json" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_01 --hmac YW5vdXRoZXJfdmVyeV9sb25nX2htYWNfZm9yX2tleWlkXzAxX3doaWNoIHdpbGxfYmUgdXNlZF9kdXJpbmcgcmVncmVzc2lvbg -d lego.acme --http run + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -issuer --noout + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Server Authentication" + + - name: "EAB - 04 - Enroll acme with a not allowed fqdn in kid.json (to fail)" + id: acmefail02 + continue-on-error: true + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure + + - name: "EAB - 04 - check result " + if: steps.acmefail02.outcome != 'failure' + run: | + echo "acmefail outcome is ${{steps.acmefail02.outcome }}" + exit 1 + + - name: "EAB - 04 - Enroll lego with a not allowed fqdn in kid.json (to fail)" + id: legofail02 + continue-on-error: true + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM -d lego.acme --http run + + - name: "EAB - 04a - check result " + if: steps.legofail02.outcome != 'failure' + run: | + echo "legofail outcome is ${{steps.legofail02.outcome }}" + exit 1 + + - name: "EAB - 05 - Enroll acme with default values from acme.cfg" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_03 --eab-hmac-key YW5kX2ZpbmFsbHlfdGhlX2xhc3RfaG1hY19rZXlfd2hpY2hfaXNfbG9uZ2VyX3RoYW5fMjU2X2JpdHNfYW5kX3Nob3VsZF93b3Jr --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "Code Signing" + + - name: "EAB - 05 - Enroll lego with default values from acme.cfg" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_03 --hmac YW5kX2ZpbmFsbHlfdGhlX2xhc3RfaG1hY19rZXlfd2hpY2hfaXNfbG9uZ2VyX3RoYW5fMjU2X2JpdHNfYW5kX3Nob3VsZF93b3Jr -d lego.acme --http run + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -issuer --noout + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "Code Signing" + - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | @@ -303,7 +554,7 @@ jobs: - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" - - name: "[ PREPARE ] setup environment for alma installation" + - name: "Setup environment for alma installation" run: | docker network create acme sudo mkdir -p data @@ -311,7 +562,7 @@ jobs: sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data - - name: "[ PREPARE ] create letsencrypt and lego folder" + - name: "Create letsencrypt and lego folder" run: | mkdir certbot mkdir lego @@ -324,7 +575,7 @@ jobs: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} - - name: "[ PREPARE ] prepare acme_srv.cfg with certifier_ca_handler" + - name: "No profile - Setup a2c with certifier_ca_handler" run: | mkdir -p data/acme_ca sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem @@ -344,199 +595,452 @@ jobs: NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "[ PREPARE ] Almalinux instance" + - name: "Prepare Almalinux instance" run: | sudo cp examples/Docker/almalinux-systemd/Dockerfile data sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - - name: "[ RUN ] Execute install scipt" + - name: "Execute install scipt" run: | docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh - - name: "Test http://acme-srv/directory is accessible" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "[ PREPARE ] prepare acme.sh container" - run: | - sudo mkdir acme-sh - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + - name: "Profile 101 - Sleep for 5s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 5s - - name: "[ REGISTER] acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 + - name: "No profile - Test http://acme-srv/directory is accessible" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ ENROLL] acme.sh" + - name: "No profile - Enroll acme.sh" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --debug 3 --output-insecure + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "revoke via acme.sh" + - name: "No profile - Revoke via acme.sh" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --revoke --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "[ REGISTER ] certbot" + - name: "No profile - Register certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ ENROLL ] HTTP-01 single domain certbot" + - name: "No profile - Enroll HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem - - name: "revoke HTTP-01 single domain certbot" + - name: "No profile - Revoke HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - - name: "[ ENROLL ] lego" + - name: "No profile - Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt - - name: "revoke HTTP-01 single domain lego" + - name: "No profile - Revoke HTTP-01 single domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke - - name: "[ * ] collecting test logs" - if: ${{ failure() }} + - name: "Profile 101 - Setup a2c with certifier_ca_handler with profile 101" run: | - mkdir -p ${{ github.workspace }}/artifact/upload - docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier - sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ - sudo rm ${{ github.workspace }}/artifact/data/*.rpm - sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ - docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig - docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf - docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh + mkdir -p data/acme_ca + sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem + sudo touch data/acme_srv.cfg + sudo chmod 777 data/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/acme_srv.cfg + sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> data/acme_srv.cfg + sudo echo "api_host: $NCM_API_HOST" >> data/acme_srv.cfg + sudo echo "api_user: $NCM_API_USER" >> data/acme_srv.cfg + sudo echo "api_password: $NCM_API_PASSWORD" >> data/acme_srv.cfg + sudo echo "ca_name: $NCM_CA_NAME" >> data/acme_srv.cfg + sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> data/acme_srv.cfg + sudo echo "profile_id: 101" >> data/acme_srv.cfg + env: + NCM_API_HOST: ${{ secrets.NCM_API_HOST }} + NCM_API_USER: ${{ secrets.NCM_API_USER }} + NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} + NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} + NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} + PROFILE: ${{ secrets.PROFILE }} - - name: "[ * ] uploading artificates" - uses: actions/upload-artifact@v4 - if: ${{ failure() }} + - name: "Profile 101 - Reconfigure a2c " + run: | + docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart + + - name: "Profile 101 - Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 with: - name: certifier_ca_handler_rpm-rh${{ matrix.rhversion }}.tar.gz - path: ${{ github.workspace }}/artifact/upload/ + time: 10s - certifier_handler_headerinfo_tests: - name: "certifier_handler_headerinfo_tests" - runs-on: ubuntu-latest - strategy: - fail-fast: false - max-parallel: 2 - matrix: - websrv: ['apache2', 'nginx'] - dbhandler: ['wsgi', 'django'] - steps: - - name: "checkout GIT" - uses: actions/checkout@v4 + - name: "Profile 101 - Test http://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" - working-directory: examples/Docker/ + - name: "Profile 101 - Enroll acme.sh" run: | - sudo mkdir -p data - sed -i "s/wsgi/$DB_HANDLER/g" .env - sed -i "s/apache2/$WEB_SRV/g" .env - cat .env - docker network create acme - docker-compose up -d - docker-compose logs - env: - WEB_SRV: ${{ matrix.websrv }} - DB_HANDLER: ${{ matrix.dbhandler }} + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "[ PREPARE ] create lego folder" + - name: "Profile 101 - Revoke via acme.sh" run: | - mkdir lego + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --revoke --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "[ PREPARE ] setup a2c with certifier_ca_handler" + - name: "Profile 101 - Register certbot" run: | - sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem - sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem - sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem - sudo cp .github/django_settings.py examples/Docker/data/settings.py - sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem - sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg - sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_host: $NCM_API_HOST" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_user: $NCM_API_USER" >> examples/Docker/data/acme_srv.cfg - sudo echo "api_password: $NCM_API_PASSWORD" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_name: $NCM_CA_NAME" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> examples/Docker/data/acme_srv.cfg - sudo sed -i "s/tnauthlist_support: False/tnauthlist_support: False\nheader_info_list: [\"HTTP_USER_AGENT\"]/g" examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - docker-compose restart - docker-compose logs + sudo rm -rf certbot/* + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email + + - name: "Profile 101 - Enroll HTTP-01 single domain certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem + sudo openssl x509 -in certbot/live/certbot/cert.pem -ext extendedKeyUsage -noout | grep -i "TLS Web Client" + + - name: "Profile 101 - Revoke HTTP-01 single domain certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot + + - name: "Profile 101 - Enroll lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Client" + + - name: "Profile 101 - Revoke HTTP-01 single domain lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke + + - name: "Profile 102 - Setup a2c with certifier_ca_handler with profile 101" + run: | + mkdir -p data/acme_ca + sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem + sudo touch data/acme_srv.cfg + sudo chmod 777 data/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/acme_srv.cfg + sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> data/acme_srv.cfg + sudo echo "api_host: $NCM_API_HOST" >> data/acme_srv.cfg + sudo echo "api_user: $NCM_API_USER" >> data/acme_srv.cfg + sudo echo "api_password: $NCM_API_PASSWORD" >> data/acme_srv.cfg + sudo echo "ca_name: $NCM_CA_NAME" >> data/acme_srv.cfg + sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> data/acme_srv.cfg + sudo echo "profile_id: 102" >> data/acme_srv.cfg env: NCM_API_HOST: ${{ secrets.NCM_API_HOST }} NCM_API_USER: ${{ secrets.NCM_API_USER }} NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} + PROFILE: ${{ secrets.PROFILE }} - - name: "Sleep for 10s" + - name: "Profile 102 - Reconfigure a2c " + run: | + docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart + + - name: "Profile 102 - Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: time: 10s - - name: "Test http://acme-srv/directory is accessable" + - name: "Profile 102 - Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "Test if https://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + - name: "Profile 102 - Enroll acme.sh" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + + - name: "Profile 102 - Revoke via acme.sh" + run: | + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --revoke --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure + + - name: "Profile 102 - Register certbot" + run: | + sudo rm -rf certbot/* + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email + + - name: "Profile 102 - Enroll HTTP-01 single domain certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem + sudo openssl x509 -in certbot/live/certbot/cert.pem -ext extendedKeyUsage -noout | grep -i "TLS Web Server" + + - name: "Profile 102 - Revoke HTTP-01 single domain certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - - name: "Prepare acme.sh container" + - name: "Profile 102 - Enroll lego" run: | - sudo mkdir acme-sh - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Server" - - name: "Register acme.sh" + - name: "Profile 102 - Revoke HTTP-01 single domain lego" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --register-account --accountemail 'acme-sh@example.com' --debug 3 + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke - - name: "Enroll acme.sh with profile_id 101" + - name: "Header-info - Setup a2c with certifier_ca_handler" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --issue -d acme-sh.acme --standalone --useragent profile_id=101 --debug 3 --output-insecure + mkdir -p data/acme_ca + sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem + sudo touch data/acme_srv.cfg + sudo chmod 777 data/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/acme_srv.cfg + sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> data/acme_srv.cfg + sudo echo "api_host: $NCM_API_HOST" >> data/acme_srv.cfg + sudo echo "api_user: $NCM_API_USER" >> data/acme_srv.cfg + sudo echo "api_password: $NCM_API_PASSWORD" >> data/acme_srv.cfg + sudo echo "ca_name: $NCM_CA_NAME" >> data/acme_srv.cfg + sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> data/acme_srv.cfg + sudo sed -i "s/tnauthlist_support: False/tnauthlist_support: False\nheader_info_list: [\"HTTP_USER_AGENT\"]/g" data/acme_srv.cfg + env: + NCM_API_HOST: ${{ secrets.NCM_API_HOST }} + NCM_API_USER: ${{ secrets.NCM_API_USER }} + NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} + NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} + NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} + PROFILE: ${{ secrets.PROFILE }} + + - name: "Header-info - Reconfigure a2c " + run: | + docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart + + - name: "Header-info - Sleep for 5s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 5s + + - name: "Header-info - 01 - Enroll acme.sh with profile_id 101" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' --useragent profile_id=101 -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Client" - - name: "Enroll lego with profile_id 101" + - name: "Header-info - 01 - Enroll lego with profile_id 101" run: | sudo rm -rf lego/* docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent profile_id=101 -d lego.acme --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Client" - - name: "Enroll acme.sh with profile_id 102" + - name: "Header-info - 02 - Enroll acme.sh with profile_id 102" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --renew --force -d acme-sh.acme --standalone --useragent profile_id=102 --debug 3 --output-insecure + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' --useragent profile_id=102 -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Server" - - name: "Enroll lego with profile_id 102" + - name: "Header-info - 02 - Enroll lego with profile_id 102" run: | sudo rm -rf lego/* docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent profile_id=102 -d lego.acme --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Server" + - name: "EAB - Setup a2c with certifier_ca_handler" + run: | + mkdir -p data/acme_ca + sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem + sudo touch data/acme_srv.cfg + sudo chmod 777 data/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/acme_srv.cfg + sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> data/acme_srv.cfg + sudo echo "api_host: $NCM_API_HOST" >> data/acme_srv.cfg + sudo echo "api_user: $NCM_API_USER" >> data/acme_srv.cfg + sudo echo "api_password: $NCM_API_PASSWORD" >> data/acme_srv.cfg + sudo echo "ca_name: $NCM_CA_NAME" >> data/acme_srv.cfg + sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> data/acme_srv.cfg + sudo echo "profile_id: 100" >> data/acme_srv.cfg + sudo echo "eab_profiling: True" >> data/acme_srv.cfg + sudo sed -i "s/tnauthlist_support: False/tnauthlist_support: False\nheader_info_list: [\"HTTP_USER_AGENT\"]/g" data/acme_srv.cfg + sudo echo -e "\n\n[EABhandler]" >> data/acme_srv.cfg + sudo echo "eab_handler_file: /opt/acme2certifier/examples/eab_handler/kid_profile_handler.py" >> data/acme_srv.cfg + sudo echo "key_file: /opt/acme2certifier/volume/acme_ca/kid_profiles.json" >> data/acme_srv.cfg + + sudo cp examples/eab_handler/kid_profiles.json data/acme_ca/kid_profiles.json + sudo chmod 777 data/acme_ca/kid_profiles.json + sudo sed -i "s/\"profile_id\"\: \[\"profile_1\", \"profile_2\", \"profile_3\"\]/\"profile_id\"\: \[\"102\", \"101\"\, \"100\"]/g" data/acme_ca/kid_profiles.json + sudo sed -i "s/\"profile_id\"\: \"profile_2\"/\"profile_id\"\: \"102\"/g" data/acme_ca/kid_profiles.json + sudo sed -i "s/\"ca_name\": \"example_ca_2\",/\"ca_name\": \"SubCA2\"/" data/acme_ca/kid_profiles.json + sudo sed -i "s/\"ca_name\": \"example_ca\",/\"unknown_key\": \"unknown_value\"/g" data/acme_ca/kid_profiles.json + sudo sed -i "s/example.net/acme/g" data/acme_ca/kid_profiles.json + sudo sed -i '18,19d' data/acme_ca/kid_profiles.json + sudo sed -i '8,9d' data/acme_ca/kid_profiles.json + env: + NCM_API_HOST: ${{ secrets.NCM_API_HOST }} + NCM_API_USER: ${{ secrets.NCM_API_USER }} + NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} + NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} + NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} + PROFILE: ${{ secrets.PROFILE }} + + - name: "EAB - Reconfigure a2c " + run: | + docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart + + - name: "EAB - Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "EAB - 01 - Enroll acme.sh without profile_id" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_00 --eab-hmac-key V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Server Authentication" + + - name: "EAB - 01 - Enroll lego without profile_id" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw -d lego.acme --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Server Authentication" + + - name: "EAB - 02a - Enroll acme with a template_name taken from header_info NOT included in kid.json (to fail)" + id: acmefail01 + continue-on-error: true + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_00 --eab-hmac-key V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --useragent profile_id=unknown -d acme-sh.acme --standalone --debug 3 --output-insecure + + - name: "EAB - 02a - check result " + if: steps.acmefail01.outcome != 'failure' + run: | + echo "acmefail outcome is ${{steps.acmefail01.outcome }}" + exit 1 + + - name: "EAB - 02b - Enroll acme with a template_name taken from header_info included in kid.json" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_00 --eab-hmac-key V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --useragent profile_id=101 -d acme-sh.acme --standalone --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Client Authentication" + + - name: "EAB - 02a - Enroll lego with a template_name taken from header_info NOT included in kid.json (to fail)" + id: legofail01 + continue-on-error: true + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --user-agent profile_id=unknown -d lego.acme --http run + + - name: "EAB - 02a - check result " + if: steps.legofail01.outcome != 'failure' + run: | + echo "legofail outcome is ${{steps.legofail01.outcome }}" + exit 1 + + - name: "EAB - 02b - Enroll lego with a template_name taken from header_info included in kid.json" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --user-agent profile_id=101 -d lego.acme --http run + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -issuer --noout + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Client Authentication" + + - name: "EAB - 03 - Enroll acme with a template_name/ca_name taken from kid.json" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_01 --eab-hmac-key YW5vdXRoZXJfdmVyeV9sb25nX2htYWNfZm9yX2tleWlkXzAxX3doaWNoIHdpbGxfYmUgdXNlZF9kdXJpbmcgcmVncmVzc2lvbg --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Server Authentication" + + - name: "EAB - 03 - Enroll lego with a template_name/ca_name taken from kid.json" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_01 --hmac YW5vdXRoZXJfdmVyeV9sb25nX2htYWNfZm9yX2tleWlkXzAxX3doaWNoIHdpbGxfYmUgdXNlZF9kdXJpbmcgcmVncmVzc2lvbg -d lego.acme --http run + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -issuer --noout + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Server Authentication" + + - name: "EAB - 04 - Enroll acme with a not allowed fqdn in kid.json (to fail)" + id: acmefail02 + continue-on-error: true + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure + + - name: "EAB - 04 - check result " + if: steps.acmefail02.outcome != 'failure' + run: | + echo "acmefail outcome is ${{steps.acmefail02.outcome }}" + exit 1 + + - name: "EAB - 04 - Enroll lego with a not allowed fqdn in kid.json (to fail)" + id: legofail02 + continue-on-error: true + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM -d lego.acme --http run + + - name: "EAB - 04a - check result " + if: steps.legofail02.outcome != 'failure' + run: | + echo "legofail outcome is ${{steps.legofail02.outcome }}" + exit 1 + + - name: "EAB - 05 - Enroll acme with default values from acme.cfg" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_03 --eab-hmac-key YW5kX2ZpbmFsbHlfdGhlX2xhc3RfaG1hY19rZXlfd2hpY2hfaXNfbG9uZ2VyX3RoYW5fMjU2X2JpdHNfYW5kX3Nob3VsZF93b3Jr --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "Code Signing" + + - name: "EAB - 05 - Enroll lego with default values from acme.cfg" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_03 --hmac YW5kX2ZpbmFsbHlfdGhlX2xhc3RfaG1hY19rZXlfd2hpY2hfaXNfbG9uZ2VyX3RoYW5fMjU2X2JpdHNfYW5kX3Nob3VsZF93b3Jr -d lego.acme --http run + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -issuer --noout + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "Code Signing" + - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | mkdir -p ${{ github.workspace }}/artifact/upload - sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ - sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ - cd examples/Docker - docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data lego + docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier + sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo rm ${{ github.workspace }}/artifact/data/*.rpm + sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf + docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh - name: "[ * ] uploading artificates" uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: certifier_handler_headerinfo-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz - path: ${{ github.workspace }}/artifact/upload/ \ No newline at end of file + name: certifier_ca_handler_rpm-rh${{ matrix.rhversion }}.tar.gz + path: ${{ github.workspace }}/artifact/upload/ + diff --git a/.github/workflows/ca_handler_tests_xca.yml b/.github/workflows/ca_handler_tests_xca.yml index ed41935d..28dc7d0a 100644 --- a/.github/workflows/ca_handler_tests_xca.yml +++ b/.github/workflows/ca_handler_tests_xca.yml @@ -41,7 +41,7 @@ jobs: mkdir certbot mkdir lego - - name: "Setup a2c with xca_ca_handler - no template" + - name: "No template - Setup a2c with xca_ca_handler" run: | sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem @@ -70,18 +70,18 @@ jobs: XCA_TEMPLATE: ${{ secrets.XCA_TEMPLATE }} XCA_DB_NAME: ${{ secrets.XCA_DB_NAME }} - - name: "Sleep for 10s" + - name: "No template - Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: time: 10s - - name: "Test http://acme-srv/directory is accessable" + - name: "No template - Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "Test if https://acme-srv/directory is accessable" + - name: "No template - Test if https://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - name: "Acme.sh" + - name: "No template - Enroll acme.sh" run: | docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer @@ -90,15 +90,15 @@ jobs: openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout | grep "Digital Signature, Key Encipherment" openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout | grep "TLS Web Server Authentication" - - name: "Revoke via acme.sh" + - name: "No template - Revoke via acme.sh" run: | docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "Register certbot" + - name: "No template - Register certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "Enroll certbot" + - name: "No template - Enroll certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem @@ -107,11 +107,11 @@ jobs: sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "Digital Signature, Key Encipherment" sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "TLS Web Server Authentication" - - name: "Revoke certbot" + - name: "No template - Revoke certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - - name: "Enroll lego" + - name: "No template - Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt @@ -120,11 +120,11 @@ jobs: sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout | grep "Digital Signature, Key Encipherment" sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout | grep "TLS Web Server Authentication" - - name: "Revoke lego" + - name: "No template - Revoke lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke - - name: "Setup a2c with xca_ca_handler - with template" + - name: "Template - Setup a2c with xca_ca_handler" run: | sudo mkdir -p examples/Docker/data/xca sudo chmod -R 777 examples/Docker/data/xca @@ -149,18 +149,18 @@ jobs: XCA_TEMPLATE: ${{ secrets.XCA_TEMPLATE }} XCA_DB_NAME: ${{ secrets.XCA_DB_NAME }} - - name: "Sleep for 10s" + - name: "Template - Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: time: 10s - - name: "Test http://acme-srv/directory is accessable" + - name: "Template - Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "Test if https://acme-srv/directory is accessable" + - name: "Template - Test if https://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - name: "Enroll acme.sh" + - name: "Template - Enroll acme.sh" run: | sudo rm -rf acme-sh/* docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure @@ -169,16 +169,16 @@ jobs: openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout | grep "TLS Web Server Authentication, TLS Web Client Authentication" - - name: "Revoke via acme.sh" + - name: "Template - Revoke via acme.sh" run: | docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --revoke --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "Register certbot" + - name: "Template - Register certbot" run: | sudo rm -rf certbot/* docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "Enroll certbot" + - name: "Template - Enroll certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile examples/Docker/data/acme_ca/root-ca-cert.pem -untrusted examples/Docker/data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem @@ -186,11 +186,11 @@ jobs: sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "TLS Web Server Authentication, TLS Web Client Authentication" - - name: "Revoke certbot" + - name: "Template - Revoke certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - - name: "Enroll lego" + - name: "Template - Enroll lego" run: | sudo rm -rf lego/* docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run @@ -199,11 +199,11 @@ jobs: sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout | grep "TLS Web Server Authentication, TLS Web Client Authentication" - - name: "Revoke lego" + - name: "Template - Revoke lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke - - name: "Setup a2c with xca_ca_handler - headerinfo-only" + - name: "Header-info - Setup a2c with xca_ca_handler" run: | sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem @@ -233,18 +233,18 @@ jobs: XCA_TEMPLATE: ${{ secrets.XCA_TEMPLATE }} XCA_DB_NAME: ${{ secrets.XCA_DB_NAME }} - - name: "Sleep for 10s" + - name: "Header-info - Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: time: 10s - - name: "Test http://acme-srv/directory is accessable" + - name: "Header-info - Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "Test if https://acme-srv/directory is accessable" + - name: "Header-info - Test if https://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - name: "01 - Enroll acme.sh without template_name" + - name: "Header-info - 01 - Enroll acme.sh without template_name" run: | sudo rm -rf acme-sh/* docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' -d acme-sh.acme --standalone --debug 3 --output-insecure @@ -254,7 +254,7 @@ jobs: openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Server Authentication, TLS Web Client Authentication" - - name: "01 - Enroll lego without template_name" + - name: "Header-info - 01 - Enroll lego without template_name" run: | sudo rm -rf lego/* docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run @@ -263,7 +263,7 @@ jobs: sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext keyUsage | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Server Authentication, TLS Web Client Authentication" - - name: "02 - Enroll acme.sh with template_name template" + - name: "Header-info - 02 - Enroll acme.sh with template_name template" run: | sudo rm -rf acme-sh/* # docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --debug 3 @@ -274,7 +274,7 @@ jobs: openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature, Non Repudiation" openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Server Authentication, Code Signing" - - name: "02 - Enroll lego with template_name template" + - name: "Header-info - 02 - Enroll lego with template_name template" run: | sudo rm -rf lego/* docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent template_name=template -d lego.acme --http run @@ -283,7 +283,7 @@ jobs: sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext keyUsage | grep "Digital Signature, Non Repudiation" sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Server Authentication, Code Signing" - - name: "Setup a2c with xca_ca_handler - profiling" + - name: "EAB - Setup a2c with xca_ca_handler - profiling" run: | sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem @@ -328,18 +328,18 @@ jobs: XCA_TEMPLATE: ${{ secrets.XCA_TEMPLATE }} XCA_DB_NAME: ${{ secrets.XCA_DB_NAME }} - - name: "Sleep for 10s" + - name: "EAB - Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: time: 10s - - name: "Test http://acme-srv/directory is accessable" + - name: "EAB - Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "Test if https://acme-srv/directory is accessable" + - name: "EAB - Test if https://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - name: "01 - Enroll acme with a template_name taken from list in kid.json" + - name: "EAB - 01 - Enroll acme with a template_name taken from list in kid.json" run: | sudo rm -rf acme-sh/* docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_00 --eab-hmac-key V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --debug 3 @@ -350,18 +350,16 @@ jobs: openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature, Non Repudiation" openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Server Authentication, Code Signing" - - name: "01 - Enroll lego with a template_name taken from list in kid.json" + - name: "EAB - 01 - Enroll lego with a template_name taken from list in kid.json" run: | sudo rm -rf lego/* docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw -d lego.acme --http run - sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout - sudo openssl x509 -in lego/certificates/lego.acme.crt -issuer --noout sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext keyUsage | grep "Digital Signature, Non Repudiation" sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Server Authentication, Code Signing" - - name: "02a - Enroll acme with a template_name taken from header_info NOT included in kid.json (to fail)" + - name: "EAB - 02a - Enroll acme with a template_name taken from header_info NOT included in kid.json (to fail)" id: acmefail01 continue-on-error: true run: | @@ -369,13 +367,13 @@ jobs: docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_00 --eab-hmac-key V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --debug 3 docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --useragent template_name=unknown -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "02a - check result " + - name: "EAB - 02a - check result " if: steps.acmefail01.outcome != 'failure' run: | echo "acmefail outcome is ${{steps.acmefail01.outcome }}" exit 1 - - name: "02b - Enroll acme with a template_name taken from header_info included in kid.json" + - name: "EAB - 02b - Enroll acme with a template_name taken from header_info included in kid.json" run: | sudo rm -rf acme-sh/* docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_00 --eab-hmac-key V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --debug 3 @@ -386,20 +384,20 @@ jobs: openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Server Authentication, TLS Web Client Authentication" - - name: "02a - Enroll lego with a template_name taken from header_info NOT included in kid.json (to fail)" + - name: "EAB - 02a - Enroll lego with a template_name taken from header_info NOT included in kid.json (to fail)" id: legofail01 continue-on-error: true run: | sudo rm -rf lego/* docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --user-agent template_name=unknown -d lego.acme --http run - - name: "02a - check result " + - name: "EAB - 02a - check result " if: steps.legofail01.outcome != 'failure' run: | echo "legofail outcome is ${{steps.legofail01.outcome }}" exit 1 - - name: "02b - Enroll lego with a template_name taken from header_info included in kid.json" + - name: "EAB - 02b - Enroll lego with a template_name taken from header_info included in kid.json" run: | sudo rm -rf lego/* docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --user-agent template_name=acme -d lego.acme --http run @@ -410,7 +408,7 @@ jobs: sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext keyUsage | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Server Authentication, TLS Web Client Authentication" - - name: "03 - Enroll acme with a template_name/ca_name taken from kid.json" + - name: "EAB - 03 - Enroll acme with a template_name/ca_name taken from kid.json" run: | sudo rm -rf acme-sh/* docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_01 --eab-hmac-key YW5vdXRoZXJfdmVyeV9sb25nX2htYWNfZm9yX2tleWlkXzAxX3doaWNoIHdpbGxfYmUgdXNlZF9kdXJpbmcgcmVncmVzc2lvbg --debug 3 @@ -421,7 +419,7 @@ jobs: openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature, Non Repudiation" openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Server Authentication, Code Signing" - - name: "03 - Enroll lego with a template_name/ca_name taken from kid.json" + - name: "EAB - 03 - Enroll lego with a template_name/ca_name taken from kid.json" run: | sudo rm -rf lego/* docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_01 --hmac YW5vdXRoZXJfdmVyeV9sb25nX2htYWNfZm9yX2tleWlkXzAxX3doaWNoIHdpbGxfYmUgdXNlZF9kdXJpbmcgcmVncmVzc2lvbg -d lego.acme --http run @@ -432,7 +430,7 @@ jobs: sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext keyUsage | grep "Digital Signature, Non Repudiation" sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Server Authentication, Code Signing" - - name: "04 - Enroll acme with a not allowed fqdn in kid.json (to fail)" + - name: "EAB - 04 - Enroll acme with a not allowed fqdn in kid.json (to fail)" id: acmefail02 continue-on-error: true run: | @@ -440,26 +438,26 @@ jobs: docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM --debug 3 docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "04 - check result " + - name: "EAB - 04 - check result " if: steps.acmefail02.outcome != 'failure' run: | echo "acmefail outcome is ${{steps.acmefail02.outcome }}" exit 1 - - name: "04 - Enroll lego with a not allowed fqdn in kid.json (to fail)" + - name: "EAB - 04 - Enroll lego with a not allowed fqdn in kid.json (to fail)" id: legofail02 continue-on-error: true run: | sudo rm -rf lego/* docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM -d lego.acme --http run - - name: "04a - check result " + - name: "EAB - 04a - check result " if: steps.legofail02.outcome != 'failure' run: | echo "legofail outcome is ${{steps.legofail02.outcome }}" exit 1 - - name: "05 - Enroll acme with default values from acme.cfg" + - name: "EAB - 05 - Enroll acme with default values from acme.cfg" run: | sudo rm -rf acme-sh/* docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_03 --eab-hmac-key YW5kX2ZpbmFsbHlfdGhlX2xhc3RfaG1hY19rZXlfd2hpY2hfaXNfbG9uZ2VyX3RoYW5fMjU2X2JpdHNfYW5kX3Nob3VsZF93b3Jr --debug 3 @@ -470,7 +468,7 @@ jobs: openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Server Authentication, TLS Web Client Authentication" - - name: "05 - Enroll lego with default values from acme.cfg" + - name: "EAB - 05 - Enroll lego with default values from acme.cfg" run: | sudo rm -rf lego/* docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_03 --hmac YW5kX2ZpbmFsbHlfdGhlX2xhc3RfaG1hY19rZXlfd2hpY2hfaXNfbG9uZ2VyX3RoYW5fMjU2X2JpdHNfYW5kX3Nob3VsZF93b3Jr -d lego.acme --http run @@ -551,7 +549,7 @@ jobs: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} - - name: "[ PREPARE ] prepare acme_srv.cfg with xca_ca_handler" + - name: "No template - Setup a2c with xca_ca_handler" run: | mkdir -p data/acme_ca sudo cp test/ca/acme2certifier-clean.xdb data/acme_ca/$XCA_DB_NAME @@ -572,21 +570,21 @@ jobs: XCA_TEMPLATE: ${{ secrets.XCA_TEMPLATE }} XCA_DB_NAME: ${{ secrets.XCA_DB_NAME }} - - name: "[ PREPARE ] Almalinux instance" + - name: "Prepare Almalinux instance" run: | sudo cp examples/Docker/almalinux-systemd/Dockerfile data sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - - name: "[ RUN ] Execute install scipt" + - name: "Execute install scipt" run: | docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh - - name: "Test http://acme-srv/directory is accessible" + - name: "No template - Test http://acme-srv/directory is accessible" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ ENROLL ] acme.sh" + - name: "No template - Enroll acme.sh" run: | docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer @@ -595,15 +593,15 @@ jobs: openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout | grep "Digital Signature, Key Encipherment" openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout | grep "TLS Web Server Authentication" - - name: "revoke via acme.sh" + - name: "No template - Revoke via acme.sh" run: | docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "[ REGISTER] certbot" + - name: "No template - Register certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ ENROLL ] HTTP-01 single domain certbot" + - name: "No template - Enroll HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem @@ -612,11 +610,11 @@ jobs: sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "Digital Signature, Key Encipherment" sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "TLS Web Server Authentication" - - name: "revoke HTTP-01 single domain certbot" + - name: "No template - Revoke HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - - name: "[ ENROLL ] lego" + - name: "No template - Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run sudo openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt @@ -625,11 +623,11 @@ jobs: sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout | grep "Digital Signature, Key Encipherment" sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout | grep "TLS Web Server Authentication" - - name: "revoke HTTP-01 single domain lego" + - name: "No template - Revoke HTTP-01 single domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke - - name: "[ PREPARE ] prepare acme_srv.cfg with xca_ca_handler" + - name: "Template - Setup a2c with xca_ca_handler" run: | mkdir -p data/acme_ca sudo cp test/ca/acme2certifier-clean.xdb data/acme_ca/$XCA_DB_NAME @@ -650,19 +648,19 @@ jobs: XCA_TEMPLATE: ${{ secrets.XCA_TEMPLATE }} XCA_DB_NAME: ${{ secrets.XCA_DB_NAME }} - - name: "Reconfigure a2c " + - name: "Template - Reconfigure a2c " run: | docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart - - name: "Sleep for 5s" + - name: "Template - Sleep for 5s" uses: juliangruber/sleep-action@v2.0.3 with: time: 5s - - name: "Test http://acme-srv/directory is accessable " + - name: "Template - Test http://acme-srv/directory is accessable " run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "Enroll acme.sh" + - name: "Template - Enroll acme.sh" run: | sudo rm -rf acme-sh/* docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure @@ -671,16 +669,16 @@ jobs: openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout | grep "TLS Web Server Authentication, TLS Web Client Authentication" - - name: "Revoke via acme.sh" + - name: "Template - Revoke via acme.sh" run: | docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --revoke --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "Register certbot" + - name: "Template - Register certbot" run: | sudo rm -rf certbot/* docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "Enroll HTTP-01 single domain certbot" + - name: "Template - Enroll HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem certbot/live/certbot/cert.pem @@ -688,11 +686,11 @@ jobs: sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" sudo openssl x509 -in certbot/archive/certbot/cert1.pem -text -noout | grep "TLS Web Server Authentication, TLS Web Client Authentication" - - name: "Revoke HTTP-01 single domain certbot" + - name: "Template - Revoke HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - - name: "Enroll lego" + - name: "Template - Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run sudo openssl verify -CAfile data/acme_ca/root-ca-cert.pem -untrusted data/acme_ca/sub-ca-cert.pem lego/certificates/lego.acme.crt @@ -700,11 +698,11 @@ jobs: sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout | grep "TLS Web Server Authentication, TLS Web Client Authentication" - - name: "Revoke HTTP-01 single domain lego" + - name: "Template - Revoke HTTP-01 single domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke - - name: "Setup a2c with xca_ca_handler - headerinfo-only" + - name: "Header-info - Setup a2c with xca_ca_handler" run: | mkdir -p data/acme_ca sudo cp test/ca/acme2certifier-clean.xdb data/acme_ca/$XCA_DB_NAME @@ -728,19 +726,19 @@ jobs: XCA_TEMPLATE: ${{ secrets.XCA_TEMPLATE }} XCA_DB_NAME: ${{ secrets.XCA_DB_NAME }} - - name: "Reconfigure a2c " + - name: "Header-info - Reconfigure a2c " run: | docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart - - name: "Sleep for 5s" + - name: "Header-info - Sleep for 5s" uses: juliangruber/sleep-action@v2.0.3 with: time: 5s - - name: "Test http://acme-srv/directory is accessable " + - name: "Header-info - Test http://acme-srv/directory is accessable " run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "01 - Enroll acme.sh without template_name" + - name: "Header-info - 01 - Enroll acme.sh without template_name" run: | sudo rm -rf acme-sh/* # docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --debug 3 @@ -751,7 +749,7 @@ jobs: openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Server Authentication, TLS Web Client Authentication" - - name: "01 - Enroll lego without template_name" + - name: "Header-info - 01 - Enroll lego without template_name" run: | sudo rm -rf lego/* docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run @@ -760,7 +758,7 @@ jobs: sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext keyUsage | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Server Authentication, TLS Web Client Authentication" - - name: "02 - Enroll acme.sh with template_name template" + - name: "Header-info - 02 - Enroll acme.sh with template_name template" run: | sudo rm -rf acme-sh/* # docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --debug 3 @@ -771,7 +769,7 @@ jobs: openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature, Non Repudiation" openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Server Authentication, Code Signing" - - name: "02 - Enroll lego with template_name template" + - name: "Header-info - 02 - Enroll lego with template_name template" run: | sudo rm -rf lego/* docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent template_name=template -d lego.acme --http run @@ -780,7 +778,7 @@ jobs: sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext keyUsage | grep "Digital Signature, Non Repudiation" sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Server Authentication, Code Signing" - - name: "Setup a2c with xca_ca_handler - profiling" + - name: "EAB - Setup a2c with xca_ca_handler" run: | mkdir -p data/acme_ca sudo cp test/ca/acme2certifier-clean.xdb data/acme_ca/$XCA_DB_NAME @@ -815,19 +813,19 @@ jobs: XCA_TEMPLATE: ${{ secrets.XCA_TEMPLATE }} XCA_DB_NAME: ${{ secrets.XCA_DB_NAME }} - - name: "Reconfigure a2c " + - name: "EAB - Reconfigure a2c " run: | docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart - - name: "Sleep for 5s" + - name: "EAB - Sleep for 5s" uses: juliangruber/sleep-action@v2.0.3 with: time: 5s - - name: "Test http://acme-srv/directory is accessable " + - name: "EAB - Test http://acme-srv/directory is accessable " run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "01 - Enroll acme with a template_name taken from list in kid.json" + - name: "EAB - 01 - Enroll acme with a template_name taken from list in kid.json" run: | sudo rm -rf acme-sh/* docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_00 --eab-hmac-key V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --debug 3 @@ -838,7 +836,7 @@ jobs: openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature, Non Repudiation" openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Server Authentication, Code Signing" - - name: "01 - Enroll lego with a template_name taken from list in kid.json" + - name: "EAB - 01 - Enroll lego with a template_name taken from list in kid.json" run: | sudo rm -rf lego/* docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw -d lego.acme --http run @@ -849,7 +847,7 @@ jobs: sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext keyUsage | grep "Digital Signature, Non Repudiation" sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Server Authentication, Code Signing" - - name: "02a - Enroll acme with a template_name taken from header_info NOT included in kid.json (to fail)" + - name: "EAB - 02a - Enroll acme with a template_name taken from header_info NOT included in kid.json (to fail)" id: acmefail01 continue-on-error: true run: | @@ -857,13 +855,13 @@ jobs: docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_00 --eab-hmac-key V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --debug 3 docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --useragent template_name=unknown -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "02a - check result " + - name: "EAB - 02a - check result " if: steps.acmefail01.outcome != 'failure' run: | echo "acmefail outcome is ${{steps.acmefail01.outcome }}" exit 1 - - name: "02b - Enroll acme with a template_name taken from header_info included in kid.json" + - name: "EAB - 02b - Enroll acme with a template_name taken from header_info included in kid.json" run: | sudo rm -rf acme-sh/* docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_00 --eab-hmac-key V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --debug 3 @@ -874,20 +872,20 @@ jobs: openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Server Authentication, TLS Web Client Authentication" - - name: "02a - Enroll lego with a template_name taken from header_info NOT included in kid.json (to fail)" + - name: "EAB - 02a - Enroll lego with a template_name taken from header_info NOT included in kid.json (to fail)" id: legofail01 continue-on-error: true run: | sudo rm -rf lego/* docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --user-agent template_name=unknown -d lego.acme --http run - - name: "02a - check result " + - name: "EAB - 02a - check result " if: steps.legofail01.outcome != 'failure' run: | echo "legofail outcome is ${{steps.legofail01.outcome }}" exit 1 - - name: "02b - Enroll lego with a template_name taken from header_info included in kid.json" + - name: "EAB - 02b - Enroll lego with a template_name taken from header_info included in kid.json" run: | sudo rm -rf lego/* docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --user-agent template_name=acme -d lego.acme --http run @@ -898,7 +896,7 @@ jobs: sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext keyUsage | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Server Authentication, TLS Web Client Authentication" - - name: "03 - Enroll acme with a template_name/ca_name taken from kid.json" + - name: "EAB - 03 - Enroll acme with a template_name/ca_name taken from kid.json" run: | sudo rm -rf acme-sh/* docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_01 --eab-hmac-key YW5vdXRoZXJfdmVyeV9sb25nX2htYWNfZm9yX2tleWlkXzAxX3doaWNoIHdpbGxfYmUgdXNlZF9kdXJpbmcgcmVncmVzc2lvbg --debug 3 @@ -909,7 +907,7 @@ jobs: openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature, Non Repudiation" openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Server Authentication, Code Signing" - - name: "03 - Enroll lego with a template_name/ca_name taken from kid.json" + - name: "EAB - 03 - Enroll lego with a template_name/ca_name taken from kid.json" run: | sudo rm -rf lego/* docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_01 --hmac YW5vdXRoZXJfdmVyeV9sb25nX2htYWNfZm9yX2tleWlkXzAxX3doaWNoIHdpbGxfYmUgdXNlZF9kdXJpbmcgcmVncmVzc2lvbg -d lego.acme --http run @@ -920,7 +918,7 @@ jobs: sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext keyUsage | grep "Digital Signature, Non Repudiation" sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Server Authentication, Code Signing" - - name: "04 - Enroll acme with a not allowed fqdn in kid.json (to fail)" + - name: "EAB - 04 - Enroll acme with a not allowed fqdn in kid.json (to fail)" id: acmefail02 continue-on-error: true run: | @@ -928,26 +926,26 @@ jobs: docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM --debug 3 docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "04 - check result " + - name: "EAB - 04 - check result " if: steps.acmefail02.outcome != 'failure' run: | echo "acmefail outcome is ${{steps.acmefail02.outcome }}" exit 1 - - name: "04 - Enroll lego with a not allowed fqdn in kid.json (to fail)" + - name: "EAB - 04 - Enroll lego with a not allowed fqdn in kid.json (to fail)" id: legofail02 continue-on-error: true run: | sudo rm -rf lego/* docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM -d lego.acme --http run - - name: "04a - check result " + - name: "EAB - 04a - check result " if: steps.legofail02.outcome != 'failure' run: | echo "legofail outcome is ${{steps.legofail02.outcome }}" exit 1 - - name: "05 - Enroll acme with default values from acme.cfg" + - name: "EAB - 05 - Enroll acme with default values from acme.cfg" run: | sudo rm -rf acme-sh/* docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_03 --eab-hmac-key YW5kX2ZpbmFsbHlfdGhlX2xhc3RfaG1hY19rZXlfd2hpY2hfaXNfbG9uZ2VyX3RoYW5fMjU2X2JpdHNfYW5kX3Nob3VsZF93b3Jr --debug 3 @@ -958,7 +956,7 @@ jobs: openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Server Authentication, TLS Web Client Authentication" - - name: "05 - Enroll lego with default values from acme.cfg" + - name: "EAB - 05 - Enroll lego with default values from acme.cfg" run: | sudo rm -rf lego/* docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_03 --hmac YW5kX2ZpbmFsbHlfdGhlX2xhc3RfaG1hY19rZXlfd2hpY2hfaXNfbG9uZ2VyX3RoYW5fMjU2X2JpdHNfYW5kX3Nob3VsZF93b3Jr -d lego.acme --http run @@ -969,7 +967,6 @@ jobs: sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext keyUsage | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Server Authentication, TLS Web Client Authentication" - - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | diff --git a/examples/ca_handler/certifier_ca_handler.py b/examples/ca_handler/certifier_ca_handler.py index 2f955447..d1eede36 100644 --- a/examples/ca_handler/certifier_ca_handler.py +++ b/examples/ca_handler/certifier_ca_handler.py @@ -556,15 +556,14 @@ def _profile_check(self, csr: str) -> str: if self.eab_handler: error = self._eab_profile_check(csr, handler_hifield) # we need to cover cases where handler_value is enabled but nothing is defined in json - elif self.header_info_field: - # no profiling - parse profileid from http_header - hil_value = header_info_lookup(self.logger, csr, self.header_info_field, handler_hifield) - if hil_value: - self.logger.debug('CAhandler._profile_check(): setting %s to %s', handler_hifield, hil_value) - self.profile_id = hil_value - setattr(self, handler_hifield, hil_value) else: self.logger.error('CAhandler._profile_check(): eab_profiling enabled but no handler defined') + elif self.header_info_field: + # no profiling - parse profileid from http_header + hil_value = header_info_lookup(self.logger, csr, self.header_info_field, handler_hifield) + if hil_value: + self.logger.debug('CAhandler._profile_check(): setting %s to %s', handler_hifield, hil_value) + setattr(self, handler_hifield, hil_value) self.logger.debug('CAhandler._profile_check() ended with %s', error) return error From daf1409ab2235df4472f5d90d738effd6e8995b7 Mon Sep 17 00:00:00 2001 From: grindsa Date: Tue, 9 Apr 2024 18:40:03 +0200 Subject: [PATCH 164/460] [fix] unittests --- test/test_certifier_handler.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test_certifier_handler.py b/test/test_certifier_handler.py index 109afedb..a71a044f 100644 --- a/test/test_certifier_handler.py +++ b/test/test_certifier_handler.py @@ -1303,7 +1303,7 @@ def test_116__eab_profile_string_check(self, mock_eab, mock_hil): @patch('examples.ca_handler.certifier_ca_handler.CAhandler._eab_profile_check') def test_117__eab_profile_string_check(self, mock_eab, mock_hil): """ test eab_profile_string_check """ - self.cahandler.eab_profiling = True + self.cahandler.eab_profiling = False self.cahandler.eab_handler = None self.cahandler.header_info_field = 'profile_id' self.cahandler.profile_id = 'profile_id' @@ -1317,7 +1317,7 @@ def test_117__eab_profile_string_check(self, mock_eab, mock_hil): @patch('examples.ca_handler.certifier_ca_handler.CAhandler._eab_profile_check') def test_118__eab_profile_string_check(self, mock_eab, mock_hil): """ test eab_profile_string_check """ - self.cahandler.eab_profiling = True + self.cahandler.eab_profiling = False self.cahandler.eab_handler = None self.cahandler.header_info_field = 'profile_id' self.cahandler.profile_id = 'profile_id' From 90664795edd9be55774baf4b231266ed39218ba1 Mon Sep 17 00:00:00 2001 From: grindsa Date: Tue, 9 Apr 2024 19:38:39 +0200 Subject: [PATCH 165/460] [fix] xca_template in testdb --- test/ca/acme2certifier-clean.xdb | Bin 200704 -> 200704 bytes test/test_xca_ca_handler.py | 3 ++- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/test/ca/acme2certifier-clean.xdb b/test/ca/acme2certifier-clean.xdb index b34e6972e8c58f3416728bad2bff54999a1d4114..d1f712dae3c3a444515214b838bd0634d2b11255 100644 GIT binary patch delta 2360 zcmeHIYiv|S6u#%qeQtN}Y$Q1LVdQA zF$=h3lcHwH){|}YL*6t;mzv)!*D^ zhP%w($hIXL{9%8e$G2*cyQIKVTwG8Z-Q`*uZFChz$6YniTvutdGV{}PD|T}DCwv~C z!bkAi_+=c%t=Nxia4~jL!?(2t2P%dBaHJy`YHJNfmW1jWpQwNOxo3shXd(2PUEQ65 zUX!M$wIOKst15D;JuU5KS0D*3fQY%Z&+K8zi%Vq-azb}M%OoE?SmfNCf;{jbm#u8i zu0SZzX4Z#0%+QR11dMWkW^jg=G?WFc<}-o5&Rz;5CT@vz&WJ71a8b&zTRbdF=edM@ z>3l59ep(v7TqnqNAOb|^Mw=$gXyWCx*!V;OTGm#z#aPjA1lCn`8Y{|-R->xQSh=2! zVZ+;R)EZ2_*l04Syk<4i3o$)9_8BW$Vymx;pj%k7{_AHtqJyf-H}S9dM|?4sxcLj5 zqaXpc=Y8PhWhAJfiSly{sJ36PLu^uV&3{Z7@q@Zty@ju_RroAjcN{Ne>H`f)?=Y=R zD}ATq>TAEc(Z@4HKkLa5WrV;n91_^kiueqN*~XWsi8Iv1G5i=)eE8O4+=nlxr|#Lf z#NlabWeQJ>+7H78JV!(TB4QNr2&t-oI1olY2GvcYjQbmpvXt2wsB3DBJJ<4Ui-MT{ z-hJ0LGl_a~*YWrc0={_H%bDZJk1wQQ#*b$vUKXanBy56g_!gIp^r$?Up+CGva@~VQ zdg(u_B)%nGS?GZ9eN{8qLm$IT<;)~|L@06nUtRB3*Bf?=o!uz`AL8%?K8KItLp06% zG5IEwpWn*ro4d;EEp>Z6Wo5pal5(RA#X*nZrF?OTx4OE*ZTJLR!b#4_9pw_5Ez_0* zmbL1%8dEz|hjL2Uu2jh1$@}GvvMP;9E5%9iUDV4R)jqfVY@M<`70t5mK)V(#h{Wc_n^68X=2BFc_ed4>7DtTa_s}<~yM6z8lhGMuLG(@|s9HWur*@nu~0u zbqxNcmnB=E86)H`iMHCs3fLadl5w*4NuN>g(`(mM`*zxk$dm>4Kp}Z40q(#;@`4pE zK*8uH8+c$u=T*Brjep12@h>#@7jcq+RJd0I6c7ZY02*1&t2*2qwGY7wJUEn<$R2%X x`>W0D?QWR&!(M)*o5#yXu?`0?86M+vQ&oW#6GdTEmKl{KMn!RSa*Vh8{|22{W{Cg* delta 1793 zcmd5+TWnNC7(V};b9VRawr95Vc6PVyr7chjwA(9Qs4!=HB`B=5-1-2^cIg&c+E8G@ zONtMKczFQkVF;Iqi3tzb1Y6V92T==345+~X60m3j5<-=&1hlc*IOmkAMB}rQoHH~3 z|9#&--<&zK`&ioUV`=+58392M%J?(gO7_pM;K7ojO)?Jwo-h&_`+GEtcnTyuP6N&z z;+}=hT^Da#*%3?7PrdaPB_;RG@VqHCS zvF{VN1D6Z98!yG*;KR5apTMJdFa8;?#b*XH)@Nb*W@%npbZh6djGdO1W^1`(1^i15 z8(mSF<-}qEY>w@kW>{!tX>1}Jh+an;Hj`*V5AyKC7A9*Fdfc3}lZ4UN z6TO2pJWaw0eV2jfiao}BO<3>!JFc$Xz||RgX1;}RoyIVUm>~1Dyw3o%g?Yh-cG8^C zJ4xeaBNHOECZOe!d|2O38rG0-m@k+YoNnAeoHT?t{mhlw`~cV&ziJ0TP7^WEzK5(d|K|719$-UU`@TK?vpM^dnKp%p4i2|+8hxz zm9pd6XepGid)a6eEMQA>&<>c-KF&c+FpoKM(KBe-EOt&qUdU&6G*kkG%;iFU2(Tj> z(%6YHa6a-lr%vsYcH81ktKdF;R#-7y z!vcAz3^e+-_!PM5sOW`UYM17Ni!PLkA%|{|9^=`=QW0d+Gg39rPVjLSEtIQywpDgR zCfy;==GmiiKFpvW$wB1IVv#&_05aMAJoGEfV5ynt8e}BTc~KQ0y_mJ;q7ckwZx~$> zyOGQHa1MJ?Lj-2Cmo&7@Yv&*9fB6Hy3yR-5f^Xq*oZ|P$=eWQoN>H9!F)SH_TIaoH z(HOi?^o|QzMM>E*T77va2+9)WI=+Nc29xtn;~E3yzf?6-wu&O;4s0>`t&Mf(P5$yP zA8a@IJ6C4DW$cEGFA8`BU;MN5FkUoWS~dq?O#Jj8YnambUf|c@Z~Ph@OFH+#H7rS@ z04(K$?4)!I Date: Wed, 10 Apr 2024 06:30:45 +0200 Subject: [PATCH 166/460] [fix] dns_validation_pause_timer --- acme_srv/challenge.py | 11 ++++++++ test/test_challenge.py | 60 ++++++++++++++++++++++++++++-------------- 2 files changed, 51 insertions(+), 20 deletions(-) diff --git a/acme_srv/challenge.py b/acme_srv/challenge.py index 9382f12f..34059790 100644 --- a/acme_srv/challenge.py +++ b/acme_srv/challenge.py @@ -3,6 +3,7 @@ # pylint: disable=r0913 from __future__ import print_function import json +import time from typing import List, Tuple, Dict from acme_srv.helper import generate_random_string, parse_url, load_config, jwk_thumbprint_get, url_get, sha256_hash, sha256_hash_hex, b64_encode, b64_url_encode, txt_get, fqdn_resolve, uts_now, uts_to_date_utc, servercert_get, cert_san_get, cert_extensions_get, fqdn_in_san_check, proxy_check, error_dic_get, ip_validate from acme_srv.db_handler import DBstore @@ -23,6 +24,7 @@ def __init__(self, debug: bool = False, srv_name: str = None, logger: object = N self.expiry = expiry self.challenge_validation_disable = False self.challenge_validation_timeout = 10 + self.dns_validation_pause_timer = 0.5 self.tnauthlist_support = False self.sectigo_sim = False self.dns_server_list = None @@ -87,6 +89,9 @@ def _challenge_validate(self, pub_key: Dict[str, str], challenge_name: str, chal if result or invalid: # break loop if we got any good or bad response break + elif challenge_dic['type'] == 'dns-01' and jwk_thumbprint: + # sleep for a while before we try again + time.sleep(self.dns_validation_pause_timer) self.logger.debug('Challenge._challenge_validate() ended with: %s/%s', result, invalid) return (result, invalid) @@ -185,6 +190,12 @@ def _config_challenge_load(self, config_dic: Dict[str, str]): except Exception as err_: self.logger.warning('Challenge._config_load() failed to load challenge_validation_timeout: %s', err_) + if 'dns_validation_pause_timer' in config_dic['Challenge']: + try: + self.dns_validation_pause_timer = int(config_dic['Challenge']['dns_validation_pause_timer']) + except Exception as err_: + self.logger.warning('Challenge._config_load() failed to load dns_validation_pause_timer: %s', err_) + self.logger.debug('Challenge._config_challenge_load() ended') def _config_load(self): diff --git a/test/test_challenge.py b/test/test_challenge.py index 9bae1d87..2e6ac685 100644 --- a/test/test_challenge.py +++ b/test/test_challenge.py @@ -397,21 +397,24 @@ def test_042_challenge__validate_tkauth_challenge(self): """ test Chalölenge.validate_tkauth_challenge() """ self.assertEqual((True, False), self.challenge._validate_tkauth_challenge('cert_name', 'type', 'fqdn', 'token', 'jwk_thumbprint', 'payload')) - def test_043_challenge__check(self): + @patch('time.sleep') + def test_043_challenge__check(self, mock_sleep): """ challenge check with incorrect challenge-dictionary """ # self.challenge.dbstore.challenge_lookup.return_value = {'token' : 'token', 'type' : 'http-01', 'status' : 'pending'} self.challenge.dbstore.challenge_lookup.return_value = {} self.assertEqual((False, False), self.challenge._check('name', 'payload')) - def test_044_challenge__check(self): + @patch('time.sleep') + def test_044_challenge__check(self, mock_sleep): """ challenge check with without jwk return """ self.challenge.dbstore.challenge_lookup.return_value = {'authorization__value' : 'authorization__value', 'type' : 'type', 'token' : 'token', 'authorization__order__account__name' : 'authorization__order__account__name'} self.challenge.dbstore.jwk_load.return_value = None self.assertEqual((False, False), self.challenge._check('name', 'payload')) + @patch('time.sleep') @patch('acme_srv.challenge.Challenge._validate_alpn_challenge') @patch('acme_srv.challenge.jwk_thumbprint_get') - def test_045_challenge__check(self, mock_jwk, mock_chall): + def test_045_challenge__check(self, mock_jwk, mock_chall, mock_sleep): """ challenge check with with failed tls-alpn challenge - for loop returns data during 1st iteration """ self.challenge.dbstore.challenge_lookup.return_value = {'authorization__type' : 'authorization__type', 'authorization__value' : 'authorization__value', 'type' : 'tls-alpn-01', 'token' : 'token', 'authorization__order__account__name' : 'authorization__order__account__name'} self.challenge.dbstore.jwk_load.return_value = 'pub_key' @@ -420,9 +423,10 @@ def test_045_challenge__check(self, mock_jwk, mock_chall): self.assertEqual((False, 'foo'), self.challenge._check('name', 'payload')) self.assertTrue(mock_chall.called) + @patch('time.sleep') @patch('acme_srv.challenge.Challenge._validate_alpn_challenge') @patch('acme_srv.challenge.jwk_thumbprint_get') - def test_046_challenge__check(self, mock_jwk, mock_chall): + def test_046_challenge__check(self, mock_jwk, mock_chall, mock_sleep): """ challenge check with with failed tls-alpn challenge - - for loop returns data during 2nd iteration """ self.challenge.dbstore.challenge_lookup.return_value = {'authorization__type' : 'authorization__type', 'authorization__value' : 'authorization__value', 'type' : 'tls-alpn-01', 'token' : 'token', 'authorization__order__account__name' : 'authorization__order__account__name'} self.challenge.dbstore.jwk_load.return_value = 'pub_key' @@ -431,9 +435,10 @@ def test_046_challenge__check(self, mock_jwk, mock_chall): self.assertEqual((False, 'foo'), self.challenge._check('name', 'payload')) self.assertTrue(mock_chall.called) + @patch('time.sleep') @patch('acme_srv.challenge.Challenge._validate_alpn_challenge') @patch('acme_srv.challenge.jwk_thumbprint_get') - def test_047_challenge__check(self, mock_jwk, mock_chall): + def test_047_challenge__check(self, mock_jwk, mock_chall, mock_sleep): """ challenge check with with failed tls-alpn challenge - - for loop returns data during 6th iteration """ self.challenge.dbstore.challenge_lookup.return_value = {'authorization__type' : 'authorization__type', 'authorization__value' : 'authorization__value', 'type' : 'tls-alpn-01', 'token' : 'token', 'authorization__order__account__name' : 'authorization__order__account__name'} self.challenge.dbstore.jwk_load.return_value = 'pub_key' @@ -442,9 +447,10 @@ def test_047_challenge__check(self, mock_jwk, mock_chall): self.assertEqual((False, False), self.challenge._check('name', 'payload')) self.assertTrue(mock_chall.called) + @patch('time.sleep') @patch('acme_srv.challenge.Challenge._validate_alpn_challenge') @patch('acme_srv.challenge.jwk_thumbprint_get') - def test_048_challenge__check(self, mock_jwk, mock_chall): + def test_048_challenge__check(self, mock_jwk, mock_chall, mock_sleep): """ challenge check with with succ tls-alpn challenge """ self.challenge.dbstore.challenge_lookup.return_value = {'authorization__type' : 'authorization__type', 'authorization__value' : 'authorization__value', 'type' : 'tls-alpn-01', 'token' : 'token', 'authorization__order__account__name' : 'authorization__order__account__name'} self.challenge.dbstore.jwk_load.return_value = 'pub_key' @@ -453,9 +459,10 @@ def test_048_challenge__check(self, mock_jwk, mock_chall): self.assertEqual((True, 'foo'), self.challenge._check('name', 'payload')) self.assertTrue(mock_chall.called) + @patch('time.sleep') @patch('acme_srv.challenge.Challenge._validate_http_challenge') @patch('acme_srv.challenge.jwk_thumbprint_get') - def test_049_challenge__check(self, mock_jwk, mock_chall): + def test_049_challenge__check(self, mock_jwk, mock_chall, mock_sleep): """ challenge check with with failed http challenge - for loop returns data during 1st iteration """ self.challenge.dbstore.challenge_lookup.return_value = {'authorization__type' : 'authorization__type', 'authorization__value' : 'authorization__value', 'type' : 'http-01', 'token' : 'token', 'authorization__order__account__name' : 'authorization__order__account__name'} self.challenge.dbstore.jwk_load.return_value = 'pub_key' @@ -463,9 +470,10 @@ def test_049_challenge__check(self, mock_jwk, mock_chall): mock_jwk.return_value = 'jwk_thumbprint' self.assertEqual((False, 'foo'), self.challenge._check('name', 'payload')) + @patch('time.sleep') @patch('acme_srv.challenge.Challenge._validate_http_challenge') @patch('acme_srv.challenge.jwk_thumbprint_get') - def test_050_challenge__check(self, mock_jwk, mock_chall): + def test_050_challenge__check(self, mock_jwk, mock_chall, mock_sleep): """ challenge check with with failed http challenge - for loop returns data during 2nd iteration """ self.challenge.dbstore.challenge_lookup.return_value = {'authorization__type' : 'authorization__type', 'authorization__value' : 'authorization__value', 'type' : 'http-01', 'token' : 'token', 'authorization__order__account__name' : 'authorization__order__account__name'} self.challenge.dbstore.jwk_load.return_value = 'pub_key' @@ -473,9 +481,10 @@ def test_050_challenge__check(self, mock_jwk, mock_chall): mock_jwk.return_value = 'jwk_thumbprint' self.assertEqual((False, 'foo'), self.challenge._check('name', 'payload')) + @patch('time.sleep') @patch('acme_srv.challenge.Challenge._validate_http_challenge') @patch('acme_srv.challenge.jwk_thumbprint_get') - def test_051_challenge__check(self, mock_jwk, mock_chall): + def test_051_challenge__check(self, mock_jwk, mock_chall, mock_sleep): """ challenge check with with succ http challenge - for loop returns data during 1st iteration """ self.challenge.dbstore.challenge_lookup.return_value = {'authorization__type' : 'authorization__type', 'authorization__value' : 'authorization__value', 'type' : 'http-01', 'token' : 'token', 'authorization__order__account__name' : 'authorization__order__account__name'} self.challenge.dbstore.jwk_load.return_value = 'pub_key' @@ -483,9 +492,10 @@ def test_051_challenge__check(self, mock_jwk, mock_chall): mock_jwk.return_value = 'jwk_thumbprint' self.assertEqual((True, 'foo'), self.challenge._check('name', 'payload')) + @patch('time.sleep') @patch('acme_srv.challenge.Challenge._validate_http_challenge') @patch('acme_srv.challenge.jwk_thumbprint_get') - def test_052_challenge__check(self, mock_jwk, mock_chall): + def test_052_challenge__check(self, mock_jwk, mock_chall, mock_sleep): """ challenge check with with succ http challenge - for loop returns data during 2nd iteration """ self.challenge.dbstore.challenge_lookup.return_value = {'authorization__type' : 'authorization__type', 'authorization__value' : 'authorization__value', 'type' : 'http-01', 'token' : 'token', 'authorization__order__account__name' : 'authorization__order__account__name'} self.challenge.dbstore.jwk_load.return_value = 'pub_key' @@ -493,9 +503,10 @@ def test_052_challenge__check(self, mock_jwk, mock_chall): mock_jwk.return_value = 'jwk_thumbprint' self.assertEqual((True, 'foo'), self.challenge._check('name', 'payload')) + @patch('time.sleep') @patch('acme_srv.challenge.Challenge._validate_dns_challenge') @patch('acme_srv.challenge.jwk_thumbprint_get') - def test_053_challenge__check(self, mock_jwk, mock_chall): + def test_053_challenge__check(self, mock_jwk, mock_chall, mock_sleep): """ challenge check with with failed dns challenge - for loop returns data during 1st iteration """ self.challenge.dbstore.challenge_lookup.return_value = {'authorization__type' : 'authorization__type', 'authorization__value' : 'authorization__value', 'type' : 'dns-01', 'token' : 'token', 'authorization__order__account__name' : 'authorization__order__account__name'} self.challenge.dbstore.jwk_load.return_value = 'pub_key' @@ -503,9 +514,10 @@ def test_053_challenge__check(self, mock_jwk, mock_chall): mock_jwk.return_value = 'jwk_thumbprint' self.assertEqual((True, 'foo'), self.challenge._check('name', 'payload')) + @patch('time.sleep') @patch('acme_srv.challenge.Challenge._validate_dns_challenge') @patch('acme_srv.challenge.jwk_thumbprint_get') - def test_054_challenge__check(self, mock_jwk, mock_chall): + def test_054_challenge__check(self, mock_jwk, mock_chall, mock_sleep): """ challenge check with with failed dns challenge - for loop returns data during 2nd iteration """ self.challenge.dbstore.challenge_lookup.return_value = {'authorization__type' : 'authorization__type', 'authorization__value' : 'authorization__value', 'type' : 'dns-01', 'token' : 'token', 'authorization__order__account__name' : 'authorization__order__account__name'} self.challenge.dbstore.jwk_load.return_value = 'pub_key' @@ -513,9 +525,10 @@ def test_054_challenge__check(self, mock_jwk, mock_chall): mock_jwk.return_value = 'jwk_thumbprint' self.assertEqual((True, 'foo'), self.challenge._check('name', 'payload')) + @patch('time.sleep') @patch('acme_srv.challenge.Challenge._validate_dns_challenge') @patch('acme_srv.challenge.jwk_thumbprint_get') - def test_055_challenge__check(self, mock_jwk, mock_chall): + def test_055_challenge__check(self, mock_jwk, mock_chall, mock_sleep): """ challenge check with with succ http challenge - for loop returns data during 1st iteration """ self.challenge.dbstore.challenge_lookup.return_value = {'authorization__type' : 'authorization__type', 'authorization__value' : 'authorization__value', 'type' : 'dns-01', 'token' : 'token', 'authorization__order__account__name' : 'authorization__order__account__name'} self.challenge.dbstore.jwk_load.return_value = 'pub_key' @@ -523,9 +536,10 @@ def test_055_challenge__check(self, mock_jwk, mock_chall): mock_jwk.return_value = 'jwk_thumbprint' self.assertTrue((False, 'foo'), self.challenge._check('name', 'payload')) + @patch('time.sleep') @patch('acme_srv.challenge.Challenge._validate_dns_challenge') @patch('acme_srv.challenge.jwk_thumbprint_get') - def test_056_challenge__check(self, mock_jwk, mock_chall): + def test_056_challenge__check(self, mock_jwk, mock_chall, mock_sleep): """ challenge check with with succ http challenge - for loop returns data during 2nd iteration """ self.challenge.dbstore.challenge_lookup.return_value = {'authorization__type' : 'authorization__type', 'authorization__value' : 'authorization__value', 'type' : 'dns-01', 'token' : 'token', 'authorization__order__account__name' : 'authorization__order__account__name'} self.challenge.dbstore.jwk_load.return_value = 'pub_key' @@ -533,9 +547,10 @@ def test_056_challenge__check(self, mock_jwk, mock_chall): mock_jwk.return_value = 'jwk_thumbprint' self.assertTrue((False, 'foo'), self.challenge._check('name', 'payload')) + @patch('time.sleep') @patch('acme_srv.challenge.Challenge._validate_tkauth_challenge') @patch('acme_srv.challenge.jwk_thumbprint_get') - def test_057_challenge__check(self, mock_jwk, mock_chall): + def test_057_challenge__check(self, mock_jwk, mock_chall, mock_sleep): """ challenge check with with failed tkauth challenge tnauthlist_support not configured """ self.challenge.dbstore.challenge_lookup.return_value = {'authorization__type' : 'authorization__type', 'authorization__value' : 'authorization__value', 'type' : 'tkauth-01', 'token' : 'token', 'authorization__order__account__name' : 'authorization__order__account__name'} self.challenge.dbstore.jwk_load.return_value = 'pub_key' @@ -546,9 +561,10 @@ def test_057_challenge__check(self, mock_jwk, mock_chall): self.assertFalse(mock_chall.called) self.assertIn('ERROR:test_a2c:unknown challenge type "tkauth-01". Setting check result to False', lcm.output) + @patch('time.sleep') @patch('acme_srv.challenge.Challenge._validate_tkauth_challenge') @patch('acme_srv.challenge.jwk_thumbprint_get') - def test_058_challenge__check(self, mock_jwk, mock_chall): + def test_058_challenge__check(self, mock_jwk, mock_chall, mock_sleep): """ challenge check with with failed tkauth challenge tnauthlist_support True - for loop returns data during 1st iteration """ self.challenge.dbstore.challenge_lookup.return_value = {'authorization__type' : 'authorization__type', 'authorization__value' : 'authorization__value', 'type' : 'tkauth-01', 'token' : 'token', 'authorization__order__account__name' : 'authorization__order__account__name'} self.challenge.dbstore.jwk_load.return_value = 'pub_key' @@ -558,9 +574,10 @@ def test_058_challenge__check(self, mock_jwk, mock_chall): self.assertEqual((False, 'foo'), self.challenge._check('name', 'payload')) self.assertTrue(mock_chall.called) + @patch('time.sleep') @patch('acme_srv.challenge.Challenge._validate_tkauth_challenge') @patch('acme_srv.challenge.jwk_thumbprint_get') - def test_059_challenge__check(self, mock_jwk, mock_chall): + def test_059_challenge__check(self, mock_jwk, mock_chall, mock_sleep): """ challenge check with with failed tkauth challenge tnauthlist_support True - for loop returns data during 2nd iteration """ self.challenge.dbstore.challenge_lookup.return_value = {'authorization__type' : 'authorization__type', 'authorization__value' : 'authorization__value', 'type' : 'tkauth-01', 'token' : 'token', 'authorization__order__account__name' : 'authorization__order__account__name'} self.challenge.dbstore.jwk_load.return_value = 'pub_key' @@ -570,9 +587,10 @@ def test_059_challenge__check(self, mock_jwk, mock_chall): self.assertEqual((False, 'foo'), self.challenge._check('name', 'payload')) self.assertTrue(mock_chall.called) + @patch('time.sleep') @patch('acme_srv.challenge.Challenge._validate_tkauth_challenge') @patch('acme_srv.challenge.jwk_thumbprint_get') - def test_060_challenge__check(self, mock_jwk, mock_chall): + def test_060_challenge__check(self, mock_jwk, mock_chall, mock_sleep): """ challenge check with with succ tkauth challenge and tnauthlist_support unset """ self.challenge.dbstore.challenge_lookup.return_value = {'authorization__type' : 'authorization__type', 'authorization__value' : 'authorization__value', 'type' : 'tkauth-01', 'token' : 'token', 'authorization__order__account__name' : 'authorization__order__account__name'} self.challenge.dbstore.jwk_load.return_value = 'pub_key' @@ -582,9 +600,10 @@ def test_060_challenge__check(self, mock_jwk, mock_chall): self.assertEqual((False, True), self.challenge._check('name', 'payload')) self.assertFalse(mock_chall.called) + @patch('time.sleep') @patch('acme_srv.challenge.Challenge._validate_tkauth_challenge') @patch('acme_srv.challenge.jwk_thumbprint_get') - def test_061_challenge__check(self, mock_jwk, mock_chall): + def test_061_challenge__check(self, mock_jwk, mock_chall, mock_sleep): """ challenge check with with succ tkauth challenge and tnauthlist support set - for loop returns data during 1st iteration """ self.challenge.dbstore.challenge_lookup.return_value = {'authorization__type' : 'authorization__type', 'authorization__value' : 'authorization__value', 'type' : 'tkauth-01', 'token' : 'token', 'authorization__order__account__name' : 'authorization__order__account__name'} self.challenge.dbstore.jwk_load.return_value = 'pub_key' @@ -593,9 +612,10 @@ def test_061_challenge__check(self, mock_jwk, mock_chall): mock_jwk.return_value = 'jwk_thumbprint' self.assertEqual((True, 'foo'), self.challenge._check('name', 'payload')) + @patch('time.sleep') @patch('acme_srv.challenge.Challenge._validate_tkauth_challenge') @patch('acme_srv.challenge.jwk_thumbprint_get') - def test_062_challenge__check(self, mock_jwk, mock_chall): + def test_062_challenge__check(self, mock_jwk, mock_chall, mock_sleep): """ challenge check with with succ tkauth challenge and tnauthlist support set - for loop returns data during 2nd iteration """ self.challenge.dbstore.challenge_lookup.return_value = {'authorization__type' : 'authorization__type', 'authorization__value' : 'authorization__value', 'type' : 'tkauth-01', 'token' : 'token', 'authorization__order__account__name' : 'authorization__order__account__name'} self.challenge.dbstore.jwk_load.return_value = 'pub_key' From 03e17d8220706e1ee20df5d43b087e4a7491fc6c Mon Sep 17 00:00:00 2001 From: grindsa Date: Thu, 11 Apr 2024 07:47:10 +0200 Subject: [PATCH 167/460] [fix] headerinfo workflow --- .../{test_headerinfo.yml => headerinfo.yml} | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) rename .github/workflows/{test_headerinfo.yml => headerinfo.yml} (88%) diff --git a/.github/workflows/test_headerinfo.yml b/.github/workflows/headerinfo.yml similarity index 88% rename from .github/workflows/test_headerinfo.yml rename to .github/workflows/headerinfo.yml index fd29e058..53c5e6b9 100644 --- a/.github/workflows/test_headerinfo.yml +++ b/.github/workflows/headerinfo.yml @@ -49,6 +49,11 @@ jobs: sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem sudo cp .github/django_settings.py examples/Docker/data/settings.py + sudo cp examples/ca_handler/xca_ca_handler.py examples/Docker/data/ca_handler.py + + sudo chmod 777 examples/Docker/data/ca_handler.py + sudo sed -i "s/error = self._profile_check(csr)/qset = header_info_get(self.logger, csr=csr)\n if qset:\n self.logger.info('header_info: %s', qset[-1]['header_info'])/g" examples/Docker/data/ca_handler.py + sudo sed -i "s/header_info_field_validate, config_headerinfo_get, config_eab_profile_load/header_info_get, header_info_field_validate, config_headerinfo_get, config_eab_profile_load/g" examples/Docker/data/ca_handler.py sudo mkdir -p examples/Docker/data/xca sudo chmod -R 777 examples/Docker/data/xca sudo cp test/ca/acme2certifier-clean.xdb examples/Docker/data/xca/$XCA_DB_NAME @@ -57,7 +62,7 @@ jobs: sudo touch examples/Docker/data/acme_srv.cfg sudo chmod 777 examples/Docker/data/acme_srv.cfg sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg - sudo echo "handler_file: /var/www/acme2certifier/examples/ca_handler/xca_ca_handler.py" >> examples/Docker/data/acme_srv.cfg + # sudo echo "handler_file: /var/www/acme2certifier/examples/ca_handler/xca_ca_handler.py" >> examples/Docker/data/acme_srv.cfg sudo echo "xdb_file: volume/xca/$XCA_DB_NAME" >> examples/Docker/data/acme_srv.cfg sudo echo "issuing_ca_name: $XCA_ISSUING_CA" >> examples/Docker/data/acme_srv.cfg sudo echo "passphrase: $XCA_PASSPHRASE" >> examples/Docker/data/acme_srv.cfg @@ -113,7 +118,7 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: _wsgi_header_info-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz + name: header_info-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ header_info_tests_rpm: @@ -172,10 +177,16 @@ jobs: sudo cp test/ca/acme2certifier-clean.xdb data/acme_ca/$XCA_DB_NAME sudo mkdir -p examples/Docker/data/acme_ca/certs sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem data/acme_ca/ + + sudo cp examples/ca_handler/xca_ca_handler.py data/acme_ca/ca_handler.py + sudo chmod 777 data/acme_ca/ca_handler.py + sudo sed -i "s/error = self._profile_check(csr)/qset = header_info_get(self.logger, csr=csr)\n if qset:\n self.logger.info('header_info: %s', qset[-1]['header_info'])/g" data/acme_ca/ca_handler.py + sudo sed -i "s/header_info_field_validate, config_headerinfo_get, config_eab_profile_load/header_info_get, header_info_field_validate, config_headerinfo_get, config_eab_profile_load/g" data/acme_ca/ca_handler.py + sudo touch data/acme_srv.cfg sudo chmod 777 data/acme_srv.cfg sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/acme_srv.cfg - sudo echo "handler_file: /opt/acme2certifier/examples/ca_handler/xca_ca_handler.py" >> data/acme_srv.cfg + sudo echo "handler_file: /opt/acme2certifier/volume/acme_ca/ca_handler.py" >> data/acme_srv.cfg sudo echo "xdb_file: volume/acme_ca/$XCA_DB_NAME" >> data/acme_srv.cfg sudo echo "issuing_ca_name: $XCA_ISSUING_CA" >> data/acme_srv.cfg sudo echo "passphrase: $XCA_PASSPHRASE" >> data/acme_srv.cfg @@ -312,10 +323,16 @@ jobs: mkdir -p data/volume/acme_ca/certs sudo cp test/ca/acme2certifier-clean.xdb data/volume/acme_ca/$XCA_DB_NAME sudo cp test/ca/sub-ca-key.pem test/ca/sub-ca-crl.pem test/ca/sub-ca-cert.pem test/ca/root-ca-cert.pem data/volume/acme_ca/ + + sudo cp examples/ca_handler/xca_ca_handler.py data/volume/ca_handler.py + sudo chmod 777 data/volume/ca_handler.py + sudo sed -i "s/error = self._profile_check(csr)/qset = header_info_get(self.logger, csr=csr)\n if qset:\n self.logger.info('header_info: %s', qset[-1]['header_info'])/g" data/volume/ca_handler.py + sudo sed -i "s/header_info_field_validate, config_headerinfo_get, config_eab_profile_load/header_info_get, header_info_field_validate, config_headerinfo_get, config_eab_profile_load/g" data/volume/ca_handler.py + sudo touch data/volume/acme_srv.cfg sudo chmod 777 data/volume/acme_srv.cfg sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/volume/acme_srv.cfg - sudo echo "handler_file: /opt/acme2certifier/examples/ca_handler/xca_ca_handler.py" >> data/volume/acme_srv.cfg + sudo echo "handler_file: /opt/acme2certifier/volume/ca_handler.py" >> data/volume/acme_srv.cfg sudo echo "xdb_file: volume/acme_ca/$XCA_DB_NAME" >> data/volume/acme_srv.cfg sudo echo "issuing_ca_name: $XCA_ISSUING_CA" >> data/volume/acme_srv.cfg sudo echo "passphrase: $XCA_PASSPHRASE" >> data/volume/acme_srv.cfg From 4496d248775ce5f93a2369baef947a0ecf420e75 Mon Sep 17 00:00:00 2001 From: grindsa Date: Thu, 11 Apr 2024 07:51:25 +0200 Subject: [PATCH 168/460] [fix] refactor config_headerinfo_get --- .github/workflows/headerinfo.yml | 6 +++--- acme_srv/helper.py | 8 +++---- examples/ca_handler/asa_ca_handler.py | 4 ++-- examples/ca_handler/certifier_ca_handler.py | 4 ++-- examples/ca_handler/mscertsrv_ca_handler.py | 4 ++-- examples/ca_handler/mswcce_ca_handler.py | 4 ++-- examples/ca_handler/xca_ca_handler.py | 4 ++-- test/test_asa_ca_handler.py | 18 ++++++++-------- test/test_helper.py | 24 ++++++++++----------- test/test_msca_handler.py | 18 ++++++++-------- test/test_mswcce_ca_handler.py | 18 ++++++++-------- 11 files changed, 56 insertions(+), 56 deletions(-) diff --git a/.github/workflows/headerinfo.yml b/.github/workflows/headerinfo.yml index 53c5e6b9..a5668530 100644 --- a/.github/workflows/headerinfo.yml +++ b/.github/workflows/headerinfo.yml @@ -53,7 +53,7 @@ jobs: sudo chmod 777 examples/Docker/data/ca_handler.py sudo sed -i "s/error = self._profile_check(csr)/qset = header_info_get(self.logger, csr=csr)\n if qset:\n self.logger.info('header_info: %s', qset[-1]['header_info'])/g" examples/Docker/data/ca_handler.py - sudo sed -i "s/header_info_field_validate, config_headerinfo_get, config_eab_profile_load/header_info_get, header_info_field_validate, config_headerinfo_get, config_eab_profile_load/g" examples/Docker/data/ca_handler.py + sudo sed -i "s/header_info_field_validate, config_headerinfo_load, config_eab_profile_load/header_info_get, header_info_field_validate, config_headerinfo_load, config_eab_profile_load/g" examples/Docker/data/ca_handler.py sudo mkdir -p examples/Docker/data/xca sudo chmod -R 777 examples/Docker/data/xca sudo cp test/ca/acme2certifier-clean.xdb examples/Docker/data/xca/$XCA_DB_NAME @@ -181,7 +181,7 @@ jobs: sudo cp examples/ca_handler/xca_ca_handler.py data/acme_ca/ca_handler.py sudo chmod 777 data/acme_ca/ca_handler.py sudo sed -i "s/error = self._profile_check(csr)/qset = header_info_get(self.logger, csr=csr)\n if qset:\n self.logger.info('header_info: %s', qset[-1]['header_info'])/g" data/acme_ca/ca_handler.py - sudo sed -i "s/header_info_field_validate, config_headerinfo_get, config_eab_profile_load/header_info_get, header_info_field_validate, config_headerinfo_get, config_eab_profile_load/g" data/acme_ca/ca_handler.py + sudo sed -i "s/header_info_field_validate, config_headerinfo_load, config_eab_profile_load/header_info_get, header_info_field_validate, config_headerinfo_load, config_eab_profile_load/g" data/acme_ca/ca_handler.py sudo touch data/acme_srv.cfg sudo chmod 777 data/acme_srv.cfg @@ -327,7 +327,7 @@ jobs: sudo cp examples/ca_handler/xca_ca_handler.py data/volume/ca_handler.py sudo chmod 777 data/volume/ca_handler.py sudo sed -i "s/error = self._profile_check(csr)/qset = header_info_get(self.logger, csr=csr)\n if qset:\n self.logger.info('header_info: %s', qset[-1]['header_info'])/g" data/volume/ca_handler.py - sudo sed -i "s/header_info_field_validate, config_headerinfo_get, config_eab_profile_load/header_info_get, header_info_field_validate, config_headerinfo_get, config_eab_profile_load/g" data/volume/ca_handler.py + sudo sed -i "s/header_info_field_validate, config_headerinfo_load, config_eab_profile_load/header_info_get, header_info_field_validate, config_headerinfo_load, config_eab_profile_load/g" data/volume/ca_handler.py sudo touch data/volume/acme_srv.cfg sudo chmod 777 data/volume/acme_srv.cfg diff --git a/acme_srv/helper.py b/acme_srv/helper.py index 5ca8fc38..b6e7d0bc 100644 --- a/acme_srv/helper.py +++ b/acme_srv/helper.py @@ -167,18 +167,18 @@ def config_eab_profile_load(logger: logging.Logger, config_dic: Dict[str, str]): return eab_profiling, eab_handler -def config_headerinfo_get(logger: logging.Logger, config_dic: Dict[str, str]): +def config_headerinfo_load(logger: logging.Logger, config_dic: Dict[str, str]): """ load parameters """ - logger.debug('config_headerinfo_get()') + logger.debug('config_headerinfo_load()') header_info_field = None if 'Order' in config_dic and 'header_info_list' in config_dic['Order'] and config_dic['Order']['header_info_list']: try: header_info_field = json.loads(config_dic['Order']['header_info_list'])[0] except Exception as err_: - logger.warning('Helper.config_headerinfo_get() header_info_list failed with error: %s', err_) + logger.warning('Helper.config_headerinfo_load() header_info_list failed with error: %s', err_) - logger.debug('config_headerinfo_get() ended') + logger.debug('config_headerinfo_load() ended') return header_info_field diff --git a/examples/ca_handler/asa_ca_handler.py b/examples/ca_handler/asa_ca_handler.py index 9d551cc8..6273c661 100644 --- a/examples/ca_handler/asa_ca_handler.py +++ b/examples/ca_handler/asa_ca_handler.py @@ -117,7 +117,7 @@ def _certificates_list(self) -> Dict[str, str]: self.logger.debug('CAhandler._certificates_list() ended') return api_response - def _config_headerinfo_get(self, config_dic: Dict[str, str]): + def _config_headerinfo_load(self, config_dic: Dict[str, str]): """ load parameters """ self.logger.debug('_config_header_info()') @@ -190,7 +190,7 @@ def _config_load(self): config_dic = load_config(self.logger, 'CAhandler') # load headerinfos - self._config_headerinfo_get(config_dic) + self._config_headerinfo_load(config_dic) if 'CAhandler' in config_dic: self._config_host_load(config_dic['CAhandler']) diff --git a/examples/ca_handler/certifier_ca_handler.py b/examples/ca_handler/certifier_ca_handler.py index d1eede36..7ee8fa2e 100644 --- a/examples/ca_handler/certifier_ca_handler.py +++ b/examples/ca_handler/certifier_ca_handler.py @@ -10,7 +10,7 @@ import requests from requests.auth import HTTPBasicAuth # pylint: disable=e0401 -from acme_srv.helper import load_config, cert_serial_get, uts_now, uts_to_date_utc, b64_decode, b64_encode, cert_pem2der, parse_url, proxy_check, error_dic_get, header_info_field_validate, header_info_lookup, config_eab_profile_load, config_headerinfo_get +from acme_srv.helper import load_config, cert_serial_get, uts_now, uts_to_date_utc, b64_decode, b64_encode, cert_pem2der, parse_url, proxy_check, error_dic_get, header_info_field_validate, header_info_lookup, config_eab_profile_load, config_headerinfo_load class CAhandler(object): @@ -307,7 +307,7 @@ def _config_load(self): # load profiling self.eab_profiling, self.eab_handler = config_eab_profile_load(self.logger, config_dic) # load header info - self.header_info_field = config_headerinfo_get(self.logger, config_dic) + self.header_info_field = config_headerinfo_load(self.logger, config_dic) # load proxy configuration self._config_proxy_load(config_dic) diff --git a/examples/ca_handler/mscertsrv_ca_handler.py b/examples/ca_handler/mscertsrv_ca_handler.py index fb558f5b..889fc492 100644 --- a/examples/ca_handler/mscertsrv_ca_handler.py +++ b/examples/ca_handler/mscertsrv_ca_handler.py @@ -60,7 +60,7 @@ def _cert_bundle_create(self, ca_pem: str = None, cert_raw: str = None) -> Tuple return (error, cert_bundle, cert_raw) - def _config_headerinfo_get(self, config_dic: Dict[str, str]): + def _config_headerinfo_load(self, config_dic: Dict[str, str]): """ load parameters """ self.logger.debug('_config_header_info()') @@ -159,7 +159,7 @@ def _config_load(self): self._config_user_load(config_dic) self._config_password_load(config_dic) self._config_parameters_load(config_dic) - self._config_headerinfo_get(config_dic) + self._config_headerinfo_load(config_dic) # load proxy config self._config_proxy_load(config_dic) diff --git a/examples/ca_handler/mswcce_ca_handler.py b/examples/ca_handler/mswcce_ca_handler.py index 656952ac..b87d644f 100644 --- a/examples/ca_handler/mswcce_ca_handler.py +++ b/examples/ca_handler/mswcce_ca_handler.py @@ -46,7 +46,7 @@ def __enter__(self): def __exit__(self, *args): """close the connection at the end of the context""" - def _config_headerinfo_get(self, config_dic: Dict[str, str]): + def _config_headerinfo_load(self, config_dic: Dict[str, str]): """ load parameters """ self.logger.debug('_config_header_info()') @@ -146,7 +146,7 @@ def _config_load(self): self._config_host_load(config_dic) self._config_credentials_load(config_dic) self._config_parameters_load(config_dic) - self._config_headerinfo_get(config_dic) + self._config_headerinfo_load(config_dic) self._config_proxy_load(config_dic) diff --git a/examples/ca_handler/xca_ca_handler.py b/examples/ca_handler/xca_ca_handler.py index 7d557065..a1fee055 100644 --- a/examples/ca_handler/xca_ca_handler.py +++ b/examples/ca_handler/xca_ca_handler.py @@ -14,7 +14,7 @@ from cryptography.x509.oid import ExtendedKeyUsageOID from OpenSSL import crypto as pyossslcrypto # pylint: disable=e0401 -from acme_srv.helper import load_config, build_pem_file, uts_now, uts_to_date_utc, b64_encode, b64_decode, b64_url_recode, cert_serial_get, convert_string_to_byte, convert_byte_to_string, csr_cn_get, csr_san_get, error_dic_get, header_info_lookup, header_info_field_validate, config_headerinfo_get, config_eab_profile_load +from acme_srv.helper import load_config, build_pem_file, uts_now, uts_to_date_utc, b64_encode, b64_decode, b64_url_recode, cert_serial_get, convert_string_to_byte, convert_byte_to_string, csr_cn_get, csr_san_get, error_dic_get, header_info_lookup, header_info_field_validate, config_headerinfo_load, config_eab_profile_load DEFAULT_DATE_FORMAT = '%Y%m%d%H%M%SZ' @@ -358,7 +358,7 @@ def _config_load(self): # load profiling self.eab_profiling, self.eab_handler = config_eab_profile_load(self.logger, config_dic) # load header info - self.header_info_field = config_headerinfo_get(self.logger, config_dic) + self.header_info_field = config_headerinfo_load(self.logger, config_dic) def _csr_import(self, csr, request_name): """ check existance of csr and load into db """ diff --git a/test/test_asa_ca_handler.py b/test/test_asa_ca_handler.py index bad2cf77..016832ae 100644 --- a/test/test_asa_ca_handler.py +++ b/test/test_asa_ca_handler.py @@ -906,23 +906,23 @@ def test_063_config_password_load(self): # self.assertIn("foo", lcm.output) self.assertFalse(self.cahandler.profile_name) - def test_064_config_headerinfo_get(self): - """ test config_headerinfo_get()""" + def test_064_config_headerinfo_load(self): + """ test config_headerinfo_load()""" config_dic = {'Order': {'header_info_list': '["foo", "bar", "foobar"]'}} - self.cahandler._config_headerinfo_get(config_dic) + self.cahandler._config_headerinfo_load(config_dic) self.assertEqual( 'foo', self.cahandler.header_info_field) - def test_065_config_headerinfo_get(self): - """ test config_headerinfo_get()""" + def test_065_config_headerinfo_load(self): + """ test config_headerinfo_load()""" config_dic = {'Order': {'header_info_list': '["foo"]'}} - self.cahandler._config_headerinfo_get(config_dic) + self.cahandler._config_headerinfo_load(config_dic) self.assertEqual( 'foo', self.cahandler.header_info_field) - def test_066_config_headerinfo_get(self): - """ test config_headerinfo_get()""" + def test_066_config_headerinfo_load(self): + """ test config_headerinfo_load()""" config_dic = {'Order': {'header_info_list': 'foo'}} with self.assertLogs('test_a2c', level='INFO') as lcm: - self.cahandler._config_headerinfo_get(config_dic) + self.cahandler._config_headerinfo_load(config_dic) self.assertFalse(self.cahandler.header_info_field) self.assertIn('WARNING:test_a2c:Order._config_orderconfig_load() header_info_list failed with error: Expecting value: line 1 column 1 (char 0)', lcm.output) diff --git a/test/test_helper.py b/test/test_helper.py index 9fd0c39d..2770d2eb 100644 --- a/test/test_helper.py +++ b/test/test_helper.py @@ -26,7 +26,7 @@ def setUp(self): """ setup unittest """ import logging logging.basicConfig(level=logging.CRITICAL) - from acme_srv.helper import b64decode_pad, b64_decode, b64_encode, b64_url_encode, b64_url_recode, convert_string_to_byte, convert_byte_to_string, decode_message, decode_deserialize, get_url, generate_random_string, signature_check, validate_email, uts_to_date_utc, date_to_uts_utc, load_config, cert_serial_get, cert_san_get, cert_san_pyopenssl_get, cert_dates_get, build_pem_file, date_to_datestr, datestr_to_date, dkeys_lower, csr_cn_get, cert_pubkey_get, csr_pubkey_get, url_get, url_get_with_own_dns, dns_server_list_load, csr_san_get, csr_san_byte_get, csr_extensions_get, fqdn_resolve, fqdn_in_san_check, sha256_hash, sha256_hash_hex, cert_der2pem, cert_pem2der, cert_extensions_get, csr_dn_get, logger_setup, logger_info, print_debug, jwk_thumbprint_get, allowed_gai_family, patched_create_connection, validate_csr, servercert_get, txt_get, proxystring_convert, proxy_check, handle_exception, ca_handler_load, eab_handler_load, hooks_load, error_dic_get, _logger_nonce_modify, _logger_certificate_modify, _logger_token_modify, _logger_challenges_modify, config_check, cert_issuer_get, cert_cn_get, string_sanitize, pembundle_to_list, certid_asn1_get, certid_check, certid_hex_get, v6_adjust, ipv6_chk, ip_validate, header_info_get, encode_url, uts_now, cert_ski_get, cert_ski_pyopenssl_get, cert_aki_get, cert_aki_pyopenssl_get, validate_fqdn, validate_ip, validate_identifier, header_info_field_validate, header_info_lookup, config_eab_profile_load, config_headerinfo_get + from acme_srv.helper import b64decode_pad, b64_decode, b64_encode, b64_url_encode, b64_url_recode, convert_string_to_byte, convert_byte_to_string, decode_message, decode_deserialize, get_url, generate_random_string, signature_check, validate_email, uts_to_date_utc, date_to_uts_utc, load_config, cert_serial_get, cert_san_get, cert_san_pyopenssl_get, cert_dates_get, build_pem_file, date_to_datestr, datestr_to_date, dkeys_lower, csr_cn_get, cert_pubkey_get, csr_pubkey_get, url_get, url_get_with_own_dns, dns_server_list_load, csr_san_get, csr_san_byte_get, csr_extensions_get, fqdn_resolve, fqdn_in_san_check, sha256_hash, sha256_hash_hex, cert_der2pem, cert_pem2der, cert_extensions_get, csr_dn_get, logger_setup, logger_info, print_debug, jwk_thumbprint_get, allowed_gai_family, patched_create_connection, validate_csr, servercert_get, txt_get, proxystring_convert, proxy_check, handle_exception, ca_handler_load, eab_handler_load, hooks_load, error_dic_get, _logger_nonce_modify, _logger_certificate_modify, _logger_token_modify, _logger_challenges_modify, config_check, cert_issuer_get, cert_cn_get, string_sanitize, pembundle_to_list, certid_asn1_get, certid_check, certid_hex_get, v6_adjust, ipv6_chk, ip_validate, header_info_get, encode_url, uts_now, cert_ski_get, cert_ski_pyopenssl_get, cert_aki_get, cert_aki_pyopenssl_get, validate_fqdn, validate_ip, validate_identifier, header_info_field_validate, header_info_lookup, config_eab_profile_load, config_headerinfo_load self.logger = logging.getLogger('test_a2c') self.allowed_gai_family = allowed_gai_family self.b64_decode = b64_decode @@ -112,7 +112,7 @@ def setUp(self): self.encode_url = encode_url self.uts_now = uts_now self.ip_validate = ip_validate - self.config_headerinfo_get = config_headerinfo_get + self.config_headerinfo_load = config_headerinfo_load self.config_eab_profile_load = config_eab_profile_load def test_001_helper_b64decode_pad(self): @@ -2374,22 +2374,22 @@ def test_314_header_info_lookup(self, mock_info, mock_json): self.assertFalse(self.header_info_lookup(self.logger, 'csr', 'header_info_field', 'foo1')) self.assertIn('ERROR:test_a2c:header_info_lookup() could not parse header_info_field: mock_json', lcm.output) - def test_315_config_headerinfo_get(self): - """ test config_headerinfo_get()""" + def test_315_config_headerinfo_load(self): + """ test config_headerinfo_load()""" config_dic = {'Order': {'header_info_list': '["foo", "bar", "foobar"]'}} - self.assertEqual('foo', self.config_headerinfo_get(self.logger, config_dic)) + self.assertEqual('foo', self.config_headerinfo_load(self.logger, config_dic)) - def test_316_config_headerinfo_get(self): - """ test config_headerinfo_get()""" + def test_316_config_headerinfo_load(self): + """ test config_headerinfo_load()""" config_dic = {'Order': {'header_info_list': '["foo"]'}} - self.assertEqual('foo', self.config_headerinfo_get(self.logger, config_dic)) + self.assertEqual('foo', self.config_headerinfo_load(self.logger, config_dic)) - def test_317_config_headerinfo_get(self): - """ test config_headerinfo_get()""" + def test_317_config_headerinfo_load(self): + """ test config_headerinfo_load()""" config_dic = {'Order': {'header_info_list': 'foo'}} with self.assertLogs('test_a2c', level='INFO') as lcm: - self.assertFalse(self.config_headerinfo_get(self.logger, config_dic)) - self.assertIn('WARNING:test_a2c:Helper.config_headerinfo_get() header_info_list failed with error: Expecting value: line 1 column 1 (char 0)', lcm.output) + self.assertFalse(self.config_headerinfo_load(self.logger, config_dic)) + self.assertIn('WARNING:test_a2c:Helper.config_headerinfo_load() header_info_list failed with error: Expecting value: line 1 column 1 (char 0)', lcm.output) @patch('acme_srv.helper.eab_handler_load') def test_318_config_eab_profile_load(self, mock_eabload): diff --git a/test/test_msca_handler.py b/test/test_msca_handler.py index c165a117..8fb1514f 100644 --- a/test/test_msca_handler.py +++ b/test/test_msca_handler.py @@ -507,23 +507,23 @@ def test_046_template_name_get(self, mock_header): self.assertFalse(self.cahandler._template_name_get('csr')) self.assertIn('ERROR:test_a2c:CAhandler._template_name_get() could not parse template: Expecting value: line 1 column 1 (char 0)', lcm.output) - def test_047_config_headerinfo_get(self): - """ test config_headerinfo_get()""" + def test_047_config_headerinfo_load(self): + """ test config_headerinfo_load()""" config_dic = {'Order': {'header_info_list': '["foo", "bar", "foobar"]'}} - self.cahandler._config_headerinfo_get(config_dic) + self.cahandler._config_headerinfo_load(config_dic) self.assertEqual( 'foo', self.cahandler.header_info_field) - def test_048_config_headerinfo_get(self): - """ test config_headerinfo_get()""" + def test_048_config_headerinfo_load(self): + """ test config_headerinfo_load()""" config_dic = {'Order': {'header_info_list': '["foo"]'}} - self.cahandler._config_headerinfo_get(config_dic) + self.cahandler._config_headerinfo_load(config_dic) self.assertEqual( 'foo', self.cahandler.header_info_field) - def test_049_config_headerinfo_get(self): - """ test config_headerinfo_get()""" + def test_049_config_headerinfo_load(self): + """ test config_headerinfo_load()""" config_dic = {'Order': {'header_info_list': 'foo'}} with self.assertLogs('test_a2c', level='INFO') as lcm: - self.cahandler._config_headerinfo_get(config_dic) + self.cahandler._config_headerinfo_load(config_dic) self.assertFalse(self.cahandler.header_info_field) self.assertIn('WARNING:test_a2c:Order._config_orderconfig_load() header_info_list failed with error: Expecting value: line 1 column 1 (char 0)', lcm.output) diff --git a/test/test_mswcce_ca_handler.py b/test/test_mswcce_ca_handler.py index 2d05103f..bb0d1863 100644 --- a/test/test_mswcce_ca_handler.py +++ b/test/test_mswcce_ca_handler.py @@ -785,23 +785,23 @@ def test_050_template_name_get(self, mock_header): self.assertFalse(self.cahandler._template_name_get('csr')) self.assertIn('ERROR:test_a2c:CAhandler._template_name_get() could not parse template: Expecting value: line 1 column 1 (char 0)', lcm.output) - def test_051_config_headerinfo_get(self): - """ test config_headerinfo_get()""" + def test_051_config_headerinfo_load(self): + """ test config_headerinfo_load()""" config_dic = {'Order': {'header_info_list': '["foo", "bar", "foobar"]'}} - self.cahandler._config_headerinfo_get(config_dic) + self.cahandler._config_headerinfo_load(config_dic) self.assertEqual( 'foo', self.cahandler.header_info_field) - def test_052_config_headerinfo_get(self): - """ test config_headerinfo_get()""" + def test_052_config_headerinfo_load(self): + """ test config_headerinfo_load()""" config_dic = {'Order': {'header_info_list': '["foo"]'}} - self.cahandler._config_headerinfo_get(config_dic) + self.cahandler._config_headerinfo_load(config_dic) self.assertEqual( 'foo', self.cahandler.header_info_field) - def test_053_config_headerinfo_get(self): - """ test config_headerinfo_get()""" + def test_053_config_headerinfo_load(self): + """ test config_headerinfo_load()""" config_dic = {'Order': {'header_info_list': 'foo'}} with self.assertLogs('test_a2c', level='INFO') as lcm: - self.cahandler._config_headerinfo_get(config_dic) + self.cahandler._config_headerinfo_load(config_dic) self.assertFalse(self.cahandler.header_info_field) self.assertIn('WARNING:test_a2c:Order._config_orderconfig_load() header_info_list failed with error: Expecting value: line 1 column 1 (char 0)', lcm.output) From 5ff88d6918cdeb303bafeb53a8aafa317ef245a2 Mon Sep 17 00:00:00 2001 From: grindsa Date: Thu, 11 Apr 2024 11:07:38 +0200 Subject: [PATCH 169/460] [fix] fix xca workflow --- .github/workflows/ca_handler_tests_xca.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ca_handler_tests_xca.yml b/.github/workflows/ca_handler_tests_xca.yml index 28dc7d0a..7ee4e409 100644 --- a/.github/workflows/ca_handler_tests_xca.yml +++ b/.github/workflows/ca_handler_tests_xca.yml @@ -272,7 +272,7 @@ jobs: openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature, Non Repudiation" - openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Server Authentication, Code Signing" + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Client Authentication, Code Signing" - name: "Header-info - 02 - Enroll lego with template_name template" run: | @@ -281,7 +281,7 @@ jobs: sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext keyUsage | grep "Digital Signature, Non Repudiation" - sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Server Authentication, Code Signing" + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Client Authentication, Code Signing" - name: "EAB - Setup a2c with xca_ca_handler - profiling" run: | From f7d9cd46829f6739575e5c6bcb1ac9f2cfe943c5 Mon Sep 17 00:00:00 2001 From: grindsa Date: Thu, 11 Apr 2024 15:45:11 +0200 Subject: [PATCH 170/460] [fix] xca-workflow extendedKeyUsage --- .github/workflows/ca_handler_tests_xca.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ca_handler_tests_xca.yml b/.github/workflows/ca_handler_tests_xca.yml index 7ee4e409..481974de 100644 --- a/.github/workflows/ca_handler_tests_xca.yml +++ b/.github/workflows/ca_handler_tests_xca.yml @@ -348,7 +348,7 @@ jobs: openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature, Non Repudiation" - openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Server Authentication, Code Signing" + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Client Authentication, Code Signing" - name: "EAB - 01 - Enroll lego with a template_name taken from list in kid.json" run: | @@ -357,7 +357,7 @@ jobs: sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext keyUsage | grep "Digital Signature, Non Repudiation" - sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Server Authentication, Code Signing" + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Client Authentication, Code Signing" - name: "EAB - 02a - Enroll acme with a template_name taken from header_info NOT included in kid.json (to fail)" id: acmefail01 @@ -417,7 +417,7 @@ jobs: openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature, Non Repudiation" - openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Server Authentication, Code Signing" + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Client Authentication, Code Signing" - name: "EAB - 03 - Enroll lego with a template_name/ca_name taken from kid.json" run: | @@ -428,7 +428,7 @@ jobs: sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext keyUsage | grep "Digital Signature, Non Repudiation" - sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Server Authentication, Code Signing" + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Client Authentication, Code Signing" - name: "EAB - 04 - Enroll acme with a not allowed fqdn in kid.json (to fail)" id: acmefail02 @@ -767,7 +767,7 @@ jobs: openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature, Non Repudiation" - openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Server Authentication, Code Signing" + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Client Authentication, Code Signing" - name: "Header-info - 02 - Enroll lego with template_name template" run: | @@ -776,7 +776,7 @@ jobs: sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext keyUsage | grep "Digital Signature, Non Repudiation" - sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Server Authentication, Code Signing" + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Client Authentication, Code Signing" - name: "EAB - Setup a2c with xca_ca_handler" run: | @@ -834,7 +834,7 @@ jobs: openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature, Non Repudiation" - openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Server Authentication, Code Signing" + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Client Authentication, Code Signing" - name: "EAB - 01 - Enroll lego with a template_name taken from list in kid.json" run: | @@ -845,7 +845,7 @@ jobs: sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext keyUsage | grep "Digital Signature, Non Repudiation" - sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Server Authentication, Code Signing" + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Client Authentication, Code Signing" - name: "EAB - 02a - Enroll acme with a template_name taken from header_info NOT included in kid.json (to fail)" id: acmefail01 @@ -905,7 +905,7 @@ jobs: openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature, Non Repudiation" - openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Server Authentication, Code Signing" + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Client Authentication, Code Signing" - name: "EAB - 03 - Enroll lego with a template_name/ca_name taken from kid.json" run: | @@ -916,7 +916,7 @@ jobs: sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext keyUsage | grep "Digital Signature, Non Repudiation" - sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Server Authentication, Code Signing" + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Client Authentication, Code Signing" - name: "EAB - 04 - Enroll acme with a not allowed fqdn in kid.json (to fail)" id: acmefail02 From bbf3fe3c58be825ab69c7ef6f4cdc3d099c8f379 Mon Sep 17 00:00:00 2001 From: grindsa Date: Thu, 11 Apr 2024 18:28:33 +0200 Subject: [PATCH 171/460] [fix] reject unknown options when eab-profiling is enabled --- examples/ca_handler/certifier_ca_handler.py | 8 +++----- examples/ca_handler/xca_ca_handler.py | 8 +++----- test/test_certifier_handler.py | 16 +++++----------- test/test_xca_ca_handler.py | 4 ++-- 4 files changed, 13 insertions(+), 23 deletions(-) diff --git a/examples/ca_handler/certifier_ca_handler.py b/examples/ca_handler/certifier_ca_handler.py index 7ee8fa2e..cdcc4d28 100644 --- a/examples/ca_handler/certifier_ca_handler.py +++ b/examples/ca_handler/certifier_ca_handler.py @@ -535,11 +535,9 @@ def _eab_profile_check(self, csr: str, handler_hifield: str) -> str: if result: break - # we need to cover cases where profiling is enabled but no profile_id is defined in json - if self.header_info_field and handler_hifield not in eab_profile_dic: - hil_value = header_info_lookup(self.logger, csr, self.header_info_field, handler_hifield) - if hil_value: - setattr(self, handler_hifield, hil_value) + # we need to reject situations where profiling is enabled but the header_hifiled is not defined in json + if self.header_info_field and not result and handler_hifield not in eab_profile_dic: + result = f'header_info field "{handler_hifield}" is not allowed by profile' self.logger.debug('CAhandler._eab_profile_check() ended with: %s', result) return result diff --git a/examples/ca_handler/xca_ca_handler.py b/examples/ca_handler/xca_ca_handler.py index a1fee055..666c4025 100644 --- a/examples/ca_handler/xca_ca_handler.py +++ b/examples/ca_handler/xca_ca_handler.py @@ -959,11 +959,9 @@ def _eab_profile_check(self, csr: str, handler_hifield: str) -> str: if result: break - # we need to cover cases where profiling is enabled but no profile_id is defined in json - if self.header_info_field and handler_hifield not in eab_profile_dic: - hil_value = header_info_lookup(self.logger, csr, self.header_info_field, handler_hifield) - if hil_value: - setattr(self, handler_hifield, hil_value) + # we need to reject situations where profiling is enabled but the header_hifiled is not defined in json + if self.header_info_field and not result and handler_hifield not in eab_profile_dic: + result = f'header_info field "{handler_hifield}" is not allowed by profile' self.logger.debug('CAhandler._eab_profile_check() ended with: %s', result) return result diff --git a/test/test_certifier_handler.py b/test/test_certifier_handler.py index a71a044f..e744a600 100644 --- a/test/test_certifier_handler.py +++ b/test/test_certifier_handler.py @@ -1198,9 +1198,8 @@ def test_109__eab_profile_check(self, mock_hil): self.assertEqual('profile_id', self.cahandler.profile_id) self.assertFalse(mock_hil.called) - @patch('examples.ca_handler.certifier_ca_handler.header_info_lookup') @patch('examples.ca_handler.certifier_ca_handler.header_info_field_validate') - def test_110__eab_profile_check(self, mock_hiv, mock_hil): + def test_110__eab_profile_check(self, mock_hiv): """ test eab_profile_check """ self.cahandler.eab_handler = MagicMock() self.cahandler.api_host = 'api_host' @@ -1209,23 +1208,20 @@ def test_110__eab_profile_check(self, mock_hiv, mock_hil): self.cahandler.profile_id = 'profile_id' self.cahandler.header_info_field = 'header_info_field' mock_hiv.return_value = ('hil_value', None) - mock_hil.return_value = 'mock_hil' self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'unknown': ['foobar', 'barfoo']} self.cahandler.eab_handler.return_value.__enter__.return_value.allowed_domains_check.return_value = None with self.assertLogs('test_a2c', level='INFO') as lcm: - self.assertFalse(self.cahandler._eab_profile_check('csr', 'profile_id')) + self.assertEqual('header_info field "profile_id" is not allowed by profile', self.cahandler._eab_profile_check('csr', 'profile_id')) self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) self.assertIn("ERROR:test_a2c:CAhandler._eab_profile_list_check(): ignore list attribute: key: unknown value: ['foobar', 'barfoo']", lcm.output) self.assertEqual('api_host', self.cahandler.api_host) self.assertEqual('api_user', self.cahandler.api_user) self.assertEqual('api_password', self.cahandler.api_password) self.assertFalse(mock_hiv.called) - self.assertTrue(mock_hil.called) - self.assertEqual('mock_hil', self.cahandler.profile_id) + self.assertEqual('profile_id', self.cahandler.profile_id) - @patch('examples.ca_handler.certifier_ca_handler.header_info_lookup') @patch('examples.ca_handler.certifier_ca_handler.header_info_field_validate') - def test_111__eab_profile_check(self, mock_hiv, mock_hil): + def test_111__eab_profile_check(self, mock_hiv): """ test eab_profile_check """ self.cahandler.eab_handler = MagicMock() self.cahandler.api_host = 'api_host' @@ -1234,11 +1230,10 @@ def test_111__eab_profile_check(self, mock_hiv, mock_hil): self.cahandler.profile_id = 'profile_id' self.cahandler.header_info_field = 'header_info_field' mock_hiv.return_value = ('hil_value', None) - mock_hil.return_value = None self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'unknown': ['foobar', 'barfoo']} self.cahandler.eab_handler.return_value.__enter__.return_value.allowed_domains_check.return_value = None with self.assertLogs('test_a2c', level='INFO') as lcm: - self.assertFalse(self.cahandler._eab_profile_check('csr', 'handler_hifield')) + self.assertEqual('header_info field "handler_hifield" is not allowed by profile', self.cahandler._eab_profile_check('csr', 'handler_hifield')) self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) self.assertIn("ERROR:test_a2c:CAhandler._eab_profile_list_check(): ignore list attribute: key: unknown value: ['foobar', 'barfoo']", lcm.output) self.assertEqual('api_host', self.cahandler.api_host) @@ -1246,7 +1241,6 @@ def test_111__eab_profile_check(self, mock_hiv, mock_hil): self.assertEqual('api_password', self.cahandler.api_password) self.assertEqual('profile_id', self.cahandler.profile_id) self.assertFalse(mock_hiv.called) - self.assertTrue(mock_hil.called) @patch('examples.ca_handler.certifier_ca_handler.header_info_lookup') @patch('examples.ca_handler.certifier_ca_handler.CAhandler._eab_profile_check') diff --git a/test/test_xca_ca_handler.py b/test/test_xca_ca_handler.py index dc5b8c91..e3bae69a 100644 --- a/test/test_xca_ca_handler.py +++ b/test/test_xca_ca_handler.py @@ -2235,9 +2235,9 @@ def test_214__eab_profile_check(self, mock_hil, mock_lookup): self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar'} mock_lookup.return_value = 'mock_lookup' with self.assertLogs('test_a2c', level='INFO') as lcm: - self.assertFalse(self.cahandler._eab_profile_check('csr', 'template_name')) + self.assertEqual('header_info field "hifield" is not allowed by profile', self.cahandler._eab_profile_check('csr', 'hifield')) self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) - self.assertEqual('mock_lookup', self.cahandler.template_name) + self.assertEqual('template_name', self.cahandler.template_name) self.assertEqual('issuing_ca_key', self.cahandler.issuing_ca_key) self.assertEqual('issuing_ca_name', self.cahandler.issuing_ca_name) self.assertEqual('passphrase', self.cahandler.passphrase) From e5f6b4a7a62fa5e34216b9a792892c17febdb137 Mon Sep 17 00:00:00 2001 From: grindsa Date: Thu, 11 Apr 2024 19:06:15 +0200 Subject: [PATCH 172/460] [fix] cornercase handling for empty strings --- examples/ca_handler/certifier_ca_handler.py | 7 +++++-- examples/ca_handler/xca_ca_handler.py | 7 +++++-- test/test_certifier_handler.py | 12 ++++++++--- test/test_xca_ca_handler.py | 22 +++++++++++++++++++++ 4 files changed, 41 insertions(+), 7 deletions(-) diff --git a/examples/ca_handler/certifier_ca_handler.py b/examples/ca_handler/certifier_ca_handler.py index cdcc4d28..924a1ade 100644 --- a/examples/ca_handler/certifier_ca_handler.py +++ b/examples/ca_handler/certifier_ca_handler.py @@ -536,8 +536,11 @@ def _eab_profile_check(self, csr: str, handler_hifield: str) -> str: break # we need to reject situations where profiling is enabled but the header_hifiled is not defined in json - if self.header_info_field and not result and handler_hifield not in eab_profile_dic: - result = f'header_info field "{handler_hifield}" is not allowed by profile' + if self.header_info_field and handler_hifield not in eab_profile_dic: + hil_value = header_info_lookup(self.logger, csr, self.header_info_field, handler_hifield) + if hil_value: + # setattr(self, handler_hifield, hil_value) + result = f'header_info field "{handler_hifield}" is not allowed by profile' self.logger.debug('CAhandler._eab_profile_check() ended with: %s', result) return result diff --git a/examples/ca_handler/xca_ca_handler.py b/examples/ca_handler/xca_ca_handler.py index 666c4025..1502b5c9 100644 --- a/examples/ca_handler/xca_ca_handler.py +++ b/examples/ca_handler/xca_ca_handler.py @@ -960,8 +960,11 @@ def _eab_profile_check(self, csr: str, handler_hifield: str) -> str: break # we need to reject situations where profiling is enabled but the header_hifiled is not defined in json - if self.header_info_field and not result and handler_hifield not in eab_profile_dic: - result = f'header_info field "{handler_hifield}" is not allowed by profile' + if self.header_info_field and handler_hifield not in eab_profile_dic: + hil_value = header_info_lookup(self.logger, csr, self.header_info_field, handler_hifield) + if hil_value: + # setattr(self, handler_hifield, hil_value) + result = f'header_info field "{handler_hifield}" is not allowed by profile' self.logger.debug('CAhandler._eab_profile_check() ended with: %s', result) return result diff --git a/test/test_certifier_handler.py b/test/test_certifier_handler.py index e744a600..44a7d110 100644 --- a/test/test_certifier_handler.py +++ b/test/test_certifier_handler.py @@ -1198,8 +1198,9 @@ def test_109__eab_profile_check(self, mock_hil): self.assertEqual('profile_id', self.cahandler.profile_id) self.assertFalse(mock_hil.called) + @patch('examples.ca_handler.certifier_ca_handler.header_info_lookup') @patch('examples.ca_handler.certifier_ca_handler.header_info_field_validate') - def test_110__eab_profile_check(self, mock_hiv): + def test_110__eab_profile_check(self, mock_hiv, mock_hil): """ test eab_profile_check """ self.cahandler.eab_handler = MagicMock() self.cahandler.api_host = 'api_host' @@ -1208,6 +1209,7 @@ def test_110__eab_profile_check(self, mock_hiv): self.cahandler.profile_id = 'profile_id' self.cahandler.header_info_field = 'header_info_field' mock_hiv.return_value = ('hil_value', None) + mock_hil.return_value = 'mock_hil' self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'unknown': ['foobar', 'barfoo']} self.cahandler.eab_handler.return_value.__enter__.return_value.allowed_domains_check.return_value = None with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -1219,9 +1221,12 @@ def test_110__eab_profile_check(self, mock_hiv): self.assertEqual('api_password', self.cahandler.api_password) self.assertFalse(mock_hiv.called) self.assertEqual('profile_id', self.cahandler.profile_id) + self.assertTrue(mock_hil.called) + self.assertEqual('profile_id', self.cahandler.profile_id) + @patch('examples.ca_handler.certifier_ca_handler.header_info_lookup') @patch('examples.ca_handler.certifier_ca_handler.header_info_field_validate') - def test_111__eab_profile_check(self, mock_hiv): + def test_111__eab_profile_check(self, mock_hiv, mock_hil): """ test eab_profile_check """ self.cahandler.eab_handler = MagicMock() self.cahandler.api_host = 'api_host' @@ -1230,10 +1235,11 @@ def test_111__eab_profile_check(self, mock_hiv): self.cahandler.profile_id = 'profile_id' self.cahandler.header_info_field = 'header_info_field' mock_hiv.return_value = ('hil_value', None) + mock_hil.return_value = None self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'unknown': ['foobar', 'barfoo']} self.cahandler.eab_handler.return_value.__enter__.return_value.allowed_domains_check.return_value = None with self.assertLogs('test_a2c', level='INFO') as lcm: - self.assertEqual('header_info field "handler_hifield" is not allowed by profile', self.cahandler._eab_profile_check('csr', 'handler_hifield')) + self.assertFalse(self.cahandler._eab_profile_check('csr', 'handler_hifield')) self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) self.assertIn("ERROR:test_a2c:CAhandler._eab_profile_list_check(): ignore list attribute: key: unknown value: ['foobar', 'barfoo']", lcm.output) self.assertEqual('api_host', self.cahandler.api_host) diff --git a/test/test_xca_ca_handler.py b/test/test_xca_ca_handler.py index e3bae69a..61f9a021 100644 --- a/test/test_xca_ca_handler.py +++ b/test/test_xca_ca_handler.py @@ -2242,7 +2242,29 @@ def test_214__eab_profile_check(self, mock_hil, mock_lookup): self.assertEqual('issuing_ca_name', self.cahandler.issuing_ca_name) self.assertEqual('passphrase', self.cahandler.passphrase) self.assertFalse(mock_hil.called) + self.assertTrue(mock_lookup.called) + @patch('examples.ca_handler.xca_ca_handler.header_info_lookup') + @patch('examples.ca_handler.xca_ca_handler.header_info_field_validate') + def test_215__eab_profile_check(self, mock_hil, mock_lookup): + """ test eab_profile_check """ + self.cahandler.eab_handler = MagicMock() + self.cahandler.template_name = 'template_name' + self.cahandler.issuing_ca_key = 'issuing_ca_key' + self.cahandler.issuing_ca_name = 'issuing_ca_name' + self.cahandler.passphrase = 'passphrase' + self.cahandler.header_info_field = 'template_name' + self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar'} + mock_lookup.return_value = None + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.cahandler._eab_profile_check('csr', 'hifield')) + self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) + self.assertEqual('template_name', self.cahandler.template_name) + self.assertEqual('issuing_ca_key', self.cahandler.issuing_ca_key) + self.assertEqual('issuing_ca_name', self.cahandler.issuing_ca_name) + self.assertEqual('passphrase', self.cahandler.passphrase) + self.assertFalse(mock_hil.called) + self.assertTrue(mock_lookup.called) if __name__ == '__main__': From eb2cecdc398ef9cca072e3f4832df407d64e232d Mon Sep 17 00:00:00 2001 From: grindsa Date: Thu, 11 Apr 2024 20:15:48 +0200 Subject: [PATCH 173/460] [wf] extended header_info tests --- .../workflows/ca_handler_tests_certifier.yml | 54 +++++++++++++++++ .github/workflows/ca_handler_tests_xca.yml | 58 +++++++++++++++++-- 2 files changed, 108 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ca_handler_tests_certifier.yml b/.github/workflows/ca_handler_tests_certifier.yml index 8c617ac4..ad48ac70 100644 --- a/.github/workflows/ca_handler_tests_certifier.yml +++ b/.github/workflows/ca_handler_tests_certifier.yml @@ -505,6 +505,33 @@ jobs: sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "Code Signing" + - name: "EAB - 06 - Enroll acme with not allowed headerinfo-field (should fail)" + id: acmefail03 + continue-on-error: true + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --useragent profile_id=101 -d acme-sh.acme --standalone --debug 3 --output-insecure + + - name: "EAB - 06 - check result " + if: steps.acmefail03.outcome != 'failure' + run: | + echo "acmefail outcome is ${{steps.acmefail03.outcome }}" + exit 1 + + - name: "EAB - 06 - Enroll lego with not allowed headerinfo-field (should fail)" + id: legofail03 + continue-on-error: true + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM --user-agent profile_id=101 -d lego.acme --http run + + - name: "EAB - 06 - check result " + if: steps.legofail03.outcome != 'failure' + run: | + echo "legofail outcome is ${{steps.legofail03.outcome }}" + exit 1 + - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | @@ -1024,6 +1051,33 @@ jobs: sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "Code Signing" + - name: "EAB - 06 - Enroll acme with not allowed headerinfo-field (should fail)" + id: acmefail03 + continue-on-error: true + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --useragent profile_id=101 -d acme-sh.acme --standalone --debug 3 --output-insecure + + - name: "EAB - 06 - check result " + if: steps.acmefail03.outcome != 'failure' + run: | + echo "acmefail outcome is ${{steps.acmefail03.outcome }}" + exit 1 + + - name: "EAB - 06 - Enroll lego with not allowed headerinfo-field (should fail)" + id: legofail03 + continue-on-error: true + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM --user-agent profile_id=101 -d lego.acme --http run + + - name: "EAB - 06 - check result " + if: steps.legofail03.outcome != 'failure' + run: | + echo "legofail outcome is ${{steps.legofail03.outcome }}" + exit 1 + - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | diff --git a/.github/workflows/ca_handler_tests_xca.yml b/.github/workflows/ca_handler_tests_xca.yml index 481974de..e8749d5b 100644 --- a/.github/workflows/ca_handler_tests_xca.yml +++ b/.github/workflows/ca_handler_tests_xca.yml @@ -63,7 +63,6 @@ jobs: # sudo echo "template_name: $XCA_TEMPLATE" >> examples/Docker/data/acme_srv.cfg cd examples/Docker/ docker-compose restart - docker-compose logs env: XCA_PASSPHRASE: ${{ secrets.XCA_PASSPHRASE }} XCA_ISSUING_CA: ${{ secrets.XCA_ISSUING_CA }} @@ -142,7 +141,6 @@ jobs: sudo echo "template_name: $XCA_TEMPLATE" >> examples/Docker/data/acme_srv.cfg cd examples/Docker/ docker-compose restart - docker-compose logs env: XCA_PASSPHRASE: ${{ secrets.XCA_PASSPHRASE }} XCA_ISSUING_CA: ${{ secrets.XCA_ISSUING_CA }} @@ -226,7 +224,6 @@ jobs: sudo sed -i "s/tnauthlist_support: False/tnauthlist_support: False\nheader_info_list: [\"HTTP_USER_AGENT\"]/g" examples/Docker/data/acme_srv.cfg cd examples/Docker/ docker-compose restart - docker-compose logs env: XCA_PASSPHRASE: ${{ secrets.XCA_PASSPHRASE }} XCA_ISSUING_CA: ${{ secrets.XCA_ISSUING_CA }} @@ -321,7 +318,6 @@ jobs: cd examples/Docker/ docker-compose restart - docker-compose logs env: XCA_PASSPHRASE: ${{ secrets.XCA_PASSPHRASE }} XCA_ISSUING_CA: ${{ secrets.XCA_ISSUING_CA }} @@ -479,6 +475,33 @@ jobs: sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext keyUsage | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Server Authentication, TLS Web Client Authentication" + - name: "EAB - 06 - Enroll acme with not allowed headerinfo-field (should fail)" + id: acmefail03 + continue-on-error: true + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --useragent template_name=acme -d acme-sh.acme --standalone --debug 3 --output-insecure + + - name: "EAB - 06 - check result " + if: steps.acmefail03.outcome != 'failure' + run: | + echo "acmefail outcome is ${{steps.acmefail03.outcome }}" + exit 1 + + - name: "EAB - 06 - Enroll lego with not allowed headerinfo-field (should fail)" + id: legofail03 + continue-on-error: true + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM --user-agent template_name=acme -d lego.acme --http run + + - name: "EAB - 06 - check result " + if: steps.legofail03.outcome != 'failure' + run: | + echo "legofail outcome is ${{steps.legofail03.outcome }}" + exit 1 + - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | @@ -967,6 +990,33 @@ jobs: sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext keyUsage | grep "Digital Signature, Non Repudiation, Key Encipherment, Key Agreement" sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Server Authentication, TLS Web Client Authentication" + - name: "EAB - 06 - Enroll acme with not allowed headerinfo-field (should fail)" + id: acmefail03 + continue-on-error: true + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --useragent template_name=acme -d acme-sh.acme --standalone --debug 3 --output-insecure + + - name: "EAB - 06 - check result " + if: steps.acmefail03.outcome != 'failure' + run: | + echo "acmefail outcome is ${{steps.acmefail03.outcome }}" + exit 1 + + - name: "EAB - 06 - Enroll lego with not allowed headerinfo-field (should fail)" + id: legofail03 + continue-on-error: true + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM --user-agent template_name=acme -d lego.acme --http run + + - name: "EAB - 06 - check result " + if: steps.legofail03.outcome != 'failure' + run: | + echo "legofail outcome is ${{steps.legofail03.outcome }}" + exit 1 + - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | From 6832bfa4aa622c0f92a5fe1a0e0e224608f0bee1 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 13 Apr 2024 08:24:24 +0200 Subject: [PATCH 174/460] [doc] eab_profiling documentation --- docs/certifier.md | 50 +++++++++++++++++- ...{account-profiling.md => eab_profiling.md} | 5 +- docs/xca.md | 49 ++++++++++++++++++ test/test_xca_ca_handler.py | 51 +++++++++++++++++++ 4 files changed, 150 insertions(+), 5 deletions(-) rename docs/{account-profiling.md => eab_profiling.md} (88%) diff --git a/docs/certifier.md b/docs/certifier.md index e30a5ac8..71734aa4 100644 --- a/docs/certifier.md +++ b/docs/certifier.md @@ -21,6 +21,7 @@ ca_bundle: ca_name: profile_id: polling_timeout: +eab_profiling: ``` - api_host - URL of the Certifier-REST service @@ -32,6 +33,7 @@ polling_timeout: - ca_name - name of the CA used to enroll certificates - profile_id - optional - profileId - polling_timeout - optional - polling timeout (default: 60s) +- eab_profiling - optional - [activate eab profiling](eab_profiling.md) (default: False) Depending on CA policy configuration a CSR may require approval. In such a situation acme2certfier will poll the CA server to check the CSR status. The polling interval can be configured in acme.server.cfg. @@ -72,9 +74,9 @@ The response to this call will show a dictionary containing the list of CAs incl ] ``` -## Passing a profileID from client to server +## Passing a profile_id from client to server -The handler makes use of the [header_info_list feature](header_info.md) allowing an acme-client to specify a profileID to be used during certificate enrollment. This feature is disabled by default and must be activate in `acme_srv.cfg` as shown below +The handler makes use of the [header_info_list feature](header_info.md) allowing an acme-client to specify a profile_id to be used during certificate enrollment. This feature is disabled by default and must be activate in `acme_srv.cfg` as shown below ```config [Order] @@ -96,6 +98,50 @@ Example for lego: docker run -i -v $PWD/lego:/.lego/ --rm --name lego goacme/lego -s http:// -a --email "lego@example.com" --user-agent profile_id=101 -d --http run ``` +# eab profiling + +This handler can use the [eab profiling feture](eab_profiling.md) to allow individual enrollment configuration per acme-account as well as restriction of CN and SANs to be submitted within the CSR. The feature is disabled by default and must be activated in `acme_srv.cfg` + +```cfg +[EABhandler] +eab_handler_file: examples/eab_handler/kid_profile_handler.py +key_file: + +[CAhandler] +eab_profiling: True +``` + +below an example key-file used during regression testing: + +```json +{ + "keyid_00": { + "hmac": "V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw", + "cahandler": { + "profile_id": ["p100", "p101", "p102"], + "allowed_domainlist": ["www.example.com", "www.example.org", "*.acme"] + } + }, + "keyid_01": { + "hmac": "YW5vdXRoZXJfdmVyeV9sb25nX2htYWNfZm9yX2tleWlkXzAxX3doaWNoIHdpbGxfYmUgdXNlZF9kdXJpbmcgcmVncmVzc2lvbg", + "cahandler": { + "profile_id": "102", + "allowed_domainlist": ["www.example.com", "www.example.org", "*.acme"], + "ca_name": "subca2" + } + }, + "keyid_02": { + "hmac": "dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM", + "cahandler": { + "allowed_domainlist": ["www.example.com", "www.example.org"] + } + }, + "keyid_03": { + "hmac": "YW5kX2ZpbmFsbHlfdGhlX2xhc3RfaG1hY19rZXlfd2hpY2hfaXNfbG9uZ2VyX3RoYW5fMjU2X2JpdHNfYW5kX3Nob3VsZF93b3Jr" + } +} +``` + ## CA policy configuration A csr generated by certbot client does not contain any subject name. Such csr will be refused by Certifier. To overcome this, you need a CA policy as below setting a subject name. diff --git a/docs/account-profiling.md b/docs/eab_profiling.md similarity index 88% rename from docs/account-profiling.md rename to docs/eab_profiling.md index 95627943..39613a3e 100644 --- a/docs/account-profiling.md +++ b/docs/eab_profiling.md @@ -1,6 +1,6 @@ -# Pass information from acme client to CA-handler +# EAB Profiling Starting with version 0.34 acme2certifier supports the configuration of account specific enrollment configuration. Depending on the handler to be used the feature allows the definition of individual authentication credentials, enrollment profiles or certificate authoritzies. @@ -22,7 +22,7 @@ eab_handler_file: examples/eab_handler/kid_profile_handler.py key_file: volume/kid_profiles.json ``` -The `key_file` allows the specification enrollmenmt parameters per (extenral) acme count. Main identifier is the key_id to be used during account registration. Any parameter used in the [CAhandler] configuration section of a handler can be customized. Below an example configuration to be used for [Insta Certifier](certifier.md) with some explaination: +The `key_file` allows the specification enrollmenmt parameters per (external) acme-account. Main identifier is the key_id to be used during account registration. Any parameter used in the [CAhandler] configuration section of a handler can be customized. Below an example configuration to be used for [Insta Certifier](certifier.md) with some explaination: ```json { @@ -43,7 +43,6 @@ The `key_file` allows the specification enrollmenmt parameters per (extenral) ac "allowed_domainlist": ["*.example.fi", "*.acme"], } }, - }, "keyid_02": { "hmac": "YW5kX2ZpbmFsbHlfdGhlX2xhc3RfaG1hY19rZXlfd2hpY2hfaXNfbG9uZ2VyX3RoYW5fMjU2X2JpdHNfYW5kX3Nob3VsZF93b3Jr" } diff --git a/docs/xca.md b/docs/xca.md index 9728f6f3..3320c45d 100644 --- a/docs/xca.md +++ b/docs/xca.md @@ -41,6 +41,7 @@ template_name: XCA template to be applied to CSRs - `passphrase` - *optional* - passphrase to access the database and decrypt the private CA Key - `ca_cert_chain_list` - *optional* - List of root and intermediate CA certificates to be added to the bundle return to an ACME-client (the issuing CA cert must not be included) - `template_name` - *optional* - name of the XCA template to be applied during certificate issuance +- eab_profiling - optional - [activate eab profiling](eab_profiling.md) (default: False) Template support has been introduced starting from v0.13. Support is limited to the below parameters which can be applied during certificate issuance: @@ -56,4 +57,52 @@ Template support has been introduced starting from v0.13. Support is limited to - S: StateOrProvinceName - C: CountryName + +# eab profiling + +This handler can use the [eab profiling feture](eab_profiling.md) to allow individual enrollment configuration per acme-account as well as restriction of CN and SANs to be submitted within the CSR. The feature is disabled by default and must be activated in `acme_srv.cfg` + +```cfg +[EABhandler] +eab_handler_file: examples/eab_handler/kid_profile_handler.py +key_file: + +[CAhandler] +eab_profiling: True +``` + +below an example key-file used during regression testing: + +```json +{ + "keyid_00": { + "hmac": "V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw", + "cahandler": { + "template_name": ["template", "acme"], + "allowed_domainlist": ["www.example.com", "www.example.org", "*.acme"], + "unknown_key": "unknown_value" + } + }, + "keyid_01": { + "hmac": "YW5vdXRoZXJfdmVyeV9sb25nX2htYWNfZm9yX2tleWlkXzAxX3doaWNoIHdpbGxfYmUgdXNlZF9kdXJpbmcgcmVncmVzc2lvbg", + "cahandler": { + "template_name": "template", + "allowed_domainlist": ["www.example.com", "www.example.org", "*.acme"], + "issuing_ca_name": "root-ca", + "issuing_ca_key": "root-ca" + } + }, + "keyid_02": { + "hmac": "dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM", + "cahandler": { + "allowed_domainlist": ["www.example.com", "www.example.org"] + } + }, + "keyid_03": { + "hmac": "YW5kX2ZpbmFsbHlfdGhlX2xhc3RfaG1hY19rZXlfd2hpY2hfaXNfbG9uZ2VyX3RoYW5fMjU2X2JpdHNfYW5kX3Nob3VsZF93b3Jr" + } +} +``` + + Enjoy enrolling and revoking certificates... diff --git a/test/test_xca_ca_handler.py b/test/test_xca_ca_handler.py index 61f9a021..2890ee04 100644 --- a/test/test_xca_ca_handler.py +++ b/test/test_xca_ca_handler.py @@ -2266,6 +2266,57 @@ def test_215__eab_profile_check(self, mock_hil, mock_lookup): self.assertFalse(mock_hil.called) self.assertTrue(mock_lookup.called) + def test_217__eab_profile_check(self): + """ test eab_profile_check """ + self.cahandler.eab_handler = MagicMock() + self.cahandler.template_name = 'template_name' + self.cahandler.issuing_ca_key = 'issuing_ca_key' + self.cahandler.issuing_ca_name = 'issuing_ca_name' + self.cahandler.passphrase = 'passphrase' + self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'issuing_ca_key': ['foo_key1', 'foo_key2'], 'issuing_ca_name': ['foo_ca1', 'foo_ca2']} + self.cahandler.eab_handler.return_value.__enter__.return_value.allowed_domains_check.return_value = 'domain_chk_error' + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.cahandler._eab_profile_check('csr', 'handler_hifield')) + self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) + self.assertEqual('template_name', self.cahandler.template_name) + self.assertEqual('foo_key1', self.cahandler.issuing_ca_key) + self.assertEqual('foo_ca1', self.cahandler.issuing_ca_name) + self.assertEqual('passphrase', self.cahandler.passphrase) + + def test_218__eab_profile_check(self): + """ test eab_profile_check """ + self.cahandler.eab_handler = MagicMock() + self.cahandler.template_name = 'template_name' + self.cahandler.issuing_ca_key = 'issuing_ca_key' + self.cahandler.issuing_ca_name = 'issuing_ca_name' + self.cahandler.passphrase = 'passphrase' + self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'issuing_ca_key': ['foo_key1', 'foo_key2'], 'issuing_ca_name': ['foo_ca1', 'foo_ca2']} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.cahandler._eab_profile_check('csr', 'handler_hifield')) + self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) + self.assertEqual('template_name', self.cahandler.template_name) + self.assertEqual('foo_key1', self.cahandler.issuing_ca_key) + self.assertEqual('foo_ca1', self.cahandler.issuing_ca_name) + self.assertEqual('passphrase', self.cahandler.passphrase) + + @patch('examples.ca_handler.xca_ca_handler.header_info_field_validate') + def test_219__eab_profile_check(self, mock_hiv): + """ test eab_profile_check """ + self.cahandler.eab_handler = MagicMock() + self.cahandler.template_name = 'template_name' + self.cahandler.issuing_ca_key = 'issuing_ca_key' + self.cahandler.issuing_ca_name = 'issuing_ca_name' + self.cahandler.passphrase = 'passphrase' + mock_hiv.side_effect = [('foo_key2', None), ('foo_ca2', None)] + self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'issuing_ca_key': ['foo_key1', 'foo_key2'], 'issuing_ca_name': ['foo_ca1', 'foo_ca2']} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.cahandler._eab_profile_check('csr', 'handler_hifield')) + self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) + self.assertEqual('template_name', self.cahandler.template_name) + self.assertEqual('foo_key2', self.cahandler.issuing_ca_key) + self.assertEqual('foo_ca2', self.cahandler.issuing_ca_name) + self.assertEqual('passphrase', self.cahandler.passphrase) + if __name__ == '__main__': From 0841c02d16a256a42941525a3e68fe0d746a7edc Mon Sep 17 00:00:00 2001 From: grindsa Date: Mon, 15 Apr 2024 19:13:53 +0200 Subject: [PATCH 175/460] [fix] profiling in asa_handler.py --- examples/ca_handler/asa_ca_handler.py | 137 +++++++--- test/test_asa_ca_handler.py | 367 ++++++++++++++++++++++---- 2 files changed, 409 insertions(+), 95 deletions(-) diff --git a/examples/ca_handler/asa_ca_handler.py b/examples/ca_handler/asa_ca_handler.py index 6273c661..31e581a7 100644 --- a/examples/ca_handler/asa_ca_handler.py +++ b/examples/ca_handler/asa_ca_handler.py @@ -7,7 +7,7 @@ import requests from requests.auth import HTTPBasicAuth # pylint: disable=e0401 -from acme_srv.helper import load_config, encode_url, csr_pubkey_get, csr_cn_get, csr_san_get, uts_now, uts_to_date_utc, b64_decode, cert_der2pem, convert_byte_to_string, cert_ski_get, header_info_get, csr_san_byte_get +from acme_srv.helper import load_config, encode_url, csr_pubkey_get, csr_cn_get, csr_san_get, uts_now, uts_to_date_utc, b64_decode, cert_der2pem, convert_byte_to_string, cert_ski_get, csr_san_byte_get, header_info_field_validate, header_info_lookup, config_eab_profile_load, config_headerinfo_load class CAhandler(object): @@ -27,6 +27,8 @@ def __init__(self, _debug: bool = None, logger: object = None): self.profile_name = None self.cert_validity_days = 30 self.header_info_field = False + self.eab_handler = None + self.eab_profiling = False def __enter__(self): """ Makes CAhandler a Context Manager """ @@ -117,18 +119,6 @@ def _certificates_list(self) -> Dict[str, str]: self.logger.debug('CAhandler._certificates_list() ended') return api_response - def _config_headerinfo_load(self, config_dic: Dict[str, str]): - """ load parameters """ - self.logger.debug('_config_header_info()') - - if 'Order' in config_dic and 'header_info_list' in config_dic['Order'] and config_dic['Order']['header_info_list']: - try: - self.header_info_field = json.loads(config_dic['Order']['header_info_list'])[0] - except Exception as err_: - self.logger.warning('Order._config_orderconfig_load() header_info_list failed with error: %s', err_) - - self.logger.debug('_config_header_info() ended') - def _config_key_load(self, config_dic: Dict[str, str]): """ load keyname """ self.logger.debug('_config_key_load()') @@ -189,9 +179,6 @@ def _config_load(self): config_dic = load_config(self.logger, 'CAhandler') - # load headerinfos - self._config_headerinfo_load(config_dic) - if 'CAhandler' in config_dic: self._config_host_load(config_dic['CAhandler']) self._config_user_load(config_dic['CAhandler']) @@ -221,6 +208,11 @@ def _config_load(self): self._auth_set() + # load profiling + self.eab_profiling, self.eab_handler = config_eab_profile_load(self.logger, config_dic) + # load header info + self.header_info_field = config_headerinfo_load(self.logger, config_dic) + self.logger.debug('CAhandler._config_load() ended') def _csr_cn_get(self, csr: str) -> str: @@ -390,26 +382,87 @@ def _enrollment_dic_create(self, csr: str) -> Dict[str, str]: return data_dic - def _profile_name_get(self, csr: str) -> str: - """ get profile id from csr """ - self.logger.debug('CAhandler._profile_name_get(%s)', csr) - profile_name = None + def _eab_profile_string_check(self, key, value): + self.logger.debug('CAhandler._eab_profile_string_check(): string: key: %s, value: %s', key, value) - # parse profileid from http_header - header_info = header_info_get(self.logger, csr=csr) - if header_info: - try: - header_info_dic = json.loads(header_info[-1]['header_info']) - if self.header_info_field in header_info_dic: - for ele in header_info_dic[self.header_info_field].split(' '): - if 'profile_name' in ele.lower(): - profile_name = ele.split('=')[1] - break - except Exception as err: - self.logger.error('CAhandler._profile_name_get() could not parse profile_name: %s', err) - - self.logger.debug('CAhandler._profile_name_get() ended with: %s', profile_name) - return profile_name + if hasattr(self, key): + self.logger.debug('CAhandler._eab_profile_string_check(): setting attribute: %s to %s', key, value) + setattr(self, key, value) + else: + self.logger.error('CAhandler._eab_profile_string_check(): ignore string attribute: key: %s value: %s', key, value) + + self.logger.debug('CAhandler._eab_profile_string_check() ended') + + def _eab_profile_list_check(self, eab_handler, csr, key, value): + self.logger.debug('CAhandler._eab_profile_list_check(): list: key: %s, value: %s', key, value) + + result = None + if hasattr(self, key): + new_value, error = header_info_field_validate(self.logger, csr, self.header_info_field, key, value) + if new_value: + self.logger.debug('CAhandler._eab_profile_list_check(): setting attribute: %s to %s', key, new_value) + setattr(self, key, new_value) + else: + result = error + elif key == 'allowed_domainlist': + # check if csr contains allowed domains + error = eab_handler.allowed_domains_check(csr, value) + if error: + result = error + else: + self.logger.error('CAhandler._eab_profile_list_check(): ignore list attribute: key: %s value: %s', key, value) + + self.logger.debug('CAhandler._eab_profile_list_check() ended with: %s', result) + return result + + def _eab_profile_check(self, csr: str, handler_hifield: str) -> str: + """ check eab profile""" + self.logger.debug('CAhandler._eab_profile_check()') + + result = None + with self.eab_handler(self.logger) as eab_handler: + eab_profile_dic = eab_handler.eab_profile_get(csr) + for key, value in eab_profile_dic.items(): + if isinstance(value, str): + self._eab_profile_string_check(key, value) + elif isinstance(value, list): + result = self._eab_profile_list_check(eab_handler, csr, key, value) + if result: + break + + # we need to reject situations where profiling is enabled but the header_hifiled is not defined in json + if self.header_info_field and handler_hifield not in eab_profile_dic: + hil_value = header_info_lookup(self.logger, csr, self.header_info_field, handler_hifield) + if hil_value: + # setattr(self, handler_hifield, hil_value) + result = f'header_info field "{handler_hifield}" is not allowed by profile' + + self.logger.debug('CAhandler._eab_profile_check() ended with: %s', result) + return result + + def _profile_check(self, csr: str) -> str: + """ check profile """ + self.logger.debug('CAhandler._profile_check()') + error = None + + # handler specific header info field + handler_hifield = "profile_name" + + if self.eab_profiling: + if self.eab_handler: + error = self._eab_profile_check(csr, handler_hifield) + # we need to cover cases where handler_value is enabled but nothing is defined in json + else: + self.logger.error('CAhandler._profile_check(): eab_profiling enabled but no handler defined') + elif self.header_info_field: + # no profiling - parse profileid from http_header + hil_value = header_info_lookup(self.logger, csr, self.header_info_field, handler_hifield) + if hil_value: + self.logger.debug('CAhandler._profile_check(): setting %s to %s', handler_hifield, hil_value) + setattr(self, handler_hifield, hil_value) + + self.logger.debug('CAhandler._profile_check() ended with %s', error) + return error def enroll(self, csr: str) -> Tuple[str, str, str, str]: """ enroll certificate """ @@ -420,18 +473,14 @@ def enroll(self, csr: str) -> Tuple[str, str, str, str]: cert_raw = None poll_indentifier = None - # verify issuer - error = self._issuer_verify() + # check for eab profiling and header_info + error = self._profile_check(csr) if not error: + # verify issuer + error = self._issuer_verify() - if self.header_info_field: - # parse profileid from http_header - profile_name = self._profile_name_get(csr=csr) - if profile_name: - self.logger.info('CAhandler._enrollment_dic_create(): profile_name found in header_info: %s', profile_name) - self.profile_name = profile_name - + if not error: # verify profile error = self._profile_verify() if not error: diff --git a/test/test_asa_ca_handler.py b/test/test_asa_ca_handler.py index 016832ae..26e09afc 100644 --- a/test/test_asa_ca_handler.py +++ b/test/test_asa_ca_handler.py @@ -5,7 +5,7 @@ import sys import os import unittest -from unittest.mock import patch, Mock +from unittest.mock import patch, Mock, MagicMock import requests import base64 @@ -553,7 +553,37 @@ def test_042___issuer_chain_get(self, mock_req, mock_pem): self.assertFalse(self.cahandler._issuer_chain_get()) self.assertFalse(mock_pem.called) - @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_name_get') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_post') + @patch('examples.ca_handler.asa_ca_handler.convert_byte_to_string') + @patch('examples.ca_handler.asa_ca_handler.cert_der2pem') + @patch('examples.ca_handler.asa_ca_handler.b64_decode') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._validity_dates_get') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._csr_cn_get') + @patch('examples.ca_handler.asa_ca_handler.csr_pubkey_get') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_chain_get') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_verify') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_check') + def test_041_enroll(self, mock_pv, mock_iv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_b64, mock_d2p, mock_b2s, mock_post): + """ test enroll() """ + mock_iv.return_value = None + mock_pv.return_value = 'pv_error' + mock_icg.return_value = 'issuer_chain' + mock_vdg.return_value = ('date1', 'date2') + mock_post.return_value = (200, 'cert') + mock_b2s.return_value = 'bcert' + self.cahandler.header_info_field = 'foo' + self.assertEqual(('pv_error', None, None, None), self.cahandler.enroll('csr')) + self.assertTrue(mock_pv.called) + self.assertFalse(mock_iv.called) + self.assertFalse(mock_icg.called) + self.assertFalse(mock_cpg.called) + self.assertFalse(mockccg.called) + self.assertFalse(mock_vdg.called) + self.assertFalse(mock_b64.called) + self.assertFalse(mock_post.called) + self.assertFalse(mock_b2s.called) + self.assertFalse(mock_d2p.called) + @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_post') @patch('examples.ca_handler.asa_ca_handler.convert_byte_to_string') @patch('examples.ca_handler.asa_ca_handler.cert_der2pem') @@ -564,7 +594,7 @@ def test_042___issuer_chain_get(self, mock_req, mock_pem): @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_chain_get') @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_verify') @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_verify') - def test_042_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_b64, mock_d2p, mock_b2s, mock_post, mock_profile): + def test_042_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_b64, mock_d2p, mock_b2s, mock_post): """ test enroll() """ mock_iv.return_value = None mock_pv.return_value = None @@ -573,10 +603,7 @@ def test_042_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vd mock_post.return_value = (200, 'cert') mock_b2s.return_value = 'bcert' self.cahandler.header_info_field = 'foo' - mock_profile.return_value = 'profile' - with self.assertLogs('test_a2c', level='INFO') as lcm: - self.assertEqual((None, 'bcertissuer_chain', 'cert', None), self.cahandler.enroll('csr')) - self.assertIn('INFO:test_a2c:CAhandler._enrollment_dic_create(): profile_name found in header_info: profile', lcm.output) + self.assertEqual((None, 'bcertissuer_chain', 'cert', None), self.cahandler.enroll('csr')) self.assertTrue(mock_iv.called) self.assertTrue(mock_pv.called) self.assertTrue(mock_icg.called) @@ -587,9 +614,7 @@ def test_042_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vd self.assertTrue(mock_post.called) self.assertTrue(mock_b2s.called) self.assertTrue(mock_d2p.called) - self.assertTrue(mock_profile.called) - @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_name_get') @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_post') @patch('examples.ca_handler.asa_ca_handler.convert_byte_to_string') @patch('examples.ca_handler.asa_ca_handler.cert_der2pem') @@ -600,7 +625,7 @@ def test_042_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vd @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_chain_get') @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_verify') @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_verify') - def test_043_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_b64, mock_d2p, mock_b2s, mock_post, mock_profile): + def test_043_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_b64, mock_d2p, mock_b2s, mock_post): """ test enroll() """ mock_iv.return_value = None mock_pv.return_value = None @@ -619,7 +644,6 @@ def test_043_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vd self.assertTrue(mock_post.called) self.assertTrue(mock_b2s.called) self.assertTrue(mock_d2p.called) - self.assertFalse(mock_profile.called) @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_post') @patch('examples.ca_handler.asa_ca_handler.convert_byte_to_string') @@ -906,56 +930,297 @@ def test_063_config_password_load(self): # self.assertIn("foo", lcm.output) self.assertFalse(self.cahandler.profile_name) - def test_064_config_headerinfo_load(self): - """ test config_headerinfo_load()""" - config_dic = {'Order': {'header_info_list': '["foo", "bar", "foobar"]'}} - self.cahandler._config_headerinfo_load(config_dic) - self.assertEqual( 'foo', self.cahandler.header_info_field) - - def test_065_config_headerinfo_load(self): - """ test config_headerinfo_load()""" - config_dic = {'Order': {'header_info_list': '["foo"]'}} - self.cahandler._config_headerinfo_load(config_dic) - self.assertEqual( 'foo', self.cahandler.header_info_field) - - def test_066_config_headerinfo_load(self): - """ test config_headerinfo_load()""" - config_dic = {'Order': {'header_info_list': 'foo'}} - with self.assertLogs('test_a2c', level='INFO') as lcm: - self.cahandler._config_headerinfo_load(config_dic) - self.assertFalse(self.cahandler.header_info_field) - self.assertIn('WARNING:test_a2c:Order._config_orderconfig_load() header_info_list failed with error: Expecting value: line 1 column 1 (char 0)', lcm.output) - - @patch('examples.ca_handler.asa_ca_handler.header_info_get') - def test_067_profile_name_get(self, mock_header): - """ test _profile_name_get()""" - mock_header.return_value = [{'header_info': '{"header_field": "profile_name=101 lego-cli/4.14.2 xenolf-acme/4.14.2 (release; linux; amd64)"}'}] - self.cahandler.header_info_field = 'header_field' - self.assertEqual('101', self.cahandler._profile_name_get('csr')) - - @patch('examples.ca_handler.asa_ca_handler.header_info_get') - def test_068_profile_name_get(self, mock_header): - """ test _profile_name_get()""" - mock_header.return_value = [{'header_info': 'header_info'}] - self.cahandler.header_info_field = 'header_field' - with self.assertLogs('test_a2c', level='INFO') as lcm: - self.assertFalse(self.cahandler._profile_name_get('csr')) - self.assertIn('ERROR:test_a2c:CAhandler._profile_name_get() could not parse profile_name: Expecting value: line 1 column 1 (char 0)', lcm.output) - - @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_name_get') @patch('examples.ca_handler.asa_ca_handler.CAhandler._validity_dates_get') @patch('examples.ca_handler.asa_ca_handler.CAhandler._csr_cn_get') @patch('examples.ca_handler.asa_ca_handler.csr_pubkey_get') - def test_069_enrollment_dic_create(self, mock_pkg, mock_ccg, mock_vdg, mock_png): + def test_069_enrollment_dic_create(self, mock_pkg, mock_ccg, mock_vdg): """ test _enrollment_dic_create()""" mock_pkg.return_value = 'pubkey' mock_ccg.return_value = 'cn' mock_vdg.return_value = ('date1', 'date2') - mock_png.return_value = 'profile_name' result = {'publicKey': 'pubkey', 'profileName': None, 'issuerName': None, 'cn': 'cn', 'notBefore': 'date1', 'notAfter': 'date2'} self.assertEqual(result, self.cahandler._enrollment_dic_create('csr')) - self.assertFalse(mock_png.called) + @patch('examples.ca_handler.asa_ca_handler.header_info_field_validate') + def test_102__eab_profile_check(self, mock_hil): + """ test eab_profile_check """ + self.cahandler.eab_handler = MagicMock() + self.cahandler.api_host = 'api_host' + self.cahandler.api_user = 'api_user' + self.cahandler.api_password = 'api_password' + self.cahandler.profile_name = 'profile_name' + self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar'} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.cahandler._eab_profile_check('csr', 'handler_hifield')) + self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) + self.assertEqual('api_host', self.cahandler.api_host) + self.assertEqual('api_user', self.cahandler.api_user) + self.assertEqual('api_password', self.cahandler.api_password) + self.assertEqual('profile_name', self.cahandler.profile_name) + self.assertFalse(mock_hil.called) + + @patch('examples.ca_handler.asa_ca_handler.header_info_lookup') + def test_103__eab_profile_check(self, mock_hil): + """ test eab_profile_check """ + self.cahandler.eab_handler = MagicMock() + self.cahandler.api_host = 'api_host' + self.cahandler.api_user = 'api_user' + self.cahandler.api_password = 'api_password' + self.cahandler.profile_name = 'profile_name' + self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'api_host': 'new_host', 'api_user': 'new_user', 'api_password': 'new_password', 'profile_name': 'new_profile'} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.cahandler._eab_profile_check('csr', 'handler_hifield')) + self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) + self.assertEqual('new_host', self.cahandler.api_host) + self.assertEqual('new_user', self.cahandler.api_user) + self.assertEqual('new_password', self.cahandler.api_password) + self.assertEqual('new_profile', self.cahandler.profile_name) + self.assertFalse(mock_hil.called) + + def test_104__eab_profile_check(self): + """ test eab_profile_check default value from list """ + self.cahandler.eab_handler = MagicMock() + self.cahandler.api_host = 'api_host' + self.cahandler.api_user = 'api_user' + self.cahandler.api_password = 'api_password' + self.cahandler.profile_name = 'profile_name' + self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'profile_name': ['profile_1', 'profile_2', 'profile_3']} + # mock_hil.return_value = ('None', None) + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.cahandler._eab_profile_check('csr', 'handler_hifield')) + self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) + self.assertEqual('api_host', self.cahandler.api_host) + self.assertEqual('api_user', self.cahandler.api_user) + self.assertEqual('api_password', self.cahandler.api_password) + self.assertEqual('profile_1', self.cahandler.profile_name) + + @patch('examples.ca_handler.asa_ca_handler.header_info_field_validate') + def test_105__eab_profile_check(self, mock_hil): + """ test eab_profile_check default value from list header info validate returns a value """ + self.cahandler.eab_handler = MagicMock() + self.cahandler.api_host = 'api_host' + self.cahandler.api_user = 'api_user' + self.cahandler.api_password = 'api_password' + self.cahandler.profile_name = 'profile_name' + mock_hil.return_value = ('profile_2', None) + self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'profile_name': ['profile_1', 'profile_2', 'profile_3']} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.cahandler._eab_profile_check('csr', 'handler_hifield')) + self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) + self.assertEqual('api_host', self.cahandler.api_host) + self.assertEqual('api_user', self.cahandler.api_user) + self.assertEqual('api_password', self.cahandler.api_password) + self.assertEqual('profile_2', self.cahandler.profile_name) + self.assertTrue(mock_hil.called) + + @patch('examples.ca_handler.asa_ca_handler.header_info_field_validate') + def test_106__eab_profile_check(self, mock_hil): + """ test eab_profile_check default value from list headerinfo_lookup returns an error """ + self.cahandler.eab_handler = MagicMock() + self.cahandler.api_host = 'api_host' + self.cahandler.api_user = 'api_user' + self.cahandler.api_password = 'api_password' + self.cahandler.profile_name = 'profile_name' + mock_hil.return_value = (None, 'error') + self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'profile_name': ['profile_1', 'profile_2', 'profile_3']} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertEqual('error', self.cahandler._eab_profile_check('csr', 'handler_hifield')) + self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) + self.assertEqual('api_host', self.cahandler.api_host) + self.assertEqual('api_user', self.cahandler.api_user) + self.assertEqual('api_password', self.cahandler.api_password) + self.assertEqual('profile_name', self.cahandler.profile_name) + self.assertTrue(mock_hil.called) + + @patch('examples.ca_handler.asa_ca_handler.header_info_field_validate') + def test_107__eab_profile_check(self, mock_hil): + """ test eab_profile_check """ + self.cahandler.eab_handler = MagicMock() + self.cahandler.api_host = 'api_host' + self.cahandler.api_user = 'api_user' + self.cahandler.api_password = 'api_password' + self.cahandler.profile_name = 'profile_name' + mock_hil.return_value = ('hil_value', None) + self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'allowed_domainlist': ['foo.bar', 'bar.foo']} + self.cahandler.eab_handler.return_value.__enter__.return_value.allowed_domains_check.return_value = 'domain_chk_error' + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertEqual('domain_chk_error', self.cahandler._eab_profile_check('csr', 'handler_hifield')) + self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) + self.assertEqual('api_host', self.cahandler.api_host) + self.assertEqual('api_user', self.cahandler.api_user) + self.assertEqual('api_password', self.cahandler.api_password) + self.assertEqual('profile_name', self.cahandler.profile_name) + self.assertFalse(mock_hil.called) + + @patch('examples.ca_handler.asa_ca_handler.header_info_field_validate') + def test_108__eab_profile_check(self, mock_hil): + """ test eab_profile_check """ + self.cahandler.eab_handler = MagicMock() + self.cahandler.api_host = 'api_host' + self.cahandler.api_user = 'api_user' + self.cahandler.api_password = 'api_password' + self.cahandler.profile_name = 'profile_name' + mock_hil.return_value = ('hil_value', None) + self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'allowed_domainlist': ['foo.bar', 'bar.foo']} + self.cahandler.eab_handler.return_value.__enter__.return_value.allowed_domains_check.return_value = None + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.cahandler._eab_profile_check('csr', 'handler_hifield')) + self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) + self.assertEqual('api_host', self.cahandler.api_host) + self.assertEqual('api_user', self.cahandler.api_user) + self.assertEqual('api_password', self.cahandler.api_password) + self.assertEqual('profile_name', self.cahandler.profile_name) + self.assertFalse(mock_hil.called) + + @patch('examples.ca_handler.asa_ca_handler.header_info_field_validate') + def test_109__eab_profile_check(self, mock_hil): + """ test eab_profile_check """ + self.cahandler.eab_handler = MagicMock() + self.cahandler.api_host = 'api_host' + self.cahandler.api_user = 'api_user' + self.cahandler.api_password = 'api_password' + self.cahandler.profile_name = 'profile_name' + mock_hil.return_value = ('hil_value', None) + self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'unknown': ['foobar', 'barfoo']} + self.cahandler.eab_handler.return_value.__enter__.return_value.allowed_domains_check.return_value = None + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.cahandler._eab_profile_check('csr', 'handler_hifield')) + self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) + self.assertIn("ERROR:test_a2c:CAhandler._eab_profile_list_check(): ignore list attribute: key: unknown value: ['foobar', 'barfoo']", lcm.output) + self.assertEqual('api_host', self.cahandler.api_host) + self.assertEqual('api_user', self.cahandler.api_user) + self.assertEqual('api_password', self.cahandler.api_password) + self.assertEqual('profile_name', self.cahandler.profile_name) + self.assertFalse(mock_hil.called) + + @patch('examples.ca_handler.asa_ca_handler.header_info_lookup') + @patch('examples.ca_handler.asa_ca_handler.header_info_field_validate') + def test_110__eab_profile_check(self, mock_hiv, mock_hil): + """ test eab_profile_check """ + self.cahandler.eab_handler = MagicMock() + self.cahandler.api_host = 'api_host' + self.cahandler.api_user = 'api_user' + self.cahandler.api_password = 'api_password' + self.cahandler.profile_name = 'profile_name' + self.cahandler.header_info_field = 'header_info_field' + mock_hiv.return_value = ('hil_value', None) + mock_hil.return_value = 'mock_hil' + self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'unknown': ['foobar', 'barfoo']} + self.cahandler.eab_handler.return_value.__enter__.return_value.allowed_domains_check.return_value = None + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertEqual('header_info field "profile_name" is not allowed by profile', self.cahandler._eab_profile_check('csr', 'profile_name')) + self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) + self.assertIn("ERROR:test_a2c:CAhandler._eab_profile_list_check(): ignore list attribute: key: unknown value: ['foobar', 'barfoo']", lcm.output) + self.assertEqual('api_host', self.cahandler.api_host) + self.assertEqual('api_user', self.cahandler.api_user) + self.assertEqual('api_password', self.cahandler.api_password) + self.assertFalse(mock_hiv.called) + self.assertEqual('profile_name', self.cahandler.profile_name) + self.assertTrue(mock_hil.called) + self.assertEqual('profile_name', self.cahandler.profile_name) + + @patch('examples.ca_handler.asa_ca_handler.header_info_lookup') + @patch('examples.ca_handler.asa_ca_handler.header_info_field_validate') + def test_111__eab_profile_check(self, mock_hiv, mock_hil): + """ test eab_profile_check """ + self.cahandler.eab_handler = MagicMock() + self.cahandler.api_host = 'api_host' + self.cahandler.api_user = 'api_user' + self.cahandler.api_password = 'api_password' + self.cahandler.profile_name = 'profile_name' + self.cahandler.header_info_field = 'header_info_field' + mock_hiv.return_value = ('hil_value', None) + mock_hil.return_value = None + self.cahandler.eab_handler.return_value.__enter__.return_value.eab_profile_get.return_value = {'foo': 'bar', 'unknown': ['foobar', 'barfoo']} + self.cahandler.eab_handler.return_value.__enter__.return_value.allowed_domains_check.return_value = None + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.cahandler._eab_profile_check('csr', 'handler_hifield')) + self.assertIn('ERROR:test_a2c:CAhandler._eab_profile_string_check(): ignore string attribute: key: foo value: bar', lcm.output) + self.assertIn("ERROR:test_a2c:CAhandler._eab_profile_list_check(): ignore list attribute: key: unknown value: ['foobar', 'barfoo']", lcm.output) + self.assertEqual('api_host', self.cahandler.api_host) + self.assertEqual('api_user', self.cahandler.api_user) + self.assertEqual('api_password', self.cahandler.api_password) + self.assertEqual('profile_name', self.cahandler.profile_name) + self.assertFalse(mock_hiv.called) + + @patch('examples.ca_handler.asa_ca_handler.header_info_lookup') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._eab_profile_check') + def test_112__profile_check(self, mock_eab, mock_hil): + """ test eab_profile_string_check """ + self.assertFalse(self.cahandler._profile_check('csr')) + self.assertFalse(mock_eab.called) + self.assertFalse(mock_hil.called) + + @patch('examples.ca_handler.asa_ca_handler.header_info_lookup') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._eab_profile_check') + def test_113__profile_check(self, mock_eab, mock_hil): + """ test eab_profile_string_check """ + self.cahandler.eab_profiling = False + self.assertFalse(self.cahandler._profile_check('csr')) + self.assertFalse(mock_eab.called) + self.assertFalse(mock_hil.called) + + @patch('examples.ca_handler.asa_ca_handler.header_info_lookup') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._eab_profile_check') + def test_114__eab_profile_string_check(self, mock_eab, mock_hil): + """ test eab_profile_string_check """ + self.cahandler.eab_profiling = True + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertFalse(self.cahandler._profile_check('csr')) + self.assertIn('ERROR:test_a2c:CAhandler._profile_check(): eab_profiling enabled but no handler defined', lcm.output) + self.assertFalse(mock_eab.called) + self.assertFalse(mock_hil.called) + + @patch('examples.ca_handler.asa_ca_handler.header_info_lookup') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._eab_profile_check') + def test_115__eab_profile_string_check(self, mock_eab, mock_hil): + """ test eab_profile_string_check """ + self.cahandler.eab_profiling = True + self.cahandler.eab_handler = MagicMock() + mock_eab.return_value = 'mock_eab' + self.assertEqual('mock_eab', self.cahandler._profile_check('csr')) + self.assertTrue(mock_eab.called) + self.assertFalse(mock_hil.called) + + @patch('examples.ca_handler.asa_ca_handler.header_info_lookup') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._eab_profile_check') + def test_116__eab_profile_string_check(self, mock_eab, mock_hil): + """ test eab_profile_string_check """ + self.cahandler.eab_profiling = True + self.cahandler.header_info_field = 'header_info_field' + self.cahandler.eab_handler = MagicMock() + mock_eab.return_value = 'mock_eab' + self.assertEqual('mock_eab', self.cahandler._profile_check('csr')) + self.assertTrue(mock_eab.called) + self.assertFalse(mock_hil.called) + + @patch('examples.ca_handler.asa_ca_handler.header_info_lookup') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._eab_profile_check') + def test_117__eab_profile_string_check(self, mock_eab, mock_hil): + """ test eab_profile_string_check """ + self.cahandler.eab_profiling = False + self.cahandler.eab_handler = None + self.cahandler.header_info_field = 'profile_name' + self.cahandler.profile_name = 'profile_name' + mock_hil.return_value = 'mock_hil' + self.assertFalse(self.cahandler._profile_check('csr')) + self.assertFalse(mock_eab.called) + self.assertTrue(mock_hil.called) + self.assertEqual('mock_hil', self.cahandler.profile_name) + + @patch('examples.ca_handler.asa_ca_handler.header_info_lookup') + @patch('examples.ca_handler.asa_ca_handler.CAhandler._eab_profile_check') + def test_118__eab_profile_string_check(self, mock_eab, mock_hil): + """ test eab_profile_string_check """ + self.cahandler.eab_profiling = False + self.cahandler.eab_handler = None + self.cahandler.header_info_field = 'profile_name' + self.cahandler.profile_name = 'profile_name' + mock_hil.return_value = None + self.assertFalse(self.cahandler._profile_check('csr')) + self.assertFalse(mock_eab.called) + self.assertTrue(mock_hil.called) + self.assertEqual('profile_name', self.cahandler.profile_name) if __name__ == '__main__': From 48327626077a6f91b06f56767a9ad15dd15390d3 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 20 Apr 2024 08:31:38 +0200 Subject: [PATCH 176/460] [wf] certifier and asa workflows including eab-profiling tests --- .github/workflows/ca_handler_tests_asa.yml | 1008 ++++++++++++++++- .../workflows/ca_handler_tests_certifier.yml | 406 ++++++- 2 files changed, 1302 insertions(+), 112 deletions(-) diff --git a/.github/workflows/ca_handler_tests_asa.yml b/.github/workflows/ca_handler_tests_asa.yml index 67bd3ad9..f49b5428 100644 --- a/.github/workflows/ca_handler_tests_asa.yml +++ b/.github/workflows/ca_handler_tests_asa.yml @@ -16,8 +16,8 @@ jobs: max-parallel: 1 fail-fast: false matrix: - websrv: ['apache2', 'nginx'] - dbhandler: ['wsgi', 'django'] + websrv: ['apache2'] + dbhandler: ['wsgi'] steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -42,7 +42,7 @@ jobs: WEB_SRV: ${{ matrix.websrv }} DB_HANDLER: ${{ matrix.dbhandler }} - - name: "[ PREPARE ] setup a2c with asa_ca_handler" + - name: "Profile ${{ secrets.ASA_PROFILE1 }} - Setup a2c with asa_ca_handler with profile ${{ secrets.ASA_PROFILE1 }}" run: | sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem @@ -73,60 +73,56 @@ jobs: ASA_CA_BUNDLE: ${{ secrets.ASA_CA_BUNDLE }} ASA_PROFILE1: ${{ secrets.ASA_PROFILE1 }} - - name: "Sleep for 10s" + - name: "Profile ${{ secrets.ASA_PROFILE1 }} - Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: time: 10s - - name: "Test http://acme-srv/directory is accessable" + - name: "Profile ${{ secrets.ASA_PROFILE1 }} - Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "Test if https://acme-srv/directory is accessable" + - name: "Profile ${{ secrets.ASA_PROFILE1 }} - Test if https://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" - run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - - name: "[ ENROLL ] acme.sh" + - name: "Profile ${{ secrets.ASA_PROFILE1 }} - Enroll acme.sh" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --keylength 2048 --debug 3 --output-insecure --force + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' -d acme-sh.acme --alpn --standalone --keylength 2048 --debug 3 --output-insecure awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature" # openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -text -noout - - name: "revoke via acme.sh" + - name: "Profile ${{ secrets.ASA_PROFILE1 }} - Revoke via acme.sh" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --revoke --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "[ REGISTER ] certbot" + - name: "Profile ${{ secrets.ASA_PROFILE1 }} - Register certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ ENROLL ] HTTP-01 single domain certbot" + - name: "Profile ${{ secrets.ASA_PROFILE1 }} - Enroll HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot --key-type rsa --rsa-key-size 2048 sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem sudo openssl x509 -in certbot/live/certbot/cert.pem -ext keyUsage -noout | grep "Digital Signature" # sudo openssl x509 -in certbot/live/certbot/cert.pem -text -noout - - name: "revoke HTTP-01 single domain certbot" + - name: "Profile ${{ secrets.ASA_PROFILE1 }} - Revoke HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - - name: "[ ENROLL ] lego" + - name: "Profile ${{ secrets.ASA_PROFILE1 }} - Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --key-type rsa2048 --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt sudo openssl x509 -in lego/certificates/lego.acme.crt -ext keyUsage -noout | grep "Digital Signature" # sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout - - name: "revoke HTTP-01 single domain lego" + - name: "Profile ${{ secrets.ASA_PROFILE1 }} - revoke HTTP-01 single domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke - - name: "[ PREPARE ] reconfiguration of a2c with a new profile" + - name: "Profile ${{ secrets.ASA_PROFILE2 }} - Reconfiguration of a2c with a new profile" run: | sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem sudo touch examples/Docker/data/acme_srv.cfg @@ -153,50 +149,515 @@ jobs: ASA_CA_BUNDLE: ${{ secrets.ASA_CA_BUNDLE }} ASA_PROFILE2: ${{ secrets.ASA_PROFILE2 }} - - name: "[ PREPARE ] create letsencrypt and lego folder" + - name: "Profile ${{ secrets.ASA_PROFILE2 }} - create letsencrypt and lego folder" run: | sudo rm -rf certbot/* sudo rm -rf lego/* sudo rm -rf acme-sh/* - docker restart acme-sh - - name: "[ ENROLL ] acme.sh" + - name: "Profile ${{ secrets.ASA_PROFILE2 }} - Enroll acme.sh" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --keylength 2048 --debug 3 --output-insecure --force + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' -d acme-sh.acme --alpn --standalone --keylength 2048 --debug 3 --output-insecure awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext keyUsage -noout | grep "Key Encipherment, Data Encipherment" # openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -text -noout - - name: "revoke via acme.sh" + - name: "Profile ${{ secrets.ASA_PROFILE2 }} - Revoke via acme.sh" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --revoke --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "[ REGISTER ] certbot" + - name: "Profile ${{ secrets.ASA_PROFILE2 }} - Register certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ ENROLL ] HTTP-01 single domain certbot" + - name: "Profile ${{ secrets.ASA_PROFILE2 }} - Enroll HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot --force-renewal --key-type rsa --rsa-key-size 2048 sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem sudo openssl x509 -in certbot/live/certbot/cert.pem -ext keyUsage -noout | grep "Key Encipherment, Data Encipherment" - - name: "revoke HTTP-01 single domain certbot" + - name: "Profile ${{ secrets.ASA_PROFILE2 }} - Revoke HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - - name: "[ ENROLL ] lego" + - name: "Profile ${{ secrets.ASA_PROFILE2 }} - Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --key-type rsa2048 --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt sudo openssl x509 -in lego/certificates/lego.acme.crt -ext keyUsage -noout | grep "Key Encipherment, Data Encipherment" # sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout - - name: "revoke HTTP-01 single domain lego" + - name: "Profile ${{ secrets.ASA_PROFILE2 }} - Revoke HTTP-01 single domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke + - name: "Header-info - Setup asa_ca_handler with header-info" + run: | + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py + sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg + sudo chmod 777 examples/Docker/data/acme_srv.cfg + sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg + sudo echo "handler_file: examples/ca_handler/asa_ca_handler.py" >> examples/Docker/data/acme_srv.cfg + sudo echo "api_host: $ASA_API_HOST" >> examples/Docker/data/acme_srv.cfg + sudo echo "api_user: $ASA_API_USER" >> examples/Docker/data/acme_srv.cfg + sudo echo "api_password: $ASA_API_PASSWORD" >> examples/Docker/data/acme_srv.cfg + sudo echo "api_key: $ASA_API_KEY" >> examples/Docker/data/acme_srv.cfg + sudo echo "ca_name: $ASA_CA_NAME" >> examples/Docker/data/acme_srv.cfg + sudo echo "ca_bundle: $ASA_CA_BUNDLE" >> examples/Docker/data/acme_srv.cfg + sudo echo "profile_name: $ASA_PROFILE1" >> examples/Docker/data/acme_srv.cfg + sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout:15/g" examples/Docker/data/acme_srv.cfg + sudo sed -i "s/tnauthlist_support: False/tnauthlist_support: False\nheader_info_list: [\"HTTP_USER_AGENT\"]/g" examples/Docker/data/acme_srv.cfg + + cd examples/Docker/ + docker-compose restart + docker-compose logs + env: + ASA_API_HOST: ${{ secrets.ASA_API_HOST }} + ASA_API_USER: ${{ secrets.ASA_API_USER }} + ASA_API_PASSWORD: ${{ secrets.ASA_API_PASSWORD }} + ASA_API_KEY: ${{ secrets.ASA_API_KEY }} + ASA_CA_NAME: ${{ secrets.ASA_CA_NAME }} + ASA_CA_BUNDLE: ${{ secrets.ASA_CA_BUNDLE }} + ASA_PROFILE1: ${{ secrets.ASA_PROFILE1 }} + + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Header-info - Test http://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "Header-info - Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "Header-info - 01 - Enroll acme.sh with profile_name ${{ secrets.ASA_PROFILE1 }}" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' --useragent profile_name=${{ secrets.ASA_PROFILE1 }} -d acme-sh.acme --alpn --standalone --keylength 2048 --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -texte -noout + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature" + + - name: "Header-info - 01 - Enroll lego with profile_id ${{ secrets.ASA_PROFILE1 }}" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent profile_name=${{ secrets.ASA_PROFILE1 }} -d lego.acme --key-type rsa2048 --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext keyUsage -noout | grep "Digital Signature" + + - name: "Header-info - 02 - Enroll acme.sh with profile_name ${{ secrets.ASA_PROFILE2 }}" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' --useragent profile_name=${{ secrets.ASA_PROFILE2 }} -d acme-sh.acme --alpn --standalone --keylength 2048 --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -texte -noout + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext keyUsage -noout | grep "Key Encipherment, Data Encipherment" + + - name: "Header-info - 02 - Enroll lego with profile_id ${{ secrets.ASA_PROFILE2 }}" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent profile_name=${{ secrets.ASA_PROFILE2 }} -d lego.acme --key-type rsa2048 --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + # sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext keyUsage -noout | grep "Key Encipherment, Data Encipherment" + + - name: "EAB without headerinfo - Setup asa_ca_handler" + run: | + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py + sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg + sudo chmod 777 examples/Docker/data/acme_srv.cfg + sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg + sudo echo "handler_file: examples/ca_handler/asa_ca_handler.py" >> examples/Docker/data/acme_srv.cfg + sudo echo "api_host: $ASA_API_HOST" >> examples/Docker/data/acme_srv.cfg + sudo echo "api_user: $ASA_API_USER" >> examples/Docker/data/acme_srv.cfg + sudo echo "api_password: $ASA_API_PASSWORD" >> examples/Docker/data/acme_srv.cfg + sudo echo "api_key: $ASA_API_KEY" >> examples/Docker/data/acme_srv.cfg + sudo echo "ca_name: $ASA_CA_NAME" >> examples/Docker/data/acme_srv.cfg + sudo echo "ca_bundle: $ASA_CA_BUNDLE" >> examples/Docker/data/acme_srv.cfg + sudo echo "profile_name: $ASA_PROFILE1" >> examples/Docker/data/acme_srv.cfg + sudo echo "eab_profiling: True" >> examples/Docker/data/acme_srv.cfg + sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout:15/g" examples/Docker/data/acme_srv.cfg + sudo echo -e "\n[EABhandler]" >> examples/Docker/data/acme_srv.cfg + sudo echo "eab_handler_file: /var/www/acme2certifier/examples/eab_handler/kid_profile_handler.py" >> examples/Docker/data/acme_srv.cfg + sudo echo "key_file: volume/kid_profiles.json" >> examples/Docker/data/acme_srv.cfg + + sudo cp examples/eab_handler/kid_profiles.json examples/Docker/data/kid_profiles.json + sudo chmod 777 examples/eab_handler/kid_profiles.json + sudo sed -i "s/\"profile_id\"\: \[\"profile_1\", \"profile_2\", \"profile_3\"\]/\"profile_name\"\: \[\"$ASA_PROFILE2\", \"$ASA_PROFILE1\"\]/g" examples/Docker/data/kid_profiles.json + sudo sed -i "s/\"profile_id\"\: \"profile_2\"/\"profile_name\"\: \"$ASA_PROFILE3\"/g" examples/Docker/data/kid_profiles.json + sudo sed -i "s/\"ca_name\": \"example_ca_2\",/\"ca_name\": \"$ASA_CA_NAME2\"/" examples/Docker/data/kid_profiles.json + sudo sed -i "s/\"ca_name\": \"example_ca\",/\"unknown_key\": \"unknown_value\"/g" examples/Docker/data/kid_profiles.json + sudo sed -i "s/example.net/acme/g" examples/Docker/data/kid_profiles.json + sudo sed -i '18,19d' examples/Docker/data/kid_profiles.json + sudo sed -i '8,9d' examples/Docker/data/kid_profiles.json + + cd examples/Docker/ + docker-compose restart + docker-compose logs + env: + ASA_API_HOST: ${{ secrets.ASA_API_HOST }} + ASA_API_USER: ${{ secrets.ASA_API_USER }} + ASA_API_PASSWORD: ${{ secrets.ASA_API_PASSWORD }} + ASA_API_KEY: ${{ secrets.ASA_API_KEY }} + ASA_CA_NAME: ${{ secrets.ASA_CA_NAME }} + ASA_CA_NAME2: ${{ secrets.ASA_CA_NAME2 }} + ASA_CA_BUNDLE: ${{ secrets.ASA_CA_BUNDLE }} + ASA_PROFILE1: ${{ secrets.ASA_PROFILE1 }} + ASA_PROFILE2: ${{ secrets.ASA_PROFILE2 }} + ASA_PROFILE3: ${{ secrets.ASA_PROFILE3 }} + + - name: "EAB without headerinfo - Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "EAB without headerinfo - Test http://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "EAB without headerinfo - Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "EAB without headerinfo - 01 - Enroll acme.sh without profile_name" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_00 --eab-hmac-key V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --keylength 2048 --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -issuer --noout | grep -i "${{ secrets.ASA_CA_NAME }}" + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext keyUsage -noout | grep -i "Key Encipherment, Data Encipherment" + + - name: "EAB without headerinfo - 01 - Enroll lego without profile_name" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw -k rsa2048 -d lego.acme --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -issuer --noout | grep -i "${{ secrets.ASA_CA_NAME }}" + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext keyUsage -noout | grep -i "Key Encipherment, Data Encipherment" + + - name: "EAB without headerinfo - 02 - Enroll acme with a profile_name taken from header_info NOT included in kid.json (to be ignored)" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_00 --eab-hmac-key V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --useragent profile_name=unknown -d acme-sh.acme --standalone --keylength 2048 --debug 3 --output-insecure + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -issuer --noout | grep -i "${{ secrets.ASA_CA_NAME }}" + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext keyUsage -noout | grep -i "Key Encipherment, Data Encipherment" + + - name: "EAB without headerinfo - 02 - Enroll lego with a profile_name taken from header_info NOT included in kid.json (to be ignored)" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --user-agent profile_name=unknown -k rsa2048 -d lego.acme --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -issuer --noout | grep -i "${{ secrets.ASA_CA_NAME }}" + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext keyUsage -noout | grep "Key Encipherment, Data Encipherment" + + - name: "EAB without headerinfo - 03 - Enroll acme with a profile_name/ca_name taken from kid.json" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_01 --eab-hmac-key YW5vdXRoZXJfdmVyeV9sb25nX2htYWNfZm9yX2tleWlkXzAxX3doaWNoIHdpbGxfYmUgdXNlZF9kdXJpbmcgcmVncmVzc2lvbg --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --keylength 2048 --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -issuer --noout | grep -i "${{ secrets.ASA_CA_NAME2 }}" + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext keyUsage -noout | grep -i "Digital Signature" + + - name: "EAB without headerinfo - 03 - Enroll lego with a profile_name/ca_name taken from kid.json" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_01 --hmac YW5vdXRoZXJfdmVyeV9sb25nX2htYWNfZm9yX2tleWlkXzAxX3doaWNoIHdpbGxfYmUgdXNlZF9kdXJpbmcgcmVncmVzc2lvbg -k rsa2048 -d lego.acme --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -issuer --noout | grep -i "${{ secrets.ASA_CA_NAME2 }}" + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext keyUsage | grep -i "Digital Signature" + + - name: "EAB with headerinfo - 04 - Enroll acme with a not allowed fqdn in kid.json (to fail)" + id: acmefail02 + continue-on-error: true + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --keylength 2048 --debug 3 --output-insecure + + - name: "EAB with headerinfo - 04 - check result " + if: steps.acmefail02.outcome != 'failure' + run: | + echo "acmefail outcome is ${{steps.acmefail02.outcome }}" + exit 1 + + - name: "EAB with headerinfo - 04 - Enroll lego with a not allowed fqdn in kid.json (to fail)" + id: legofail02 + continue-on-error: true + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM -k rsa2048 -d lego.acme --http run + + - name: "EAB with headerinfo - 04a - check result " + if: steps.legofail02.outcome != 'failure' + run: | + echo "legofail outcome is ${{steps.legofail02.outcome }}" + exit 1 + + - name: "EAB with headerinfo - 05 - Enroll acme with default values from acme.cfg" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_03 --eab-hmac-key YW5kX2ZpbmFsbHlfdGhlX2xhc3RfaG1hY19rZXlfd2hpY2hfaXNfbG9uZ2VyX3RoYW5fMjU2X2JpdHNfYW5kX3Nob3VsZF93b3Jr --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --keylength 2048 --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -issuer --noout | grep -i "${{ secrets.ASA_CA_NAME }}" + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature" + + - name: "EAB with headerinfo - 05 - Enroll lego with default values from acme.cfg" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_03 --hmac YW5kX2ZpbmFsbHlfdGhlX2xhc3RfaG1hY19rZXlfd2hpY2hfaXNfbG9uZ2VyX3RoYW5fMjU2X2JpdHNfYW5kX3Nob3VsZF93b3Jr -k rsa2048 -d lego.acme --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -issuer --noout | grep -i "${{ secrets.ASA_CA_NAME }}" + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext keyUsage | grep "Digital Signature" + + - name: "EAB with headerinfo - Setup asa_ca_handler" + run: | + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py + sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg + sudo chmod 777 examples/Docker/data/acme_srv.cfg + sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg + sudo echo "handler_file: examples/ca_handler/asa_ca_handler.py" >> examples/Docker/data/acme_srv.cfg + sudo echo "api_host: $ASA_API_HOST" >> examples/Docker/data/acme_srv.cfg + sudo echo "api_user: $ASA_API_USER" >> examples/Docker/data/acme_srv.cfg + sudo echo "api_password: $ASA_API_PASSWORD" >> examples/Docker/data/acme_srv.cfg + sudo echo "api_key: $ASA_API_KEY" >> examples/Docker/data/acme_srv.cfg + sudo echo "ca_name: $ASA_CA_NAME" >> examples/Docker/data/acme_srv.cfg + sudo echo "ca_bundle: $ASA_CA_BUNDLE" >> examples/Docker/data/acme_srv.cfg + sudo echo "profile_name: $ASA_PROFILE1" >> examples/Docker/data/acme_srv.cfg + sudo echo "eab_profiling: True" >> examples/Docker/data/acme_srv.cfg + sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout:15/g" examples/Docker/data/acme_srv.cfg + sudo sed -i "s/tnauthlist_support: False/tnauthlist_support: False\nheader_info_list: [\"HTTP_USER_AGENT\"]/g" examples/Docker/data/acme_srv.cfg + sudo echo -e "\n[EABhandler]" >> examples/Docker/data/acme_srv.cfg + sudo echo "eab_handler_file: /var/www/acme2certifier/examples/eab_handler/kid_profile_handler.py" >> examples/Docker/data/acme_srv.cfg + sudo echo "key_file: volume/kid_profiles.json" >> examples/Docker/data/acme_srv.cfg + + sudo cp examples/eab_handler/kid_profiles.json examples/Docker/data/kid_profiles.json + sudo chmod 777 examples/eab_handler/kid_profiles.json + sudo sed -i "s/\"profile_id\"\: \[\"profile_1\", \"profile_2\", \"profile_3\"\]/\"profile_name\"\: \[\"$ASA_PROFILE2\", \"$ASA_PROFILE1\"\]/g" examples/Docker/data/kid_profiles.json + sudo sed -i "s/\"profile_id\"\: \"profile_2\"/\"profile_name\"\: \"$ASA_PROFILE3\"/g" examples/Docker/data/kid_profiles.json + sudo sed -i "s/\"ca_name\": \"example_ca_2\",/\"ca_name\": \"$ASA_CA_NAME2\"/" examples/Docker/data/kid_profiles.json + sudo sed -i "s/\"ca_name\": \"example_ca\",/\"unknown_key\": \"unknown_value\"/g" examples/Docker/data/kid_profiles.json + sudo sed -i "s/example.net/acme/g" examples/Docker/data/kid_profiles.json + sudo sed -i '18,19d' examples/Docker/data/kid_profiles.json + sudo sed -i '8,9d' examples/Docker/data/kid_profiles.json + + cd examples/Docker/ + docker-compose restart + docker-compose logs + env: + ASA_API_HOST: ${{ secrets.ASA_API_HOST }} + ASA_API_USER: ${{ secrets.ASA_API_USER }} + ASA_API_PASSWORD: ${{ secrets.ASA_API_PASSWORD }} + ASA_API_KEY: ${{ secrets.ASA_API_KEY }} + ASA_CA_NAME: ${{ secrets.ASA_CA_NAME }} + ASA_CA_NAME2: ${{ secrets.ASA_CA_NAME2 }} + ASA_CA_BUNDLE: ${{ secrets.ASA_CA_BUNDLE }} + ASA_PROFILE1: ${{ secrets.ASA_PROFILE1 }} + ASA_PROFILE2: ${{ secrets.ASA_PROFILE2 }} + ASA_PROFILE3: ${{ secrets.ASA_PROFILE3 }} + + - name: "EAB with headerinfo - Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "EAB with headerinfo - Test http://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "EAB with headerinfo - Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "EAB with headerinfo - 01 - Enroll acme.sh without profile_name" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_00 --eab-hmac-key V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --keylength 2048 --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -issuer --noout | grep -i "${{ secrets.ASA_CA_NAME }}" + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext keyUsage -noout | grep -i "Key Encipherment, Data Encipherment" + + - name: "EAB with headerinfo - 01 - Enroll lego without profile_name" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw -k rsa2048 -d lego.acme --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -issuer --noout | grep -i "${{ secrets.ASA_CA_NAME }}" + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext keyUsage -noout | grep -i "Key Encipherment, Data Encipherment" + + - name: "EAB with headerinfo - 02a - Enroll acme with a profile_name taken from header_info NOT included in kid.json (to fail)" + id: acmefail01 + continue-on-error: true + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_00 --eab-hmac-key V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --useragent profile_name=unknown -d acme-sh.acme --standalone --keylength 2048 --debug 3 --output-insecure + + - name: "EAB with headerinfo - 02a - check result " + if: steps.acmefail01.outcome != 'failure' + run: | + echo "acmefail outcome is ${{steps.acmefail01.outcome }}" + exit 1 + + - name: "EAB with headerinfo - 02b - Enroll acme with a profile_name taken from header_info included in kid.json" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_00 --eab-hmac-key V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --useragent profile_name=ACME -d acme-sh.acme --standalone --keylength 2048 --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -issuer --noout | grep -i "${{ secrets.ASA_CA_NAME }}" + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature" + + - name: "EAB with headerinfo - 02a - Enroll lego with a profile_name taken from header_info NOT included in kid.json (to fail)" + id: legofail01 + continue-on-error: true + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --user-agent profile_name=unknown -k rsa2048 -d lego.acme --http run + + - name: "EAB with headerinfo - 02a - check result " + if: steps.legofail01.outcome != 'failure' + run: | + echo "legofail outcome is ${{steps.legofail01.outcome }}" + exit 1 + + - name: "EAB with headerinfo - 02b - Enroll lego with a profile_name taken from header_info included in kid.json" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --user-agent profile_name=ACME -k rsa2048 -d lego.acme --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -issuer --noout | grep -i "${{ secrets.ASA_CA_NAME }}" + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext keyUsage -noout | grep "Digital Signature" + + - name: "EAB with headerinfo - 03 - Enroll acme with a profile_name/ca_name taken from kid.json" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_01 --eab-hmac-key YW5vdXRoZXJfdmVyeV9sb25nX2htYWNfZm9yX2tleWlkXzAxX3doaWNoIHdpbGxfYmUgdXNlZF9kdXJpbmcgcmVncmVzc2lvbg --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --keylength 2048 --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -issuer --noout | grep -i "${{ secrets.ASA_CA_NAME2 }}" + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext keyUsage -noout | grep -i "Digital Signature" + + - name: "EAB with headerinfo - 03 - Enroll lego with a profile_name/ca_name taken from kid.json" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_01 --hmac YW5vdXRoZXJfdmVyeV9sb25nX2htYWNfZm9yX2tleWlkXzAxX3doaWNoIHdpbGxfYmUgdXNlZF9kdXJpbmcgcmVncmVzc2lvbg -k rsa2048 -d lego.acme --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -issuer --noout | grep -i "${{ secrets.ASA_CA_NAME2 }}" + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext keyUsage | grep -i "Digital Signature" + + - name: "EAB with headerinfo - 04 - Enroll acme with a not allowed fqdn in kid.json (to fail)" + id: acmefail021 + continue-on-error: true + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --keylength 2048 --debug 3 --output-insecure + + - name: "EAB with headerinfo - 04 - check result " + if: steps.acmefail021.outcome != 'failure' + run: | + echo "acmefail outcome is ${{steps.acmefail021.outcome }}" + exit 1 + + - name: "EAB with headerinfo - 04 - Enroll lego with a not allowed fqdn in kid.json (to fail)" + id: legofail021 + continue-on-error: true + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM -k rsa2048 -d lego.acme --http run + + - name: "EAB with headerinfo - 04a - check result " + if: steps.legofail021.outcome != 'failure' + run: | + echo "legofail outcome is ${{steps.legofail021.outcome }}" + exit 1 + + - name: "EAB with headerinfo - 05 - Enroll acme with default values from acme.cfg" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_03 --eab-hmac-key YW5kX2ZpbmFsbHlfdGhlX2xhc3RfaG1hY19rZXlfd2hpY2hfaXNfbG9uZ2VyX3RoYW5fMjU2X2JpdHNfYW5kX3Nob3VsZF93b3Jr --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --keylength 2048 --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -issuer --noout | grep -i "${{ secrets.ASA_CA_NAME }}" + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature" + + - name: "EAB with headerinfo - 05 - Enroll lego with default values from acme.cfg" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_03 --hmac YW5kX2ZpbmFsbHlfdGhlX2xhc3RfaG1hY19rZXlfd2hpY2hfaXNfbG9uZ2VyX3RoYW5fMjU2X2JpdHNfYW5kX3Nob3VsZF93b3Jr -k rsa2048 -d lego.acme --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -issuer --noout | grep -i "${{ secrets.ASA_CA_NAME }}" + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext keyUsage | grep "Digital Signature" + + - name: "EAB with headerinfo - 06 - Enroll acme with not allowed headerinfo-field (should fail)" + id: acmefail03 + continue-on-error: true + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --useragent profile_id=101 -d acme-sh.acme --keylength 2048 --standalone --debug 3 --output-insecure + + - name: "EAB with headerinfo - 06 - check result " + if: steps.acmefail03.outcome != 'failure' + run: | + echo "acmefail outcome is ${{steps.acmefail03.outcome }}" + exit 1 + + - name: "EAB with headerinfo - 06 - Enroll lego with not allowed headerinfo-field (should fail)" + id: legofail03 + continue-on-error: true + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM --user-agent profile_id=101 -k rsa2048 -d lego.acme --http run + + - name: "EAB with headerinfo - 06 - check result " + if: steps.legofail03.outcome != 'failure' + run: | + echo "legofail outcome is ${{steps.legofail03.outcome }}" + exit 1 + - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | @@ -223,7 +684,7 @@ jobs: max-parallel: 1 fail-fast: false matrix: - rhversion: [8, 9] + rhversion: [8] steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -269,7 +730,7 @@ jobs: GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} - - name: "[ PREPARE ] prepare acme_srv.cfg with certifier_ca_handler" + - name: "Profile ${{ secrets.ASA_PROFILE1 }} - Setup a2c with asa_ca_handler with profile ${{ secrets.ASA_PROFILE1 }}" run: | mkdir -p data/acme_ca sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem @@ -294,63 +755,59 @@ jobs: ASA_CA_BUNDLE: ${{ secrets.ASA_CA_BUNDLE }} ASA_PROFILE1: ${{ secrets.ASA_PROFILE1 }} - - name: "[ PREPARE ] Almalinux instance" + - name: "Profile ${{ secrets.ASA_PROFILE1 }} - Almalinux instance" run: | sudo cp examples/Docker/almalinux-systemd/Dockerfile data sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - - name: "[ RUN ] Execute install scipt" + - name: "Profile ${{ secrets.ASA_PROFILE1 }} - Execute install scipt" run: | docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh - - name: "Test http://acme-srv/directory is accessible" + - name: "Profile ${{ secrets.ASA_PROFILE1 }} - Test http://acme-srv/directory is accessible" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "[ PREPARE ] prepare acme.sh container" - run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - - name: "[ ENROLL ] acme.sh" + - name: "Profile ${{ secrets.ASA_PROFILE1 }} - Enroll acme.sh" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --keylength 2048 --debug 3 --output-insecure --force + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' -d acme-sh.acme --alpn --standalone --keylength 2048 --debug 3 --output-insecure awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature" # openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -text -noout - - name: "revoke via acme.sh" + - name: "Profile ${{ secrets.ASA_PROFILE1 }} - Revoke via acme.sh" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --revoke --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "[ REGISTER ] certbot" + - name: "Profile ${{ secrets.ASA_PROFILE1 }} - Register certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ ENROLL ] HTTP-01 single domain certbot" + - name: "Profile ${{ secrets.ASA_PROFILE1 }} - Enroll HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot --key-type rsa --rsa-key-size 2048 sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem sudo openssl x509 -in certbot/live/certbot/cert.pem -ext keyUsage -noout | grep "Digital Signature" # sudo openssl x509 -in certbot/live/certbot/cert.pem -text -noout - - name: "revoke HTTP-01 single domain certbot" + - name: "Profile ${{ secrets.ASA_PROFILE1 }} - Revoke HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - - name: "[ ENROLL ] lego" + - name: "Profile ${{ secrets.ASA_PROFILE1 }} - Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --key-type rsa2048 --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt sudo openssl x509 -in lego/certificates/lego.acme.crt -ext keyUsage -noout | grep "Digital Signature" # sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout - - name: "revoke HTTP-01 single domain lego" + - name: "Profile ${{ secrets.ASA_PROFILE1 }} - Revoke HTTP-01 single domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke - - name: "[ PREPARE ] prepare acme_srv.cfg with certifier_ca_handler" + - name: "Profile ${{ secrets.ASA_PROFILE2 }} - Setup a2c with asa_ca_handler with profile ${{ secrets.ASA_PROFILE1 }}" run: | sudo touch data/acme_srv.cfg sudo chmod 777 data/acme_srv.cfg @@ -373,55 +830,482 @@ jobs: ASA_CA_BUNDLE: ${{ secrets.ASA_CA_BUNDLE }} ASA_PROFILE2: ${{ secrets.ASA_PROFILE2 }} - - name: "[ PREPARE ] reconfigure a2c " + - name: "Profile ${{ secrets.ASA_PROFILE2 }} - reconfigure a2c " run: | docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart - - name: "[ PREPARE ] create letsencrypt and lego folder" + - name: "Profile ${{ secrets.ASA_PROFILE2 }} - create letsencrypt and lego folder" run: | sudo rm -rf certbot/* sudo rm -rf lego/* sudo rm -rf acme-sh/* - docker restart acme-sh - - name: "[ ENROLL ] acme.sh" + - name: "Profile ${{ secrets.ASA_PROFILE2 }} - acme.sh" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --standalone --keylength 2048 --debug 3 --output-insecure --force + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' -d acme-sh.acme --alpn --standalone --keylength 2048 --debug 3 --output-insecure awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext keyUsage -noout | grep "Key Encipherment, Data Encipherment" # openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -text -noout - - name: "revoke via acme.sh" + - name: "Profile ${{ secrets.ASA_PROFILE2 }} - revoke via acme.sh" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --revoke -d acme-sh.acme --standalone --debug 3 --output-insecure + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --revoke --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "[ REGISTER ] certbot" + - name: "Profile ${{ secrets.ASA_PROFILE2 }} - register certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "[ ENROLL ] HTTP-01 single domain certbot" + - name: "Profile ${{ secrets.ASA_PROFILE2 }} - Enroll HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot --force-renewal --key-type rsa --rsa-key-size 2048 sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem certbot/live/certbot/cert.pem sudo openssl x509 -in certbot/live/certbot/cert.pem -ext keyUsage -noout | grep "Key Encipherment, Data Encipherment" # sudo openssl x509 -in certbot/live/certbot/cert.pem -text -noout - - name: "revoke HTTP-01 single domain certbot" + - name: "Profile ${{ secrets.ASA_PROFILE2 }} - Revoke HTTP-01 single domain certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot revoke --delete-after-revoke --server http://acme-srv -d certbot.acme --cert-name certbot - - name: "[ ENROLL ] lego" + - name: "Profile ${{ secrets.ASA_PROFILE2 }} - Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --key-type rsa2048 --http run sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt sudo openssl x509 -in lego/certificates/lego.acme.crt -ext keyUsage -noout | grep "Key Encipherment, Data Encipherment" # sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout - - name: "revoke HTTP-01 single domain lego" + - name: "Profile ${{ secrets.ASA_PROFILE2 }} - revoke HTTP-01 single domain lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme revoke + - name: "Header-info - Setup asa_ca_handler with header-info" + run: | + sudo touch data/acme_srv.cfg + sudo chmod 777 data/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/acme_srv.cfg + sudo echo "handler_file: examples/ca_handler/asa_ca_handler.py" >> data/acme_srv.cfg + sudo echo "api_host: $ASA_API_HOST" >> data/acme_srv.cfg + sudo echo "api_user: $ASA_API_USER" >> data/acme_srv.cfg + sudo echo "api_password: $ASA_API_PASSWORD" >> data/acme_srv.cfg + sudo echo "api_key: $ASA_API_KEY" >> data/acme_srv.cfg + sudo echo "ca_name: $ASA_CA_NAME" >> data/acme_srv.cfg + sudo echo "ca_bundle: $ASA_CA_BUNDLE" >> data/acme_srv.cfg + sudo echo "profile_name: $ASA_PROFILE1" >> data/acme_srv.cfg + sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout:15/g" data/acme_srv.cfg + sudo sed -i "s/tnauthlist_support: False/tnauthlist_support: False\nheader_info_list: [\"HTTP_USER_AGENT\"]/g" data/acme_srv.cfg + env: + ASA_API_HOST: ${{ secrets.ASA_API_HOST }} + ASA_API_USER: ${{ secrets.ASA_API_USER }} + ASA_API_PASSWORD: ${{ secrets.ASA_API_PASSWORD }} + ASA_API_KEY: ${{ secrets.ASA_API_KEY }} + ASA_CA_NAME: ${{ secrets.ASA_CA_NAME }} + ASA_CA_BUNDLE: ${{ secrets.ASA_CA_BUNDLE }} + ASA_PROFILE1: ${{ secrets.ASA_PROFILE1 }} + + - name: "Profile ${{ secrets.ASA_PROFILE2 }} - reconfigure a2c " + run: | + docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart + + - name: "Header-info - 01 - Enroll acme.sh with profile_name ${{ secrets.ASA_PROFILE1 }}" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' --useragent profile_name=${{ secrets.ASA_PROFILE1 }} -d acme-sh.acme --alpn --standalone --keylength 2048 --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -texte -noout + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature" + + - name: "Header-info - 01 - Enroll lego with profile_id ${{ secrets.ASA_PROFILE1 }}" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent profile_name=${{ secrets.ASA_PROFILE1 }} -d lego.acme --key-type rsa2048 --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext keyUsage -noout | grep "Digital Signature" + + - name: "Header-info - 02 - Enroll acme.sh with profile_name ${{ secrets.ASA_PROFILE2 }}" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' --useragent profile_name=${{ secrets.ASA_PROFILE2 }} -d acme-sh.acme --alpn --standalone --keylength 2048 --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -texte -noout + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext keyUsage -noout | grep "Key Encipherment, Data Encipherment" + + - name: "Header-info - 02 - Enroll lego with profile_id ${{ secrets.ASA_PROFILE2 }}" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent profile_name=${{ secrets.ASA_PROFILE2 }} -d lego.acme --key-type rsa2048 --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + # sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext keyUsage -noout | grep "Key Encipherment, Data Encipherment" + + - name: "EAB without headerinfo - Setup asa_ca_handler" + run: | + sudo touch data/acme_srv.cfg + sudo chmod 777 data/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/acme_srv.cfg + sudo echo "handler_file: examples/ca_handler/asa_ca_handler.py" >> data/acme_srv.cfg + sudo echo "api_host: $ASA_API_HOST" >> data/acme_srv.cfg + sudo echo "api_user: $ASA_API_USER" >> data/acme_srv.cfg + sudo echo "api_password: $ASA_API_PASSWORD" >> data/acme_srv.cfg + sudo echo "api_key: $ASA_API_KEY" >> data/acme_srv.cfg + sudo echo "ca_name: $ASA_CA_NAME" >> data/acme_srv.cfg + sudo echo "ca_bundle: $ASA_CA_BUNDLE" >> data/acme_srv.cfg + sudo echo "profile_name: $ASA_PROFILE1" >> data/acme_srv.cfg + sudo echo "eab_profiling: True" >> data/acme_srv.cfg + sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout:15/g" data/acme_srv.cfg + sudo echo -e "\n\n[EABhandler]" >> data/acme_srv.cfg + sudo echo "eab_handler_file: /opt/acme2certifier/examples/eab_handler/kid_profile_handler.py" >> data/acme_srv.cfg + sudo echo "key_file: /opt/acme2certifier/volume/acme_ca/kid_profiles.json" >> data/acme_srv.cfg + + sudo cp examples/eab_handler/kid_profiles.json data/acme_ca/kid_profiles.json + sudo chmod 777 data/acme_ca/kid_profiles.json + sudo sed -i "s/\"profile_id\"\: \[\"profile_1\", \"profile_2\", \"profile_3\"\]/\"profile_name\"\: \[\"$ASA_PROFILE2\", \"$ASA_PROFILE1\"\]/g" data/acme_ca/kid_profiles.json + sudo sed -i "s/\"profile_id\"\: \"profile_2\"/\"profile_name\"\: \"$ASA_PROFILE3\"/g" data/acme_ca/kid_profiles.json + sudo sed -i "s/\"ca_name\": \"example_ca_2\",/\"ca_name\": \"$ASA_CA_NAME2\"/" data/acme_ca/kid_profiles.json + sudo sed -i "s/\"ca_name\": \"example_ca\",/\"unknown_key\": \"unknown_value\"/g" data/acme_ca/kid_profiles.json + sudo sed -i "s/example.net/acme/g" data/acme_ca/kid_profiles.json + sudo sed -i '18,19d' data/acme_ca/kid_profiles.json + sudo sed -i '8,9d' data/acme_ca/kid_profiles.json + env: + ASA_API_HOST: ${{ secrets.ASA_API_HOST }} + ASA_API_USER: ${{ secrets.ASA_API_USER }} + ASA_API_PASSWORD: ${{ secrets.ASA_API_PASSWORD }} + ASA_API_KEY: ${{ secrets.ASA_API_KEY }} + ASA_CA_NAME: ${{ secrets.ASA_CA_NAME }} + ASA_CA_NAME2: ${{ secrets.ASA_CA_NAME2 }} + ASA_CA_BUNDLE: ${{ secrets.ASA_CA_BUNDLE }} + ASA_PROFILE1: ${{ secrets.ASA_PROFILE1 }} + ASA_PROFILE2: ${{ secrets.ASA_PROFILE2 }} + ASA_PROFILE3: ${{ secrets.ASA_PROFILE3 }} + + - name: "EAB without headerinfo - Reconfigure a2c " + run: | + docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart + + - name: "EAB without headerinfo - Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "EAB without headerinfo - 01 - Enroll acme.sh without profile_name" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_00 --eab-hmac-key V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --keylength 2048 --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -issuer --noout | grep -i "${{ secrets.ASA_CA_NAME }}" + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext keyUsage -noout | grep -i "Key Encipherment, Data Encipherment" + + - name: "EAB without headerinfo - 01 - Enroll lego without profile_name" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw -k rsa2048 -d lego.acme --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -issuer --noout | grep -i "${{ secrets.ASA_CA_NAME }}" + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext keyUsage -noout | grep -i "Key Encipherment, Data Encipherment" + + - name: "EAB without headerinfo - 02 - Enroll acme with a profile_name taken from header_info NOT included in kid.json (to be ignored)" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_00 --eab-hmac-key V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --useragent profile_name=unknown -d acme-sh.acme --standalone --keylength 2048 --debug 3 --output-insecure + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -issuer --noout | grep -i "${{ secrets.ASA_CA_NAME }}" + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext keyUsage -noout | grep -i "Key Encipherment, Data Encipherment" + + - name: "EAB without headerinfo - 02 - Enroll lego with a profile_name taken from header_info NOT included in kid.json (to be ignored)" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --user-agent profile_name=unknown -k rsa2048 -d lego.acme --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -issuer --noout | grep -i "${{ secrets.ASA_CA_NAME }}" + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext keyUsage -noout | grep "Key Encipherment, Data Encipherment" + + - name: "EAB without headerinfo - 03 - Enroll acme with a profile_name/ca_name taken from kid.json" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_01 --eab-hmac-key YW5vdXRoZXJfdmVyeV9sb25nX2htYWNfZm9yX2tleWlkXzAxX3doaWNoIHdpbGxfYmUgdXNlZF9kdXJpbmcgcmVncmVzc2lvbg --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --keylength 2048 --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -issuer --noout | grep -i "${{ secrets.ASA_CA_NAME2 }}" + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext keyUsage -noout | grep -i "Digital Signature" + + - name: "EAB without headerinfo - 03 - Enroll lego with a profile_name/ca_name taken from kid.json" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_01 --hmac YW5vdXRoZXJfdmVyeV9sb25nX2htYWNfZm9yX2tleWlkXzAxX3doaWNoIHdpbGxfYmUgdXNlZF9kdXJpbmcgcmVncmVzc2lvbg -k rsa2048 -d lego.acme --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -issuer --noout | grep -i "${{ secrets.ASA_CA_NAME2 }}" + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext keyUsage | grep -i "Digital Signature" + + - name: "EAB with headerinfo - 04 - Enroll acme with a not allowed fqdn in kid.json (to fail)" + id: acmefail02 + continue-on-error: true + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --keylength 2048 --debug 3 --output-insecure + + - name: "EAB with headerinfo - 04 - check result " + if: steps.acmefail02.outcome != 'failure' + run: | + echo "acmefail outcome is ${{steps.acmefail02.outcome }}" + exit 1 + + - name: "EAB with headerinfo - 04 - Enroll lego with a not allowed fqdn in kid.json (to fail)" + id: legofail02 + continue-on-error: true + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM -k rsa2048 -d lego.acme --http run + + - name: "EAB with headerinfo - 04a - check result " + if: steps.legofail02.outcome != 'failure' + run: | + echo "legofail outcome is ${{steps.legofail02.outcome }}" + exit 1 + + - name: "EAB with headerinfo - 05 - Enroll acme with default values from acme.cfg" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_03 --eab-hmac-key YW5kX2ZpbmFsbHlfdGhlX2xhc3RfaG1hY19rZXlfd2hpY2hfaXNfbG9uZ2VyX3RoYW5fMjU2X2JpdHNfYW5kX3Nob3VsZF93b3Jr --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --keylength 2048 --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -issuer --noout | grep -i "${{ secrets.ASA_CA_NAME }}" + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature" + + - name: "EAB with headerinfo - 05 - Enroll lego with default values from acme.cfg" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_03 --hmac YW5kX2ZpbmFsbHlfdGhlX2xhc3RfaG1hY19rZXlfd2hpY2hfaXNfbG9uZ2VyX3RoYW5fMjU2X2JpdHNfYW5kX3Nob3VsZF93b3Jr -k rsa2048 -d lego.acme --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -issuer --noout | grep -i "${{ secrets.ASA_CA_NAME }}" + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext keyUsage | grep "Digital Signature" + + - name: "EAB with headerinfo - Setup asa_ca_handler" + run: | + sudo touch data/acme_srv.cfg + sudo chmod 777 data/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/acme_srv.cfg + sudo echo "handler_file: examples/ca_handler/asa_ca_handler.py" >> data/acme_srv.cfg + sudo echo "api_host: $ASA_API_HOST" >> data/acme_srv.cfg + sudo echo "api_user: $ASA_API_USER" >> data/acme_srv.cfg + sudo echo "api_password: $ASA_API_PASSWORD" >> data/acme_srv.cfg + sudo echo "api_key: $ASA_API_KEY" >> data/acme_srv.cfg + sudo echo "ca_name: $ASA_CA_NAME" >> data/acme_srv.cfg + sudo echo "ca_bundle: $ASA_CA_BUNDLE" >> data/acme_srv.cfg + sudo echo "profile_name: $ASA_PROFILE1" >> data/acme_srv.cfg + sudo echo "eab_profiling: True" >> data/acme_srv.cfg + sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout:15/g" data/acme_srv.cfg + sudo sed -i "s/tnauthlist_support: False/tnauthlist_support: False\nheader_info_list: [\"HTTP_USER_AGENT\"]/g" data/acme_srv.cfg + sudo echo -e "\n\n[EABhandler]" >> data/acme_srv.cfg + sudo echo "eab_handler_file: /opt/acme2certifier/examples/eab_handler/kid_profile_handler.py" >> data/acme_srv.cfg + sudo echo "key_file: /opt/acme2certifier/volume/acme_ca/kid_profiles.json" >> data/acme_srv.cfg + + sudo cp examples/eab_handler/kid_profiles.json data/acme_ca/kid_profiles.json + sudo chmod 777 data/acme_ca/kid_profiles.json + sudo sed -i "s/\"profile_id\"\: \[\"profile_1\", \"profile_2\", \"profile_3\"\]/\"profile_name\"\: \[\"$ASA_PROFILE2\", \"$ASA_PROFILE1\"\]/g" data/acme_ca/kid_profiles.json + sudo sed -i "s/\"profile_id\"\: \"profile_2\"/\"profile_name\"\: \"$ASA_PROFILE3\"/g" data/acme_ca/kid_profiles.json + sudo sed -i "s/\"ca_name\": \"example_ca_2\",/\"ca_name\": \"$ASA_CA_NAME2\"/" data/acme_ca/kid_profiles.json + sudo sed -i "s/\"ca_name\": \"example_ca\",/\"unknown_key\": \"unknown_value\"/g" data/acme_ca/kid_profiles.json + sudo sed -i "s/example.net/acme/g" data/acme_ca/kid_profiles.json + sudo sed -i '18,19d' data/acme_ca/kid_profiles.json + sudo sed -i '8,9d' data/acme_ca/kid_profiles.json + env: + ASA_API_HOST: ${{ secrets.ASA_API_HOST }} + ASA_API_USER: ${{ secrets.ASA_API_USER }} + ASA_API_PASSWORD: ${{ secrets.ASA_API_PASSWORD }} + ASA_API_KEY: ${{ secrets.ASA_API_KEY }} + ASA_CA_NAME: ${{ secrets.ASA_CA_NAME }} + ASA_CA_NAME2: ${{ secrets.ASA_CA_NAME2 }} + ASA_CA_BUNDLE: ${{ secrets.ASA_CA_BUNDLE }} + ASA_PROFILE1: ${{ secrets.ASA_PROFILE1 }} + ASA_PROFILE2: ${{ secrets.ASA_PROFILE2 }} + ASA_PROFILE3: ${{ secrets.ASA_PROFILE3 }} + + - name: "EAB without headerinfo - Reconfigure a2c " + run: | + docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart + + - name: "EAB without headerinfo - Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "EAB with headerinfo - 01 - Enroll acme.sh without profile_name" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_00 --eab-hmac-key V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --keylength 2048 --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -issuer --noout | grep -i "${{ secrets.ASA_CA_NAME }}" + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext keyUsage -noout | grep -i "Key Encipherment, Data Encipherment" + + - name: "EAB with headerinfo - 01 - Enroll lego without profile_name" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw -k rsa2048 -d lego.acme --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -issuer --noout | grep -i "${{ secrets.ASA_CA_NAME }}" + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext keyUsage -noout | grep -i "Key Encipherment, Data Encipherment" + + - name: "EAB with headerinfo - 02a - Enroll acme with a profile_name taken from header_info NOT included in kid.json (to fail)" + id: acmefail01 + continue-on-error: true + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_00 --eab-hmac-key V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --useragent profile_name=unknown -d acme-sh.acme --standalone --keylength 2048 --debug 3 --output-insecure + + - name: "EAB with headerinfo - 02a - check result " + if: steps.acmefail01.outcome != 'failure' + run: | + echo "acmefail outcome is ${{steps.acmefail01.outcome }}" + exit 1 + + - name: "EAB with headerinfo - 02b - Enroll acme with a profile_name taken from header_info included in kid.json" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_00 --eab-hmac-key V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --useragent profile_name=ACME -d acme-sh.acme --standalone --keylength 2048 --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -issuer --noout | grep -i "${{ secrets.ASA_CA_NAME }}" + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature" + + - name: "EAB with headerinfo - 02a - Enroll lego with a profile_name taken from header_info NOT included in kid.json (to fail)" + id: legofail01 + continue-on-error: true + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --user-agent profile_name=unknown -k rsa2048 -d lego.acme --http run + + - name: "EAB with headerinfo - 02a - check result " + if: steps.legofail01.outcome != 'failure' + run: | + echo "legofail outcome is ${{steps.legofail01.outcome }}" + exit 1 + + - name: "EAB with headerinfo - 02b - Enroll lego with a profile_name taken from header_info included in kid.json" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --user-agent profile_name=ACME -k rsa2048 -d lego.acme --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -issuer --noout | grep -i "${{ secrets.ASA_CA_NAME }}" + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext keyUsage -noout | grep "Digital Signature" + + - name: "EAB with headerinfo - 03 - Enroll acme with a profile_name/ca_name taken from kid.json" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_01 --eab-hmac-key YW5vdXRoZXJfdmVyeV9sb25nX2htYWNfZm9yX2tleWlkXzAxX3doaWNoIHdpbGxfYmUgdXNlZF9kdXJpbmcgcmVncmVzc2lvbg --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --keylength 2048 --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -issuer --noout | grep -i "${{ secrets.ASA_CA_NAME2 }}" + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext keyUsage -noout | grep -i "Digital Signature" + + - name: "EAB with headerinfo - 03 - Enroll lego with a profile_name/ca_name taken from kid.json" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_01 --hmac YW5vdXRoZXJfdmVyeV9sb25nX2htYWNfZm9yX2tleWlkXzAxX3doaWNoIHdpbGxfYmUgdXNlZF9kdXJpbmcgcmVncmVzc2lvbg -k rsa2048 -d lego.acme --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -issuer --noout | grep -i "${{ secrets.ASA_CA_NAME2 }}" + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext keyUsage | grep -i "Digital Signature" + + - name: "EAB with headerinfo - 04 - Enroll acme with a not allowed fqdn in kid.json (to fail)" + id: acmefail021 + continue-on-error: true + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --keylength 2048 --debug 3 --output-insecure + + - name: "EAB with headerinfo - 04 - check result " + if: steps.acmefail021.outcome != 'failure' + run: | + echo "acmefail outcome is ${{steps.acmefail021.outcome }}" + exit 1 + + - name: "EAB with headerinfo - 04 - Enroll lego with a not allowed fqdn in kid.json (to fail)" + id: legofail021 + continue-on-error: true + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM -k rsa2048 -d lego.acme --http run + + - name: "EAB with headerinfo - 04a - check result " + if: steps.legofail021.outcome != 'failure' + run: | + echo "legofail outcome is ${{steps.legofail021.outcome }}" + exit 1 + + - name: "EAB with headerinfo - 05 - Enroll acme with default values from acme.cfg" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_03 --eab-hmac-key YW5kX2ZpbmFsbHlfdGhlX2xhc3RfaG1hY19rZXlfd2hpY2hfaXNfbG9uZ2VyX3RoYW5fMjU2X2JpdHNfYW5kX3Nob3VsZF93b3Jr --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --keylength 2048 --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -issuer --noout | grep -i "${{ secrets.ASA_CA_NAME }}" + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext keyUsage -noout | grep "Digital Signature" + + - name: "EAB with headerinfo - 05 - Enroll lego with default values from acme.cfg" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_03 --hmac YW5kX2ZpbmFsbHlfdGhlX2xhc3RfaG1hY19rZXlfd2hpY2hfaXNfbG9uZ2VyX3RoYW5fMjU2X2JpdHNfYW5kX3Nob3VsZF93b3Jr -k rsa2048 -d lego.acme --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -issuer --noout | grep -i "${{ secrets.ASA_CA_NAME }}" + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext keyUsage | grep "Digital Signature" + + - name: "EAB with headerinfo - 06 - Enroll acme with not allowed headerinfo-field (should fail)" + id: acmefail03 + continue-on-error: true + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --useragent profile_id=101 -d acme-sh.acme --keylength 2048 --standalone --debug 3 --output-insecure + + - name: "EAB with headerinfo - 06 - check result " + if: steps.acmefail03.outcome != 'failure' + run: | + echo "acmefail outcome is ${{steps.acmefail03.outcome }}" + exit 1 + + - name: "EAB with headerinfo - 06 - Enroll lego with not allowed headerinfo-field (should fail)" + id: legofail03 + continue-on-error: true + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM --user-agent profile_id=101 -k rsa2048 -d lego.acme --http run + + - name: "EAB with headerinfo - 06 - check result " + if: steps.legofail03.outcome != 'failure' + run: | + echo "legofail outcome is ${{steps.legofail03.outcome }}" + exit 1 + - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | diff --git a/.github/workflows/ca_handler_tests_certifier.yml b/.github/workflows/ca_handler_tests_certifier.yml index ad48ac70..f38487aa 100644 --- a/.github/workflows/ca_handler_tests_certifier.yml +++ b/.github/workflows/ca_handler_tests_certifier.yml @@ -16,8 +16,8 @@ jobs: max-parallel: 2 fail-fast: false matrix: - websrv: ['apache2', 'nginx'] - dbhandler: ['wsgi', 'django'] + websrv: ['apache2'] + dbhandler: ['wsgi'] steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -319,7 +319,164 @@ jobs: sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Server" - - name: "EAB - Setup a2c with certifier_ca_handler" + - name: "EAB without headerinfo - Setup a2c with certifier_ca_handler" + run: | + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py + sudo cp .github/openssl_ca_handler.py_acme_srv_default_handler.cfg examples/Docker/data/acme_srv.cfg + sudo chmod 777 examples/Docker/data/acme_srv.cfg + sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg + sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> examples/Docker/data/acme_srv.cfg + sudo echo "api_host: $NCM_API_HOST" >> examples/Docker/data/acme_srv.cfg + sudo echo "api_user: $NCM_API_USER" >> examples/Docker/data/acme_srv.cfg + sudo echo "api_password: $NCM_API_PASSWORD" >> examples/Docker/data/acme_srv.cfg + sudo echo "ca_name: $NCM_CA_NAME" >> examples/Docker/data/acme_srv.cfg + sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> examples/Docker/data/acme_srv.cfg + sudo echo "profile_id: 100" >> examples/Docker/data/acme_srv.cfg + sudo echo "eab_profiling: True" >> examples/Docker/data/acme_srv.cfg + sudo echo -e "\n[EABhandler]" >> examples/Docker/data/acme_srv.cfg + sudo echo "eab_handler_file: /var/www/acme2certifier/examples/eab_handler/kid_profile_handler.py" >> examples/Docker/data/acme_srv.cfg + sudo echo "key_file: volume/kid_profiles.json" >> examples/Docker/data/acme_srv.cfg + + sudo cp examples/eab_handler/kid_profiles.json examples/Docker/data/kid_profiles.json + sudo chmod 777 examples/eab_handler/kid_profiles.json + sudo sed -i "s/\"profile_id\"\: \[\"profile_1\", \"profile_2\", \"profile_3\"\]/\"profile_id\"\: \[\"102\", \"101\"\, \"100\"]/g" examples/Docker/data/kid_profiles.json + sudo sed -i "s/\"profile_id\"\: \"profile_2\"/\"profile_id\"\: \"102\"/g" examples/Docker/data/kid_profiles.json + sudo sed -i "s/\"ca_name\": \"example_ca_2\",/\"ca_name\": \"SubCA2\"/" examples/Docker/data/kid_profiles.json + sudo sed -i "s/\"ca_name\": \"example_ca\",/\"unknown_key\": \"unknown_value\"/g" examples/Docker/data/kid_profiles.json + sudo sed -i "s/example.net/acme/g" examples/Docker/data/kid_profiles.json + sudo sed -i '18,19d' examples/Docker/data/kid_profiles.json + sudo sed -i '8,9d' examples/Docker/data/kid_profiles.json + + cd examples/Docker/ + docker-compose restart + docker-compose logs + env: + NCM_API_HOST: ${{ secrets.NCM_API_HOST }} + NCM_API_USER: ${{ secrets.NCM_API_USER }} + NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} + NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} + NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} + + - name: "EAB without headerinfo - Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "EAB without headerinfo - Test http://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "EAB without headerinfo - Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory + + - name: "EAB without headerinfo - Enroll acme.sh without profile_id" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_00 --eab-hmac-key V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Server Authentication" + + - name: "EAB without headerinfo - Enroll lego without profile_id" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw -d lego.acme --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Server Authentication" + + - name: "EAB without headerinfo - 02 - Enroll acme with a template_name taken from header_info NOT included in kid.json (to be ignored)" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_00 --eab-hmac-key V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --useragent profile_id=unknown -d acme-sh.acme --standalone --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Server Authentication" + + - name: "EAB without headerinfo - 02 - Enroll lego with a template_name taken from header_info NOT included in kid.json (to be ignored)" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --user-agent profile_id=unknown -d lego.acme --http run + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --user-agent profile_id=101 -d lego.acme --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Server Authentication" + + - name: "EAB without headerinfo - 03 - Enroll acme with a template_name/ca_name taken from kid.json" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_01 --eab-hmac-key YW5vdXRoZXJfdmVyeV9sb25nX2htYWNfZm9yX2tleWlkXzAxX3doaWNoIHdpbGxfYmUgdXNlZF9kdXJpbmcgcmVncmVzc2lvbg --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Server Authentication" + + - name: "EAB without headerinfo - 03 - Enroll lego with a template_name/ca_name taken from kid.json" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_01 --hmac YW5vdXRoZXJfdmVyeV9sb25nX2htYWNfZm9yX2tleWlkXzAxX3doaWNoIHdpbGxfYmUgdXNlZF9kdXJpbmcgcmVncmVzc2lvbg -d lego.acme --http run + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -issuer --noout + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Server Authentication" + + - name: "EAB without headerinfo - 04 - Enroll acme with a not allowed fqdn in kid.json (to fail)" + id: acmefail021 + continue-on-error: true + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure + + - name: "EAB without headerinfo - 04 - check result " + if: steps.acmefail021.outcome != 'failure' + run: | + echo "acmefail outcome is ${{steps.acmefail021.outcome }}" + exit 1 + + - name: "EAB without headerinfo - 04 - Enroll lego with a not allowed fqdn in kid.json (to fail)" + id: legofail021 + continue-on-error: true + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM -d lego.acme --http run + + - name: "EAB without headerinfo - 04a - check result " + if: steps.legofail021.outcome != 'failure' + run: | + echo "legofail outcome is ${{steps.legofail021.outcome }}" + exit 1 + + - name: "EAB without headerinfo - 05 - Enroll acme with default values from acme.cfg" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_03 --eab-hmac-key YW5kX2ZpbmFsbHlfdGhlX2xhc3RfaG1hY19rZXlfd2hpY2hfaXNfbG9uZ2VyX3RoYW5fMjU2X2JpdHNfYW5kX3Nob3VsZF93b3Jr --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "Code Signing" + + - name: "EAB without headerinfo - 05 - Enroll lego with default values from acme.cfg" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_03 --hmac YW5kX2ZpbmFsbHlfdGhlX2xhc3RfaG1hY19rZXlfd2hpY2hfaXNfbG9uZ2VyX3RoYW5fMjU2X2JpdHNfYW5kX3Nob3VsZF93b3Jr -d lego.acme --http run + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -issuer --noout + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "Code Signing" + + - name: "EAB with headerinfo - Setup a2c with certifier_ca_handler" run: | sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem @@ -362,18 +519,18 @@ jobs: NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} - - name: "EAB - Sleep for 10s" + - name: "EAB with headerinfo - Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: time: 10s - - name: "EAB - Test http://acme-srv/directory is accessable" + - name: "EAB with headerinfo - Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "EAB - Test if https://acme-srv/directory is accessable" + - name: "EAB with headerinfo - Test if https://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - name: "EAB - 01 - Enroll acme.sh without profile_id" + - name: "EAB with headerinfo - 01 - Enroll acme.sh without profile_id" run: | sudo rm -rf acme-sh/* docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_00 --eab-hmac-key V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --debug 3 @@ -383,7 +540,7 @@ jobs: openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Server Authentication" - - name: "EAB - 01 - Enroll lego without profile_id" + - name: "EAB with headerinfo - 01 - Enroll lego without profile_id" run: | sudo rm -rf lego/* docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw -d lego.acme --http run @@ -391,7 +548,7 @@ jobs: sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Server Authentication" - - name: "EAB - 02a - Enroll acme with a template_name taken from header_info NOT included in kid.json (to fail)" + - name: "EAB with headerinfo - 02a - Enroll acme with a template_name taken from header_info NOT included in kid.json (to fail)" id: acmefail01 continue-on-error: true run: | @@ -399,13 +556,13 @@ jobs: docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_00 --eab-hmac-key V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --debug 3 docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --useragent profile_id=unknown -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "EAB - 02a - check result " + - name: "EAB with headerinfo - 02a - check result " if: steps.acmefail01.outcome != 'failure' run: | echo "acmefail outcome is ${{steps.acmefail01.outcome }}" exit 1 - - name: "EAB - 02b - Enroll acme with a template_name taken from header_info included in kid.json" + - name: "EAB with headerinfo - 02b - Enroll acme with a template_name taken from header_info included in kid.json" run: | sudo rm -rf acme-sh/* docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_00 --eab-hmac-key V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --debug 3 @@ -415,20 +572,20 @@ jobs: openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Client Authentication" - - name: "EAB - 02a - Enroll lego with a template_name taken from header_info NOT included in kid.json (to fail)" + - name: "EAB with headerinfo - 02a - Enroll lego with a template_name taken from header_info NOT included in kid.json (to fail)" id: legofail01 continue-on-error: true run: | sudo rm -rf lego/* docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --user-agent profile_id=unknown -d lego.acme --http run - - name: "EAB - 02a - check result " + - name: "EAB with headerinfo - 02a - check result " if: steps.legofail01.outcome != 'failure' run: | echo "legofail outcome is ${{steps.legofail01.outcome }}" exit 1 - - name: "EAB - 02b - Enroll lego with a template_name taken from header_info included in kid.json" + - name: "EAB with headerinfo - 02b - Enroll lego with a template_name taken from header_info included in kid.json" run: | sudo rm -rf lego/* docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --user-agent profile_id=101 -d lego.acme --http run @@ -438,7 +595,7 @@ jobs: sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Client Authentication" - - name: "EAB - 03 - Enroll acme with a template_name/ca_name taken from kid.json" + - name: "EAB with headerinfo - 03 - Enroll acme with a template_name/ca_name taken from kid.json" run: | sudo rm -rf acme-sh/* docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_01 --eab-hmac-key YW5vdXRoZXJfdmVyeV9sb25nX2htYWNfZm9yX2tleWlkXzAxX3doaWNoIHdpbGxfYmUgdXNlZF9kdXJpbmcgcmVncmVzc2lvbg --debug 3 @@ -448,7 +605,7 @@ jobs: openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Server Authentication" - - name: "EAB - 03 - Enroll lego with a template_name/ca_name taken from kid.json" + - name: "EAB with headerinfo - 03 - Enroll lego with a template_name/ca_name taken from kid.json" run: | sudo rm -rf lego/* docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_01 --hmac YW5vdXRoZXJfdmVyeV9sb25nX2htYWNfZm9yX2tleWlkXzAxX3doaWNoIHdpbGxfYmUgdXNlZF9kdXJpbmcgcmVncmVzc2lvbg -d lego.acme --http run @@ -458,7 +615,7 @@ jobs: sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Server Authentication" - - name: "EAB - 04 - Enroll acme with a not allowed fqdn in kid.json (to fail)" + - name: "EAB with headerinfo - 04 - Enroll acme with a not allowed fqdn in kid.json (to fail)" id: acmefail02 continue-on-error: true run: | @@ -466,26 +623,26 @@ jobs: docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM --debug 3 docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "EAB - 04 - check result " + - name: "EAB with headerinfo - 04 - check result " if: steps.acmefail02.outcome != 'failure' run: | echo "acmefail outcome is ${{steps.acmefail02.outcome }}" exit 1 - - name: "EAB - 04 - Enroll lego with a not allowed fqdn in kid.json (to fail)" + - name: "EAB with headerinfo - 04 - Enroll lego with a not allowed fqdn in kid.json (to fail)" id: legofail02 continue-on-error: true run: | sudo rm -rf lego/* docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM -d lego.acme --http run - - name: "EAB - 04a - check result " + - name: "EAB with headerinfo - 04a - check result " if: steps.legofail02.outcome != 'failure' run: | echo "legofail outcome is ${{steps.legofail02.outcome }}" exit 1 - - name: "EAB - 05 - Enroll acme with default values from acme.cfg" + - name: "EAB with headerinfo - 05 - Enroll acme with default values from acme.cfg" run: | sudo rm -rf acme-sh/* docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_03 --eab-hmac-key YW5kX2ZpbmFsbHlfdGhlX2xhc3RfaG1hY19rZXlfd2hpY2hfaXNfbG9uZ2VyX3RoYW5fMjU2X2JpdHNfYW5kX3Nob3VsZF93b3Jr --debug 3 @@ -495,7 +652,7 @@ jobs: openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "Code Signing" - - name: "EAB - 05 - Enroll lego with default values from acme.cfg" + - name: "EAB with headerinfo - 05 - Enroll lego with default values from acme.cfg" run: | sudo rm -rf lego/* docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_03 --hmac YW5kX2ZpbmFsbHlfdGhlX2xhc3RfaG1hY19rZXlfd2hpY2hfaXNfbG9uZ2VyX3RoYW5fMjU2X2JpdHNfYW5kX3Nob3VsZF93b3Jr -d lego.acme --http run @@ -505,7 +662,7 @@ jobs: sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "Code Signing" - - name: "EAB - 06 - Enroll acme with not allowed headerinfo-field (should fail)" + - name: "EAB with headerinfo - 06 - Enroll acme with not allowed headerinfo-field (should fail)" id: acmefail03 continue-on-error: true run: | @@ -513,20 +670,20 @@ jobs: docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM --debug 3 docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --useragent profile_id=101 -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "EAB - 06 - check result " + - name: "EAB with headerinfo - 06 - check result " if: steps.acmefail03.outcome != 'failure' run: | echo "acmefail outcome is ${{steps.acmefail03.outcome }}" exit 1 - - name: "EAB - 06 - Enroll lego with not allowed headerinfo-field (should fail)" + - name: "EAB with headerinfo - 06 - Enroll lego with not allowed headerinfo-field (should fail)" id: legofail03 continue-on-error: true run: | sudo rm -rf lego/* docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM --user-agent profile_id=101 -d lego.acme --http run - - name: "EAB - 06 - check result " + - name: "EAB with headerinfo - 06 - check result " if: steps.legofail03.outcome != 'failure' run: | echo "legofail outcome is ${{steps.legofail03.outcome }}" @@ -557,7 +714,7 @@ jobs: strategy: fail-fast: false matrix: - rhversion: [8, 9] + rhversion: [8] steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -873,7 +1030,156 @@ jobs: sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Server" - - name: "EAB - Setup a2c with certifier_ca_handler" + - name: "EAB without headerinfo - Setup a2c with certifier_ca_handler" + run: | + mkdir -p data/acme_ca + sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem + sudo touch data/acme_srv.cfg + sudo chmod 777 data/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/acme_srv.cfg + sudo echo "handler_file: examples/ca_handler/certifier_ca_handler.py" >> data/acme_srv.cfg + sudo echo "api_host: $NCM_API_HOST" >> data/acme_srv.cfg + sudo echo "api_user: $NCM_API_USER" >> data/acme_srv.cfg + sudo echo "api_password: $NCM_API_PASSWORD" >> data/acme_srv.cfg + sudo echo "ca_name: $NCM_CA_NAME" >> data/acme_srv.cfg + sudo echo "ca_bundle: $NCM_CA_BUNDLE" >> data/acme_srv.cfg + sudo echo "profile_id: 100" >> data/acme_srv.cfg + sudo echo "eab_profiling: True" >> data/acme_srv.cfg + sudo echo -e "\n\n[EABhandler]" >> data/acme_srv.cfg + sudo echo "eab_handler_file: /opt/acme2certifier/examples/eab_handler/kid_profile_handler.py" >> data/acme_srv.cfg + sudo echo "key_file: /opt/acme2certifier/volume/acme_ca/kid_profiles.json" >> data/acme_srv.cfg + + sudo cp examples/eab_handler/kid_profiles.json data/acme_ca/kid_profiles.json + sudo chmod 777 data/acme_ca/kid_profiles.json + sudo sed -i "s/\"profile_id\"\: \[\"profile_1\", \"profile_2\", \"profile_3\"\]/\"profile_id\"\: \[\"102\", \"101\"\, \"100\"]/g" data/acme_ca/kid_profiles.json + sudo sed -i "s/\"profile_id\"\: \"profile_2\"/\"profile_id\"\: \"102\"/g" data/acme_ca/kid_profiles.json + sudo sed -i "s/\"ca_name\": \"example_ca_2\",/\"ca_name\": \"SubCA2\"/" data/acme_ca/kid_profiles.json + sudo sed -i "s/\"ca_name\": \"example_ca\",/\"unknown_key\": \"unknown_value\"/g" data/acme_ca/kid_profiles.json + sudo sed -i "s/example.net/acme/g" data/acme_ca/kid_profiles.json + sudo sed -i '18,19d' data/acme_ca/kid_profiles.json + sudo sed -i '8,9d' data/acme_ca/kid_profiles.json + env: + NCM_API_HOST: ${{ secrets.NCM_API_HOST }} + NCM_API_USER: ${{ secrets.NCM_API_USER }} + NCM_API_PASSWORD: ${{ secrets.NCM_API_PASSWORD }} + NCM_CA_NAME: ${{ secrets.NCM_CA_NAME }} + NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} + PROFILE: ${{ secrets.PROFILE }} + + - name: "EAB without headerinfo - Reconfigure a2c " + run: | + docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart + + - name: "EAB without headerinfo - Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "EAB without headerinfo - Enroll acme.sh without profile_id" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_00 --eab-hmac-key V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Server Authentication" + + - name: "EAB without headerinfo - Enroll lego without profile_id" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw -d lego.acme --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Server Authentication" + + - name: "EAB without headerinfo - 02 - Enroll acme with a template_name taken from header_info NOT included in kid.json (to be ignored)" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_00 --eab-hmac-key V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --useragent profile_id=unknown -d acme-sh.acme --standalone --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Server Authentication" + + - name: "EAB without headerinfo - 02 - Enroll lego with a template_name taken from header_info NOT included in kid.json (to be ignored)" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --user-agent profile_id=unknown -d lego.acme --http run + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --user-agent profile_id=101 -d lego.acme --http run + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Server Authentication" + + - name: "EAB without headerinfo - 03 - Enroll acme with a template_name/ca_name taken from kid.json" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_01 --eab-hmac-key YW5vdXRoZXJfdmVyeV9sb25nX2htYWNfZm9yX2tleWlkXzAxX3doaWNoIHdpbGxfYmUgdXNlZF9kdXJpbmcgcmVncmVzc2lvbg --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Server Authentication" + + - name: "EAB without headerinfo - 03 - Enroll lego with a template_name/ca_name taken from kid.json" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_01 --hmac YW5vdXRoZXJfdmVyeV9sb25nX2htYWNfZm9yX2tleWlkXzAxX3doaWNoIHdpbGxfYmUgdXNlZF9kdXJpbmcgcmVncmVzc2lvbg -d lego.acme --http run + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -issuer --noout + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Server Authentication" + + - name: "EAB without headerinfo - 04 - Enroll acme with a not allowed fqdn in kid.json (to fail)" + id: acmefail021 + continue-on-error: true + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure + + - name: "EAB without headerinfo - 04 - check result " + if: steps.acmefail021.outcome != 'failure' + run: | + echo "acmefail outcome is ${{steps.acmefail021.outcome }}" + exit 1 + + - name: "EAB without headerinfo - 04 - Enroll lego with a not allowed fqdn in kid.json (to fail)" + id: legofail021 + continue-on-error: true + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM -d lego.acme --http run + + - name: "EAB without headerinfo - 04a - check result " + if: steps.legofail021.outcome != 'failure' + run: | + echo "legofail outcome is ${{steps.legofail021.outcome }}" + exit 1 + + - name: "EAB without headerinfo - 05 - Enroll acme with default values from acme.cfg" + run: | + sudo rm -rf acme-sh/* + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_03 --eab-hmac-key YW5kX2ZpbmFsbHlfdGhlX2xhc3RfaG1hY19rZXlfd2hpY2hfaXNfbG9uZ2VyX3RoYW5fMjU2X2JpdHNfYW5kX3Nob3VsZF93b3Jr --debug 3 + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure + awk 'BEGIN {c=0;} /BEGIN CERT/{c++} { print > "cert-" c ".pem"}' < acme-sh/acme-sh.acme_ecc/ca.cer + openssl verify -CAfile cert-2.pem -untrusted cert-1.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "Code Signing" + + - name: "EAB without headerinfo - 05 - Enroll lego with default values from acme.cfg" + run: | + sudo rm -rf lego/* + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_03 --hmac YW5kX2ZpbmFsbHlfdGhlX2xhc3RfaG1hY19rZXlfd2hpY2hfaXNfbG9uZ2VyX3RoYW5fMjU2X2JpdHNfYW5kX3Nob3VsZF93b3Jr -d lego.acme --http run + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -issuer --noout + sudo openssl verify -CAfile cert-2.pem -untrusted cert-1.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout + sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "Code Signing" + + - name: "EAB with headerinfo - Setup a2c with certifier_ca_handler" run: | mkdir -p data/acme_ca sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem @@ -910,16 +1216,16 @@ jobs: NCM_CA_BUNDLE: ${{ secrets.NCM_CA_BUNDLE }} PROFILE: ${{ secrets.PROFILE }} - - name: "EAB - Reconfigure a2c " + - name: "EAB with headerinfo - Reconfigure a2c " run: | docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart - - name: "EAB - Sleep for 10s" + - name: "EAB with headerinfo - Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: time: 10s - - name: "EAB - 01 - Enroll acme.sh without profile_id" + - name: "EAB with headerinfo - 01 - Enroll acme.sh without profile_id" run: | sudo rm -rf acme-sh/* docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_00 --eab-hmac-key V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --debug 3 @@ -929,7 +1235,7 @@ jobs: openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Server Authentication" - - name: "EAB - 01 - Enroll lego without profile_id" + - name: "EAB with headerinfo - 01 - Enroll lego without profile_id" run: | sudo rm -rf lego/* docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw -d lego.acme --http run @@ -937,7 +1243,7 @@ jobs: sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Server Authentication" - - name: "EAB - 02a - Enroll acme with a template_name taken from header_info NOT included in kid.json (to fail)" + - name: "EAB with headerinfo - 02a - Enroll acme with a template_name taken from header_info NOT included in kid.json (to fail)" id: acmefail01 continue-on-error: true run: | @@ -945,13 +1251,13 @@ jobs: docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_00 --eab-hmac-key V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --debug 3 docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --useragent profile_id=unknown -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "EAB - 02a - check result " + - name: "EAB with headerinfo - 02a - check result " if: steps.acmefail01.outcome != 'failure' run: | echo "acmefail outcome is ${{steps.acmefail01.outcome }}" exit 1 - - name: "EAB - 02b - Enroll acme with a template_name taken from header_info included in kid.json" + - name: "EAB with headerinfo - 02b - Enroll acme with a template_name taken from header_info included in kid.json" run: | sudo rm -rf acme-sh/* docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_00 --eab-hmac-key V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --debug 3 @@ -961,20 +1267,20 @@ jobs: openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Client Authentication" - - name: "EAB - 02a - Enroll lego with a template_name taken from header_info NOT included in kid.json (to fail)" + - name: "EAB with headerinfo - 02a - Enroll lego with a template_name taken from header_info NOT included in kid.json (to fail)" id: legofail01 continue-on-error: true run: | sudo rm -rf lego/* docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --user-agent profile_id=unknown -d lego.acme --http run - - name: "EAB - 02a - check result " + - name: "EAB with headerinfo - 02a - check result " if: steps.legofail01.outcome != 'failure' run: | echo "legofail outcome is ${{steps.legofail01.outcome }}" exit 1 - - name: "EAB - 02b - Enroll lego with a template_name taken from header_info included in kid.json" + - name: "EAB with headerinfo - 02b - Enroll lego with a template_name taken from header_info included in kid.json" run: | sudo rm -rf lego/* docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_00 --hmac V2VfbmVlZF9hbm90aGVyX3ZlcnkfX2xvbmdfaG1hY190b19jaGVja19lYWJfZm9yX2tleWlkXzAwX2FzX2xlZ29fZW5mb3JjZXNfYW5faG1hY19sb25nZXJfdGhhbl8yNTZfYml0cw --user-agent profile_id=101 -d lego.acme --http run @@ -984,7 +1290,7 @@ jobs: sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Client Authentication" - - name: "EAB - 03 - Enroll acme with a template_name/ca_name taken from kid.json" + - name: "EAB with headerinfo - 03 - Enroll acme with a template_name/ca_name taken from kid.json" run: | sudo rm -rf acme-sh/* docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_01 --eab-hmac-key YW5vdXRoZXJfdmVyeV9sb25nX2htYWNfZm9yX2tleWlkXzAxX3doaWNoIHdpbGxfYmUgdXNlZF9kdXJpbmcgcmVncmVzc2lvbg --debug 3 @@ -994,7 +1300,7 @@ jobs: openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "TLS Web Server Authentication" - - name: "EAB - 03 - Enroll lego with a template_name/ca_name taken from kid.json" + - name: "EAB with headerinfo - 03 - Enroll lego with a template_name/ca_name taken from kid.json" run: | sudo rm -rf lego/* docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_01 --hmac YW5vdXRoZXJfdmVyeV9sb25nX2htYWNfZm9yX2tleWlkXzAxX3doaWNoIHdpbGxfYmUgdXNlZF9kdXJpbmcgcmVncmVzc2lvbg -d lego.acme --http run @@ -1004,7 +1310,7 @@ jobs: sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "TLS Web Server Authentication" - - name: "EAB - 04 - Enroll acme with a not allowed fqdn in kid.json (to fail)" + - name: "EAB with headerinfo - 04 - Enroll acme with a not allowed fqdn in kid.json (to fail)" id: acmefail02 continue-on-error: true run: | @@ -1012,26 +1318,26 @@ jobs: docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM --debug 3 docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "EAB - 04 - check result " + - name: "EAB with headerinfo - 04 - check result " if: steps.acmefail02.outcome != 'failure' run: | echo "acmefail outcome is ${{steps.acmefail02.outcome }}" exit 1 - - name: "EAB - 04 - Enroll lego with a not allowed fqdn in kid.json (to fail)" + - name: "EAB with headerinfo - 04 - Enroll lego with a not allowed fqdn in kid.json (to fail)" id: legofail02 continue-on-error: true run: | sudo rm -rf lego/* docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM -d lego.acme --http run - - name: "EAB - 04a - check result " + - name: "EAB with headerinfo - 04a - check result " if: steps.legofail02.outcome != 'failure' run: | echo "legofail outcome is ${{steps.legofail02.outcome }}" exit 1 - - name: "EAB - 05 - Enroll acme with default values from acme.cfg" + - name: "EAB with headerinfo - 05 - Enroll acme with default values from acme.cfg" run: | sudo rm -rf acme-sh/* docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_03 --eab-hmac-key YW5kX2ZpbmFsbHlfdGhlX2xhc3RfaG1hY19rZXlfd2hpY2hfaXNfbG9uZ2VyX3RoYW5fMjU2X2JpdHNfYW5kX3Nob3VsZF93b3Jr --debug 3 @@ -1041,7 +1347,7 @@ jobs: openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -text -noout openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep "Code Signing" - - name: "EAB - 05 - Enroll lego with default values from acme.cfg" + - name: "EAB with headerinfo - 05 - Enroll lego with default values from acme.cfg" run: | sudo rm -rf lego/* docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_03 --hmac YW5kX2ZpbmFsbHlfdGhlX2xhc3RfaG1hY19rZXlfd2hpY2hfaXNfbG9uZ2VyX3RoYW5fMjU2X2JpdHNfYW5kX3Nob3VsZF93b3Jr -d lego.acme --http run @@ -1051,7 +1357,7 @@ jobs: sudo openssl x509 -in lego/certificates/lego.acme.crt -text -noout sudo openssl x509 -in lego/certificates/lego.acme.crt -text -ext extendedKeyUsage | grep "Code Signing" - - name: "EAB - 06 - Enroll acme with not allowed headerinfo-field (should fail)" + - name: "EAB with headerinfo - 06 - Enroll acme with not allowed headerinfo-field (should fail)" id: acmefail03 continue-on-error: true run: | @@ -1059,20 +1365,20 @@ jobs: docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --register-account --server http://acme-srv --accountemail 'acme-sh@example.com' --eab-kid keyid_02 --eab-hmac-key dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM --debug 3 docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --useragent profile_id=101 -d acme-sh.acme --standalone --debug 3 --output-insecure - - name: "EAB - 06 - check result " + - name: "EAB with headerinfo - 06 - check result " if: steps.acmefail03.outcome != 'failure' run: | echo "acmefail outcome is ${{steps.acmefail03.outcome }}" exit 1 - - name: "EAB - 06 - Enroll lego with not allowed headerinfo-field (should fail)" + - name: "EAB with headerinfo - 06 - Enroll lego with not allowed headerinfo-field (should fail)" id: legofail03 continue-on-error: true run: | sudo rm -rf lego/* docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --eab --kid keyid_02 --hmac dGhpc19pc19hX3ZlcnlfbG9uZ19obWFjX3RvX21ha2Vfc3VyZV90aGF0X2l0c19tb3JlX3RoYW5fMjU2X2JpdHM --user-agent profile_id=101 -d lego.acme --http run - - name: "EAB - 06 - check result " + - name: "EAB with headerinfo - 06 - check result " if: steps.legofail03.outcome != 'failure' run: | echo "legofail outcome is ${{steps.legofail03.outcome }}" From a8f10cc5703c408cc5a4e3c448f68e61310975a1 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 20 Apr 2024 09:20:26 +0200 Subject: [PATCH 177/460] [doc] documentation update --- CHANGES.md | 2 +- docs/eab_profiling.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 48ead986..7ca9466f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -9,7 +9,7 @@ and pick the appropriate release branch. **Features and Improvements**: -- [Account profiling](docs/account-profiling.md) +- [Enrollment profiling via external account binding](docs/eab_profiling.md) - [#144](https://github.com/grindsa/acme2certifier/issues/144) configuration option to supress product name - [#143](https://github.com/grindsa/acme2certifier/issues/143) template name as part of the user-agent field in wcce/wes handler - configuration option to limit the number of identifiers in a single order request diff --git a/docs/eab_profiling.md b/docs/eab_profiling.md index 39613a3e..81f59c3e 100644 --- a/docs/eab_profiling.md +++ b/docs/eab_profiling.md @@ -1,6 +1,6 @@ - -# EAB Profiling + +# Enrollment profiling via external account binding Starting with version 0.34 acme2certifier supports the configuration of account specific enrollment configuration. Depending on the handler to be used the feature allows the definition of individual authentication credentials, enrollment profiles or certificate authoritzies. From 2fca389c893a4c7111d9a4f2cf8e8f94ec182d79 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 20 Apr 2024 09:23:21 +0200 Subject: [PATCH 178/460] [wf] matrix extension in asa and certifier workflows --- .github/workflows/ca_handler_tests_asa.yml | 6 +++--- .github/workflows/ca_handler_tests_certifier.yml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ca_handler_tests_asa.yml b/.github/workflows/ca_handler_tests_asa.yml index f49b5428..5ac7c7ed 100644 --- a/.github/workflows/ca_handler_tests_asa.yml +++ b/.github/workflows/ca_handler_tests_asa.yml @@ -16,8 +16,8 @@ jobs: max-parallel: 1 fail-fast: false matrix: - websrv: ['apache2'] - dbhandler: ['wsgi'] + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -684,7 +684,7 @@ jobs: max-parallel: 1 fail-fast: false matrix: - rhversion: [8] + rhversion: [8, 9] steps: - name: "checkout GIT" uses: actions/checkout@v4 diff --git a/.github/workflows/ca_handler_tests_certifier.yml b/.github/workflows/ca_handler_tests_certifier.yml index f38487aa..38b4fdcd 100644 --- a/.github/workflows/ca_handler_tests_certifier.yml +++ b/.github/workflows/ca_handler_tests_certifier.yml @@ -16,8 +16,8 @@ jobs: max-parallel: 2 fail-fast: false matrix: - websrv: ['apache2'] - dbhandler: ['wsgi'] + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] steps: - name: "checkout GIT" uses: actions/checkout@v4 @@ -714,7 +714,7 @@ jobs: strategy: fail-fast: false matrix: - rhversion: [8] + rhversion: [8, 9] steps: - name: "checkout GIT" uses: actions/checkout@v4 From a80a617acf2fb72f91b71b967d1fcd9c20fbed77 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 20 Apr 2024 10:27:53 +0200 Subject: [PATCH 179/460] [fix] address code_smells --- acme_srv/challenge.py | 54 +++++++++++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/acme_srv/challenge.py b/acme_srv/challenge.py index 9382f12f..b3cd6c7b 100644 --- a/acme_srv/challenge.py +++ b/acme_srv/challenge.py @@ -66,24 +66,35 @@ def _challengelist_search(self, key: str, value: str, vlist: List = ('name', 'ty self.logger.debug('Challenge._challengelist_search() ended with: %s', challenge_list) return challenge_list + def _challenge_validate_loop(self, challenge_name: str, challenge_dic: Dict[str, str], payload: Dict[str, str], jwk_thumbprint: str) -> Tuple[bool, bool]: + """ inner loop function to validate challenges """ + self.logger.debug('Challenge._challenge_validate_loop(%s)', challenge_name) + + if challenge_dic['type'] == 'http-01' and jwk_thumbprint: + (result, invalid) = self._validate_http_challenge(challenge_name, challenge_dic['authorization__type'], challenge_dic['authorization__value'], challenge_dic['token'], jwk_thumbprint) + elif challenge_dic['type'] == 'dns-01' and jwk_thumbprint: + (result, invalid) = self._validate_dns_challenge(challenge_name, challenge_dic['authorization__type'], challenge_dic['authorization__value'], challenge_dic['token'], jwk_thumbprint) + elif challenge_dic['type'] == 'tls-alpn-01' and jwk_thumbprint: + (result, invalid) = self._validate_alpn_challenge(challenge_name, challenge_dic['authorization__type'], challenge_dic['authorization__value'], challenge_dic['token'], jwk_thumbprint) + elif challenge_dic['type'] == 'tkauth-01' and jwk_thumbprint and self.tnauthlist_support: + (result, invalid) = self._validate_tkauth_challenge(challenge_name, challenge_dic['authorization__type'], challenge_dic['authorization__value'], challenge_dic['token'], jwk_thumbprint, payload) + else: + self.logger.error('unknown challenge type "%s". Setting check result to False', challenge_dic['type']) + result = False + invalid = True + + self.logger.debug('Challenge._challenge_validate_loop() ended with: %s/%s', result, invalid) + return (result, invalid) + def _challenge_validate(self, pub_key: Dict[str, str], challenge_name: str, challenge_dic: Dict[str, str], payload: Dict[str, str]) -> Tuple[bool, bool]: """ challenge validate """ self.logger.debug('Challenge._challenge_validate(%s)', challenge_name) jwk_thumbprint = jwk_thumbprint_get(self.logger, pub_key) + for _ele in range(0, 5): - if challenge_dic['type'] == 'http-01' and jwk_thumbprint: - (result, invalid) = self._validate_http_challenge(challenge_name, challenge_dic['authorization__type'], challenge_dic['authorization__value'], challenge_dic['token'], jwk_thumbprint) - elif challenge_dic['type'] == 'dns-01' and jwk_thumbprint: - (result, invalid) = self._validate_dns_challenge(challenge_name, challenge_dic['authorization__type'], challenge_dic['authorization__value'], challenge_dic['token'], jwk_thumbprint) - elif challenge_dic['type'] == 'tls-alpn-01' and jwk_thumbprint: - (result, invalid) = self._validate_alpn_challenge(challenge_name, challenge_dic['authorization__type'], challenge_dic['authorization__value'], challenge_dic['token'], jwk_thumbprint) - elif challenge_dic['type'] == 'tkauth-01' and jwk_thumbprint and self.tnauthlist_support: - (result, invalid) = self._validate_tkauth_challenge(challenge_name, challenge_dic['authorization__type'], challenge_dic['authorization__value'], challenge_dic['token'], jwk_thumbprint, payload) - else: - self.logger.error('unknown challenge type "%s". Setting check result to False', challenge_dic['type']) - result = False - invalid = True + + result, invalid = self._challenge_validate_loop(challenge_name, challenge_dic, payload, jwk_thumbprint) if result or invalid: # break loop if we got any good or bad response break @@ -167,6 +178,18 @@ def _config_proxy_load(self, config_dic: Dict[str, str]): self.logger.debug('Challenge._config_proxy_load() ended') + def _config_dns_load(self, config_dic: Dict[str, str]): + """ load dns config """ + self.logger.debug('Challenge._config_dns_load()') + + if 'Challenge' in config_dic and 'dns_server_list' in config_dic['Challenge']: + try: + self.dns_server_list = json.loads(config_dic['Challenge']['dns_server_list']) + except Exception as err_: + self.logger.warning('Challenge._config_load() dns_server_list failed with error: %s', err_) + + self.logger.debug('Challenge._config_dns_load() ended') + def _config_challenge_load(self, config_dic: Dict[str, str]): """ load proxy config """ self.logger.debug('Challenge._config_challenge_load()') @@ -174,11 +197,7 @@ def _config_challenge_load(self, config_dic: Dict[str, str]): if 'Challenge' in config_dic: self.challenge_validation_disable = config_dic.getboolean('Challenge', 'challenge_validation_disable', fallback=False) self.sectigo_sim = config_dic.getboolean('Challenge', 'sectigo_sim', fallback=False) - if 'dns_server_list' in config_dic['Challenge']: - try: - self.dns_server_list = json.loads(config_dic['Challenge']['dns_server_list']) - except Exception as err_: - self.logger.warning('Challenge._config_load() dns_server_list failed with error: %s', err_) + if 'challenge_validation_timeout' in config_dic['Challenge']: try: self.challenge_validation_timeout = int(config_dic['Challenge']['challenge_validation_timeout']) @@ -194,6 +213,7 @@ def _config_load(self): # load challenge parameters self._config_challenge_load(config_dic) + self._config_dns_load(config_dic) if 'Order' in config_dic: self.tnauthlist_support = config_dic.getboolean('Order', 'tnauthlist_support', fallback=False) From 24fc09717fe494cc93887a1961b90b0e4c739d71 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 20 Apr 2024 10:29:13 +0200 Subject: [PATCH 180/460] [fix] _config_dns_load() --- acme_srv/challenge.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/acme_srv/challenge.py b/acme_srv/challenge.py index 32503083..4c2550a8 100644 --- a/acme_srv/challenge.py +++ b/acme_srv/challenge.py @@ -193,6 +193,12 @@ def _config_dns_load(self, config_dic: Dict[str, str]): except Exception as err_: self.logger.warning('Challenge._config_load() dns_server_list failed with error: %s', err_) + if 'dns_validation_pause_timer' in config_dic['Challenge']: + try: + self.dns_validation_pause_timer = int(config_dic['Challenge']['dns_validation_pause_timer']) + except Exception as err_: + self.logger.warning('Challenge._config_load() failed to load dns_validation_pause_timer: %s', err_) + self.logger.debug('Challenge._config_dns_load() ended') def _config_challenge_load(self, config_dic: Dict[str, str]): @@ -209,12 +215,6 @@ def _config_challenge_load(self, config_dic: Dict[str, str]): except Exception as err_: self.logger.warning('Challenge._config_load() failed to load challenge_validation_timeout: %s', err_) - if 'dns_validation_pause_timer' in config_dic['Challenge']: - try: - self.dns_validation_pause_timer = int(config_dic['Challenge']['dns_validation_pause_timer']) - except Exception as err_: - self.logger.warning('Challenge._config_load() failed to load dns_validation_pause_timer: %s', err_) - self.logger.debug('Challenge._config_challenge_load() ended') def _config_load(self): From 1f94afea289436a7878d7490a2ca6c26f5a83898 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 20 Apr 2024 11:07:55 +0200 Subject: [PATCH 181/460] [fix] linting --- docs/xca.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/xca.md b/docs/xca.md index 3320c45d..37bb121e 100644 --- a/docs/xca.md +++ b/docs/xca.md @@ -57,7 +57,6 @@ Template support has been introduced starting from v0.13. Support is limited to - S: StateOrProvinceName - C: CountryName - # eab profiling This handler can use the [eab profiling feture](eab_profiling.md) to allow individual enrollment configuration per acme-account as well as restriction of CN and SANs to be submitted within the CSR. The feature is disabled by default and must be activated in `acme_srv.cfg` @@ -104,5 +103,4 @@ below an example key-file used during regression testing: } ``` - Enjoy enrolling and revoking certificates... From 2bf1648e0d4111b9d4ba793ba59567f3ace802b1 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 20 Apr 2024 16:29:12 +0200 Subject: [PATCH 182/460] [fix] strict sequential processing of workflow --- .github/workflows/ca_handler_tests_msca.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ca_handler_tests_msca.yml b/.github/workflows/ca_handler_tests_msca.yml index 0b81c28c..fb77ed6d 100644 --- a/.github/workflows/ca_handler_tests_msca.yml +++ b/.github/workflows/ca_handler_tests_msca.yml @@ -371,6 +371,7 @@ jobs: msca_handler_tests_rpm: name: "msca_handler_tests_rpm" runs-on: ubuntu-latest + needs: msca_handler_tests strategy: max-parallel: 1 fail-fast: false From d401f92b4d1605b1646478944ef505f00a9da300 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 20 Apr 2024 16:36:38 +0200 Subject: [PATCH 183/460] [rel] versiob bump to v0.34 --- CHANGES.md | 18 ++++++++++++++++++ acme_srv/version.py | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index db5e8bd5..3ab51f8e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,6 +5,24 @@ This is a high-level summary of the most important changes. For a full list of changes, see the [git commit log](https://github.com/grindsa/acme2certifier/commits) and pick the appropriate release branch. +# Changes in 0.34 + +**Features and Improvements**: + +- [Enrollment profiling via external account binding](docs/eab_profiling.md) +- [#144](https://github.com/grindsa/acme2certifier/issues/144) configuration option to supress product name +- [#143](https://github.com/grindsa/acme2certifier/issues/143) template name as part of the user-agent field in wcce/wes handler +- configuration option to limit the number of identifiers in a single order request +- `burst` parameter in example nginx.conf to ratelimit incoming requests +- [container images for arm64 plattforms](https://hub.docker.com/layers/grindsa/acme2certifier/apache2-wsgi/images/sha256-9092e98ad23fa94dfb17534333a9306ec447b274c2e4b5bbaee0b8bc41c6becc?context=repo) +- regression tests on arm64 plattforms + +**Bugfixes**: + +- [#147](https://github.com/grindsa/acme2certifier/pull/147) correct content-type for problem+json message +- updated [eab-example files](https://github.com/grindsa/acme2certifier/tree/master/examples/eab_handler) as hmac must be longer than 256bits +- identifier sanitizing + # Changes in 0.33.3 **Features and Improvements**: diff --git a/acme_srv/version.py b/acme_srv/version.py index 499cbcf9..09b688e9 100644 --- a/acme_srv/version.py +++ b/acme_srv/version.py @@ -3,5 +3,5 @@ # 1) we don't load dependencies by storing it in __init__.py # 2) we can import it in setup.py for the same reason # 3) we can import it into your module module -__version__ = '0.33.3' +__version__ = '0.34' __dbversion__ = '0.33.2' From be6df651242dd946327fe88732a4ecd4f557f59e Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 20 Apr 2024 19:36:21 +0200 Subject: [PATCH 184/460] [wf] bandit in code-scannining workflow --- .github/workflows/codescanner.yml | 35 ++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/.github/workflows/codescanner.yml b/.github/workflows/codescanner.yml index dfe56d71..69116654 100644 --- a/.github/workflows/codescanner.yml +++ b/.github/workflows/codescanner.yml @@ -4,8 +4,41 @@ on: branches: - 'master' - 'devel' - - 'ccov' + - 'min-devel' + - 'min' + - 'code-scanner_wf' + jobs: + + bandit: + permissions: + contents: read # for actions/checkout to fetch code + security-events: write # for github/codeql-action/upload-sarif to upload SARIF results + actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status + + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Bandit Scan + uses: shundor/python-bandit-scan@9cc5aa4a006482b8a7f91134412df6772dbda22c + with: # optional arguments + # exit with 0, even with results found + exit_zero: true # optional, default is DEFAULT + # Github token of the repository (automatically created by Github) + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information. + # File or directory to run bandit on + # path: # optional, default is . + # Report only issues of a given severity level or higher. Can be LOW, MEDIUM or HIGH. Default is UNDEFINED (everything) + # level: # optional, default is UNDEFINED + # Report only issues of a given confidence level or higher. Can be LOW, MEDIUM or HIGH. Default is UNDEFINED (everything) + # confidence: # optional, default is UNDEFINED + # comma-separated list of paths (glob patterns supported) to exclude from scan (note that these are in addition to the excluded paths provided in the config file) (default: .svn,CVS,.bzr,.hg,.git,__pycache__,.tox,.eggs,*.egg) + # excluded_paths: # optional, default is DEFAULT + # comma-separated list of test IDs to skip + # skips: # optional, default is DEFAULT + # path to a .bandit file that supplies command line arguments + # ini_path: # optional, default is DEFAULT + codecov: name: Codecov Analysis runs-on: ubuntu-latest From 41a66645b8aba0865e7f5a80f2df9ae2154086ab Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 20 Apr 2024 20:29:33 +0200 Subject: [PATCH 185/460] [wf] -fN paramter for ssh tunnel --- .github/workflows/ca_handler_tests_cmp.yml | 6 +++--- .github/workflows/ca_handler_tests_msca.yml | 9 ++++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ca_handler_tests_cmp.yml b/.github/workflows/ca_handler_tests_cmp.yml index 27bf001e..ee99a185 100644 --- a/.github/workflows/ca_handler_tests_cmp.yml +++ b/.github/workflows/ca_handler_tests_cmp.yml @@ -112,7 +112,7 @@ jobs: KNOWN_HOSTS: ${{ secrets.WCCE_SSH_KNOWN_HOSTS }} - name: "Establish SSH connection" - run: sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -p $SSH_PORT -o UserKnownHostsFile=/tmp/rd/known_hosts -L 8086:$CMP_HOST:8086 -g ping -c 270 $CMP_HOST & + run: sudo ssh $SSH_USER@$SSH_HOST -fN -i /tmp/rd/ak.tmp -p $SSH_PORT -o UserKnownHostsFile=/tmp/rd/known_hosts -L 8086:$CMP_HOST:8086 -g env: SSH_USER: ${{ secrets.CMP_SSH_USER }} SSH_HOST: ${{ secrets.CMP_SSH_HOST }} @@ -312,7 +312,7 @@ jobs: KNOWN_HOSTS: ${{ secrets.WCCE_SSH_KNOWN_HOSTS }} - name: "[ PREPARE ] establish SSH connection" - run: sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -p $SSH_PORT -o UserKnownHostsFile=/tmp/rd/known_hosts -L 8086:$CMP_HOST:8086 -g ping -c 180 $CMP_HOST & + run: sudo ssh $SSH_USER@$SSH_HOST -fN -i /tmp/rd/ak.tmp -p $SSH_PORT -o UserKnownHostsFile=/tmp/rd/known_hosts -L 8086:$CMP_HOST:8086 -g env: SSH_USER: ${{ secrets.CMP_SSH_USER }} SSH_HOST: ${{ secrets.CMP_SSH_HOST }} @@ -462,7 +462,7 @@ jobs: KNOWN_HOSTS: ${{ secrets.WCCE_SSH_KNOWN_HOSTS }} - name: "[ PREPARE ] establish SSH connection" - run: sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -p $SSH_PORT -o UserKnownHostsFile=/tmp/rd/known_hosts -L 8086:$CMP_HOST:8086 -g ping -c 180 $CMP_HOST & + run: sudo ssh $SSH_USER@$SSH_HOST -fN -i /tmp/rd/ak.tmp -p $SSH_PORT -o UserKnownHostsFile=/tmp/rd/known_hosts -L 8086:$CMP_HOST:8086 -g env: SSH_USER: ${{ secrets.CMP_SSH_USER }} SSH_HOST: ${{ secrets.CMP_SSH_HOST }} diff --git a/.github/workflows/ca_handler_tests_msca.yml b/.github/workflows/ca_handler_tests_msca.yml index fb77ed6d..ce546e2c 100644 --- a/.github/workflows/ca_handler_tests_msca.yml +++ b/.github/workflows/ca_handler_tests_msca.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest strategy: fail-fast: false - max-parallel: 1 + # max-parallel: 1 matrix: websrv: ['apache2', 'nginx'] dbhandler: ['wsgi', 'django'] @@ -142,7 +142,7 @@ jobs: KNOWN_HOSTS: ${{ secrets.WCCE_SSH_KNOWN_HOSTS }} - name: "Establish SSH connection" - run: sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -p $SSH_PORT -o UserKnownHostsFile=/tmp/rd/known_hosts -L 445:$WCCE_HOST:445 -L 88:$WCCE_HOST:88 -L 443:$WES_IP:443 -g ping -c 300 $CMP_HOST & + run: sudo ssh $SSH_USER@$SSH_HOST -fN -i /tmp/rd/ak.tmp -p $SSH_PORT -o UserKnownHostsFile=/tmp/rd/known_hosts -L 445:$WCCE_HOST:445 -L 88:$WCCE_HOST:88 -L 443:$WES_IP:443 -g env: SSH_USER: ${{ secrets.WCCE_SSH_USER }} SSH_HOST: ${{ secrets.WCCE_SSH_HOST }} @@ -371,9 +371,8 @@ jobs: msca_handler_tests_rpm: name: "msca_handler_tests_rpm" runs-on: ubuntu-latest - needs: msca_handler_tests strategy: - max-parallel: 1 + # max-parallel: 1 fail-fast: false matrix: rhversion: [8, 9] @@ -528,7 +527,7 @@ jobs: KNOWN_HOSTS: ${{ secrets.WCCE_SSH_KNOWN_HOSTS }} - name: "Establish SSH connection" - run: sudo ssh $SSH_USER@$SSH_HOST -i /tmp/rd/ak.tmp -p $SSH_PORT -o UserKnownHostsFile=/tmp/rd/known_hosts -L 445:$WCCE_HOST:445 -L 88:$WCCE_HOST:88 -L 443:$WES_IP:443 -g ping -c 300 $CMP_HOST & + run: sudo ssh $SSH_USER@$SSH_HOST -fN -i /tmp/rd/ak.tmp -p $SSH_PORT -o UserKnownHostsFile=/tmp/rd/known_hosts -L 445:$WCCE_HOST:445 -L 88:$WCCE_HOST:88 -L 443:$WES_IP:443 -g env: SSH_USER: ${{ secrets.WCCE_SSH_USER }} SSH_HOST: ${{ secrets.WCCE_SSH_HOST }} From 86adc033e7a81459258303a6c8e5a43c4b871df3 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 20 Apr 2024 21:33:23 +0200 Subject: [PATCH 186/460] [doc] documentation --- docs/acme_srv.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/acme_srv.md b/docs/acme_srv.md index fb158f48..fcba5410 100644 --- a/docs/acme_srv.md +++ b/docs/acme_srv.md @@ -20,6 +20,7 @@ | `Challenge` | `challenge_validation_disable` | disable challenge validation via http or dns. THIS IS A SEVERE SECURITY ISSUE! Please enable for testing/debugging purposes only. | True/False | False| | `Challenge` | `challenge_validation_timeout` | Timeout in seconds for challenge validation | Integer | 10 | | `Challenge` | `dns_server_list` | Use own dns servers for name resolution during challenge verification| ["ip1", "ip2"] | []| +| `Challenge` | `dns_validation_pause_timer ` | pause interval in seconds after failed validation of a dns challenge | 10 | 0.5 | | `Challenge` | `sectigo_sim` | provide `sectigo-email-01` challenges - Only for development and testing! | True/False | False | | `DBhandler` | `dbfile` | path and name of database file. If not specified `acme_srv/acme_srv.db` will be used. Parameter is only available for a wsgi handler and will be ignored if django handler is getting used | 'acme/database.db' | `acme_srv/acme_srv.db`| | `Directory` | `db_check` | check database connection compare schemes and report as OK/NOK in meta information | True/False | False| From c1ac77d7e5fd47249b6fb1950703445603bc238e Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 20 Apr 2024 22:22:27 +0200 Subject: [PATCH 187/460] [fix] linting in acme_srv.md --- docs/acme_srv.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/acme_srv.md b/docs/acme_srv.md index fcba5410..6044474e 100644 --- a/docs/acme_srv.md +++ b/docs/acme_srv.md @@ -20,7 +20,7 @@ | `Challenge` | `challenge_validation_disable` | disable challenge validation via http or dns. THIS IS A SEVERE SECURITY ISSUE! Please enable for testing/debugging purposes only. | True/False | False| | `Challenge` | `challenge_validation_timeout` | Timeout in seconds for challenge validation | Integer | 10 | | `Challenge` | `dns_server_list` | Use own dns servers for name resolution during challenge verification| ["ip1", "ip2"] | []| -| `Challenge` | `dns_validation_pause_timer ` | pause interval in seconds after failed validation of a dns challenge | 10 | 0.5 | +| `Challenge` | `dns_validation_pause_timer` | pause interval in seconds after failed validation of a dns challenge | 10 | 0.5 | | `Challenge` | `sectigo_sim` | provide `sectigo-email-01` challenges - Only for development and testing! | True/False | False | | `DBhandler` | `dbfile` | path and name of database file. If not specified `acme_srv/acme_srv.db` will be used. Parameter is only available for a wsgi handler and will be ignored if django handler is getting used | 'acme/database.db' | `acme_srv/acme_srv.db`| | `Directory` | `db_check` | check database connection compare schemes and report as OK/NOK in meta information | True/False | False| From da3e63f9cc70031f3e437c41d7ad3e1e88c2ae2c Mon Sep 17 00:00:00 2001 From: grindsa Date: Thu, 25 Apr 2024 14:49:48 +0200 Subject: [PATCH 188/460] [feat] #153 kerberos support in msca_handler.py --- examples/ca_handler/certsrv.py | 37 ++++-- examples/ca_handler/mscertsrv_ca_handler.py | 64 +++++++---- test/test_asa_ca_handler.py | 82 +++++++------- test/test_msca_handler.py | 118 ++++++++++++++------ test/test_xca_ca_handler.py | 6 +- 5 files changed, 196 insertions(+), 111 deletions(-) diff --git a/examples/ca_handler/certsrv.py b/examples/ca_handler/certsrv.py index ede31100..a8f19c20 100644 --- a/examples/ca_handler/certsrv.py +++ b/examples/ca_handler/certsrv.py @@ -59,11 +59,14 @@ class Certsrv(object): username: The username for authentication. password: The password for authentication. auth_method: The chosen authentication method. Either 'basic' (the default), - 'ntlm' or 'cert' (SSL client certificate). + 'ntlm', 'cert' (SSL client certificate) or 'gssapi' (GSSAPI, Kerberos) cafile: A PEM file containing the CA certificates that should be trusted. + verify: Boolean to enable/disable CA certificate checking. timeout: The timeout to use against the CA server, in seconds. The default is 30. - + proxies: Dictionary of proxy server for post of get operations + {'http': 'http://foo.bar:3128', 'https': 'socks5://foo.bar:1080'} + The default is None Note: If you use a client certificate for authentication (auth_method=cert), the username parameter should be the path to a certificate, and @@ -71,7 +74,7 @@ class Certsrv(object): """ # pylint: disable=r0913 def __init__(self, server, username, password, auth_method="basic", - cafile=None, timeout=TIMEOUT, proxies=None): + cafile=None, verify=True, timeout=TIMEOUT, proxies=None): self.server = server self.timeout = timeout @@ -79,7 +82,9 @@ def __init__(self, server, username, password, auth_method="basic", self.session = requests.Session() self.proxies = proxies - if cafile: + if not verify: + self.session.verify = False + elif cafile: self.session.verify = cafile else: # requests uses it's own CA bundle by default @@ -105,6 +110,18 @@ def _set_credentials(self, username, password): self.session.auth = HttpNtlmAuth(username, password) elif self.auth_method == "cert": self.session.cert = (username, password) + elif self.auth_method == "gssapi": + from requests_gssapi import HTTPSPNEGOAuth + import gssapi + oid = '1.3.6.1.5.5.2' # SPNEGO + # pylint: disable=e1101 + cred = gssapi.raw.acquire_cred_with_password( + gssapi.Name(username, gssapi.NameType.user), + password.encode("utf-8"), + mechs=[gssapi.OID.from_int_seq(oid)], + usage="initiate", + ) + self.session.auth = HTTPSPNEGOAuth(creds=cred.creds) else: self.session.auth = (username, password) @@ -329,7 +346,7 @@ def update_credentials(self, username, password): username: The username for authentication. password: The password for authentication. """ - if self.auth_method in ("ntlm", "cert"): + if self.auth_method in ("ntlm", "cert", "gssapi"): # NTLM and SSL is connection based, # so we need to close the connection # to be able to re-authenticate @@ -369,7 +386,7 @@ def get_cert(server, csr, template, username, password, encoding="b64", **kwargs encoding: The desired encoding for the returned certificate. Possible values are 'bin' for binary and 'b64' for Base64 (PEM). auth_method: The chosen authentication method. Either 'basic' (the default), - 'ntlm' or 'cert' (ssl client certificate). + 'ntlm', 'cert' (ssl client certificate) or 'gssapi' (GSSAPI, Kerberos). cafile: A PEM file containing the CA certificates that should be trusted. Returns: @@ -407,7 +424,7 @@ def get_existing_cert(server, req_id, username, password, encoding="b64", **kwar encoding: The desired encoding for the returned certificate. Possible values are 'bin' for binary and 'b64' for Base64 (PEM). auth_method: The chosen authentication method. Either 'basic' (the default), - 'ntlm' or 'cert' (ssl client certificate). + 'ntlm', 'cert' (ssl client certificate) or 'gssapi' (GSSAPI, Kerberos). cafile: A PEM file containing the CA certificates that should be trusted. Returns: @@ -440,7 +457,7 @@ def get_ca_cert(server, username, password, encoding="b64", **kwargs): encoding: The desired encoding for the returned certificate. Possible values are 'bin' for binary and 'b64' for Base64 (PEM). auth_method: The chosen authentication method. Either 'basic' (the default), - 'ntlm' or 'cert' (ssl client certificate). + 'ntlm', 'cert' (ssl client certificate) or 'gssapi' (GSSAPI, Kerberos). cafile: A PEM file containing the CA certificates that should be trusted. Returns: @@ -469,7 +486,7 @@ def get_chain(server, username, password, encoding="bin", **kwargs): encoding: The desired encoding for the returned certificates. Possible values are 'bin' for binary and 'b64' for Base64 (PEM). auth_method: The chosen authentication method. Either 'basic' (the default), - 'ntlm' or 'cert' (ssl client certificate). + 'ntlm', 'cert' (ssl client certificate) or 'gssapi' (GSSAPI, Kerberos). cafile: A PEM file containing the CA certificates that should be trusted. Returns: @@ -496,7 +513,7 @@ def check_credentials(server, username, password, **kwargs): username: The username for authentication. pasword: The password for authentication. auth_method: The chosen authentication method. Either 'basic' (the default), - 'ntlm' or 'cert' (ssl client certificate). + 'ntlm', 'cert' (ssl client certificate) or 'gssapi' (GSSAPI, Kerberos). cafile: A PEM file containing the CA certificates that should be trusted. Returns: diff --git a/examples/ca_handler/mscertsrv_ca_handler.py b/examples/ca_handler/mscertsrv_ca_handler.py index 889fc492..e4784b6a 100644 --- a/examples/ca_handler/mscertsrv_ca_handler.py +++ b/examples/ca_handler/mscertsrv_ca_handler.py @@ -23,6 +23,7 @@ def __init__(self, _debug: bool = False, logger: object = None): self.auth_method = 'basic' self.ca_bundle = False self.template = None + self.krb5_config = None self.proxy = None self.header_info_field = False @@ -126,11 +127,13 @@ def _config_parameters_load(self, config_dic: Dict[str, str]): if 'template' in config_dic['CAhandler']: self.template = config_dic['CAhandler']['template'] - if 'auth_method' in config_dic['CAhandler'] and config_dic['CAhandler']['auth_method'] == 'ntlm': + if 'auth_method' in config_dic['CAhandler'] and config_dic['CAhandler']['auth_method'] in ['basic', 'ntlm', 'gssapi']: self.auth_method = config_dic['CAhandler']['auth_method'] # check if we get a ca bundle for verification if 'ca_bundle' in config_dic['CAhandler']: self.ca_bundle = config_dic['CAhandler']['ca_bundle'] + if 'krb5_config' in config_dic['CAhandler']: + self.krb5_config = config_dic['CAhandler']['krb5_config'] self.logger.debug('CAhandler._config_parameters_load() ended') @@ -212,6 +215,34 @@ def _template_name_get(self, csr: str) -> str: self.logger.debug('CAhandler._template_name_get() ended with: %s', template_name) return template_name + def _csr_process(self, ca_server, csr: str) -> Tuple[str, str, str]: + + # recode csr + csr = textwrap.fill(b64_url_recode(self.logger, csr), 64) + '\n' + + # get ca_chain + try: + ca_pkcs7 = convert_byte_to_string(ca_server.get_chain(encoding='b64')) + ca_pem = self._pkcs7_to_pem(ca_pkcs7) + # replace crlf with lf + # ca_pem = ca_pem.replace('\r\n', '\n') + except Exception as err_: + ca_pem = None + self.logger.error('ca_server.get_chain() failed with error: %s', err_) + + try: + cert_raw = convert_byte_to_string(ca_server.get_cert(csr, self.template)) + # replace crlf with lf + cert_raw = cert_raw.replace('\r\n', '\n') + except Exception as err_: + cert_raw = None + self.logger.error('ca_server.get_cert() failed with error: %s', err_) + + # create bundle + (error, cert_bundle, cert_raw) = self._cert_bundle_create(ca_pem, cert_raw) + + return (error, cert_bundle, cert_raw) + def enroll(self, csr: str) -> Tuple[str, str, str, bool]: """ enroll certificate from via MS certsrv """ self.logger.debug('CAhandler.enroll(%s)', self.template) @@ -219,6 +250,10 @@ def enroll(self, csr: str) -> Tuple[str, str, str, bool]: error = None cert_raw = None + if self.krb5_config: + self.logger.info('CAhandler.enroll(): load krb5config from %s', self.krb5_config) + os.environ['KRB5_CONFIG'] = self.krb5_config + # lookup http header information from request if self.header_info_field: user_template = self._template_name_get(csr) @@ -231,30 +266,11 @@ def enroll(self, csr: str) -> Tuple[str, str, str, bool]: # check connection and credentials auth_check = self._check_credentials(ca_server) + if auth_check: - # recode csr - csr = textwrap.fill(b64_url_recode(self.logger, csr), 64) + '\n' - - # get ca_chain - try: - ca_pkcs7 = convert_byte_to_string(ca_server.get_chain(encoding='b64')) - ca_pem = self._pkcs7_to_pem(ca_pkcs7) - # replace crlf with lf - # ca_pem = ca_pem.replace('\r\n', '\n') - except Exception as err_: - ca_pem = None - self.logger.error('ca_server.get_chain() failed with error: %s', err_) - - try: - cert_raw = convert_byte_to_string(ca_server.get_cert(csr, self.template)) - # replace crlf with lf - cert_raw = cert_raw.replace('\r\n', '\n') - except Exception as err_: - cert_raw = None - self.logger.error('ca_server.get_cert() failed with error: %s', err_) - - # create bundle - (error, cert_bundle, cert_raw) = self._cert_bundle_create(ca_pem, cert_raw) + + # enroll certificate + (error, cert_bundle, cert_raw) = self._csr_process(ca_server, csr) else: self.logger.error('Connection or Credentialcheck failed') diff --git a/test/test_asa_ca_handler.py b/test/test_asa_ca_handler.py index 26e09afc..64a08277 100644 --- a/test/test_asa_ca_handler.py +++ b/test/test_asa_ca_handler.py @@ -563,7 +563,7 @@ def test_042___issuer_chain_get(self, mock_req, mock_pem): @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_chain_get') @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_verify') @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_check') - def test_041_enroll(self, mock_pv, mock_iv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_b64, mock_d2p, mock_b2s, mock_post): + def test_043_enroll(self, mock_pv, mock_iv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_b64, mock_d2p, mock_b2s, mock_post): """ test enroll() """ mock_iv.return_value = None mock_pv.return_value = 'pv_error' @@ -594,7 +594,7 @@ def test_041_enroll(self, mock_pv, mock_iv, mock_icg, mock_cpg, mockccg, mock_vd @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_chain_get') @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_verify') @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_verify') - def test_042_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_b64, mock_d2p, mock_b2s, mock_post): + def test_044_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_b64, mock_d2p, mock_b2s, mock_post): """ test enroll() """ mock_iv.return_value = None mock_pv.return_value = None @@ -625,7 +625,7 @@ def test_042_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vd @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_chain_get') @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_verify') @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_verify') - def test_043_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_b64, mock_d2p, mock_b2s, mock_post): + def test_045_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_b64, mock_d2p, mock_b2s, mock_post): """ test enroll() """ mock_iv.return_value = None mock_pv.return_value = None @@ -656,7 +656,7 @@ def test_043_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vd @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_chain_get') @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_verify') @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_verify') - def test_044_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_csbg, mock_b64, mock_d2p, mock_b2s, mock_post): + def test_046_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_csbg, mock_b64, mock_d2p, mock_b2s, mock_post): """ test enroll() """ mock_iv.return_value = 'mock_iv' mock_pv.return_value = None @@ -688,7 +688,7 @@ def test_044_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vd @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_chain_get') @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_verify') @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_verify') - def test_045_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_csbg, mock_b64, mock_d2p, mock_b2s, mock_post): + def test_047_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_csbg, mock_b64, mock_d2p, mock_b2s, mock_post): """ test enroll() """ mock_iv.return_value = None mock_pv.return_value = 'mock_pv' @@ -719,7 +719,7 @@ def test_045_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vd @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_chain_get') @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_verify') @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_verify') - def test_046_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_b64, mock_d2p, mock_b2s, mock_post): + def test_048_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_b64, mock_d2p, mock_b2s, mock_post): """ test enroll() """ mock_iv.return_value = None mock_pv.return_value = None @@ -750,7 +750,7 @@ def test_046_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vd @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_chain_get') @patch('examples.ca_handler.asa_ca_handler.CAhandler._profile_verify') @patch('examples.ca_handler.asa_ca_handler.CAhandler._issuer_verify') - def test_047_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_csbg, mock_b64, mock_d2p, mock_b2s, mock_post): + def test_049_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vdg, mock_csbg, mock_b64, mock_d2p, mock_b2s, mock_post): """ test enroll() """ mock_iv.return_value = None mock_pv.return_value = None @@ -776,7 +776,7 @@ def test_047_enroll(self, mock_iv, mock_pv, mock_icg, mock_cpg, mockccg, mock_vd @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_post') @patch('examples.ca_handler.asa_ca_handler.cert_ski_get') - def test_048_revoke(self, mock_ski, mock_post): + def test_050_revoke(self, mock_ski, mock_post): """ test revoke() """ self.cahandler.ca_name = 'ca_name' mock_ski.return_value = 'serial' @@ -787,7 +787,7 @@ def test_048_revoke(self, mock_ski, mock_post): @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_post') @patch('examples.ca_handler.asa_ca_handler.cert_ski_get') - def test_049_revoke(self, mock_ski, mock_post): + def test_051_revoke(self, mock_ski, mock_post): """ test revoke() """ self.cahandler.ca_name = 'ca_name' mock_ski.return_value = 'mock_ski' @@ -798,7 +798,7 @@ def test_049_revoke(self, mock_ski, mock_post): @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_post') @patch('examples.ca_handler.asa_ca_handler.cert_ski_get') - def test_050_revoke(self, mock_ski, mock_post): + def test_052_revoke(self, mock_ski, mock_post): """ test revoke() """ self.cahandler.ca_name = 'ca_name' mock_ski.return_value = 'ski' @@ -809,7 +809,7 @@ def test_050_revoke(self, mock_ski, mock_post): @patch('examples.ca_handler.asa_ca_handler.CAhandler._api_post') @patch('examples.ca_handler.asa_ca_handler.cert_ski_get') - def test_051_revoke(self, mock_ski, mock_post): + def test_053_revoke(self, mock_ski, mock_post): """ test revoke() """ self.cahandler.ca_name = 'ca_name' mock_ski.return_value = 'ski' @@ -819,7 +819,7 @@ def test_051_revoke(self, mock_ski, mock_post): self.assertTrue(mock_post.called) @patch.dict('os.environ', {'api_user_var': 'user_var'}) - def test_052_config_user_load(self): + def test_054_config_user_load(self): """ test _config_load - load template with user variable """ config_dic = {'api_user_variable': 'api_user_var'} self.cahandler._config_user_load(config_dic) @@ -827,7 +827,7 @@ def test_052_config_user_load(self): self.assertFalse(self.cahandler.profile_name) @patch.dict('os.environ', {'api_user_var': 'user_var'}) - def test_053_config_user_load(self): + def test_055_config_user_load(self): """ test _config_load - load template with user variable """ config_dic = {'api_user_variable': 'does_not_exist'} with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -837,7 +837,7 @@ def test_053_config_user_load(self): self.assertFalse(self.cahandler.profile_name) @patch.dict('os.environ', {'api_user_var': 'user_var'}) - def test_054_config_user_load(self): + def test_056_config_user_load(self): """ test _config_load - load template with user variable """ config_dic = {'api_user_variable': 'api_user_var', 'api_user': 'api_user'} self.cahandler._config_user_load(config_dic) @@ -847,7 +847,7 @@ def test_054_config_user_load(self): self.assertFalse(self.cahandler.profile_name) @patch.dict('os.environ', {'api_host_var': 'host_var'}) - def test_055_config_host_load(self): + def test_057_config_host_load(self): """ test _config_load - load template with host variable """ config_dic = {'api_host_variable': 'api_host_var'} self.cahandler._config_host_load(config_dic) @@ -855,7 +855,7 @@ def test_055_config_host_load(self): self.assertFalse(self.cahandler.profile_name) @patch.dict('os.environ', {'api_host_var': 'host_var'}) - def test_056_config_host_load(self): + def test_058_config_host_load(self): """ test _config_load - load template with host variable """ config_dic = {'api_host_variable': 'does_not_exist'} with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -865,7 +865,7 @@ def test_056_config_host_load(self): self.assertFalse(self.cahandler.profile_name) @patch.dict('os.environ', {'api_host_var': 'host_var'}) - def test_057_config_host_load(self): + def test_059_config_host_load(self): """ test _config_load - load template with host variable """ config_dic = {'api_host_variable': 'api_host_var', 'api_host': 'api_host'} self.cahandler._config_host_load(config_dic) @@ -875,7 +875,7 @@ def test_057_config_host_load(self): self.assertFalse(self.cahandler.profile_name) @patch.dict('os.environ', {'api_key_var': 'key_var'}) - def test_058_config_key_load(self): + def test_060_config_key_load(self): """ test _config_load - load template with key variable """ config_dic = {'api_key_variable': 'api_key_var'} self.cahandler._config_key_load(config_dic) @@ -883,7 +883,7 @@ def test_058_config_key_load(self): self.assertFalse(self.cahandler.profile_name) @patch.dict('os.environ', {'api_key_var': 'key_var'}) - def test_059_config_key_load(self): + def test_061_config_key_load(self): """ test _config_load - load template with key variable """ config_dic = {'api_key_variable': 'does_not_exist'} with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -893,7 +893,7 @@ def test_059_config_key_load(self): self.assertFalse(self.cahandler.profile_name) @patch.dict('os.environ', {'api_key_var': 'key_var'}) - def test_060_config_key_load(self): + def test_062_config_key_load(self): """ test _config_load - load template with key variable """ config_dic = {'api_key_variable': 'api_key_var', 'api_key': 'api_key'} self.cahandler._config_key_load(config_dic) @@ -903,7 +903,7 @@ def test_060_config_key_load(self): self.assertFalse(self.cahandler.profile_name) @patch.dict('os.environ', {'api_password_var': 'password_var'}) - def test_061_config_password_load(self): + def test_063_config_password_load(self): """ test _config_load - load template with password variable """ config_dic = {'api_password_variable': 'api_password_var'} self.cahandler._config_password_load(config_dic) @@ -911,7 +911,7 @@ def test_061_config_password_load(self): self.assertFalse(self.cahandler.profile_name) @patch.dict('os.environ', {'api_password_var': 'password_var'}) - def test_062_config_password_load(self): + def test_064_config_password_load(self): """ test _config_load - load template with password variable """ config_dic = {'api_password_variable': 'does_not_exist'} with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -921,7 +921,7 @@ def test_062_config_password_load(self): self.assertFalse(self.cahandler.profile_name) @patch.dict('os.environ', {'api_password_var': 'password_var'}) - def test_063_config_password_load(self): + def test_065_config_password_load(self): """ test _config_load - load template with password variable """ config_dic = {'api_password_variable': 'api_password_var', 'api_password': 'api_password'} self.cahandler._config_password_load(config_dic) @@ -933,7 +933,7 @@ def test_063_config_password_load(self): @patch('examples.ca_handler.asa_ca_handler.CAhandler._validity_dates_get') @patch('examples.ca_handler.asa_ca_handler.CAhandler._csr_cn_get') @patch('examples.ca_handler.asa_ca_handler.csr_pubkey_get') - def test_069_enrollment_dic_create(self, mock_pkg, mock_ccg, mock_vdg): + def test_066_enrollment_dic_create(self, mock_pkg, mock_ccg, mock_vdg): """ test _enrollment_dic_create()""" mock_pkg.return_value = 'pubkey' mock_ccg.return_value = 'cn' @@ -942,7 +942,7 @@ def test_069_enrollment_dic_create(self, mock_pkg, mock_ccg, mock_vdg): self.assertEqual(result, self.cahandler._enrollment_dic_create('csr')) @patch('examples.ca_handler.asa_ca_handler.header_info_field_validate') - def test_102__eab_profile_check(self, mock_hil): + def test_067__eab_profile_check(self, mock_hil): """ test eab_profile_check """ self.cahandler.eab_handler = MagicMock() self.cahandler.api_host = 'api_host' @@ -960,7 +960,7 @@ def test_102__eab_profile_check(self, mock_hil): self.assertFalse(mock_hil.called) @patch('examples.ca_handler.asa_ca_handler.header_info_lookup') - def test_103__eab_profile_check(self, mock_hil): + def test_068__eab_profile_check(self, mock_hil): """ test eab_profile_check """ self.cahandler.eab_handler = MagicMock() self.cahandler.api_host = 'api_host' @@ -977,7 +977,7 @@ def test_103__eab_profile_check(self, mock_hil): self.assertEqual('new_profile', self.cahandler.profile_name) self.assertFalse(mock_hil.called) - def test_104__eab_profile_check(self): + def test_069__eab_profile_check(self): """ test eab_profile_check default value from list """ self.cahandler.eab_handler = MagicMock() self.cahandler.api_host = 'api_host' @@ -995,7 +995,7 @@ def test_104__eab_profile_check(self): self.assertEqual('profile_1', self.cahandler.profile_name) @patch('examples.ca_handler.asa_ca_handler.header_info_field_validate') - def test_105__eab_profile_check(self, mock_hil): + def test_070__eab_profile_check(self, mock_hil): """ test eab_profile_check default value from list header info validate returns a value """ self.cahandler.eab_handler = MagicMock() self.cahandler.api_host = 'api_host' @@ -1014,7 +1014,7 @@ def test_105__eab_profile_check(self, mock_hil): self.assertTrue(mock_hil.called) @patch('examples.ca_handler.asa_ca_handler.header_info_field_validate') - def test_106__eab_profile_check(self, mock_hil): + def test_071__eab_profile_check(self, mock_hil): """ test eab_profile_check default value from list headerinfo_lookup returns an error """ self.cahandler.eab_handler = MagicMock() self.cahandler.api_host = 'api_host' @@ -1033,7 +1033,7 @@ def test_106__eab_profile_check(self, mock_hil): self.assertTrue(mock_hil.called) @patch('examples.ca_handler.asa_ca_handler.header_info_field_validate') - def test_107__eab_profile_check(self, mock_hil): + def test_072__eab_profile_check(self, mock_hil): """ test eab_profile_check """ self.cahandler.eab_handler = MagicMock() self.cahandler.api_host = 'api_host' @@ -1053,7 +1053,7 @@ def test_107__eab_profile_check(self, mock_hil): self.assertFalse(mock_hil.called) @patch('examples.ca_handler.asa_ca_handler.header_info_field_validate') - def test_108__eab_profile_check(self, mock_hil): + def test_073__eab_profile_check(self, mock_hil): """ test eab_profile_check """ self.cahandler.eab_handler = MagicMock() self.cahandler.api_host = 'api_host' @@ -1073,7 +1073,7 @@ def test_108__eab_profile_check(self, mock_hil): self.assertFalse(mock_hil.called) @patch('examples.ca_handler.asa_ca_handler.header_info_field_validate') - def test_109__eab_profile_check(self, mock_hil): + def test_074__eab_profile_check(self, mock_hil): """ test eab_profile_check """ self.cahandler.eab_handler = MagicMock() self.cahandler.api_host = 'api_host' @@ -1095,7 +1095,7 @@ def test_109__eab_profile_check(self, mock_hil): @patch('examples.ca_handler.asa_ca_handler.header_info_lookup') @patch('examples.ca_handler.asa_ca_handler.header_info_field_validate') - def test_110__eab_profile_check(self, mock_hiv, mock_hil): + def test_075__eab_profile_check(self, mock_hiv, mock_hil): """ test eab_profile_check """ self.cahandler.eab_handler = MagicMock() self.cahandler.api_host = 'api_host' @@ -1121,7 +1121,7 @@ def test_110__eab_profile_check(self, mock_hiv, mock_hil): @patch('examples.ca_handler.asa_ca_handler.header_info_lookup') @patch('examples.ca_handler.asa_ca_handler.header_info_field_validate') - def test_111__eab_profile_check(self, mock_hiv, mock_hil): + def test_076__eab_profile_check(self, mock_hiv, mock_hil): """ test eab_profile_check """ self.cahandler.eab_handler = MagicMock() self.cahandler.api_host = 'api_host' @@ -1145,7 +1145,7 @@ def test_111__eab_profile_check(self, mock_hiv, mock_hil): @patch('examples.ca_handler.asa_ca_handler.header_info_lookup') @patch('examples.ca_handler.asa_ca_handler.CAhandler._eab_profile_check') - def test_112__profile_check(self, mock_eab, mock_hil): + def test_077__profile_check(self, mock_eab, mock_hil): """ test eab_profile_string_check """ self.assertFalse(self.cahandler._profile_check('csr')) self.assertFalse(mock_eab.called) @@ -1153,7 +1153,7 @@ def test_112__profile_check(self, mock_eab, mock_hil): @patch('examples.ca_handler.asa_ca_handler.header_info_lookup') @patch('examples.ca_handler.asa_ca_handler.CAhandler._eab_profile_check') - def test_113__profile_check(self, mock_eab, mock_hil): + def test_078__profile_check(self, mock_eab, mock_hil): """ test eab_profile_string_check """ self.cahandler.eab_profiling = False self.assertFalse(self.cahandler._profile_check('csr')) @@ -1162,7 +1162,7 @@ def test_113__profile_check(self, mock_eab, mock_hil): @patch('examples.ca_handler.asa_ca_handler.header_info_lookup') @patch('examples.ca_handler.asa_ca_handler.CAhandler._eab_profile_check') - def test_114__eab_profile_string_check(self, mock_eab, mock_hil): + def test_079__eab_profile_string_check(self, mock_eab, mock_hil): """ test eab_profile_string_check """ self.cahandler.eab_profiling = True with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -1173,7 +1173,7 @@ def test_114__eab_profile_string_check(self, mock_eab, mock_hil): @patch('examples.ca_handler.asa_ca_handler.header_info_lookup') @patch('examples.ca_handler.asa_ca_handler.CAhandler._eab_profile_check') - def test_115__eab_profile_string_check(self, mock_eab, mock_hil): + def test_080__eab_profile_string_check(self, mock_eab, mock_hil): """ test eab_profile_string_check """ self.cahandler.eab_profiling = True self.cahandler.eab_handler = MagicMock() @@ -1184,7 +1184,7 @@ def test_115__eab_profile_string_check(self, mock_eab, mock_hil): @patch('examples.ca_handler.asa_ca_handler.header_info_lookup') @patch('examples.ca_handler.asa_ca_handler.CAhandler._eab_profile_check') - def test_116__eab_profile_string_check(self, mock_eab, mock_hil): + def test_081__eab_profile_string_check(self, mock_eab, mock_hil): """ test eab_profile_string_check """ self.cahandler.eab_profiling = True self.cahandler.header_info_field = 'header_info_field' @@ -1196,7 +1196,7 @@ def test_116__eab_profile_string_check(self, mock_eab, mock_hil): @patch('examples.ca_handler.asa_ca_handler.header_info_lookup') @patch('examples.ca_handler.asa_ca_handler.CAhandler._eab_profile_check') - def test_117__eab_profile_string_check(self, mock_eab, mock_hil): + def test_082__eab_profile_string_check(self, mock_eab, mock_hil): """ test eab_profile_string_check """ self.cahandler.eab_profiling = False self.cahandler.eab_handler = None @@ -1210,7 +1210,7 @@ def test_117__eab_profile_string_check(self, mock_eab, mock_hil): @patch('examples.ca_handler.asa_ca_handler.header_info_lookup') @patch('examples.ca_handler.asa_ca_handler.CAhandler._eab_profile_check') - def test_118__eab_profile_string_check(self, mock_eab, mock_hil): + def test_083__eab_profile_string_check(self, mock_eab, mock_hil): """ test eab_profile_string_check """ self.cahandler.eab_profiling = False self.cahandler.eab_handler = None diff --git a/test/test_msca_handler.py b/test/test_msca_handler.py index 8fb1514f..f185f9f2 100644 --- a/test/test_msca_handler.py +++ b/test/test_msca_handler.py @@ -75,6 +75,7 @@ def test_007_config_load(self, mock_load_cfg): self.assertEqual('basic', self.cahandler.auth_method) self.assertFalse(self.cahandler.ca_bundle) self.assertFalse(self.cahandler.template) + self.assertFalse(self.cahandler.krb5_config) @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_008_config_load(self, mock_load_cfg): @@ -87,6 +88,7 @@ def test_008_config_load(self, mock_load_cfg): self.assertEqual('basic', self.cahandler.auth_method) self.assertFalse(self.cahandler.ca_bundle) self.assertFalse(self.cahandler.template) + self.assertFalse(self.cahandler.krb5_config) @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_009_config_load(self, mock_load_cfg): @@ -99,6 +101,7 @@ def test_009_config_load(self, mock_load_cfg): self.assertEqual('basic', self.cahandler.auth_method) self.assertFalse(self.cahandler.ca_bundle) self.assertFalse(self.cahandler.template) + self.assertFalse(self.cahandler.krb5_config) @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_010_config_load(self, mock_load_cfg): @@ -111,6 +114,7 @@ def test_010_config_load(self, mock_load_cfg): self.assertEqual('basic', self.cahandler.auth_method) self.assertFalse(self.cahandler.ca_bundle) self.assertFalse(self.cahandler.template) + self.assertFalse(self.cahandler.krb5_config) @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_011_config_load(self, mock_load_cfg): @@ -123,6 +127,7 @@ def test_011_config_load(self, mock_load_cfg): self.assertEqual('basic', self.cahandler.auth_method) self.assertFalse(self.cahandler.ca_bundle) self.assertFalse(self.cahandler.template) + self.assertFalse(self.cahandler.krb5_config) @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_012_config_load(self, mock_load_cfg): @@ -135,6 +140,7 @@ def test_012_config_load(self, mock_load_cfg): self.assertEqual('basic', self.cahandler.auth_method) self.assertFalse(self.cahandler.ca_bundle) self.assertFalse(self.cahandler.template) + self.assertFalse(self.cahandler.krb5_config) @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_013_config_load(self, mock_load_cfg): @@ -147,6 +153,7 @@ def test_013_config_load(self, mock_load_cfg): self.assertEqual('ntlm', self.cahandler.auth_method) self.assertFalse(self.cahandler.ca_bundle) self.assertFalse(self.cahandler.template) + self.assertFalse(self.cahandler.krb5_config) @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_014_config_load(self, mock_load_cfg): @@ -159,6 +166,7 @@ def test_014_config_load(self, mock_load_cfg): self.assertEqual('basic', self.cahandler.auth_method) self.assertFalse(self.cahandler.ca_bundle) self.assertFalse(self.cahandler.template) + self.assertFalse(self.cahandler.krb5_config) @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_015_config_load(self, mock_load_cfg): @@ -171,6 +179,7 @@ def test_015_config_load(self, mock_load_cfg): self.assertEqual('basic', self.cahandler.auth_method) self.assertEqual('ca_bundle', self.cahandler.ca_bundle) self.assertFalse(self.cahandler.template) + self.assertFalse(self.cahandler.krb5_config) @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_016_config_load(self, mock_load_cfg): @@ -183,10 +192,24 @@ def test_016_config_load(self, mock_load_cfg): self.assertEqual('basic', self.cahandler.auth_method) self.assertFalse(self.cahandler.ca_bundle) self.assertEqual('template', self.cahandler.template) + self.assertFalse(self.cahandler.krb5_config) - @patch.dict('os.environ', {'host_variable': 'host'}) @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_017_config_load(self, mock_load_cfg): + """ test _config_load cahandler section with template value """ + mock_load_cfg.return_value = {'CAhandler': {'krb5_config': 'krb5_config'}} + self.cahandler._config_load() + self.assertFalse(self.cahandler.host) + self.assertFalse(self.cahandler.user) + self.assertFalse(self.cahandler.password) + self.assertEqual('basic', self.cahandler.auth_method) + self.assertFalse(self.cahandler.ca_bundle) + self.assertFalse(self.cahandler.template) + self.assertEqual('krb5_config', self.cahandler.krb5_config) + + @patch.dict('os.environ', {'host_variable': 'host'}) + @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') + def test_018_config_load(self, mock_load_cfg): """ test _config_load - load with host variable """ mock_load_cfg.return_value = {'CAhandler': {'host_variable': 'host_variable'}} self.cahandler._config_load() @@ -194,7 +217,7 @@ def test_017_config_load(self, mock_load_cfg): @patch.dict('os.environ', {'host_variable': 'host'}) @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') - def test_018_config_load(self, mock_load_cfg): + def test_019_config_load(self, mock_load_cfg): """ test _config_load - load with host variable which does not exist """ mock_load_cfg.return_value = {'CAhandler': {'host_variable': 'doesnotexist'}} with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -204,7 +227,7 @@ def test_018_config_load(self, mock_load_cfg): @patch.dict('os.environ', {'host_variable': 'host'}) @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') - def test_019_config_load(self, mock_load_cfg): + def test_020_config_load(self, mock_load_cfg): """ test _config_load - load with host variable which gets overwritten """ mock_load_cfg.return_value = {'CAhandler': {'host_variable': 'host_variable', 'host': 'host_local'}} with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -214,7 +237,7 @@ def test_019_config_load(self, mock_load_cfg): @patch.dict('os.environ', {'user_variable': 'user'}) @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') - def test_020_config_load(self, mock_load_cfg): + def test_021_config_load(self, mock_load_cfg): """ test _config_load - load with user variable """ mock_load_cfg.return_value = {'CAhandler': {'user_variable': 'user_variable'}} self.cahandler._config_load() @@ -222,7 +245,7 @@ def test_020_config_load(self, mock_load_cfg): @patch.dict('os.environ', {'user_variable': 'user'}) @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') - def test_021_config_load(self, mock_load_cfg): + def test_022_config_load(self, mock_load_cfg): """ test _config_load - load with user variable which does not exist """ mock_load_cfg.return_value = {'CAhandler': {'user_variable': 'doesnotexist'}} with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -232,7 +255,7 @@ def test_021_config_load(self, mock_load_cfg): @patch.dict('os.environ', {'user_variable': 'user'}) @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') - def test_022_config_load(self, mock_load_cfg): + def test_023_config_load(self, mock_load_cfg): """ test _config_load - load with user variable which gets overwritten """ mock_load_cfg.return_value = {'CAhandler': {'user_variable': 'user_variable', 'user': 'user_local'}} with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -242,7 +265,7 @@ def test_022_config_load(self, mock_load_cfg): @patch.dict('os.environ', {'password_variable': 'password'}) @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') - def test_023_config_load(self, mock_load_cfg): + def test_024_config_load(self, mock_load_cfg): """ test _config_load - load with password variable """ mock_load_cfg.return_value = {'CAhandler': {'password_variable': 'password_variable'}} self.cahandler._config_load() @@ -250,7 +273,7 @@ def test_023_config_load(self, mock_load_cfg): @patch.dict('os.environ', {'password_variable': 'password'}) @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') - def test_024_config_load(self, mock_load_cfg): + def test_025_config_load(self, mock_load_cfg): """ test _config_load - load with password variable which does not exist """ mock_load_cfg.return_value = {'CAhandler': {'password_variable': 'doesnotexist'}} with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -260,7 +283,7 @@ def test_024_config_load(self, mock_load_cfg): @patch.dict('os.environ', {'password_variable': 'password'}) @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') - def test_025_config_load(self, mock_load_cfg): + def test_026_config_load(self, mock_load_cfg): """ test _config_load - load with password variable which gets overwritten """ mock_load_cfg.return_value = {'CAhandler': {'password_variable': 'password_variable', 'password': 'password_local'}} with self.assertLogs('test_a2c', level='INFO') as lcm: @@ -271,7 +294,7 @@ def test_025_config_load(self, mock_load_cfg): @patch('examples.ca_handler.mscertsrv_ca_handler.proxy_check') @patch('json.loads') @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') - def test_026_config_load(self, mock_load_cfg, mock_json, mock_chk): + def test_027_config_load(self, mock_load_cfg, mock_json, mock_chk): """ test _config_load ca_handler configured load proxies """ mock_load_cfg.return_value = {'DEFAULT': {'proxy_server_list': 'foo'}} mock_json.return_value = 'foo.bar.local' @@ -284,7 +307,7 @@ def test_026_config_load(self, mock_load_cfg, mock_json, mock_chk): @patch('examples.ca_handler.mscertsrv_ca_handler.proxy_check') @patch('json.loads') @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') - def test_027_config_load(self, mock_load_cfg, mock_json, mock_chk): + def test_028_config_load(self, mock_load_cfg, mock_json, mock_chk): """ test _config_load ca_handler configured load proxies failed with exception in json.load """ mock_load_cfg.return_value = {'DEFAULT': {'proxy_server_list': 'foo'}} mock_json.side_effect = Exception('exc_load_config') @@ -296,53 +319,53 @@ def test_027_config_load(self, mock_load_cfg, mock_json, mock_chk): self.assertFalse(self.cahandler.proxy ) self.assertIn('WARNING:test_a2c:CAhandler._config_load() proxy_server_list failed with error: exc_load_config', lcm.output) - def test_028_revoke(self): + def test_029_revoke(self): """ test revocation """ self.assertEqual((500, 'urn:ietf:params:acme:error:serverInternal', 'Revocation is not supported.'), self.cahandler.revoke('cert', 'rev_reason', 'rev_date')) - def test_029_poll(self): + def test_030_poll(self): """ test polling """ self.assertEqual(('Method not implemented.', None, None, 'poll_identifier', False), self.cahandler.poll('cert_name', 'poll_identifier', 'csr')) - def test_030_trigger(self): + def test_031_trigger(self): """ test polling """ self.assertEqual(('Method not implemented.', None, None), self.cahandler.trigger('payload')) - def test_031_check_credentials(self): + def test_032_check_credentials(self): """ test polling """ ca_server = Mock() ca_server.check_credentials = Mock(return_value=True) self.assertTrue(self.cahandler._check_credentials(ca_server)) - def test_032_check_credentials(self): + def test_033_check_credentials(self): """ test polling """ ca_server = Mock() ca_server.check_credentials = Mock(return_value=False) self.assertFalse(self.cahandler._check_credentials(ca_server)) @patch('examples.ca_handler.mscertsrv_ca_handler.CAhandler._config_load') - def test_033__enter__(self, mock_cfg): + def test_034__enter__(self, mock_cfg): """ test enter called """ mock_cfg.return_value = True self.cahandler.__enter__() self.assertTrue(mock_cfg.called) - def test_034_enroll(self): + def test_035_enroll(self): """ enroll without having self.host """ self.assertEqual(('Config incomplete', None, None, None), self.cahandler.enroll('csr')) - def test_035_enroll(self): + def test_036_enroll(self): """ enroll without having self.user """ self.cahandler.host = 'host' self.assertEqual(('Config incomplete', None, None, None), self.cahandler.enroll('csr')) - def test_036_enroll(self): + def test_037_enroll(self): """ enroll without having self.password """ self.cahandler.host = 'host' self.cahandler.user = 'user' self.assertEqual(('Config incomplete', None, None, None), self.cahandler.enroll('csr')) - def test_037_enroll(self): + def test_038_enroll(self): """ enroll without having self.template """ self.cahandler.host = 'host' self.cahandler.user = 'user' @@ -351,7 +374,7 @@ def test_037_enroll(self): @patch('examples.ca_handler.mscertsrv_ca_handler.CAhandler._check_credentials') @patch('certsrv.Certsrv') - def test_038_enroll(self, mock_certserver, mock_credchk): + def test_039_enroll(self, mock_certserver, mock_credchk): """ enroll credential check failed """ self.cahandler.host = 'host' self.cahandler.user = 'user' @@ -367,7 +390,7 @@ def test_038_enroll(self, mock_certserver, mock_credchk): @patch('textwrap.fill') @patch('examples.ca_handler.mscertsrv_ca_handler.CAhandler._check_credentials') @patch('examples.ca_handler.mscertsrv_ca_handler.Certsrv') - def test_039_enroll(self, mock_certserver, mock_credchk, mockwrap, mock_b2s, mock_p2p, mock_tmpl): + def test_040_enroll(self, mock_certserver, mock_credchk, mockwrap, mock_b2s, mock_p2p, mock_tmpl): """ enroll enroll successful """ self.cahandler.host = 'host' self.cahandler.user = 'user' @@ -390,7 +413,7 @@ def test_039_enroll(self, mock_certserver, mock_credchk, mockwrap, mock_b2s, moc @patch('textwrap.fill') @patch('examples.ca_handler.mscertsrv_ca_handler.CAhandler._check_credentials') @patch('examples.ca_handler.mscertsrv_ca_handler.Certsrv') - def test_040_enroll(self, mock_certserver, mock_credchk, mockwrap, mock_b2s, mock_p2p, mock_tmpl): + def test_041_enroll(self, mock_certserver, mock_credchk, mockwrap, mock_b2s, mock_p2p, mock_tmpl): """ enroll enroll successful """ self.cahandler.host = 'host' self.cahandler.user = 'user' @@ -416,7 +439,36 @@ def test_040_enroll(self, mock_certserver, mock_credchk, mockwrap, mock_b2s, moc @patch('textwrap.fill') @patch('examples.ca_handler.mscertsrv_ca_handler.CAhandler._check_credentials') @patch('examples.ca_handler.mscertsrv_ca_handler.Certsrv') - def test_041_enroll(self, mock_certserver, mock_credchk, mockwrap, mock_b2s, mock_p2p, mock_tmpl): + def test_042_enroll(self, mock_certserver, mock_credchk, mockwrap, mock_b2s, mock_p2p, mock_tmpl): + """ enroll enroll successful """ + self.cahandler.host = 'host' + self.cahandler.user = 'user' + self.cahandler.password = 'password' + self.cahandler.template = 'template' + self.cahandler.header_info_field = 'header_info' + self.cahandler.krb5_config = 'krb5_config' + mockresponse = MagicMock() + mockresponse.get_chain.return_value = "get_chain" + mockresponse.get_cert.return_value = "get_cert" + mock_tmpl.return_value = 'new_template' + mock_certserver = mockresponse + mock_credchk.return_value = True + mockwrap.return_value = 'mockwrap' + mock_b2s.side_effect = ['get_chain', 'get_cert'] + mock_p2p.return_value = 'p2p' + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertEqual((None, 'get_certp2p', 'get_cert', None), self.cahandler.enroll('csr')) + self.assertIn('INFO:test_a2c:CAhandler.enroll(): load krb5config from krb5_config', lcm.output) + self.assertTrue(mock_tmpl.called) + self.assertEqual('new_template', self.cahandler.template) + + @patch('examples.ca_handler.mscertsrv_ca_handler.CAhandler._template_name_get') + @patch('examples.ca_handler.mscertsrv_ca_handler.CAhandler._pkcs7_to_pem') + @patch('examples.ca_handler.mscertsrv_ca_handler.convert_byte_to_string') + @patch('textwrap.fill') + @patch('examples.ca_handler.mscertsrv_ca_handler.CAhandler._check_credentials') + @patch('examples.ca_handler.mscertsrv_ca_handler.Certsrv') + def test_043_enroll(self, mock_certserver, mock_credchk, mockwrap, mock_b2s, mock_p2p, mock_tmpl): """ enroll enroll successful """ self.cahandler.host = 'host' self.cahandler.user = 'user' @@ -441,7 +493,7 @@ def test_041_enroll(self, mock_certserver, mock_credchk, mockwrap, mock_b2s, moc @patch('textwrap.fill') @patch('examples.ca_handler.mscertsrv_ca_handler.CAhandler._check_credentials') @patch('examples.ca_handler.mscertsrv_ca_handler.Certsrv') - def test_042_enroll(self, mock_certserver, mock_credchk, mockwrap, mock_b2s, mock_p2p): + def test_044_enroll(self, mock_certserver, mock_credchk, mockwrap, mock_b2s, mock_p2p): """ enroll exceütption in get chain """ self.cahandler.host = 'host' self.cahandler.user = 'user' @@ -465,7 +517,7 @@ def test_042_enroll(self, mock_certserver, mock_credchk, mockwrap, mock_b2s, moc @patch('textwrap.fill') @patch('examples.ca_handler.mscertsrv_ca_handler.CAhandler._check_credentials') @patch('examples.ca_handler.mscertsrv_ca_handler.Certsrv') - def test_043_enroll(self, mock_certserver, mock_credchk, mockwrap, mock_b2s, mock_p2p): + def test_045_enroll(self, mock_certserver, mock_credchk, mockwrap, mock_b2s, mock_p2p): """ enroll exceütption in get cert """ self.cahandler.host = 'host' self.cahandler.user = 'user' @@ -485,21 +537,21 @@ def test_043_enroll(self, mock_certserver, mock_credchk, mockwrap, mock_b2s, moc self.assertIn('ERROR:test_a2c:cert bundling failed', lcm.output) @patch('examples.ca_handler.mscertsrv_ca_handler.header_info_get') - def test_044_template_name_get(self, mock_header): + def test_046_template_name_get(self, mock_header): """ test _template_name_get()""" mock_header.return_value = [{'header_info': '{"header_field": "template=foo lego-cli/4.14.2 xenolf-acme/4.14.2 (release; linux; amd64)"}'}] self.cahandler.header_info_field = 'header_field' self.assertEqual('foo', self.cahandler._template_name_get('csr')) @patch('examples.ca_handler.mscertsrv_ca_handler.header_info_get') - def test_045_template_name_get(self, mock_header): + def test_047_template_name_get(self, mock_header): """ test _template_name_get()""" mock_header.return_value = [{'header_info': '{"header_field": "Template=foo lego-cli/4.14.2 xenolf-acme/4.14.2 (release; linux; amd64)"}'}] self.cahandler.header_info_field = 'header_field' self.assertEqual('foo', self.cahandler._template_name_get('csr')) @patch('examples.ca_handler.mscertsrv_ca_handler.header_info_get') - def test_046_template_name_get(self, mock_header): + def test_048_template_name_get(self, mock_header): """ test _template_name_get()""" mock_header.return_value = [{'header_info': 'header_info'}] self.cahandler.header_info_field = 'header_field' @@ -507,19 +559,19 @@ def test_046_template_name_get(self, mock_header): self.assertFalse(self.cahandler._template_name_get('csr')) self.assertIn('ERROR:test_a2c:CAhandler._template_name_get() could not parse template: Expecting value: line 1 column 1 (char 0)', lcm.output) - def test_047_config_headerinfo_load(self): + def test_049_config_headerinfo_load(self): """ test config_headerinfo_load()""" config_dic = {'Order': {'header_info_list': '["foo", "bar", "foobar"]'}} self.cahandler._config_headerinfo_load(config_dic) self.assertEqual( 'foo', self.cahandler.header_info_field) - def test_048_config_headerinfo_load(self): + def test_050_config_headerinfo_load(self): """ test config_headerinfo_load()""" config_dic = {'Order': {'header_info_list': '["foo"]'}} self.cahandler._config_headerinfo_load(config_dic) self.assertEqual( 'foo', self.cahandler.header_info_field) - def test_049_config_headerinfo_load(self): + def test_051_config_headerinfo_load(self): """ test config_headerinfo_load()""" config_dic = {'Order': {'header_info_list': 'foo'}} with self.assertLogs('test_a2c', level='INFO') as lcm: diff --git a/test/test_xca_ca_handler.py b/test/test_xca_ca_handler.py index 2890ee04..88babad7 100644 --- a/test/test_xca_ca_handler.py +++ b/test/test_xca_ca_handler.py @@ -2266,7 +2266,7 @@ def test_215__eab_profile_check(self, mock_hil, mock_lookup): self.assertFalse(mock_hil.called) self.assertTrue(mock_lookup.called) - def test_217__eab_profile_check(self): + def test_216__eab_profile_check(self): """ test eab_profile_check """ self.cahandler.eab_handler = MagicMock() self.cahandler.template_name = 'template_name' @@ -2283,7 +2283,7 @@ def test_217__eab_profile_check(self): self.assertEqual('foo_ca1', self.cahandler.issuing_ca_name) self.assertEqual('passphrase', self.cahandler.passphrase) - def test_218__eab_profile_check(self): + def test_217__eab_profile_check(self): """ test eab_profile_check """ self.cahandler.eab_handler = MagicMock() self.cahandler.template_name = 'template_name' @@ -2300,7 +2300,7 @@ def test_218__eab_profile_check(self): self.assertEqual('passphrase', self.cahandler.passphrase) @patch('examples.ca_handler.xca_ca_handler.header_info_field_validate') - def test_219__eab_profile_check(self, mock_hiv): + def test_218__eab_profile_check(self, mock_hiv): """ test eab_profile_check """ self.cahandler.eab_handler = MagicMock() self.cahandler.template_name = 'template_name' From cf07ec24581e8f7b7a10c1797d8a27cc8d706031 Mon Sep 17 00:00:00 2001 From: grindsa Date: Thu, 25 Apr 2024 14:59:26 +0200 Subject: [PATCH 189/460] [fix] liniting --- examples/ca_handler/mscertsrv_ca_handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/ca_handler/mscertsrv_ca_handler.py b/examples/ca_handler/mscertsrv_ca_handler.py index e4784b6a..51ffc667 100644 --- a/examples/ca_handler/mscertsrv_ca_handler.py +++ b/examples/ca_handler/mscertsrv_ca_handler.py @@ -215,7 +215,7 @@ def _template_name_get(self, csr: str) -> str: self.logger.debug('CAhandler._template_name_get() ended with: %s', template_name) return template_name - def _csr_process(self, ca_server, csr: str) -> Tuple[str, str, str]: + def _csr_process(self, ca_server, csr: str) -> Tuple[str, str, str]: # recode csr csr = textwrap.fill(b64_url_recode(self.logger, csr), 64) + '\n' From ef2c1b10cba6ba1d575d9ee7b6105877940a01da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gu=C3=B0r=C3=BAn=20=C3=93lafsd=C3=B3ttir?= Date: Tue, 30 Apr 2024 08:09:30 +0000 Subject: [PATCH 190/460] adding whitelist function to mscertsrv --- examples/ca_handler/mscertsrv_ca_handler.py | 171 ++++++++++++++------ 1 file changed, 122 insertions(+), 49 deletions(-) diff --git a/examples/ca_handler/mscertsrv_ca_handler.py b/examples/ca_handler/mscertsrv_ca_handler.py index 889fc492..331b291d 100644 --- a/examples/ca_handler/mscertsrv_ca_handler.py +++ b/examples/ca_handler/mscertsrv_ca_handler.py @@ -4,12 +4,15 @@ import os import textwrap import json +import re from typing import List, Tuple, Dict from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.serialization.pkcs7 import load_pem_pkcs7_certificates, load_der_pkcs7_certificates -# pylint: disable=e0401, e0611 +# pylint: disable=C0209, E0401, E0611 from examples.ca_handler.certsrv import Certsrv -from acme_srv.helper import load_config, b64_url_recode, convert_byte_to_string, proxy_check, convert_string_to_byte, header_info_get +# pylint: disable=E0401 +from acme_srv.helper import load_config, b64_url_recode, convert_byte_to_string, proxy_check, convert_string_to_byte, csr_san_get, csr_cn_get + class CAhandler(object): @@ -24,7 +27,7 @@ def __init__(self, _debug: bool = False, logger: object = None): self.ca_bundle = False self.template = None self.proxy = None - self.header_info_field = False + self.allowed_domainlist = [] def __enter__(self): """ Makes CAhandler a Context Manager """ @@ -39,7 +42,7 @@ def _check_credentials(self, ca_server: str) -> bool: """ check creadentials """ self.logger.debug('CAhandler.__check_credentials()') auth_check = ca_server.check_credentials() - self.logger.debug('CAhandler.__check_credentials() ended with %s', auth_check) + self.logger.debug('CAhandler.__check_credentials() ended with {0}'.format(auth_check)) return auth_check def _cert_bundle_create(self, ca_pem: str = None, cert_raw: str = None) -> Tuple[str, str, str]: @@ -60,18 +63,6 @@ def _cert_bundle_create(self, ca_pem: str = None, cert_raw: str = None) -> Tuple return (error, cert_bundle, cert_raw) - def _config_headerinfo_load(self, config_dic: Dict[str, str]): - """ load parameters """ - self.logger.debug('_config_header_info()') - - if 'Order' in config_dic and 'header_info_list' in config_dic['Order'] and config_dic['Order']['header_info_list']: - try: - self.header_info_field = json.loads(config_dic['Order']['header_info_list'])[0] - except Exception as err_: - self.logger.warning('Order._config_orderconfig_load() header_info_list failed with error: %s', err_) - - self.logger.debug('_config_header_info() ended') - def _config_user_load(self, config_dic: Dict[str, str]): """ load username """ self.logger.debug('CAhandler._config_user_load()') @@ -80,7 +71,7 @@ def _config_user_load(self, config_dic: Dict[str, str]): try: self.user = os.environ[config_dic['CAhandler']['user_variable']] except Exception as err: - self.logger.error('CAhandler._config_load() could not load user_variable:%s', err) + self.logger.error('CAhandler._config_load() could not load user_variable:{0}'.format(err)) if 'user' in config_dic['CAhandler']: if self.user: self.logger.info('CAhandler._config_load() overwrite user') @@ -96,7 +87,7 @@ def _config_password_load(self, config_dic: Dict[str, str]): try: self.password = os.environ[config_dic['CAhandler']['password_variable']] except Exception as err: - self.logger.error('CAhandler._config_load() could not load password_variable:%s', err) + self.logger.error('CAhandler._config_load() could not load password_variable:{0}'.format(err)) if 'password' in config_dic['CAhandler']: if self.password: self.logger.info('CAhandler._config_load() overwrite password') @@ -112,7 +103,7 @@ def _config_hostname_load(self, config_dic: Dict[str, str]): try: self.host = os.environ[config_dic['CAhandler']['host_variable']] except Exception as err: - self.logger.error('CAhandler._config_load() could not load host_variable:%s', err) + self.logger.error('CAhandler._config_load() could not load host_variable:{0}'.format(err)) if 'host' in config_dic['CAhandler']: if self.host: self.logger.info('CAhandler._config_load() overwrite host') @@ -132,6 +123,15 @@ def _config_parameters_load(self, config_dic: Dict[str, str]): if 'ca_bundle' in config_dic['CAhandler']: self.ca_bundle = config_dic['CAhandler']['ca_bundle'] + + if 'allowed_domainlist' in config_dic['CAhandler']: + try: + self.allowed_domainlist = json.loads(config_dic['CAhandler']['allowed_domainlist']) + except Exception as err: + self.logger.error('CAhandler._config_load(): failed to parse allowed_domainlist: {0}'.format(err)) + + + self.logger.debug('CAhandler._config_parameters_load() ended') def _config_proxy_load(self, config_dic: Dict[str, str]): @@ -144,7 +144,7 @@ def _config_proxy_load(self, config_dic: Dict[str, str]): proxy_server = proxy_check(self.logger, self.host, proxy_list) self.proxy = {'http': proxy_server, 'https': proxy_server} except Exception as err_: - self.logger.warning('CAhandler._config_load() proxy_server_list failed with error: %s', err_) + self.logger.warning('CAhandler._config_load() proxy_server_list failed with error: {0}'.format(err_)) self.logger.debug('CAhandler._config_proxy_load() ended') @@ -159,7 +159,6 @@ def _config_load(self): self._config_user_load(config_dic) self._config_password_load(config_dic) self._config_parameters_load(config_dic) - self._config_headerinfo_load(config_dic) # load proxy config self._config_proxy_load(config_dic) @@ -191,41 +190,115 @@ def _pkcs7_to_pem(self, pkcs7_content: str, outform: str = 'string') -> List[str self.logger.debug('Certificate._pkcs7_to_pem() ended') return result - def _template_name_get(self, csr: str) -> str: - """ get templaate from csr """ - self.logger.debug('CAhandler._template_name_get(%s)', csr) - template_name = None + def _sancheck_lists_create(self, csr: str) -> Tuple[List[str], List[str]]: + self.logger.debug('CAhandler.sancheck_lists_create()') - # parse profileid from http_header - header_info = header_info_get(self.logger, csr=csr) - if header_info: - try: - header_info_dic = json.loads(header_info[-1]['header_info']) - if self.header_info_field in header_info_dic: - for ele in header_info_dic[self.header_info_field].split(' '): - if 'template' in ele.lower(): - template_name = ele.split('=')[1] - break - except Exception as err: - self.logger.error('CAhandler._template_name_get() could not parse template: %s', err) + check_list = [] + san_list = [] + + # get sans and build a list + _san_list = csr_san_get(self.logger, csr) + + if _san_list: + for san in _san_list: + try: + # SAN list must be modified/filtered) + (_san_type, san_value) = san.lower().split(':') + san_list.append(san_value) + except Exception: + # force check to fail as something went wrong during parsing + check_list.append(False) + self.logger.debug('CAhandler._csr_check(): san_list parsing failed at entry: {0}'.format(san)) + + # get common name and attach it to san_list + cn_ = csr_cn_get(self.logger, csr) + + if cn_: + cn_ = cn_.lower() + if cn_ not in san_list: + # append cn to san_list + self.logger.debug('Ahandler._csr_check(): append cn to san_list') + san_list.append(cn_) + + return (san_list, check_list) + + def _csr_check(self, csr: str) -> bool: + """ check CSR against definied whitelists """ + self.logger.debug('CAhandler._csr_check()') + + if self.allowed_domainlist: + + result = False + + (san_list, check_list) = self._sancheck_lists_create(csr) + + # go over the san list and check each entry + for san in san_list: + check_list.append(self._list_check(san, self.allowed_domainlist)) + + if check_list: + # cover a cornercase with empty checklist (no san, no cn) + if False in check_list: + result = False + else: + result = True + else: + result = True + + self.logger.debug('CAhandler._csr_check() ended with: {0}'.format(result)) + return result + + def _list_check(self, entry: str, list_: List[str], toggle: bool = False) -> bool: + """ check string against list """ + self.logger.debug('CAhandler._list_check({0}:{1})'.format(entry, toggle)) + self.logger.debug('check against list: {0}'.format(list_)) + + # default setting + check_result = False + + if entry: + if list_: + for regex in list_: + # check entry + check_result = self._entry_check(entry, regex, check_result) + else: + # empty list, flip parameter to make the check successful + check_result = True + + if toggle: + # toggle result if this is a blacklist + check_result = not check_result + + self.logger.debug('CAhandler._list_check() ended with: {0}'.format(check_result)) + return check_result + + def _entry_check(self, entry: str, regex: str, check_result: bool) -> bool: + """ check string against regex """ + self.logger.debug('_entry_check({0}/{1}):'.format(entry, regex)) + + if regex.startswith('*.'): + regex = regex.replace('*.', '.') + regex_compiled = re.compile(regex) + + if bool(regex_compiled.search(entry)): + # parameter is in set flag accordingly and stop loop + check_result = True + + self.logger.debug('_entry_check() ended with: {0}'.format(check_result)) + return check_result - self.logger.debug('CAhandler._template_name_get() ended with: %s', template_name) - return template_name def enroll(self, csr: str) -> Tuple[str, str, str, bool]: """ enroll certificate from via MS certsrv """ - self.logger.debug('CAhandler.enroll(%s)', self.template) + self.logger.debug('CAhandler.enroll({0})'.format(self.template)) cert_bundle = None error = None cert_raw = None - # lookup http header information from request - if self.header_info_field: - user_template = self._template_name_get(csr) - if user_template: - self.template = user_template + result = self._csr_check(csr) + - if self.host and self.user and self.password and self.template: + if self.host and self.user and self.password and self.template and result: # setup certserv ca_server = Certsrv(self.host, self.user, self.password, self.auth_method, self.ca_bundle, proxies=self.proxy) @@ -243,7 +316,7 @@ def enroll(self, csr: str) -> Tuple[str, str, str, bool]: # ca_pem = ca_pem.replace('\r\n', '\n') except Exception as err_: ca_pem = None - self.logger.error('ca_server.get_chain() failed with error: %s', err_) + self.logger.error('ca_server.get_chain() failed with error: {0}'.format(err_)) try: cert_raw = convert_byte_to_string(ca_server.get_cert(csr, self.template)) @@ -251,7 +324,7 @@ def enroll(self, csr: str) -> Tuple[str, str, str, bool]: cert_raw = cert_raw.replace('\r\n', '\n') except Exception as err_: cert_raw = None - self.logger.error('ca_server.get_cert() failed with error: %s', err_) + self.logger.error('ca_server.get_cert() failed with error: {0}'.format(err_)) # create bundle (error, cert_bundle, cert_raw) = self._cert_bundle_create(ca_pem, cert_raw) @@ -297,5 +370,5 @@ def trigger(self, _payload: str) -> Tuple[int, str, str]: cert_bundle = None cert_raw = None - self.logger.debug('CAhandler.trigger() ended with error: %s', error) + self.logger.debug('CAhandler.trigger() ended with error: {0}'.format(error)) return (error, cert_bundle, cert_raw) From f5c2bf00d6cad3f4d25806ec27f056f3c2efd1f1 Mon Sep 17 00:00:00 2001 From: Gbit <34913299+gbit-is@users.noreply.github.com> Date: Tue, 30 Apr 2024 08:13:58 +0000 Subject: [PATCH 191/460] Add allowed_domainlist to documentation --- docs/mscertsrv.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/mscertsrv.md b/docs/mscertsrv.md index 09a7bfac..5d919188 100644 --- a/docs/mscertsrv.md +++ b/docs/mscertsrv.md @@ -80,6 +80,7 @@ template: - ca_bundle - CA certificate bundle in pem format needed to validate the server certificate - auth_method - authentication method (either "basic" or "ntlm") - template - certificate template used for enrollment +- allowed_domainlist - *optional* - list of domain-names allowed for enrollment in json format example: ["bar.local$, bar.foo.local] ## Passing a template from client to server From f717550606a2f8d8d11c5da43a5d6f73811cb096 Mon Sep 17 00:00:00 2001 From: grindsa Date: Wed, 1 May 2024 08:00:38 +0200 Subject: [PATCH 192/460] some smaller modifications --- examples/ca_handler/mscertsrv_ca_handler.py | 67 +++++++++++++++++---- 1 file changed, 54 insertions(+), 13 deletions(-) diff --git a/examples/ca_handler/mscertsrv_ca_handler.py b/examples/ca_handler/mscertsrv_ca_handler.py index 331b291d..666896c9 100644 --- a/examples/ca_handler/mscertsrv_ca_handler.py +++ b/examples/ca_handler/mscertsrv_ca_handler.py @@ -4,14 +4,13 @@ import os import textwrap import json -import re from typing import List, Tuple, Dict from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.serialization.pkcs7 import load_pem_pkcs7_certificates, load_der_pkcs7_certificates -# pylint: disable=C0209, E0401, E0611 +# pylint: disable=e0401, e0611 from examples.ca_handler.certsrv import Certsrv -# pylint: disable=E0401 -from acme_srv.helper import load_config, b64_url_recode, convert_byte_to_string, proxy_check, convert_string_to_byte, csr_san_get, csr_cn_get + +from acme_srv.helper import load_config, b64_url_recode, convert_byte_to_string, proxy_check, convert_string_to_byte, csr_san_get, csr_cn_get, header_info_get # pylint: disable=e0401 @@ -28,6 +27,7 @@ def __init__(self, _debug: bool = False, logger: object = None): self.template = None self.proxy = None self.allowed_domainlist = [] + self.header_info_field = False def __enter__(self): """ Makes CAhandler a Context Manager """ @@ -42,7 +42,7 @@ def _check_credentials(self, ca_server: str) -> bool: """ check creadentials """ self.logger.debug('CAhandler.__check_credentials()') auth_check = ca_server.check_credentials() - self.logger.debug('CAhandler.__check_credentials() ended with {0}'.format(auth_check)) + self.logger.debug('CAhandler.__check_credentials() ended with %s', auth_check) return auth_check def _cert_bundle_create(self, ca_pem: str = None, cert_raw: str = None) -> Tuple[str, str, str]: @@ -63,6 +63,18 @@ def _cert_bundle_create(self, ca_pem: str = None, cert_raw: str = None) -> Tuple return (error, cert_bundle, cert_raw) + def _config_headerinfo_load(self, config_dic: Dict[str, str]): + """ load parameters """ + self.logger.debug('_config_header_info()') + + if 'Order' in config_dic and 'header_info_list' in config_dic['Order'] and config_dic['Order']['header_info_list']: + try: + self.header_info_field = json.loads(config_dic['Order']['header_info_list'])[0] + except Exception as err_: + self.logger.warning('Order._config_orderconfig_load() header_info_list failed with error: %s', err_) + + self.logger.debug('_config_header_info() ended') + def _config_user_load(self, config_dic: Dict[str, str]): """ load username """ self.logger.debug('CAhandler._config_user_load()') @@ -71,7 +83,7 @@ def _config_user_load(self, config_dic: Dict[str, str]): try: self.user = os.environ[config_dic['CAhandler']['user_variable']] except Exception as err: - self.logger.error('CAhandler._config_load() could not load user_variable:{0}'.format(err)) + self.logger.error('CAhandler._config_load() could not load user_variable:%s', err) if 'user' in config_dic['CAhandler']: if self.user: self.logger.info('CAhandler._config_load() overwrite user') @@ -87,7 +99,7 @@ def _config_password_load(self, config_dic: Dict[str, str]): try: self.password = os.environ[config_dic['CAhandler']['password_variable']] except Exception as err: - self.logger.error('CAhandler._config_load() could not load password_variable:{0}'.format(err)) + self.logger.error('CAhandler._config_load() could not load password_variable:%s', err) if 'password' in config_dic['CAhandler']: if self.password: self.logger.info('CAhandler._config_load() overwrite password') @@ -103,7 +115,7 @@ def _config_hostname_load(self, config_dic: Dict[str, str]): try: self.host = os.environ[config_dic['CAhandler']['host_variable']] except Exception as err: - self.logger.error('CAhandler._config_load() could not load host_variable:{0}'.format(err)) + self.logger.error('CAhandler._config_load() could not load host_variable:%s', err) if 'host' in config_dic['CAhandler']: if self.host: self.logger.info('CAhandler._config_load() overwrite host') @@ -144,7 +156,7 @@ def _config_proxy_load(self, config_dic: Dict[str, str]): proxy_server = proxy_check(self.logger, self.host, proxy_list) self.proxy = {'http': proxy_server, 'https': proxy_server} except Exception as err_: - self.logger.warning('CAhandler._config_load() proxy_server_list failed with error: {0}'.format(err_)) + self.logger.warning('CAhandler._config_load() proxy_server_list failed with error: %s', err_) self.logger.debug('CAhandler._config_proxy_load() ended') @@ -159,6 +171,7 @@ def _config_load(self): self._config_user_load(config_dic) self._config_password_load(config_dic) self._config_parameters_load(config_dic) + self._config_headerinfo_load(config_dic) # load proxy config self._config_proxy_load(config_dic) @@ -190,6 +203,27 @@ def _pkcs7_to_pem(self, pkcs7_content: str, outform: str = 'string') -> List[str self.logger.debug('Certificate._pkcs7_to_pem() ended') return result + def _template_name_get(self, csr: str) -> str: + """ get templaate from csr """ + self.logger.debug('CAhandler._template_name_get(%s)', csr) + template_name = None + + # parse profileid from http_header + header_info = header_info_get(self.logger, csr=csr) + if header_info: + try: + header_info_dic = json.loads(header_info[-1]['header_info']) + if self.header_info_field in header_info_dic: + for ele in header_info_dic[self.header_info_field].split(' '): + if 'template' in ele.lower(): + template_name = ele.split('=')[1] + break + except Exception as err: + self.logger.error('CAhandler._template_name_get() could not parse template: %s', err) + + self.logger.debug('CAhandler._template_name_get() ended with: %s', template_name) + return template_name + def _sancheck_lists_create(self, csr: str) -> Tuple[List[str], List[str]]: self.logger.debug('CAhandler.sancheck_lists_create()') @@ -290,11 +324,18 @@ def _entry_check(self, entry: str, regex: str, check_result: bool) -> bool: def enroll(self, csr: str) -> Tuple[str, str, str, bool]: """ enroll certificate from via MS certsrv """ - self.logger.debug('CAhandler.enroll({0})'.format(self.template)) + self.logger.debug('CAhandler.enroll(%s)', self.template) cert_bundle = None error = None cert_raw = None + + # lookup http header information from request + if self.header_info_field: + user_template = self._template_name_get(csr) + if user_template: + self.template = user_template + result = self._csr_check(csr) @@ -316,7 +357,7 @@ def enroll(self, csr: str) -> Tuple[str, str, str, bool]: # ca_pem = ca_pem.replace('\r\n', '\n') except Exception as err_: ca_pem = None - self.logger.error('ca_server.get_chain() failed with error: {0}'.format(err_)) + self.logger.error('ca_server.get_chain() failed with error: %s', err_) try: cert_raw = convert_byte_to_string(ca_server.get_cert(csr, self.template)) @@ -324,7 +365,7 @@ def enroll(self, csr: str) -> Tuple[str, str, str, bool]: cert_raw = cert_raw.replace('\r\n', '\n') except Exception as err_: cert_raw = None - self.logger.error('ca_server.get_cert() failed with error: {0}'.format(err_)) + self.logger.error('ca_server.get_cert() failed with error: %s', err_) # create bundle (error, cert_bundle, cert_raw) = self._cert_bundle_create(ca_pem, cert_raw) @@ -370,5 +411,5 @@ def trigger(self, _payload: str) -> Tuple[int, str, str]: cert_bundle = None cert_raw = None - self.logger.debug('CAhandler.trigger() ended with error: {0}'.format(error)) + self.logger.debug('CAhandler.trigger() ended with error: %s', error) return (error, cert_bundle, cert_raw) From a1043eb9eb867286023f0abf1ed485e4319c1e71 Mon Sep 17 00:00:00 2001 From: grindsa Date: Wed, 1 May 2024 19:25:32 +0200 Subject: [PATCH 193/460] [feat] allowe_domainlist in mscertsrv_ca_handler.py --- acme_srv/helper.py | 97 ++++++++++++ examples/ca_handler/mscertsrv_ca_handler.py | 157 ++++---------------- test/test_helper.py | 152 ++++++++++++++++++- test/test_msca_handler.py | 124 ++++++++++++++++ 4 files changed, 405 insertions(+), 125 deletions(-) diff --git a/acme_srv/helper.py b/acme_srv/helper.py index b6e7d0bc..0f8e53fc 100644 --- a/acme_srv/helper.py +++ b/acme_srv/helper.py @@ -1535,3 +1535,100 @@ def ipv6_chk(logger: logging.Logger, address: str) -> bool: logger.debug('ipv6_chk() ended with %s', result) return result + + +def domainlist_check(logger, entry: str, list_: List[str], toggle: bool = False) -> bool: + """ check string against list """ + logger.debug('domainlist_checkk(%s:%s)', entry, toggle) + logger.debug('check against list: {0}', list_) + + # default setting + check_result = False + + if entry: + if list_: + for regex in list_: + # check entry + check_result = domainlist_entry_check(logger, entry, regex, check_result) + else: + # empty list, flip parameter to make the check successful + check_result = True + + if toggle: + # toggle result if this is a blacklist + check_result = not check_result + + logger.debug('domainlist_check() ended with: %s', check_result) + return check_result + + +def domainlist_entry_check(logger, entry: str, regex: str, check_result: bool) -> bool: + """ check string against regex """ + logger.debug('domainlist_entry_check(%s/%s):', entry, regex) + + if regex.startswith('*.'): + regex = regex.replace('*.', '.') + regex_compiled = re.compile(regex) + + if bool(regex_compiled.search(entry)): + # parameter is in set flag accordingly and stop loop + check_result = True + + logger.debug('_entry_check() ended with: %s', check_result) + return check_result + + +def allowed_domainlist_check(logger: logging.Logger, csr, allowed_domain_list: List[str]) -> bool: + """ check if domain is in allowed domain list """ + logger.debug('allowed_domainlist_check(%s)') + + result = False + (san_list, check_list) = sancheck_lists_create(logger, csr) + + # go over the san list and check each entry + for san in san_list: + check_list.append(domainlist_check(logger, san, allowed_domain_list)) + + if check_list: + # cover a cornercase with empty checklist (no san, no cn) + if False in check_list: + result = False + else: + result = True + + logger.debug('allowed_domainlist_check() ended with: %s', result) + return result + + +def sancheck_lists_create(logger, csr: str) -> Tuple[List[str], List[str]]: + """ create lists for san check """ + logger.debug('CAhandler.sancheck_lists_create()') + + check_list = [] + san_list = [] + + # get sans and build a list + _san_list = csr_san_get(logger, csr) + + if _san_list: + for san in _san_list: + try: + # SAN list must be modified/filtered) + (_san_type, san_value) = san.lower().split(':') + san_list.append(san_value) + except Exception: + # force check to fail as something went wrong during parsing + check_list.append(False) + logger.debug('sancheck_lists_create(): san_list parsing failed at entry: $s', san) + + # get common name and attach it to san_list + cn = csr_cn_get(logger, csr) + + if cn: + cn = cn.lower() + if cn not in san_list: + # append cn to san_list + logger.debug('sancheck_lists_create()): append cn to san_list') + san_list.append(cn) + + return (san_list, check_list) diff --git a/examples/ca_handler/mscertsrv_ca_handler.py b/examples/ca_handler/mscertsrv_ca_handler.py index c2715893..0fd7b04b 100644 --- a/examples/ca_handler/mscertsrv_ca_handler.py +++ b/examples/ca_handler/mscertsrv_ca_handler.py @@ -9,9 +9,7 @@ from cryptography.hazmat.primitives.serialization.pkcs7 import load_pem_pkcs7_certificates, load_der_pkcs7_certificates # pylint: disable=e0401, e0611 from examples.ca_handler.certsrv import Certsrv - -from acme_srv.helper import load_config, b64_url_recode, convert_byte_to_string, proxy_check, convert_string_to_byte, csr_san_get, csr_cn_get, header_info_get # pylint: disable=e0401 - +from acme_srv.helper import load_config, b64_url_recode, convert_byte_to_string, proxy_check, convert_string_to_byte, header_info_get, allowed_domainlist_check # pylint: disable=e0401 class CAhandler(object): @@ -138,14 +136,11 @@ def _config_parameters_load(self, config_dic: Dict[str, str]): if 'krb5_config' in config_dic['CAhandler']: self.krb5_config = config_dic['CAhandler']['krb5_config'] - if 'allowed_domainlist' in config_dic['CAhandler']: try: self.allowed_domainlist = json.loads(config_dic['CAhandler']['allowed_domainlist']) except Exception as err: - self.logger.error('CAhandler._config_load(): failed to parse allowed_domainlist: {0}'.format(err)) - - + self.logger.error('CAhandler._config_load(): failed to parse allowed_domainlist: %s', err) self.logger.debug('CAhandler._config_parameters_load() ended') @@ -227,105 +222,7 @@ def _template_name_get(self, csr: str) -> str: self.logger.debug('CAhandler._template_name_get() ended with: %s', template_name) return template_name - - def _sancheck_lists_create(self, csr: str) -> Tuple[List[str], List[str]]: - self.logger.debug('CAhandler.sancheck_lists_create()') - - check_list = [] - san_list = [] - - # get sans and build a list - _san_list = csr_san_get(self.logger, csr) - - if _san_list: - for san in _san_list: - try: - # SAN list must be modified/filtered) - (_san_type, san_value) = san.lower().split(':') - san_list.append(san_value) - except Exception: - # force check to fail as something went wrong during parsing - check_list.append(False) - self.logger.debug('CAhandler._csr_check(): san_list parsing failed at entry: {0}'.format(san)) - - # get common name and attach it to san_list - cn_ = csr_cn_get(self.logger, csr) - - if cn_: - cn_ = cn_.lower() - if cn_ not in san_list: - # append cn to san_list - self.logger.debug('Ahandler._csr_check(): append cn to san_list') - san_list.append(cn_) - - return (san_list, check_list) - - def _csr_check(self, csr: str) -> bool: - """ check CSR against definied whitelists """ - self.logger.debug('CAhandler._csr_check()') - - if self.allowed_domainlist: - - result = False - - (san_list, check_list) = self._sancheck_lists_create(csr) - - # go over the san list and check each entry - for san in san_list: - check_list.append(self._list_check(san, self.allowed_domainlist)) - - if check_list: - # cover a cornercase with empty checklist (no san, no cn) - if False in check_list: - result = False - else: - result = True - else: - result = True - - self.logger.debug('CAhandler._csr_check() ended with: {0}'.format(result)) - return result - - def _list_check(self, entry: str, list_: List[str], toggle: bool = False) -> bool: - """ check string against list """ - self.logger.debug('CAhandler._list_check({0}:{1})'.format(entry, toggle)) - self.logger.debug('check against list: {0}'.format(list_)) - - # default setting - check_result = False - - if entry: - if list_: - for regex in list_: - # check entry - check_result = self._entry_check(entry, regex, check_result) - else: - # empty list, flip parameter to make the check successful - check_result = True - - if toggle: - # toggle result if this is a blacklist - check_result = not check_result - - self.logger.debug('CAhandler._list_check() ended with: {0}'.format(check_result)) - return check_result - - def _entry_check(self, entry: str, regex: str, check_result: bool) -> bool: - """ check string against regex """ - self.logger.debug('_entry_check({0}/{1}):'.format(entry, regex)) - - if regex.startswith('*.'): - regex = regex.replace('*.', '.') - regex_compiled = re.compile(regex) - - if bool(regex_compiled.search(entry)): - # parameter is in set flag accordingly and stop loop - check_result = True - - self.logger.debug('_entry_check() ended with: {0}'.format(check_result)) - return check_result - - def _csr_process(self, ca_server, csr: str) -> Tuple[str, str, str]: + def _csr_process(self, ca_server, csr: str) -> Tuple[str, str, str]: # recode csr csr = textwrap.fill(b64_url_recode(self.logger, csr), 64) + '\n' @@ -353,13 +250,8 @@ def _csr_process(self, ca_server, csr: str) -> Tuple[str, str, str]: return (error, cert_bundle, cert_raw) - def enroll(self, csr: str) -> Tuple[str, str, str, bool]: - """ enroll certificate from via MS certsrv """ - self.logger.debug('CAhandler.enroll(%s)', self.template) - cert_bundle = None - error = None - cert_raw = None - + def _parameter_overwrite(self, csr: str): + """ overwrite overwrite krb5.conf or user-template """ if self.krb5_config: self.logger.info('CAhandler.enroll(): load krb5config from %s', self.krb5_config) os.environ['KRB5_CONFIG'] = self.krb5_config @@ -370,24 +262,41 @@ def enroll(self, csr: str) -> Tuple[str, str, str, bool]: if user_template: self.template = user_template - result = self._csr_check(csr) + def enroll(self, csr: str) -> Tuple[str, str, str, bool]: + """ enroll certificate from via MS certsrv """ + self.logger.debug('CAhandler.enroll(%s)', self.template) + cert_bundle = None + error = None + cert_raw = None + + self._parameter_overwrite(csr) + if self.host and self.user and self.password and self.template: - if self.host and self.user and self.password and self.template and result: - # setup certserv - ca_server = Certsrv(self.host, self.user, self.password, self.auth_method, self.ca_bundle, proxies=self.proxy) + if self.allowed_domainlist: + # check sans / cn against list of allowed comains from config + result = allowed_domainlist_check(self.logger, csr, self.allowed_domainlist) + else: + result = True + + if result: + # setup certserv + ca_server = Certsrv(self.host, self.user, self.password, self.auth_method, self.ca_bundle, proxies=self.proxy) - # check connection and credentials - auth_check = self._check_credentials(ca_server) + # check connection and credentials + auth_check = self._check_credentials(ca_server) - if auth_check: + if auth_check: - # enroll certificate - (error, cert_bundle, cert_raw) = self._csr_process(ca_server, csr) + # enroll certificate + (error, cert_bundle, cert_raw) = self._csr_process(ca_server, csr) + else: + self.logger.error('Connection or Credentialcheck failed') + error = 'Connection or Credentialcheck failed.' else: - self.logger.error('Connection or Credentialcheck failed') - error = 'Connection or Credentialcheck failed.' + self.logger.error('SAN/CN check failed') + error = 'SAN/CN check failed' else: self.logger.error('Config incomplete') error = 'Config incomplete' diff --git a/test/test_helper.py b/test/test_helper.py index 2770d2eb..469f3c29 100644 --- a/test/test_helper.py +++ b/test/test_helper.py @@ -26,7 +26,7 @@ def setUp(self): """ setup unittest """ import logging logging.basicConfig(level=logging.CRITICAL) - from acme_srv.helper import b64decode_pad, b64_decode, b64_encode, b64_url_encode, b64_url_recode, convert_string_to_byte, convert_byte_to_string, decode_message, decode_deserialize, get_url, generate_random_string, signature_check, validate_email, uts_to_date_utc, date_to_uts_utc, load_config, cert_serial_get, cert_san_get, cert_san_pyopenssl_get, cert_dates_get, build_pem_file, date_to_datestr, datestr_to_date, dkeys_lower, csr_cn_get, cert_pubkey_get, csr_pubkey_get, url_get, url_get_with_own_dns, dns_server_list_load, csr_san_get, csr_san_byte_get, csr_extensions_get, fqdn_resolve, fqdn_in_san_check, sha256_hash, sha256_hash_hex, cert_der2pem, cert_pem2der, cert_extensions_get, csr_dn_get, logger_setup, logger_info, print_debug, jwk_thumbprint_get, allowed_gai_family, patched_create_connection, validate_csr, servercert_get, txt_get, proxystring_convert, proxy_check, handle_exception, ca_handler_load, eab_handler_load, hooks_load, error_dic_get, _logger_nonce_modify, _logger_certificate_modify, _logger_token_modify, _logger_challenges_modify, config_check, cert_issuer_get, cert_cn_get, string_sanitize, pembundle_to_list, certid_asn1_get, certid_check, certid_hex_get, v6_adjust, ipv6_chk, ip_validate, header_info_get, encode_url, uts_now, cert_ski_get, cert_ski_pyopenssl_get, cert_aki_get, cert_aki_pyopenssl_get, validate_fqdn, validate_ip, validate_identifier, header_info_field_validate, header_info_lookup, config_eab_profile_load, config_headerinfo_load + from acme_srv.helper import b64decode_pad, b64_decode, b64_encode, b64_url_encode, b64_url_recode, convert_string_to_byte, convert_byte_to_string, decode_message, decode_deserialize, get_url, generate_random_string, signature_check, validate_email, uts_to_date_utc, date_to_uts_utc, load_config, cert_serial_get, cert_san_get, cert_san_pyopenssl_get, cert_dates_get, build_pem_file, date_to_datestr, datestr_to_date, dkeys_lower, csr_cn_get, cert_pubkey_get, csr_pubkey_get, url_get, url_get_with_own_dns, dns_server_list_load, csr_san_get, csr_san_byte_get, csr_extensions_get, fqdn_resolve, fqdn_in_san_check, sha256_hash, sha256_hash_hex, cert_der2pem, cert_pem2der, cert_extensions_get, csr_dn_get, logger_setup, logger_info, print_debug, jwk_thumbprint_get, allowed_gai_family, patched_create_connection, validate_csr, servercert_get, txt_get, proxystring_convert, proxy_check, handle_exception, ca_handler_load, eab_handler_load, hooks_load, error_dic_get, _logger_nonce_modify, _logger_certificate_modify, _logger_token_modify, _logger_challenges_modify, config_check, cert_issuer_get, cert_cn_get, string_sanitize, pembundle_to_list, certid_asn1_get, certid_check, certid_hex_get, v6_adjust, ipv6_chk, ip_validate, header_info_get, encode_url, uts_now, cert_ski_get, cert_ski_pyopenssl_get, cert_aki_get, cert_aki_pyopenssl_get, validate_fqdn, validate_ip, validate_identifier, header_info_field_validate, header_info_lookup, config_eab_profile_load, config_headerinfo_load, domainlist_check, allowed_domainlist_check self.logger = logging.getLogger('test_a2c') self.allowed_gai_family = allowed_gai_family self.b64_decode = b64_decode @@ -114,6 +114,8 @@ def setUp(self): self.ip_validate = ip_validate self.config_headerinfo_load = config_headerinfo_load self.config_eab_profile_load = config_eab_profile_load + self.domainlist_check = domainlist_check + self.allowed_domainlist_check = allowed_domainlist_check def test_001_helper_b64decode_pad(self): """ test b64decode_pad() method with a regular base64 encoded string """ @@ -2447,5 +2449,153 @@ def test_322_config_eab_profile_load(self, mock_eabload): self.assertEqual((False, None), self.config_eab_profile_load(self.logger, config_dic)) self.assertFalse(mock_eabload.called) + def test_062_domainlist_check(self): + """ domainlist_check failed check as empty entry""" + list_ = ['bar.foo$', 'foo.bar$'] + entry = None + self.assertFalse(self.domainlist_check(self.logger, entry, list_)) + + def test_063_domainlist_check(self): + """ domainlist_check check against empty list""" + list_ = [] + entry = 'host.bar.foo' + self.assertTrue(self.domainlist_check(self.logger, entry, list_)) + + def test_064_domainlist_check(self): + """ domainlist_check successful check against 1st element of a list""" + list_ = ['bar.foo$', 'foo.bar$'] + entry = 'host.bar.foo' + self.assertTrue(self.domainlist_check(self.logger, entry, list_)) + + def test_065_domainlist_check(self): + """ domainlist_check unsuccessful as endcheck failed""" + list_ = ['bar.foo$', 'foo.bar$'] + entry = 'host.bar.foo.bar_' + self.assertFalse(self.domainlist_check(self.logger, entry, list_)) + + def test_066_domainlist_check(self): + """ domainlist_check successful without $""" + list_ = ['bar.foo', 'foo.bar$'] + entry = 'host.bar.foo.bar_' + self.assertTrue(self.domainlist_check(self.logger, entry, list_)) + + def test_067_domainlist_check(self): + """ domainlist_check wildcard check""" + list_ = ['bar.foo$', 'foo.bar$'] + entry = '*.bar.foo' + self.assertTrue(self.domainlist_check(self.logger, entry, list_)) + + def test_068_domainlist_check(self): + """ domainlist_check failed wildcard check""" + list_ = ['bar.foo$', 'foo.bar$'] + entry = '*.bar.foo_' + self.assertFalse(self.domainlist_check(self.logger, entry, list_)) + + def test_069_domainlist_check(self): + """ domainlist_check not end check""" + list_ = ['bar.foo$', 'foo.bar$'] + entry = 'bar.foo gna' + self.assertFalse(self.domainlist_check(self.logger, entry, list_)) + + def test_070_domainlist_check(self): + """ domainlist_check $ at the end""" + list_ = ['bar.foo$', 'foo.bar$'] + entry = 'bar.foo$' + self.assertFalse(self.domainlist_check(self.logger, entry, list_)) + + def test_071_domainlist_check(self): + """ domainlist_check check against empty list flip""" + list_ = [] + entry = 'host.bar.foo' + self.assertFalse(self.domainlist_check(self.logger, entry, list_, True)) + + def test_072_domainlist_check(self): + """ domainlist_check flip successful check """ + list_ = ['bar.foo$', 'foo.bar$'] + entry = 'host.bar.foo' + self.assertFalse(self.domainlist_check(self.logger, entry, list_, True)) + + def test_073_domainlist_check(self): + """ domainlist_check flip unsuccessful check""" + list_ = ['bar.foo$', 'foo.bar$'] + entry = 'host.bar.foo' + self.assertFalse(self.domainlist_check(self.logger, entry, list_, True)) + + def test_074_domainlist_check(self): + """ domainlist_check unsuccessful whildcard check""" + list_ = ['foo.bar$', r'\*.bar.foo'] + entry = 'host.bar.foo' + self.assertFalse(self.domainlist_check(self.logger, entry, list_)) + + def test_075_domainlist_check(self): + """ domainlist_check successful whildcard check""" + list_ = ['foo.bar$', r'\*.bar.foo'] + entry = '*.bar.foo' + self.assertTrue(self.domainlist_check(self.logger, entry, list_)) + + def test_076_domainlist_check(self): + """ domainlist_check successful whildcard in list but not in string """ + list_ = ['foo.bar$', '*.bar.foo'] + entry = 'foo.bar.foo' + self.assertTrue(self.domainlist_check(self.logger, entry, list_)) + + @patch('acme_srv.helper.csr_cn_get') + @patch('acme_srv.helper.csr_san_get') + def test_077_allowed_domainlist_check(self, mock_san, mock_cn): + """ CAhandler._check_csr with empty allowed_domainlist """ + allowed_domainlist = [] + mock_san.return_value = ['DNS:host.foo.bar'] + mock_cn.return_value = 'host2.foo.bar' + csr = 'csr' + self.assertTrue(self.allowed_domainlist_check(self.logger, csr, allowed_domainlist)) + + @patch('acme_srv.helper.domainlist_check') + @patch('acme_srv.helper.csr_cn_get') + @patch('acme_srv.helper.csr_san_get') + def test_078_allowed_domainlist_check(self, mock_san, mock_cn, mock_lcheck): + """ CAhandler._check_csr with list and failed check """ + allowed_domainlist = ['foo.bar'] + mock_san.return_value = ['DNS:host.foo.bar'] + mock_cn.return_value = 'host2.foo.bar' + mock_lcheck.side_effect = [True, False] + csr = 'csr' + self.assertFalse(self.allowed_domainlist_check(self.logger, csr, allowed_domainlist)) + + @patch('acme_srv.helper.domainlist_check') + @patch('acme_srv.helper.csr_cn_get') + @patch('acme_srv.helper.csr_san_get') + def test_079_allowed_domainlist_check(self, mock_san, mock_cn, mock_lcheck): + """ CAhandler._check_csr with list and successful check """ + allowed_domainlist = ['foo.bar'] + mock_san.return_value = ['DNS:host.foo.bar'] + mock_cn.return_value = 'host2.foo.bar' + mock_lcheck.side_effect = [True, True] + csr = 'csr' + self.assertTrue(self.allowed_domainlist_check(self.logger, csr, allowed_domainlist)) + + @patch('acme_srv.helper.domainlist_check') + @patch('acme_srv.helper.csr_cn_get') + @patch('acme_srv.helper.csr_san_get') + def test_080_allowed_domainlist_check(self, mock_san, mock_cn, mock_lcheck): + """ CAhandler._check_csr san parsing failed """ + allowed_domainlist = ['foo.bar'] + mock_san.return_value = ['host.google.com'] + mock_cn.return_value = 'host2.foo.bar' + mock_lcheck.side_effect = [True, True] + csr = 'csr' + self.assertFalse(self.allowed_domainlist_check(self.logger, csr, allowed_domainlist)) + + @patch('acme_srv.helper.csr_cn_get') + @patch('acme_srv.helper.csr_san_get') + def test_081_allowed_domainlist_check(self, mock_san, mock_cn): + """ CAhandler._check_csr san parsing failed """ + allowed_domainlist = ['foo.bar'] + mock_san.return_value = [] + mock_cn.return_value = None + csr = 'csr' + self.assertFalse(self.allowed_domainlist_check(self.logger, csr, allowed_domainlist)) + + + if __name__ == '__main__': unittest.main() diff --git a/test/test_msca_handler.py b/test/test_msca_handler.py index f185f9f2..a52b0c7a 100644 --- a/test/test_msca_handler.py +++ b/test/test_msca_handler.py @@ -76,6 +76,7 @@ def test_007_config_load(self, mock_load_cfg): self.assertFalse(self.cahandler.ca_bundle) self.assertFalse(self.cahandler.template) self.assertFalse(self.cahandler.krb5_config) + self.assertFalse,(self.cahandler.allowed_domainlist) @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_008_config_load(self, mock_load_cfg): @@ -89,6 +90,7 @@ def test_008_config_load(self, mock_load_cfg): self.assertFalse(self.cahandler.ca_bundle) self.assertFalse(self.cahandler.template) self.assertFalse(self.cahandler.krb5_config) + self.assertFalse,(self.cahandler.allowed_domainlist) @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_009_config_load(self, mock_load_cfg): @@ -102,6 +104,7 @@ def test_009_config_load(self, mock_load_cfg): self.assertFalse(self.cahandler.ca_bundle) self.assertFalse(self.cahandler.template) self.assertFalse(self.cahandler.krb5_config) + self.assertFalse,(self.cahandler.allowed_domainlist) @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_010_config_load(self, mock_load_cfg): @@ -115,6 +118,7 @@ def test_010_config_load(self, mock_load_cfg): self.assertFalse(self.cahandler.ca_bundle) self.assertFalse(self.cahandler.template) self.assertFalse(self.cahandler.krb5_config) + self.assertFalse,(self.cahandler.allowed_domainlist) @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_011_config_load(self, mock_load_cfg): @@ -128,6 +132,7 @@ def test_011_config_load(self, mock_load_cfg): self.assertFalse(self.cahandler.ca_bundle) self.assertFalse(self.cahandler.template) self.assertFalse(self.cahandler.krb5_config) + self.assertFalse,(self.cahandler.allowed_domainlist) @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_012_config_load(self, mock_load_cfg): @@ -141,6 +146,7 @@ def test_012_config_load(self, mock_load_cfg): self.assertFalse(self.cahandler.ca_bundle) self.assertFalse(self.cahandler.template) self.assertFalse(self.cahandler.krb5_config) + self.assertFalse,(self.cahandler.allowed_domainlist) @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_013_config_load(self, mock_load_cfg): @@ -154,6 +160,7 @@ def test_013_config_load(self, mock_load_cfg): self.assertFalse(self.cahandler.ca_bundle) self.assertFalse(self.cahandler.template) self.assertFalse(self.cahandler.krb5_config) + self.assertFalse,(self.cahandler.allowed_domainlist) @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_014_config_load(self, mock_load_cfg): @@ -167,6 +174,7 @@ def test_014_config_load(self, mock_load_cfg): self.assertFalse(self.cahandler.ca_bundle) self.assertFalse(self.cahandler.template) self.assertFalse(self.cahandler.krb5_config) + self.assertFalse,(self.cahandler.allowed_domainlist) @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_015_config_load(self, mock_load_cfg): @@ -180,6 +188,7 @@ def test_015_config_load(self, mock_load_cfg): self.assertEqual('ca_bundle', self.cahandler.ca_bundle) self.assertFalse(self.cahandler.template) self.assertFalse(self.cahandler.krb5_config) + self.assertFalse,(self.cahandler.allowed_domainlist) @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_016_config_load(self, mock_load_cfg): @@ -193,6 +202,7 @@ def test_016_config_load(self, mock_load_cfg): self.assertFalse(self.cahandler.ca_bundle) self.assertEqual('template', self.cahandler.template) self.assertFalse(self.cahandler.krb5_config) + self.assertFalse,(self.cahandler.allowed_domainlist) @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_017_config_load(self, mock_load_cfg): @@ -206,6 +216,7 @@ def test_017_config_load(self, mock_load_cfg): self.assertFalse(self.cahandler.ca_bundle) self.assertFalse(self.cahandler.template) self.assertEqual('krb5_config', self.cahandler.krb5_config) + self.assertFalse,(self.cahandler.allowed_domainlist) @patch.dict('os.environ', {'host_variable': 'host'}) @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') @@ -280,6 +291,7 @@ def test_025_config_load(self, mock_load_cfg): self.cahandler._config_load() self.assertFalse(self.cahandler.password) self.assertIn("ERROR:test_a2c:CAhandler._config_load() could not load password_variable:'doesnotexist'", lcm.output) + self.assertFalse,(self.cahandler.allowed_domainlist) @patch.dict('os.environ', {'password_variable': 'password'}) @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') @@ -290,6 +302,7 @@ def test_026_config_load(self, mock_load_cfg): self.cahandler._config_load() self.assertEqual('password_local', self.cahandler.password) self.assertIn('INFO:test_a2c:CAhandler._config_load() overwrite password', lcm.output) + self.assertFalse,(self.cahandler.allowed_domainlist) @patch('examples.ca_handler.mscertsrv_ca_handler.proxy_check') @patch('json.loads') @@ -303,6 +316,7 @@ def test_027_config_load(self, mock_load_cfg, mock_json, mock_chk): self.assertTrue(mock_json.called) self.assertTrue(mock_chk.called) self.assertEqual({'http': 'proxy.bar.local', 'https': 'proxy.bar.local'},self.cahandler.proxy ) + self.assertFalse,(self.cahandler.allowed_domainlist) @patch('examples.ca_handler.mscertsrv_ca_handler.proxy_check') @patch('json.loads') @@ -318,6 +332,37 @@ def test_028_config_load(self, mock_load_cfg, mock_json, mock_chk): self.assertFalse(mock_chk.called) self.assertFalse(self.cahandler.proxy ) self.assertIn('WARNING:test_a2c:CAhandler._config_load() proxy_server_list failed with error: exc_load_config', lcm.output) + self.assertFalse,(self.cahandler.allowed_domainlist) + + @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') + def test_029_config_load(self, mock_load_cfg): + """ allowd_domain_list """ + mock_load_cfg.return_value = {'CAhandler': {'allowed_domainlist': '["allowed_domainlist"]'}} + self.cahandler._config_load() + self.assertFalse(self.cahandler.host) + self.assertFalse(self.cahandler.user) + self.assertFalse(self.cahandler.password) + self.assertEqual('basic', self.cahandler.auth_method) + self.assertFalse(self.cahandler.ca_bundle) + self.assertFalse(self.cahandler.template) + self.assertFalse(self.cahandler.krb5_config) + self.assertEqual(['allowed_domainlist'], self.cahandler.allowed_domainlist) + + @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') + def test_030_config_load(self, mock_load_cfg): + """ allowd_domain_list """ + mock_load_cfg.return_value = {'CAhandler': {'allowed_domainlist': 'wrongstring'}} + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.cahandler._config_load() + self.assertFalse(self.cahandler.host) + self.assertFalse(self.cahandler.user) + self.assertFalse(self.cahandler.password) + self.assertEqual('basic', self.cahandler.auth_method) + self.assertFalse(self.cahandler.ca_bundle) + self.assertFalse(self.cahandler.template) + self.assertFalse(self.cahandler.krb5_config) + self.assertFalse,(self.cahandler.allowed_domainlist) + self.assertIn('ERROR:test_a2c:CAhandler._config_load(): failed to parse allowed_domainlist: Expecting value: line 1 column 1 (char 0)', lcm.output) def test_029_revoke(self): """ test revocation """ @@ -407,6 +452,85 @@ def test_040_enroll(self, mock_certserver, mock_credchk, mockwrap, mock_b2s, moc self.assertEqual((None, 'get_certp2p', 'get_cert', None), self.cahandler.enroll('csr')) self.assertFalse(mock_tmpl.called) + @patch('examples.ca_handler.mscertsrv_ca_handler.allowed_domainlist_check') + @patch('examples.ca_handler.mscertsrv_ca_handler.CAhandler._template_name_get') + @patch('examples.ca_handler.mscertsrv_ca_handler.CAhandler._pkcs7_to_pem') + @patch('examples.ca_handler.mscertsrv_ca_handler.convert_byte_to_string') + @patch('textwrap.fill') + @patch('examples.ca_handler.mscertsrv_ca_handler.CAhandler._check_credentials') + @patch('examples.ca_handler.mscertsrv_ca_handler.Certsrv') + def test_140_enroll(self, mock_certserver, mock_credchk, mockwrap, mock_b2s, mock_p2p, mock_tmpl, mock_adc): + """ enroll enroll successful """ + self.cahandler.host = 'host' + self.cahandler.user = 'user' + self.cahandler.password = 'password' + self.cahandler.template = 'template' + mockresponse = MagicMock() + mockresponse.get_chain.return_value = "get_chain" + mockresponse.get_cert.return_value = "get_cert" + mock_certserver = mockresponse + mock_credchk.return_value = True + mockwrap.return_value = 'mockwrap' + mock_b2s.side_effect = ['get_chain', 'get_cert'] + mock_p2p.return_value = 'p2p' + self.assertEqual((None, 'get_certp2p', 'get_cert', None), self.cahandler.enroll('csr')) + self.assertFalse(mock_tmpl.called) + self.assertFalse(mock_adc.called) + + @patch('examples.ca_handler.mscertsrv_ca_handler.allowed_domainlist_check') + @patch('examples.ca_handler.mscertsrv_ca_handler.CAhandler._template_name_get') + @patch('examples.ca_handler.mscertsrv_ca_handler.CAhandler._pkcs7_to_pem') + @patch('examples.ca_handler.mscertsrv_ca_handler.convert_byte_to_string') + @patch('textwrap.fill') + @patch('examples.ca_handler.mscertsrv_ca_handler.CAhandler._check_credentials') + @patch('examples.ca_handler.mscertsrv_ca_handler.Certsrv') + def test_141_enroll(self, mock_certserver, mock_credchk, mockwrap, mock_b2s, mock_p2p, mock_tmpl, mock_adc): + """ enroll enroll successful """ + self.cahandler.host = 'host' + self.cahandler.user = 'user' + self.cahandler.password = 'password' + self.cahandler.template = 'template' + self.cahandler.allowed_domainlist = ['allowed_domainlist'] + mockresponse = MagicMock() + mockresponse.get_chain.return_value = "get_chain" + mockresponse.get_cert.return_value = "get_cert" + mock_adc.return_value = True + mock_certserver = mockresponse + mock_credchk.return_value = True + mockwrap.return_value = 'mockwrap' + mock_b2s.side_effect = ['get_chain', 'get_cert'] + mock_p2p.return_value = 'p2p' + self.assertEqual((None, 'get_certp2p', 'get_cert', None), self.cahandler.enroll('csr')) + self.assertFalse(mock_tmpl.called) + self.assertTrue(mock_adc.called) + + @patch('examples.ca_handler.mscertsrv_ca_handler.allowed_domainlist_check') + @patch('examples.ca_handler.mscertsrv_ca_handler.CAhandler._template_name_get') + @patch('examples.ca_handler.mscertsrv_ca_handler.CAhandler._pkcs7_to_pem') + @patch('examples.ca_handler.mscertsrv_ca_handler.convert_byte_to_string') + @patch('textwrap.fill') + @patch('examples.ca_handler.mscertsrv_ca_handler.CAhandler._check_credentials') + @patch('examples.ca_handler.mscertsrv_ca_handler.Certsrv') + def test_142_enroll(self, mock_certserver, mock_credchk, mockwrap, mock_b2s, mock_p2p, mock_tmpl, mock_adc): + """ enroll enroll successful """ + self.cahandler.host = 'host' + self.cahandler.user = 'user' + self.cahandler.password = 'password' + self.cahandler.template = 'template' + self.cahandler.allowed_domainlist = ['allowed_domainlist'] + mockresponse = MagicMock() + mockresponse.get_chain.return_value = "get_chain" + mockresponse.get_cert.return_value = "get_cert" + mock_adc.return_value = False + mock_certserver = mockresponse + mock_credchk.return_value = True + mockwrap.return_value = 'mockwrap' + mock_b2s.side_effect = ['get_chain', 'get_cert'] + mock_p2p.return_value = 'p2p' + self.assertEqual(('SAN/CN check failed', None, None, None), self.cahandler.enroll('csr')) + self.assertFalse(mock_tmpl.called) + self.assertTrue(mock_adc.called) + @patch('examples.ca_handler.mscertsrv_ca_handler.CAhandler._template_name_get') @patch('examples.ca_handler.mscertsrv_ca_handler.CAhandler._pkcs7_to_pem') @patch('examples.ca_handler.mscertsrv_ca_handler.convert_byte_to_string') From 4a40ff42b43c65db55c38c16a101f1699ec0190d Mon Sep 17 00:00:00 2001 From: grindsa Date: Wed, 1 May 2024 19:26:02 +0200 Subject: [PATCH 194/460] [fix] refactor acme_ca_handler.py to avoid code duplications --- examples/ca_handler/acme_ca_handler.py | 105 +----------- test/test_acme_ca_handler.py | 216 +++++-------------------- 2 files changed, 50 insertions(+), 271 deletions(-) diff --git a/examples/ca_handler/acme_ca_handler.py b/examples/ca_handler/acme_ca_handler.py index 42c45846..34459a70 100644 --- a/examples/ca_handler/acme_ca_handler.py +++ b/examples/ca_handler/acme_ca_handler.py @@ -15,7 +15,7 @@ from cryptography.hazmat.backends import default_backend from acme import client, messages from acme_srv.db_handler import DBstore -from acme_srv.helper import load_config, b64_url_recode, csr_cn_get, csr_san_get, parse_url +from acme_srv.helper import load_config, b64_url_recode, csr_cn_get, csr_san_get, parse_url, allowed_domainlist_check """ Config file section: @@ -140,103 +140,6 @@ def _challenge_store(self, challenge_name: str, challenge_content: str): # store challenge into db self.dbstore.cahandler_add(data_dic) - def _sancheck_lists_create(self, csr: str) -> Tuple[List[str], List[str]]: - self.logger.debug('CAhandler.sancheck_lists_create()') - - check_list = [] - san_list = [] - - # get sans and build a list - _san_list = csr_san_get(self.logger, csr) - - if _san_list: - for san in _san_list: - try: - # SAN list must be modified/filtered) - (_san_type, san_value) = san.lower().split(':') - san_list.append(san_value) - except Exception: - # force check to fail as something went wrong during parsing - check_list.append(False) - self.logger.debug('CAhandler._csr_check(): san_list parsing failed at entry: %s', san) - - # get common name and attach it to san_list - cn_ = csr_cn_get(self.logger, csr) - - if cn_: - cn_ = cn_.lower() - if cn_ not in san_list: - # append cn to san_list - self.logger.debug('Ahandler._csr_check(): append cn to san_list') - san_list.append(cn_) - - return (san_list, check_list) - - def _csr_check(self, csr: str) -> bool: - """ check CSR against definied whitelists """ - self.logger.debug('CAhandler._csr_check()') - - if self.allowed_domainlist: - - result = False - - (san_list, check_list) = self._sancheck_lists_create(csr) - - # go over the san list and check each entry - for san in san_list: - check_list.append(self._list_check(san, self.allowed_domainlist)) - - if check_list: - # cover a cornercase with empty checklist (no san, no cn) - if False in check_list: - result = False - else: - result = True - else: - result = True - - self.logger.debug('CAhandler._csr_check() ended with: %s', result) - return result - - def _entry_check(self, entry: str, regex: str, check_result: bool) -> bool: - """ check string against regex """ - self.logger.debug('_entry_check(%s/%s):', entry, regex) - - if regex.startswith('*.'): - regex = regex.replace('*.', '.') - regex_compiled = re.compile(regex) - - if bool(regex_compiled.search(entry)): - # parameter is in set flag accordingly and stop loop - check_result = True - - self.logger.debug('_entry_check() ended with: %s', format(check_result)) - return check_result - - def _list_check(self, entry: str, list_: List[str], toggle: bool = False) -> bool: - """ check string against list """ - self.logger.debug('CAhandler._list_check(%s:%s)', entry, toggle) - self.logger.debug('check against list: %s', list_) - - # default setting - check_result = False - - if entry: - if list_: - for regex in list_: - # check entry - check_result = self._entry_check(entry, regex, check_result) - else: - # empty list, flip parameter to make the check successful - check_result = True - - if toggle: - # toggle result if this is a blacklist - check_result = not check_result - - self.logger.debug('CAhandler._list_check() ended with: %s', check_result) - return check_result - def _challenge_info(self, authzr: messages.AuthorizationResource, user_key: josepy.jwk.JWKRSA): """ filter challenges and get challenge details """ self.logger.debug('CAhandler._challenge_info()') @@ -446,7 +349,11 @@ def enroll(self, csr: str) -> Tuple[str, str, str, str]: user_key = None # check CN and SAN against black/whitlist - result = self._csr_check(csr) + if self.allowed_domainlist: + # check sans / cn against list of allowed comains from config + result = allowed_domainlist_check(self.logger, csr, self.allowed_domainlist) + else: + result = True if result: try: diff --git a/test/test_acme_ca_handler.py b/test/test_acme_ca_handler.py index d62fe522..79529fcb 100644 --- a/test/test_acme_ca_handler.py +++ b/test/test_acme_ca_handler.py @@ -643,7 +643,7 @@ def test_046_enroll(self, mock_messages, mock_clientnw, mock_c2o, mock_ach, mock self.assertTrue(mock_ach.called) self.assertTrue(mock_reg.called) - @patch('examples.ca_handler.acme_ca_handler.CAhandler._csr_check') + @patch('examples.ca_handler.acme_ca_handler.allowed_domainlist_check') @patch('OpenSSL.crypto.load_certificate') @patch('OpenSSL.crypto.dump_certificate') @patch('examples.ca_handler.acme_ca_handler.CAhandler._challenge_store') @@ -680,7 +680,7 @@ def test_047_enroll(self, mock_messages, mock_clientnw, mock_c2o, mock_ach, mock self.assertTrue(mock_ach.called) self.assertTrue(mock_reg.called) - @patch('examples.ca_handler.acme_ca_handler.CAhandler._csr_check') + @patch('examples.ca_handler.acme_ca_handler.allowed_domainlist_check') @patch('OpenSSL.crypto.load_certificate') @patch('OpenSSL.crypto.dump_certificate') @patch('examples.ca_handler.acme_ca_handler.CAhandler._challenge_store') @@ -719,7 +719,7 @@ def test_048_enroll(self, mock_messages, mock_clientnw, mock_c2o, mock_ach, mock self.assertTrue(mock_reg.called) self.assertIn('ERROR:test_a2c:CAhandler.enroll: Bad ACME account: error', lcm.output) - @patch('examples.ca_handler.acme_ca_handler.CAhandler._csr_check') + @patch('examples.ca_handler.acme_ca_handler.allowed_domainlist_check') @patch('OpenSSL.crypto.load_certificate') @patch('OpenSSL.crypto.dump_certificate') @patch('examples.ca_handler.acme_ca_handler.CAhandler._challenge_store') @@ -758,7 +758,7 @@ def test_049_enroll(self, mock_messages, mock_clientnw, mock_c2o, mock_ach, mock self.assertTrue(mock_ach.called) self.assertTrue(mock_reg.called) - @patch('examples.ca_handler.acme_ca_handler.CAhandler._csr_check') + @patch('examples.ca_handler.acme_ca_handler.allowed_domainlist_check') @patch('acme.client.ClientV2.query_registration') @patch('acme.client.ClientNetwork') @patch('examples.ca_handler.acme_ca_handler.CAhandler._account_register') @@ -776,7 +776,7 @@ def test_050_enroll(self, mock_key, mock_store, mock_reg, mock_nw, mock_newreg, self.assertFalse(mock_reg.called) self.assertFalse(mock_newreg.called) - @patch('examples.ca_handler.acme_ca_handler.CAhandler._csr_check') + @patch('examples.ca_handler.acme_ca_handler.allowed_domainlist_check') @patch('acme.client.ClientV2.query_registration') @patch('acme.client.ClientNetwork') @patch('examples.ca_handler.acme_ca_handler.CAhandler._account_register') @@ -785,6 +785,7 @@ def test_050_enroll(self, mock_key, mock_store, mock_reg, mock_nw, mock_newreg, def test_051_enroll(self, mock_key, mock_store, mock_reg, mock_nw, mock_newreg, mock_csrchk): """ test enroll exception during enrollment """ mock_csrchk.return_value = False + self.cahandler.allowed_domainlist = ['allowed_domain'] mock_key.side_effect = Exception('ex_user_key_load') with self.assertLogs('test_a2c', level='INFO') as lcm: self.assertEqual(('CSR rejected. Either CN or SANs are not allowed by policy', None, None, None), self.cahandler.enroll('csr')) @@ -794,9 +795,27 @@ def test_051_enroll(self, mock_key, mock_store, mock_reg, mock_nw, mock_newreg, self.assertFalse(mock_reg.called) self.assertFalse(mock_newreg.called) + @patch('examples.ca_handler.acme_ca_handler.allowed_domainlist_check') + @patch('acme.client.ClientV2.query_registration') + @patch('acme.client.ClientNetwork') + @patch('examples.ca_handler.acme_ca_handler.CAhandler._account_register') + @patch('examples.ca_handler.acme_ca_handler.CAhandler._challenge_store') + @patch('examples.ca_handler.acme_ca_handler.CAhandler._user_key_load') + def test_052_enroll(self, mock_key, mock_store, mock_reg, mock_nw, mock_newreg, mock_csrchk): + """ test enroll exception during enrollment """ + mock_csrchk.return_value = False + self.cahandler.allowed_domainlist = ['allowed_domain'] + mock_key.side_effect = Exception('ex_user_key_load') + with self.assertLogs('test_a2c', level='INFO') as lcm: + self.assertEqual(('CSR rejected. Either CN or SANs are not allowed by policy', None, None, None), self.cahandler.enroll('csr')) + self.assertIn('ERROR:test_a2c:CAhandler.enroll: CSR rejected. Either CN or SANs are not allowed by policy.', lcm.output) + self.assertFalse(mock_store.called) + self.assertFalse(mock_nw.called) + self.assertFalse(mock_reg.called) + self.assertFalse(mock_newreg.called) @patch('examples.ca_handler.acme_ca_handler.CAhandler._order_issue') - @patch('examples.ca_handler.acme_ca_handler.CAhandler._csr_check') + @patch('examples.ca_handler.acme_ca_handler.allowed_domainlist_check') @patch('OpenSSL.crypto.load_certificate') @patch('OpenSSL.crypto.dump_certificate') @patch('examples.ca_handler.acme_ca_handler.CAhandler._challenge_store') @@ -808,7 +827,7 @@ def test_051_enroll(self, mock_key, mock_store, mock_reg, mock_nw, mock_newreg, @patch('acme.client.ClientV2.new_order') @patch('acme.client.ClientNetwork') @patch('acme.messages') - def test_052_enroll(self, mock_messages, mock_clientnw, mock_c2o, mock_ach, mock_pof, mock_key, mock_reg, mock_cinfo, mock_store, mock_dumpcert, mock_loadcert, mock_csrchk, mock_issue): + def test_053_enroll(self, mock_messages, mock_clientnw, mock_c2o, mock_ach, mock_pof, mock_key, mock_reg, mock_cinfo, mock_store, mock_dumpcert, mock_loadcert, mock_csrchk, mock_issue): """ test enroll with bodystatus None (existing account) """ mock_key.return_value = 'key' mock_messages = Mock() @@ -839,7 +858,7 @@ def test_052_enroll(self, mock_messages, mock_clientnw, mock_c2o, mock_ach, mock @patch('acme.messages') - def test_053__account_lookup(self, mock_messages): + def test_054__account_lookup(self, mock_messages): """ test account register existing account - no replacement """ response = Mock() response.uri = 'urluriacc_info' @@ -853,7 +872,7 @@ def test_053__account_lookup(self, mock_messages): self.assertEqual('urluriacc_info', self.cahandler.account) @patch('acme.messages') - def test_054__account_lookup(self, mock_messages): + def test_055__account_lookup(self, mock_messages): """ test account register existing account - url replacement """ response = Mock() response.uri = 'urluriacc_info' @@ -868,7 +887,7 @@ def test_054__account_lookup(self, mock_messages): self.assertEqual('uriacc_info', self.cahandler.account) @patch('acme.messages') - def test_055__account_lookup(self, mock_messages): + def test_056__account_lookup(self, mock_messages): """ test account register existing account - acct_path replacement """ response = Mock() response.uri = 'urluriacc_info' @@ -883,7 +902,7 @@ def test_055__account_lookup(self, mock_messages): self.assertEqual('urluri', self.cahandler.account) @patch('acme.messages') - def test_056__account_lookup(self, mock_messages): + def test_057__account_lookup(self, mock_messages): """ test account register existing account - acct_path replacement """ response = Mock() response.uri = 'urluriacc_info' @@ -907,7 +926,7 @@ def test_056__account_lookup(self, mock_messages): @patch('josepy.ComparableX509') @patch('OpenSSL.crypto.load_certificate') @patch('os.path.exists') - def test_057_revoke(self, mock_exists, mock_load, mock_comp, mock_kload, mock_nw, mock_mess, mock_reg, mock_revoke): + def test_058_revoke(self, mock_exists, mock_load, mock_comp, mock_kload, mock_nw, mock_mess, mock_reg, mock_revoke): """ test revoke successful """ self.cahandler.keyfile = 'keyfile' self.cahandler.account = 'account' @@ -926,7 +945,7 @@ def test_057_revoke(self, mock_exists, mock_load, mock_comp, mock_kload, mock_nw @patch('josepy.ComparableX509') @patch('OpenSSL.crypto.load_certificate') @patch('os.path.exists') - def test_058_revoke(self, mock_exists, mock_load, mock_comp, mock_kload, mock_nw, mock_mess, mock_reg, mock_revoke): + def test_059_revoke(self, mock_exists, mock_load, mock_comp, mock_kload, mock_nw, mock_mess, mock_reg, mock_revoke): """ test revoke invalid status after reglookup """ self.cahandler.keyfile = 'keyfile' self.cahandler.account = 'account' @@ -945,7 +964,7 @@ def test_058_revoke(self, mock_exists, mock_load, mock_comp, mock_kload, mock_nw @patch('josepy.ComparableX509') @patch('OpenSSL.crypto.load_certificate') @patch('os.path.exists') - def test_059_revoke(self, mock_exists, mock_load, mock_comp, mock_kload, mock_nw, mock_mess, mock_lookup): + def test_060_revoke(self, mock_exists, mock_load, mock_comp, mock_kload, mock_nw, mock_mess, mock_lookup): """ test revoke account lookup failed """ self.cahandler.keyfile = 'keyfile' mock_exists.return_value = True @@ -960,7 +979,7 @@ def test_059_revoke(self, mock_exists, mock_load, mock_comp, mock_kload, mock_nw @patch('josepy.ComparableX509') @patch('OpenSSL.crypto.load_certificate') @patch('os.path.exists') - def test_060_revoke(self, mock_exists, mock_load, mock_comp, mock_kload, mock_nw, mock_mess, mock_lookup): + def test_061_revoke(self, mock_exists, mock_load, mock_comp, mock_kload, mock_nw, mock_mess, mock_lookup): """ test revoke user key load failed """ self.cahandler.keyfile = 'keyfile' mock_exists.return_value = False @@ -972,7 +991,7 @@ def test_060_revoke(self, mock_exists, mock_load, mock_comp, mock_kload, mock_nw @patch("builtins.open", mock_open(read_data='mock_open'), create=True) @patch('josepy.ComparableX509') @patch('OpenSSL.crypto.load_certificate') - def test_061_revoke(self, mock_load, mock_comp): + def test_062_revoke(self, mock_load, mock_comp): """ test revoke exception during processing """ self.cahandler.keyfile = 'keyfile' mock_load.side_effect = Exception('ex_user_key_load') @@ -980,155 +999,8 @@ def test_061_revoke(self, mock_load, mock_comp): self.assertEqual((500, 'urn:ietf:params:acme:error:serverInternal', 'ex_user_key_load'), self.cahandler.revoke('cert', 'reason', 'date')) self.assertIn('ERROR:test_a2c:CAhandler.enroll: error: ex_user_key_load', lcm.output) - def test_062_list_check(self): - """ CAhandler._list_check failed check as empty entry""" - list_ = ['bar.foo$', 'foo.bar$'] - entry = None - self.assertFalse(self.cahandler._list_check(entry, list_)) - - def test_063_list_check(self): - """ CAhandler._list_check check against empty list""" - list_ = [] - entry = 'host.bar.foo' - self.assertTrue(self.cahandler._list_check(entry, list_)) - - def test_064_list_check(self): - """ CAhandler._list_check successful check against 1st element of a list""" - list_ = ['bar.foo$', 'foo.bar$'] - entry = 'host.bar.foo' - self.assertTrue(self.cahandler._list_check(entry, list_)) - - def test_065_list_check(self): - """ CAhandler._list_check unsuccessful as endcheck failed""" - list_ = ['bar.foo$', 'foo.bar$'] - entry = 'host.bar.foo.bar_' - self.assertFalse(self.cahandler._list_check(entry, list_)) - - def test_066_list_check(self): - """ CAhandler._list_check successful without $""" - list_ = ['bar.foo', 'foo.bar$'] - entry = 'host.bar.foo.bar_' - self.assertTrue(self.cahandler._list_check(entry, list_)) - - def test_067_list_check(self): - """ CAhandler._list_check wildcard check""" - list_ = ['bar.foo$', 'foo.bar$'] - entry = '*.bar.foo' - self.assertTrue(self.cahandler._list_check(entry, list_)) - - def test_068_list_check(self): - """ CAhandler._list_check failed wildcard check""" - list_ = ['bar.foo$', 'foo.bar$'] - entry = '*.bar.foo_' - self.assertFalse(self.cahandler._list_check(entry, list_)) - - def test_069_list_check(self): - """ CAhandler._list_check not end check""" - list_ = ['bar.foo$', 'foo.bar$'] - entry = 'bar.foo gna' - self.assertFalse(self.cahandler._list_check(entry, list_)) - - def test_070_list_check(self): - """ CAhandler._list_check $ at the end""" - list_ = ['bar.foo$', 'foo.bar$'] - entry = 'bar.foo$' - self.assertFalse(self.cahandler._list_check(entry, list_)) - - def test_071_list_check(self): - """ CAhandler._list_check check against empty list flip""" - list_ = [] - entry = 'host.bar.foo' - self.assertFalse(self.cahandler._list_check(entry, list_, True)) - - def test_072_list_check(self): - """ CAhandler._list_check flip successful check """ - list_ = ['bar.foo$', 'foo.bar$'] - entry = 'host.bar.foo' - self.assertFalse(self.cahandler._list_check(entry, list_, True)) - - def test_073_list_check(self): - """ CAhandler._list_check flip unsuccessful check""" - list_ = ['bar.foo$', 'foo.bar$'] - entry = 'host.bar.foo' - self.assertFalse(self.cahandler._list_check(entry, list_, True)) - - def test_074_list_check(self): - """ CAhandler._list_check unsuccessful whildcard check""" - list_ = ['foo.bar$', r'\*.bar.foo'] - entry = 'host.bar.foo' - self.assertFalse(self.cahandler._list_check(entry, list_)) - - def test_075_list_check(self): - """ CAhandler._list_check successful whildcard check""" - list_ = ['foo.bar$', r'\*.bar.foo'] - entry = '*.bar.foo' - self.assertTrue(self.cahandler._list_check(entry, list_)) - - def test_076_list_check(self): - """ CAhandler._list_check successful whildcard in list but not in string """ - list_ = ['foo.bar$', '*.bar.foo'] - entry = 'foo.bar.foo' - self.assertTrue(self.cahandler._list_check(entry, list_)) - - @patch('examples.ca_handler.acme_ca_handler.csr_cn_get') - @patch('examples.ca_handler.acme_ca_handler.csr_san_get') - def test_077_csr_check(self, mock_san, mock_cn): - """ CAhandler._check_csr with empty allowed_domainlist """ - self.cahandler.allowed_domainlist = [] - self.cahandler.blacklist = [] - mock_san.return_value = ['DNS:host.foo.bar'] - mock_cn.return_value = 'host2.foo.bar' - csr = 'csr' - self.assertTrue(self.cahandler._csr_check(csr)) - - @patch('examples.ca_handler.acme_ca_handler.CAhandler._list_check') - @patch('examples.ca_handler.acme_ca_handler.csr_cn_get') - @patch('examples.ca_handler.acme_ca_handler.csr_san_get') - def test_078_csr_check(self, mock_san, mock_cn, mock_lcheck): - """ CAhandler._check_csr with list and failed check """ - self.cahandler.allowed_domainlist = ['foo.bar'] - mock_san.return_value = ['DNS:host.foo.bar'] - mock_cn.return_value = 'host2.foo.bar' - mock_lcheck.side_effect = [True, False] - csr = 'csr' - self.assertFalse(self.cahandler._csr_check(csr)) - - @patch('examples.ca_handler.acme_ca_handler.CAhandler._list_check') - @patch('examples.ca_handler.acme_ca_handler.csr_cn_get') - @patch('examples.ca_handler.acme_ca_handler.csr_san_get') - def test_079_csr_check(self, mock_san, mock_cn, mock_lcheck): - """ CAhandler._check_csr with list and successful check """ - self.cahandler.allowed_domainlist = ['foo.bar'] - mock_san.return_value = ['DNS:host.foo.bar'] - mock_cn.return_value = 'host2.foo.bar' - mock_lcheck.side_effect = [True, True] - csr = 'csr' - self.assertTrue(self.cahandler._csr_check(csr)) - - @patch('examples.ca_handler.acme_ca_handler.CAhandler._list_check') - @patch('examples.ca_handler.acme_ca_handler.csr_cn_get') - @patch('examples.ca_handler.acme_ca_handler.csr_san_get') - def test_080_csr_check(self, mock_san, mock_cn, mock_lcheck): - """ CAhandler._check_csr san parsing failed """ - self.cahandler.allowed_domainlist = ['foo.bar'] - mock_san.return_value = ['host.google.com'] - mock_cn.return_value = 'host2.foo.bar' - mock_lcheck.side_effect = [True, True] - csr = 'csr' - self.assertFalse(self.cahandler._csr_check(csr)) - - @patch('examples.ca_handler.acme_ca_handler.csr_cn_get') - @patch('examples.ca_handler.acme_ca_handler.csr_san_get') - def test_081_csr_check(self, mock_san, mock_cn): - """ CAhandler._check_csr san parsing failed """ - self.cahandler.allowed_domainlist = ['foo.bar'] - mock_san.return_value = [] - mock_cn.return_value = None - csr = 'csr' - self.assertFalse(False, self.cahandler._csr_check(csr)) - @patch('requests.post') - def test_082__zerossl_eab_get(self, mock_post): + def test_063__zerossl_eab_get(self, mock_post): """ CAhandler._zerossl_eab_get() - all ok """ mock_post.return_value.json.return_value = {'success': True, 'eab_kid': 'eab_kid', 'eab_hmac_key': 'eab_hmac_key'} self.cahandler._zerossl_eab_get() @@ -1137,7 +1009,7 @@ def test_082__zerossl_eab_get(self, mock_post): self.assertEqual('eab_hmac_key', self.cahandler.eab_hmac_key) @patch('requests.post') - def test_083__zerossl_eab_get(self, mock_post): + def test_064__zerossl_eab_get(self, mock_post): """ CAhandler._zerossl_eab_get() - success false """ mock_post.return_value.json.return_value = {'success': False, 'eab_kid': 'eab_kid', 'eab_hmac_key': 'eab_hmac_key'} mock_post.return_value.text = 'text' @@ -1149,7 +1021,7 @@ def test_083__zerossl_eab_get(self, mock_post): self.assertIn('ERROR:test_a2c:CAhandler._zerossl_eab_get() failed: text', lcm.output) @patch('requests.post') - def test_084__zerossl_eab_get(self, mock_post): + def test_065__zerossl_eab_get(self, mock_post): """ CAhandler._zerossl_eab_get() - no success key """ mock_post.return_value.json.return_value = {'eab_kid': 'eab_kid', 'eab_hmac_key': 'eab_hmac_key'} mock_post.return_value.text = 'text' @@ -1161,7 +1033,7 @@ def test_084__zerossl_eab_get(self, mock_post): self.assertIn('ERROR:test_a2c:CAhandler._zerossl_eab_get() failed: text', lcm.output) @patch('requests.post') - def test_085__zerossl_eab_get(self, mock_post): + def test_066__zerossl_eab_get(self, mock_post): """ CAhandler._zerossl_eab_get() - no eab_kid key """ mock_post.return_value.json.return_value = {'success': True, 'eab_hmac_key': 'eab_hmac_key'} mock_post.return_value.text = 'text' @@ -1173,7 +1045,7 @@ def test_085__zerossl_eab_get(self, mock_post): self.assertIn('ERROR:test_a2c:CAhandler._zerossl_eab_get() failed: text', lcm.output) @patch('requests.post') - def test_086__zerossl_eab_get(self, mock_post): + def test_067__zerossl_eab_get(self, mock_post): """ CAhandler._zerossl_eab_get() - no eab_mac key """ mock_post.return_value.json.return_value = {'success': True, 'eab_kid': 'eab_kid'} mock_post.return_value.text = 'text' @@ -1185,7 +1057,7 @@ def test_086__zerossl_eab_get(self, mock_post): self.assertIn('ERROR:test_a2c:CAhandler._zerossl_eab_get() failed: text', lcm.output) @patch('examples.ca_handler.acme_ca_handler.CAhandler._challenge_info') - def test_087__order_authorization(self, mock_info): + def test_068__order_authorization(self, mock_info): """ CAhandler._order_authorization - sectigo challenge """ order = Mock() order.authorizations = ['foo'] @@ -1193,7 +1065,7 @@ def test_087__order_authorization(self, mock_info): self.assertTrue(self.cahandler._order_authorization('acmeclient', order, 'user_key')) @patch('examples.ca_handler.acme_ca_handler.CAhandler._challenge_info') - def test_088__order_authorization(self, mock_info): + def test_069__order_authorization(self, mock_info): """ CAhandler._order_authorization - sectigo challenge """ order = Mock() order.authorizations = ['foo'] @@ -1201,7 +1073,7 @@ def test_088__order_authorization(self, mock_info): self.assertFalse(self.cahandler._order_authorization('acmeclient', order, 'user_key')) @patch('examples.ca_handler.acme_ca_handler.CAhandler._challenge_info') - def test_089__order_authorization(self, mock_info): + def test_070__order_authorization(self, mock_info): """ CAhandler._order_authorization - sectigo challenge """ order = Mock() order.authorizations = ['foo'] @@ -1209,7 +1081,7 @@ def test_089__order_authorization(self, mock_info): self.assertFalse(self.cahandler._order_authorization('acmeclient', order, 'user_key')) @patch('examples.ca_handler.acme_ca_handler.CAhandler._challenge_info') - def test_090__order_authorization(self, mock_info): + def test_071__order_authorization(self, mock_info): """ CAhandler._order_authorization - sectigo challenge """ order = Mock() order.authorizations = ['foo'] From f67daf48a2e3784daf91a1a8f243ced607689151 Mon Sep 17 00:00:00 2001 From: grindsa Date: Fri, 3 May 2024 07:33:44 +0200 Subject: [PATCH 195/460] [fix] logging list_ during domain check --- acme_srv/helper.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/acme_srv/helper.py b/acme_srv/helper.py index 0f8e53fc..6a05af85 100644 --- a/acme_srv/helper.py +++ b/acme_srv/helper.py @@ -1539,8 +1539,9 @@ def ipv6_chk(logger: logging.Logger, address: str) -> bool: def domainlist_check(logger, entry: str, list_: List[str], toggle: bool = False) -> bool: """ check string against list """ - logger.debug('domainlist_checkk(%s:%s)', entry, toggle) - logger.debug('check against list: {0}', list_) + logger.debug('domainlist_check(%s:%s)', entry, toggle) + # print(list_) + logger.debug('check against list: %s', list_) # default setting check_result = False From 36546e588d98a788f9c183f90b41fda6c93fd9ef Mon Sep 17 00:00:00 2001 From: grindsa Date: Fri, 3 May 2024 08:12:59 +0200 Subject: [PATCH 196/460] [fix] add verify parameter to turn off cert validation --- examples/ca_handler/mscertsrv_ca_handler.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/ca_handler/mscertsrv_ca_handler.py b/examples/ca_handler/mscertsrv_ca_handler.py index 0fd7b04b..7cd7afbe 100644 --- a/examples/ca_handler/mscertsrv_ca_handler.py +++ b/examples/ca_handler/mscertsrv_ca_handler.py @@ -27,6 +27,7 @@ def __init__(self, _debug: bool = False, logger: object = None): self.proxy = None self.allowed_domainlist = [] self.header_info_field = False + self.verify = True def __enter__(self): """ Makes CAhandler a Context Manager """ @@ -135,6 +136,7 @@ def _config_parameters_load(self, config_dic: Dict[str, str]): self.ca_bundle = config_dic['CAhandler']['ca_bundle'] if 'krb5_config' in config_dic['CAhandler']: self.krb5_config = config_dic['CAhandler']['krb5_config'] + self.verify = config_dic.getboolean('CAhandler', 'verify', fallback=True) if 'allowed_domainlist' in config_dic['CAhandler']: try: @@ -281,7 +283,7 @@ def enroll(self, csr: str) -> Tuple[str, str, str, bool]: if result: # setup certserv - ca_server = Certsrv(self.host, self.user, self.password, self.auth_method, self.ca_bundle, proxies=self.proxy) + ca_server = Certsrv(self.host, self.user, self.password, self.auth_method, self.ca_bundle, verify=self.verify, proxies=self.proxy) # check connection and credentials auth_check = self._check_credentials(ca_server) From a30d6fd43776e9d24af8a34266280ff858add2a2 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 4 May 2024 18:37:08 +0200 Subject: [PATCH 197/460] [fix] krb5 in doccker files --- .github/workflows/ca_handler_tests_msca.yml | 629 +++++++------------- examples/Docker/apache2/django/Dockerfile | 6 +- examples/Docker/apache2/wsgi/Dockerfile | 6 +- examples/Docker/nginx/django/Dockerfile | 6 +- requirements.txt | 4 +- 5 files changed, 235 insertions(+), 416 deletions(-) diff --git a/.github/workflows/ca_handler_tests_msca.yml b/.github/workflows/ca_handler_tests_msca.yml index ce546e2c..1aabb0e8 100644 --- a/.github/workflows/ca_handler_tests_msca.yml +++ b/.github/workflows/ca_handler_tests_msca.yml @@ -9,8 +9,8 @@ on: - cron: '0 2 * * 6' jobs: - msca_handler_tests: - name: "msca_handler_tests" + mswcce_handler_tests: + name: "mswcce_handler_tests" runs-on: ubuntu-latest strategy: fail-fast: false @@ -82,7 +82,33 @@ jobs: WEB_SRV: ${{ matrix.websrv }} DB_HANDLER: ${{ matrix.dbhandler }} - - name: "Setup a2c with ms_wcce_ca_handler (ntlm)" + - name: "Prepare ssh environment on ramdisk " + run: | + sudo mkdir -p /tmp/rd + sudo mount -t tmpfs -o size=5M none /tmp/rd + sudo echo "$SSH_KEY" > /tmp/rd/ak.tmp + sudo chmod 600 /tmp/rd/ak.tmp + sudo echo "$KNOWN_HOSTS" > /tmp/rd/known_hosts + env: + SSH_KEY: ${{ secrets.WCCE_SSH_ACCESS_KEY }} + KNOWN_HOSTS: ${{ secrets.WCCE_SSH_KNOWN_HOSTS }} + + - name: "Establish SSH connection" + run: sudo ssh $SSH_USER@$SSH_HOST -fN -i /tmp/rd/ak.tmp -p $SSH_PORT -o UserKnownHostsFile=/tmp/rd/known_hosts -L 445:$WCCE_HOST:445 -L 88:$WCCE_HOST:88 -L 443:$WES_IP:443 -g + env: + SSH_USER: ${{ secrets.WCCE_SSH_USER }} + SSH_HOST: ${{ secrets.WCCE_SSH_HOST }} + SSH_PORT: ${{ secrets.WCCE_SSH_PORT }} + WCCE_HOST: ${{ secrets.WCCE_HOST }} + WES_IP: ${{ secrets.WES_IP }} + CMP_HOST: ${{ secrets.CMP_HOST }} + + - name: "Sleep for 5s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 5s + + - name: "NTLM - Setup a2c with ms_wcce_ca_handler (ntlm)" run: | sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem @@ -124,62 +150,32 @@ jobs: with: time: 10s - - name: "Test http://acme-srv/directory is accessable" + - name: "NTLM - Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "Test if https://acme-srv/directory is accessable" + - name: "NTLM - Test if https://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - name: "Prepare ssh environment on ramdisk " - run: | - sudo mkdir -p /tmp/rd - sudo mount -t tmpfs -o size=5M none /tmp/rd - sudo echo "$SSH_KEY" > /tmp/rd/ak.tmp - sudo chmod 600 /tmp/rd/ak.tmp - sudo echo "$KNOWN_HOSTS" > /tmp/rd/known_hosts - env: - SSH_KEY: ${{ secrets.WCCE_SSH_ACCESS_KEY }} - KNOWN_HOSTS: ${{ secrets.WCCE_SSH_KNOWN_HOSTS }} - - - name: "Establish SSH connection" - run: sudo ssh $SSH_USER@$SSH_HOST -fN -i /tmp/rd/ak.tmp -p $SSH_PORT -o UserKnownHostsFile=/tmp/rd/known_hosts -L 445:$WCCE_HOST:445 -L 88:$WCCE_HOST:88 -L 443:$WES_IP:443 -g - env: - SSH_USER: ${{ secrets.WCCE_SSH_USER }} - SSH_HOST: ${{ secrets.WCCE_SSH_HOST }} - SSH_PORT: ${{ secrets.WCCE_SSH_PORT }} - WCCE_HOST: ${{ secrets.WCCE_HOST }} - WES_IP: ${{ secrets.WES_IP }} - CMP_HOST: ${{ secrets.CMP_HOST }} - - - name: "Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 5s - - - name: "Prepare acme.sh container" + - name: "NTLM - Enroll acme.sh" run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon - - - name: "Enroll acme.sh" - run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force openssl verify -CAfile examples/Docker/data/ca_certs.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - - name: "Register certbot" + - name: "NTLM - Register certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "Enroll certbot" + - name: "NTLM - Enroll certbot" run: | docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot sudo openssl verify -CAfile examples/Docker/data/ca_certs.pem certbot/live/certbot/cert.pem - - name: "Enroll lego" + - name: "NTLM - Enroll lego" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run sudo openssl verify -CAfile examples/Docker/data/ca_certs.pem lego/certificates/lego.acme.crt - - name: "Setup a2c with ms_wcce_ca_handler (Kerboros)" + - name: "KRB - Setup a2c with ms_wcce_ca_handler (Kerboros)" run: | sudo touch examples/Docker/data/ca_certs.pem sudo chmod 777 examples/Docker/data/ca_certs.pem @@ -213,138 +209,56 @@ jobs: WCCE_CA_BUNDLE: ${{ secrets.WCCE_CA_BUNDLE }} WCCE_FQDN: ${{ secrets.WCCE_FQDN }} - - name: "Sleep for 10s" + - name: "KRB - Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: time: 10s - - name: "Test http://acme-srv/directory is accessable" + - name: "KRB - Test http://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - name: "Test if https://acme-srv/directory is accessable" + - name: "KRB - Test if https://acme-srv/directory is accessable" run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - name: "Enroll acme.sh" + - name: "KRB - Enroll acme.sh" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force openssl verify -CAfile examples/Docker/data/ca_certs.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Server" - - name: Check for kerberos connection" + - name: "KRB - Check for kerberos connection" working-directory: examples/Docker/ run: | docker-compose logs | grep -i "Trying to connect" - - name: "Register certbot" + - name: "KRB - Register certbot" run: | sudo rm -rf certbot/ docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - name: "Enroll lego with template in acme_srv.cfg (WebServer)" + - name: "KRB - Enroll lego with template in acme_srv.cfg (WebServer)" run: | docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run sudo openssl verify -CAfile examples/Docker/data/ca_certs.pem lego/certificates/lego.acme.crt sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Server" - - name: "Enroll acme.sh with template in acme_srv.cfg (WebServer)" + - name: "KRB - Enroll acme.sh with template in acme_srv.cfg (WebServer)" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force openssl verify -CAfile examples/Docker/data/ca_certs.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Server" - - name: "Enroll lego with template submitted in command line (WebServerModified)" + - name: "KRB - Enroll lego with template submitted in command line (WebServerModified)" run: | sudo rm -rf lego/ docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent template=WebServerModified --key-type=rsa2048 -d lego.acme --http run sudo openssl verify -CAfile examples/Docker/data/ca_certs.pem lego/certificates/lego.acme.crt sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Client" - - name: "Enroll acme.sh with template submitted in command line (WebServerModified)" + - name: "KRB - Enroll acme.sh with template submitted in command line (WebServerModified)" run: | sudo rm -rf acme-sh/ - docker restart acme-sh - docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --keylength 2048 --issue -d acme-sh.acme --alpn --standalone --useragent template=WebServerModified --debug 3 --output-insecure --force - openssl verify -CAfile examples/Docker/data/ca_certs.pem acme-sh/acme-sh.acme/acme-sh.acme.cer - openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Client" - - - name: "Setup a2c with mscertsrv_ca_handler" - run: | - sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem - sudo touch examples/Docker/data/acme_srv.cfg - sudo chmod 777 examples/Docker/data/acme_srv.cfg - sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg - sudo echo "handler_file: examples/ca_handler/mscertsrv_ca_handler.py" >> examples/Docker/data/acme_srv.cfg - sudo echo "host: $WES_HOST" >> examples/Docker/data/acme_srv.cfg - sudo echo "user: $WES_USER" >> examples/Docker/data/acme_srv.cfg - sudo echo "password: $WES_PASSWORD" >> examples/Docker/data/acme_srv.cfg - sudo echo "auth_method: $WES_AUTHMETHOD" >> examples/Docker/data/acme_srv.cfg - sudo echo "template: $WES_TEMPLATE" >> examples/Docker/data/acme_srv.cfg - sudo echo "ca_bundle: volume/ca_certs.pem" >> examples/Docker/data/acme_srv.cfg - sudo echo "WCCE_HOST: $WCCE_HOST" >> examples/Docker/data/acme_srv.cfg - sudo echo "request_timeout: 30" >> examples/Docker/data/acme_srv.cfg - sudo sed -i "s/tnauthlist_support: False/tnauthlist_support: False\nheader_info_list: [\"HTTP_USER_AGENT\"]/g" examples/Docker/data/acme_srv.cfg - sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout: 40/g" examples/Docker/data/acme_srv.cfg - cd examples/Docker/ - docker-compose restart - docker-compose logs - env: - WES_HOST: ${{ secrets.WES_HOST }} - WES_USER: ${{ secrets.WES_USER }} - WES_PASSWORD: ${{ secrets.WES_PASSWORD }} - WES_TEMPLATE: ${{ secrets.WES_TEMPLATE }} - WES_AUTHMETHOD: ${{ secrets.WES_AUTHMETHOD }} - WCCE_HOST: ${{ secrets.WCCE_HOST }} - - - name: "Sleep for 10s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 10s - - - name: "Test http://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory - - - name: "Test if https://acme-srv/directory is accessable" - run: docker run -i --rm --network acme curlimages/curl --insecure -f https://acme-srv/directory - - - name: "Register certbot" - run: | - sudo rm -rf certbot/ - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - - name: "Enroll lego with template in acme_srv.cfg (WebServer)" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - sudo openssl verify -CAfile examples/Docker/data/ca_certs.pem lego/certificates/lego.acme.crt - sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Server" - - - name: "Enroll acme.sh with template in acme_srv.cfg (WebServer)" - run: | - sudo rm -rf acme-sh/ - docker restart acme-sh - docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force - openssl verify -CAfile examples/Docker/data/ca_certs.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Server" - - - name: "Enroll lego with template submitted in command line (WebServerModified)" - run: | - sudo rm -rf lego/ - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent template=WebServerModified --key-type=rsa2048 -d lego.acme --http run - sudo openssl verify -CAfile examples/Docker/data/ca_certs.pem lego/certificates/lego.acme.crt - sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Client" - - - name: "Enroll acme.sh with template submitted in command line (WebServerModified)" - run: | - sudo rm -rf acme-sh/ - docker restart acme-sh - docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --keylength 2048 --issue -d acme-sh.acme --alpn --standalone --useragent template=WebServerModified --debug 3 --output-insecure --force - openssl verify -CAfile examples/Docker/data/ca_certs.pem acme-sh/acme-sh.acme/acme-sh.acme.cer - openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Client" - - - name: "Enroll acme.sh with template submitted in command line (WebServerModified)" - run: | - sudo rm -rf acme-sh/ - docker restart acme-sh - docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --keylength 2048 --issue -d acme-sh.acme --alpn --standalone --useragent template=WebServerModified --debug 3 --output-insecure --force + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' --keylength 2048 --issue -d acme-sh.acme --alpn --standalone --useragent template=WebServerModified --debug 3 --output-insecure --force openssl verify -CAfile examples/Docker/data/ca_certs.pem acme-sh/acme-sh.acme/acme-sh.acme.cer openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Client" @@ -365,157 +279,38 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: msca-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz + name: mswcce_handler_tests-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ - msca_handler_tests_rpm: - name: "msca_handler_tests_rpm" + mscertsrv_handler_tests: + name: "mscertsrv_handler_tests" runs-on: ubuntu-latest + needs: mswcce_handler_tests strategy: - # max-parallel: 1 fail-fast: false + # max-parallel: 1 matrix: - rhversion: [8, 9] + websrv: ['apache2', 'nginx'] + dbhandler: ['wsgi', 'django'] steps: - name: "checkout GIT" uses: actions/checkout@v4 - - name: "Get runner ip" - run: | - echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV - echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV - - - run: echo "runner IP is ${{ env.RUNNER_IP }}" - - - name: "Install dnsmasq" - run: | - sudo apt-get update - sudo apt-get install -y dnsmasq - sudo systemctl disable systemd-resolved - sudo systemctl stop systemd-resolved - # sudo chmod -R 777 /etc/resolv.conf - # sudo echo "nameserver 8.8.8.8" > /etc/resolv.conf - sudo mkdir -p dnsmasq - sudo cp .github/dnsmasq.conf dnsmasq/ - sudo chmod -R 777 dnsmasq/dnsmasq.conf - sudo sed -i "s/RUNNER_IP/$RUNNER_IP/g" dnsmasq/dnsmasq.conf - sudo echo "address=/$WCCE_FQDN/$RUNNER_IP" >> dnsmasq/dnsmasq.conf - sudo echo "address=/$WCCE_ADS_DOMAIN/$RUNNER_IP" >> dnsmasq/dnsmasq.conf - sudo echo "address=/$WES_HOST/$RUNNER_IP" >> dnsmasq/dnsmasq.conf - cat dnsmasq/dnsmasq.conf - sudo cp dnsmasq/dnsmasq.conf /etc/ - sudo sed -i "s/ --local-service/ /g" /etc/init.d/dnsmasq - sudo systemctl enable dnsmasq - sudo systemctl start dnsmasq - env: - RUNNER_IP: ${{ env.RUNNER_IP }} - WCCE_ADS_DOMAIN: ${{ secrets.WCCE_ADS_DOMAIN }} - WCCE_FQDN: ${{ secrets.WCCE_FQDN }} - WES_HOST: ${{ secrets.WES_HOST }} - - - name: "Test dns resulution" - run: | - host $WCCE_ADS_DOMAIN ${{ env.RUNNER_IP }} - host $WCCE_FQDN ${{ env.RUNNER_IP }} - host $WES_HOST 127.0.0.1 - env: - WCCE_ADS_DOMAIN: ${{ secrets.WCCE_ADS_DOMAIN }} - WCCE_FQDN: ${{ secrets.WCCE_FQDN }} - WES_HOST: ${{ secrets.WES_HOST }} - - - name: Retrieve Version from version.py - run: | - echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV - - - run: echo "Latest tag is ${{ env.TAG_NAME }}" - - - name: update version number in spec file - run: | - # sudo sed -i "s/Source0:.*/Source0: %{name}-%{version}.tar.gz/g" examples/install_scripts/rpm/acme2certifier.spec - sudo sed -i "s/__version__/${{ env.TAG_NAME }}/g" examples/install_scripts/rpm/acme2certifier.spec - cat examples/install_scripts/rpm/acme2certifier.spec - - - name: build RPM package - id: rpm - uses: grindsa/rpmbuild@alma9 - with: - spec_file: "examples/install_scripts/rpm/acme2certifier.spec" - - - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" - - - name: "Setup environment for alma installation" + - name: "create folders and networks" run: | - docker network create acme - sudo mkdir -p data - sudo chmod -R 777 data - sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data - sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data - - - name: "Retrieve rpms from SBOM repo" - run: | - git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom - cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data - env: - GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} - GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} - - - name: "Prepare acme_srv.cfg with ms_wcce_ca_handler" - run: | - mkdir -p data/acme_ca - sudo touch data/acme_ca/ca_certs.pem - sudo chmod 777 data/acme_ca/ca_certs.pem - sudo echo "$WCCE_CA_BUNDLE" > data/acme_ca/ca_certs.pem - sudo touch data/acme_ca/acme_srv.cfg - sudo chmod 777 data/acme_ca/acme_srv.cfg - sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/acme_srv.cfg - sudo echo "handler_file: /opt/acme2certifier/examples/ca_handler/mswcce_ca_handler.py" >> data/acme_srv.cfg - sudo echo "host: $RUNNER_IP" >> data/acme_srv.cfg - sudo echo "user: $WCCE_USER" >> data/acme_srv.cfg - sudo echo "password: $WCCE_PASSWORD" >> data/acme_srv.cfg - sudo echo "template: $WCCE_TEMPLATE" >> data/acme_srv.cfg - sudo echo "ca_name: $WCCE_CA_NAME" >> data/acme_srv.cfg - sudo echo "target_domain: $WCCE_ADS_DOMAIN" >> data/acme_srv.cfg - sudo echo "ca_bundle: /opt/acme2certifier/volume/acme_ca/ca_certs.pem" >> data/acme_srv.cfg - sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout: 40/g" data/acme_srv.cfg - env: - RUNNER_IP: ${{ env.RUNNER_IP }} - WCCE_USER: ${{ secrets.WCCE_USER }} - WCCE_PASSWORD: ${{ secrets.WCCE_PASSWORD }} - WCCE_TEMPLATE: ${{ secrets.WCCE_TEMPLATE }} - WCCE_CA_NAME: ${{ secrets.WCCE_CA_NAME }} - WCCE_ADS_DOMAIN: ${{ secrets.WCCE_ADS_DOMAIN }} - WCCE_CA_BUNDLE: ${{ secrets.WCCE_CA_BUNDLE }} - - - name: "Prepare Almalinux instance" - run: | - sudo cp examples/Docker/almalinux-systemd/Dockerfile data - sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile - cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache - docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd - - - name: "Create letsencrypt and lego folder" - run: | - mkdir certbot + docker network create local mkdir lego mkdir acme-sh + mkdir certbot - - name: "Execute install scipt" + - name: "Get runner ip" run: | - docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh - - - name: "Sleep for 5s" - uses: juliangruber/sleep-action@v2.0.3 - with: - time: 5s - - - name: "Test http://acme-srv/directory is accessable " - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV + echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV - - name: "Prepare acme.sh container" - run: | - docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + - run: echo "runner IP is ${{ env.RUNNER_IP }}" - - name: "[ PREPARE ] ssh environment on ramdisk " + - name: "Prepare ssh environment on ramdisk " run: | sudo mkdir -p /tmp/rd sudo mount -t tmpfs -o size=5M none /tmp/rd @@ -526,210 +321,220 @@ jobs: SSH_KEY: ${{ secrets.WCCE_SSH_ACCESS_KEY }} KNOWN_HOSTS: ${{ secrets.WCCE_SSH_KNOWN_HOSTS }} - - name: "Establish SSH connection" - run: sudo ssh $SSH_USER@$SSH_HOST -fN -i /tmp/rd/ak.tmp -p $SSH_PORT -o UserKnownHostsFile=/tmp/rd/known_hosts -L 445:$WCCE_HOST:445 -L 88:$WCCE_HOST:88 -L 443:$WES_IP:443 -g + - name: "Setup ssh forwarder" + run: | + docker run -d --rm --network local --name=$WCCE_FQDN_WOTLD -e "MAPPINGS=445:$WCCE_HOST:445; 443:$WCCE_HOST:443; 88:$WCCE_HOST:88" -e "SSH_HOST=$SSH_HOST" -e "SSH_PORT=$SSH_PORT" -e "SSH_USER=$SSH_USER" -p 443:443 -p 445:445 -p 88:88 -v "/tmp/rd/ak.tmp:/ssh_key:ro" davidlor/ssh-port-forward-client:dev env: SSH_USER: ${{ secrets.WCCE_SSH_USER }} SSH_HOST: ${{ secrets.WCCE_SSH_HOST }} SSH_PORT: ${{ secrets.WCCE_SSH_PORT }} WCCE_HOST: ${{ secrets.WCCE_HOST }} - WES_IP: ${{ secrets.WES_IP }} - CMP_HOST: ${{ secrets.CMP_HOST }} + WCCE_FQDN_WOTLD: ${{ secrets.WCCE_FQDN_WOTLD }} - - name: "Sleep for 5s" + - name: "Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: - time: 5s + time: 10s - - name: "Enroll acme.sh" + - name: "Test conection to mscertsrv via ssh tunnel" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force - openssl verify -CAfile data/acme_ca/ca_certs.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + docker run -i --rm --network local curlimages/curl --insecure -f https://$WCCE_FQDN + env: + WCCE_FQDN: ${{ secrets.WCCE_FQDN }} - - name: "Register certbot" + - name: "Build docker-compose (${{ matrix.websrv }}_${{ matrix.dbhandler }})" + working-directory: examples/Docker/ run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email + sudo mkdir -p data + sed -i "s/wsgi/$DB_HANDLER/g" .env + sed -i "s/apache2/$WEB_SRV/g" .env + cat .env + sed -i "s/name: acme/name: local/g" docker-compose.yml + docker-compose up -d + docker-compose logs + env: + WEB_SRV: ${{ matrix.websrv }} + DB_HANDLER: ${{ matrix.dbhandler }} - - name: "Enroll certbot" + - name: "KRB - Setup a2c with mscertsrv_ca_handler using kerberos" run: | - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot - sudo openssl verify -CAfile data/acme_ca/ca_certs.pem certbot/live/certbot/cert.pem + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py + sudo touch examples/Docker/data/ca_certs.pem + sudo chmod 777 examples/Docker/data/ca_certs.pem + sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem + sudo touch examples/Docker/data/acme_srv.cfg + sudo chmod 777 examples/Docker/data/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg + sudo echo "handler_file: examples/ca_handler/mscertsrv_ca_handler.py" >> examples/Docker/data/acme_srv.cfg + sudo echo "host: $WCCE_FQDN" >> examples/Docker/data/acme_srv.cfg + sudo echo "user: $WES_USER" >> examples/Docker/data/acme_srv.cfg + sudo echo "password: $WES_PASSWORD" >> examples/Docker/data/acme_srv.cfg + sudo echo "auth_method: gssapi" >> examples/Docker/data/acme_srv.cfg + sudo echo "template: $WES_TEMPLATE" >> examples/Docker/data/acme_srv.cfg + sudo echo "ca_bundle: /var/www/acme2certifier/volume/ca_certs.pem" >> examples/Docker/data/acme_srv.cfg + sudo echo "krb5_config: /var/www/acme2certifier/volume/krb5.conf" >> examples/Docker/data/acme_srv.cfg + sudo echo "verify: False" >> examples/Docker/data/acme_srv.cfg + sudo echo "request_timeout: 30" >> examples/Docker/data/acme_srv.cfg + sudo sed -i "s/tnauthlist_support: False/tnauthlist_support: False\nheader_info_list: [\"HTTP_USER_AGENT\"]/g" examples/Docker/data/acme_srv.cfg + sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout: 40/g" examples/Docker/data/acme_srv.cfg - - name: "Enroll lego" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - sudo openssl verify -CAfile data/acme_ca/ca_certs.pem lego/certificates/lego.acme.crt - - - name: "Setup a2c with ms_wcce_ca_handler (Kerboros)" - run: | - mkdir -p data/acme_ca - sudo touch data/acme_ca/ca_certs.pem - sudo chmod 777 data/acme_ca/ca_certs.pem - sudo echo "$WCCE_CA_BUNDLE" > data/acme_ca/ca_certs.pem - sudo touch data/acme_ca/acme_srv.cfg - sudo chmod 777 data/acme_ca/acme_srv.cfg - sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/acme_srv.cfg - sudo echo "handler_file: /opt/acme2certifier/examples/ca_handler/mswcce_ca_handler.py" >> data/acme_srv.cfg - sudo echo "host: $WCCE_FQDN" >> data/acme_srv.cfg - sudo echo "user: $WCCE_USER" >> data/acme_srv.cfg - sudo echo "password: $WCCE_PASSWORD" >> data/acme_srv.cfg - sudo echo "template: $WCCE_TEMPLATE" >> data/acme_srv.cfg - sudo echo "ca_name: $WCCE_CA_NAME" >> data/acme_srv.cfg - sudo echo "target_domain: $WCCE_ADS_DOMAIN" >> data/acme_srv.cfg - sudo echo "domain_controller: $RUNNER_IP" >> data/acme_srv.cfg - sudo echo "ca_bundle: /opt/acme2certifier/volume/acme_ca/ca_certs.pem" >> data/acme_srv.cfg - sudo echo "use_kerberos: True" >> data/acme_srv.cfg - sudo sed -i "s/tnauthlist_support: False/tnauthlist_support: False\nheader_info_list: [\"HTTP_USER_AGENT\"]/g" data/acme_srv.cfg - sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout: 40/g" data/acme_srv.cfg + sudo touch examples/Docker/data/krb5.conf + sudo chmod 777 examples/Docker/data/krb5.conf + cat < examples/Docker/data/krb5.conf + $WES_KRB5_CONF + EOF + + cd examples/Docker/ + docker-compose restart + docker-compose logs env: - RUNNER_IP: ${{ env.RUNNER_IP }} - WCCE_USER: ${{ secrets.WCCE_USER }} - WCCE_PASSWORD: ${{ secrets.WCCE_PASSWORD }} - WCCE_TEMPLATE: ${{ secrets.WCCE_TEMPLATE }} - WCCE_CA_NAME: ${{ secrets.WCCE_CA_NAME }} + WES_HOST: ${{ secrets.WES_HOST }} + WES_USER: ${{ secrets.WES_USER }} + WES_PASSWORD: ${{ secrets.WES_PASSWORD }} + WES_TEMPLATE: ${{ secrets.WES_TEMPLATE }} + WES_AUTHMETHOD: ${{ secrets.WES_AUTHMETHOD }} + WCCE_HOST: ${{ secrets.WCCE_HOST }} WCCE_ADS_DOMAIN: ${{ secrets.WCCE_ADS_DOMAIN }} - WCCE_CA_BUNDLE: ${{ secrets.WCCE_CA_BUNDLE }} + WES_KRB5_CONF: ${{ secrets.WES_KRB5_CONF }} WCCE_FQDN: ${{ secrets.WCCE_FQDN }} + WCCE_FQDN_WOTLD: ${{ secrets.WCCE_FQDN_WOTLD }} - - name: "Reconfigure a2c " - run: | - docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart - - - name: "Sleep for 5s" + - name: "Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: - time: 5s + time: 10s - - name: "Test http://acme-srv/directory is accessable " - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + - name: "KRB - Test http://acme-srv/directory is accessable" + run: docker run -i --rm --network local curlimages/curl -f http://acme-srv/directory + + - name: "KRB - Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network local curlimages/curl --insecure -f https://acme-srv/directory - - name: "Register certbot" + - name: "KRB - Enroll acme.sh with template in acme_srv.cfg (WebServer)" run: | - sudo rm -rf certbot/ - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email + sudo rm -rf acme-sh/ + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network local --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' -d acme-sh.local --alpn --standalone --debug 3 --output-insecure + openssl verify -CAfile examples/Docker/data/ca_certs.pem acme-sh/acme-sh.local_ecc/acme-sh.local.cer + openssl x509 -in acme-sh/acme-sh.local_ecc/acme-sh.local.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Server" - - name: "Enroll lego with template in acme_srv.cfg (WebServer)" + - name: "KRB - Enroll lego with template in acme_srv.cfg (WebServer)" run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - sudo openssl verify -CAfile data/acme_ca/ca_certs.pem lego/certificates/lego.acme.crt - sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Server" + sudo rm -rf lego/ + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network local goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.local --http run + sudo openssl verify -CAfile examples/Docker/data/ca_certs.pem lego/certificates/lego.local.crt + sudo openssl x509 -in lego/certificates/lego.local.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Server" - - name: "Enroll acme.sh with template in acme_srv.cfg (WebServer)" + - name: "KRB - Enroll acme.sh with template submitted in command line (WebServerModified)" run: | - docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force - openssl verify -CAfile data/acme_ca/ca_certs.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Server" + sudo rm -rf acme-sh/ + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network local --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' -d acme-sh.local --alpn --standalone --useragent template=WebServerModified --keylength 2048 --debug 3 --output-insecure + openssl verify -CAfile examples/Docker/data/ca_certs.pem acme-sh/acme-sh.local/acme-sh.local.cer + openssl x509 -in acme-sh/acme-sh.local/acme-sh.local.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Client" - - name: "Enroll lego with template submitted in command line (WebServerModified)" + - name: "KRB - Enroll lego with template submitted in command line (WebServerModified)" run: | sudo rm -rf lego/ - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent template=WebServerModified --key-type=rsa2048 -d lego.acme --http run - sudo openssl verify -CAfile data/acme_ca/ca_certs.pem lego/certificates/lego.acme.crt - sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Client" + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network local goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent template=WebServerModified --key-type=rsa2048 -d lego.local --http run + sudo openssl verify -CAfile examples/Docker/data/ca_certs.pem lego/certificates/lego.local.crt + sudo openssl x509 -in lego/certificates/lego.local.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Client" - - name: "Enroll acme.sh with template submitted in command line (WebServerModified)" + - name: "NTLM - Setup a2c with mscertsrv_ca_handler using ntlm" run: | - sudo rm -rf acme-sh/ - docker restart acme-sh - docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --keylength 2048 --issue -d acme-sh.acme --alpn --standalone --useragent template=WebServerModified --debug 3 --output-insecure --force - openssl verify -CAfile data/acme_ca/ca_certs.pem acme-sh/acme-sh.acme/acme-sh.acme.cer - openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Client" - - - name: "Setup a2c with mscertsrv_ca_handler" - run: | - mkdir -p data/acme_ca - sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem - sudo touch data/acme_srv.cfg - sudo chmod 777 data/acme_srv.cfg - sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/acme_srv.cfg - sudo echo "handler_file: /opt/acme2certifier/examples/ca_handler/mscertsrv_ca_handler.py" >> data/acme_srv.cfg - sudo echo "host: $WES_HOST" >> data/acme_srv.cfg - sudo echo "user: $WES_USER" >> data/acme_srv.cfg - sudo echo "password: $WES_PASSWORD" >> data/acme_srv.cfg - sudo echo "auth_method: $WES_AUTHMETHOD" >> data/acme_srv.cfg - sudo echo "template: $WES_TEMPLATE" >> data/acme_srv.cfg - sudo echo "ca_bundle: volume/acme_ca/ca_certs.pem" >> data/acme_srv.cfg - sudo echo "request_timeout: 30" >> data/acme_srv.cfg - sudo sed -i "s/tnauthlist_support: False/tnauthlist_support: False\nheader_info_list: [\"HTTP_USER_AGENT\"]/g" data/acme_srv.cfg - sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout: 40/g" data/acme_srv.cfg + sudo cp .github/acme2certifier.pem examples/Docker/data/acme2certifier.pem + sudo cp .github/acme2certifier_cert.pem examples/Docker/data/acme2certifier_cert.pem + sudo cp .github/acme2certifier_key.pem examples/Docker/data/acme2certifier_key.pem + sudo cp .github/django_settings.py examples/Docker/data/settings.py + sudo touch examples/Docker/data/ca_certs.pem + sudo chmod 777 examples/Docker/data/ca_certs.pem + sudo cp test/ca/certsrv_ca_certs.pem examples/Docker/data/ca_certs.pem + sudo touch examples/Docker/data/acme_srv.cfg + sudo chmod 777 examples/Docker/data/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > examples/Docker/data/acme_srv.cfg + sudo echo "handler_file: examples/ca_handler/mscertsrv_ca_handler.py" >> examples/Docker/data/acme_srv.cfg + sudo echo "host: $WCCE_FQDN" >> examples/Docker/data/acme_srv.cfg + sudo echo "user: $WES_USER" >> examples/Docker/data/acme_srv.cfg + sudo echo "password: $WES_PASSWORD" >> examples/Docker/data/acme_srv.cfg + sudo echo "auth_method: ntlm" >> examples/Docker/data/acme_srv.cfg + sudo echo "template: $WES_TEMPLATE" >> examples/Docker/data/acme_srv.cfg + sudo echo "ca_bundle: /var/www/acme2certifier/volume/ca_certs.pem" >> examples/Docker/data/acme_srv.cfg + sudo echo "verify: False" >> examples/Docker/data/acme_srv.cfg + sudo echo "request_timeout: 30" >> examples/Docker/data/acme_srv.cfg + sudo sed -i "s/tnauthlist_support: False/tnauthlist_support: False\nheader_info_list: [\"HTTP_USER_AGENT\"]/g" examples/Docker/data/acme_srv.cfg + sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout: 40/g" examples/Docker/data/acme_srv.cfg + cd examples/Docker/ + docker-compose restart + docker-compose logs env: WES_HOST: ${{ secrets.WES_HOST }} WES_USER: ${{ secrets.WES_USER }} WES_PASSWORD: ${{ secrets.WES_PASSWORD }} - WES_AUTHMETHOD: ${{ secrets.WES_AUTHMETHOD }} WES_TEMPLATE: ${{ secrets.WES_TEMPLATE }} + WES_AUTHMETHOD: ${{ secrets.WES_AUTHMETHOD }} + WCCE_HOST: ${{ secrets.WCCE_HOST }} + WCCE_ADS_DOMAIN: ${{ secrets.WCCE_ADS_DOMAIN }} + WES_KRB5_CONF: ${{ secrets.WES_KRB5_CONF }} + WCCE_FQDN: ${{ secrets.WCCE_FQDN }} + WCCE_FQDN_WOTLD: ${{ secrets.WCCE_FQDN_WOTLD }} - - name: "Reconfigure a2c " - run: | - docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart - - - name: "Sleep for 5s" + - name: "NTLM - Sleep for 10s" uses: juliangruber/sleep-action@v2.0.3 with: - time: 5s + time: 10s - - name: "Test http://acme-srv/directory is accessable " - run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + - name: "NTLM - Test http://acme-srv/directory is accessable" + run: docker run -i --rm --network local curlimages/curl -f http://acme-srv/directory - - name: "Register certbot" - run: | - sudo rm -rf certbot/ - docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email - - - name: "Enroll lego with template in acme_srv.cfg (WebServer)" - run: | - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run - sudo openssl verify -CAfile data/acme_ca/ca_certs.pem lego/certificates/lego.acme.crt - sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Server" + - name: "NTLM - Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network local curlimages/curl --insecure -f https://acme-srv/directory - - name: "Enroll acme.sh with template in acme_srv.cfg (WebServer)" + - name: "NTLM - Enroll acme.sh with template in acme_srv.cfg (WebServer)" run: | sudo rm -rf acme-sh/ - docker restart acme-sh - docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force - openssl verify -CAfile data/acme_ca/ca_certs.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer - openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Server" + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network local --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' -d acme-sh.local --alpn --standalone --debug 3 --output-insecure + openssl verify -CAfile examples/Docker/data/ca_certs.pem acme-sh/acme-sh.local_ecc/acme-sh.local.cer + openssl x509 -in acme-sh/acme-sh.local_ecc/acme-sh.local.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Server" - - name: "Enroll lego with template submitted in command line (WebServerModified)" + - name: "NTLM - Enroll lego with template in acme_srv.cfg (WebServer)" run: | sudo rm -rf lego/ - docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent template=WebServerModified --key-type=rsa2048 -d lego.acme --http run - sudo openssl verify -CAfile data/acme_ca/ca_certs.pem lego/certificates/lego.acme.crt - sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Client" + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network local goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.local --http run + sudo openssl verify -CAfile examples/Docker/data/ca_certs.pem lego/certificates/lego.local.crt + sudo openssl x509 -in lego/certificates/lego.local.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Server" - - name: "Enroll acme.sh with template submitted in command line (WebServerModified)" + - name: "NTLM - Enroll acme.sh with template submitted in command line (WebServerModified)" run: | sudo rm -rf acme-sh/ - docker restart acme-sh - docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --keylength 2048 --issue -d acme-sh.acme --alpn --standalone --useragent template=WebServerModified --debug 3 --output-insecure --force - openssl verify -CAfile data/acme_ca/ca_certs.pem acme-sh/acme-sh.acme/acme-sh.acme.cer - openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Client" + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network local --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' -d acme-sh.local --alpn --standalone --useragent template=WebServerModified --keylength 2048 --debug 3 --output-insecure + openssl verify -CAfile examples/Docker/data/ca_certs.pem acme-sh/acme-sh.local/acme-sh.local.cer + openssl x509 -in acme-sh/acme-sh.local/acme-sh.local.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Client" - - name: "Enroll acme.sh with template submitted in command line (WebServerModified)" + - name: "NTLM - Enroll lego with template submitted in command line (WebServerModified)" run: | - sudo rm -rf acme-sh/ - docker restart acme-sh - docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --keylength 2048 --issue -d acme-sh.acme --alpn --standalone --useragent template=WebServerModified --debug 3 --output-insecure --force - openssl verify -CAfile data/acme_ca/ca_certs.pem acme-sh/acme-sh.acme/acme-sh.acme.cer - openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Client" + sudo rm -rf lego/ + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network local goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent template=WebServerModified --key-type=rsa2048 -d lego.local --http run + sudo openssl verify -CAfile examples/Docker/data/ca_certs.pem lego/certificates/lego.local.crt + sudo openssl x509 -in lego/certificates/lego.local.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Client" - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | mkdir -p ${{ github.workspace }}/artifact/upload - docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier - sudo rm -rf data/*.rpm - sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo cp -rp examples/Docker/data/ ${{ github.workspace }}/artifact/data/ + sudo cp /etc/hosts ${{ github.workspace }}/artifact/data/ + sudo cp /etc/resolv.conf ${{ github.workspace }}/artifact/data/ sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ - sudo cp -rp dnsmasq/ ${{ github.workspace }}/artifact/dnsmasq/ - # docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig - # docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf - docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log - sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh dnsmasq + sudo cp -rp certbot/ ${{ github.workspace }}/artifact/certbot/ + sudo cp -rp lego/ ${{ github.workspace }}/artifact/lego/ + cd examples/Docker + docker-compose logs > ${{ github.workspace }}/artifact/docker-compose.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz docker-compose.log data acme-sh certbot lego dnsmasq - name: "[ * ] uploading artificates" uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: msca_handler_tests_rpm-rh${{ matrix.rhversion }}.tar.gz - path: ${{ github.workspace }}/artifact/upload/ \ No newline at end of file + name: mscertsrv_handler_tests-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz + path: ${{ github.workspace }}/artifact/upload/ diff --git a/examples/Docker/apache2/django/Dockerfile b/examples/Docker/apache2/django/Dockerfile index 2df89c5e..9cb23e98 100644 --- a/examples/Docker/apache2/django/Dockerfile +++ b/examples/Docker/apache2/django/Dockerfile @@ -7,12 +7,16 @@ ENV APACHE_LOG_DIR /var/log/apache2 RUN apt-get update && \ DEBIAN_FRONTEND="noninteractive" apt-get install -y --no-install-recommends -y tzdata && \ - apt-get install --no-install-recommends -y \ + DEBIAN_FRONTEND="noninteractive" apt-get install --no-install-recommends -y \ python3-pip \ apache2 \ apache2-data \ libapache2-mod-wsgi-py3 \ curl \ + krb5-user \ + libgssapi-krb5-2 \ + libkrb5-3 \ + python3-gssapi \ python3-django \ python3-mysqldb \ python3-pymysql \ diff --git a/examples/Docker/apache2/wsgi/Dockerfile b/examples/Docker/apache2/wsgi/Dockerfile index 657edce8..d3bc7649 100644 --- a/examples/Docker/apache2/wsgi/Dockerfile +++ b/examples/Docker/apache2/wsgi/Dockerfile @@ -7,12 +7,16 @@ ENV APACHE_LOG_DIR /var/log/apache2 RUN apt-get update && \ DEBIAN_FRONTEND="noninteractive" apt-get -y install --no-install-recommends tzdata && \ - apt-get install --no-install-recommends -y \ + DEBIAN_FRONTEND="noninteractive" apt-get install --no-install-recommends -y \ python3-pip \ apache2 \ apache2-data \ libapache2-mod-wsgi-py3 \ curl \ + krb5-user \ + libgssapi-krb5-2 \ + libkrb5-3 \ + python3-gssapi \ && rm -rf /var/lib/apt/lists/* &&\ mkdir -p /var/www/acme2certifier/volume && \ mkdir -p /var/www/acme2certifier/examples /var/www/acme2certifier/examples/ diff --git a/examples/Docker/nginx/django/Dockerfile b/examples/Docker/nginx/django/Dockerfile index 727c0cf0..ee7fc638 100644 --- a/examples/Docker/nginx/django/Dockerfile +++ b/examples/Docker/nginx/django/Dockerfile @@ -3,12 +3,16 @@ LABEL maintainer="grindelsack@gmail.com" RUN apt-get update && \ DEBIAN_FRONTEND="noninteractive" apt-get install -y --no-install-recommends tzdata && \ - apt-get install --no-install-recommends -y \ + DEBIAN_FRONTEND="noninteractive" apt-get install --no-install-recommends -y \ python3-pip \ nginx \ uwsgi \ uwsgi-plugin-python3 \ curl \ + krb5-user \ + libgssapi-krb5-2 \ + libkrb5-3 \ + python3-gssapi \ python3-django \ python3-mysqldb \ python3-pymysql \ diff --git a/requirements.txt b/requirements.txt index 717db087..95f18deb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,4 +15,6 @@ impacket xmltodict pyasn1 pyasn1_modules -requests_pkcs12 \ No newline at end of file +requests_pkcs12 +requests_gssapi +gssapi \ No newline at end of file From e3808381d3987fde8b2290c546144ac5dc5afce4 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 4 May 2024 18:37:51 +0200 Subject: [PATCH 198/460] [fix] misisng krb5 support in nginx wsgi --- examples/Docker/nginx/wsgi/Dockerfile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/Docker/nginx/wsgi/Dockerfile b/examples/Docker/nginx/wsgi/Dockerfile index fb501b6b..a3c01725 100644 --- a/examples/Docker/nginx/wsgi/Dockerfile +++ b/examples/Docker/nginx/wsgi/Dockerfile @@ -2,12 +2,16 @@ FROM ubuntu:22.04 LABEL maintainer="grindelsack@gmail.com" RUN apt-get update && \ DEBIAN_FRONTEND="noninteractive" apt-get install -y --no-install-recommends tzdata && \ - apt-get install --no-install-recommends -y \ + DEBIAN_FRONTEND="noninteractive" apt-get install --no-install-recommends -y \ python3-pip \ nginx \ uwsgi \ uwsgi-plugin-python3 \ curl \ + krb5-user \ + libgssapi-krb5-2 \ + libkrb5-3 \ + python3-gssapi \ && rm -rf /var/lib/apt/lists/* &&\ mkdir -p /var/www/acme2certifier/volume && \ mkdir -p /var/www/acme2certifier/examples /var/www/acme2certifier/examples/ && \ From 7ac5328e7e74fa46819eff4694cbf13bc4e58b76 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 11 May 2024 10:12:37 +0200 Subject: [PATCH 199/460] [fix] gssapi backwards compatibility with older requests-gssapi modules --- examples/ca_handler/certsrv.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/ca_handler/certsrv.py b/examples/ca_handler/certsrv.py index a8f19c20..8c335d21 100644 --- a/examples/ca_handler/certsrv.py +++ b/examples/ca_handler/certsrv.py @@ -121,7 +121,7 @@ def _set_credentials(self, username, password): mechs=[gssapi.OID.from_int_seq(oid)], usage="initiate", ) - self.session.auth = HTTPSPNEGOAuth(creds=cred.creds) + self.session.auth = HTTPSPNEGOAuth(creds=cred.creds, mech=gssapi.OID.from_int_seq(oid)) else: self.session.auth = (username, password) From 91fcc13592a18f952cf35b89d58a62b18f6b329d Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 11 May 2024 11:39:45 +0200 Subject: [PATCH 200/460] [feat] workflow and documentation --- .github/workflows/ca_handler_tests_msca.yml | 623 +++++++++++++++++++- docs/mscertsrv.md | 18 +- 2 files changed, 636 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ca_handler_tests_msca.yml b/.github/workflows/ca_handler_tests_msca.yml index 1aabb0e8..340d4cb7 100644 --- a/.github/workflows/ca_handler_tests_msca.yml +++ b/.github/workflows/ca_handler_tests_msca.yml @@ -9,12 +9,13 @@ on: - cron: '0 2 * * 6' jobs: + mswcce_handler_tests: name: "mswcce_handler_tests" runs-on: ubuntu-latest strategy: fail-fast: false - # max-parallel: 1 + max-parallel: 2 matrix: websrv: ['apache2', 'nginx'] dbhandler: ['wsgi', 'django'] @@ -288,7 +289,7 @@ jobs: needs: mswcce_handler_tests strategy: fail-fast: false - # max-parallel: 1 + max-parallel: 2 matrix: websrv: ['apache2', 'nginx'] dbhandler: ['wsgi', 'django'] @@ -518,6 +519,45 @@ jobs: sudo openssl verify -CAfile examples/Docker/data/ca_certs.pem lego/certificates/lego.local.crt sudo openssl x509 -in lego/certificates/lego.local.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Client" + - name: "NTLM - Setup a2c with mscertsrv_ca_handler with allowed_domainlist configuration" + run: | + sudo sed -i "s/challenge_validation_disable: False/challenge_validation_disable: True/g" examples/Docker/data/acme_srv.cfg + sudo echo "allowed_domainlist: [\"*.acme\", \"foo1.bar\", \"*.bar.local\"]" >> examples/Docker/data/acme_srv.cfg + cd examples/Docker/ + docker-compose restart + docker-compose logs + + - name: "NTLM - Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "NTLM - Test http://acme-srv/directory is accessable" + run: docker run -i --rm --network local curlimages/curl -f http://acme-srv/directory + + - name: "NTLM - Test if https://acme-srv/directory is accessable" + run: docker run -i --rm --network local curlimages/curl --insecure -f https://acme-srv/directory + + - name: "NTLM - Enroll acme.sh with fqdn not part of allowed_domainlist (should fail)" + id: acmefail01 + continue-on-error: true + run: | + sudo rm -rf acme-sh/ + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network local --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' -d acme-sh.local --alpn --standalone --debug 3 --output-insecure + + - name: "NTLM - Check result " + if: steps.acmefail01.outcome != 'failure' + run: | + echo "acmefail outcome is ${{steps.acmefail01.outcome }}" + exit 1 + + - name: "NTLM - Enroll acme.sh with fqdn part of allowed_domainlist" + run: | + sudo rm -rf acme-sh/ + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network local --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure + openssl verify -CAfile examples/Docker/data/ca_certs.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Server" + - name: "[ * ] collecting test logs" if: ${{ failure() }} run: | @@ -538,3 +578,582 @@ jobs: with: name: mscertsrv_handler_tests-${{ matrix.websrv }}-${{ matrix.dbhandler }}.tar.gz path: ${{ github.workspace }}/artifact/upload/ + + mswcce_handler_tests_rpm: + name: "mswcce_handler_tests_rpm" + runs-on: ubuntu-latest + strategy: + # max-parallel: 1 + fail-fast: false + matrix: + rhversion: [8, 9] + steps: + - name: "checkout GIT" + uses: actions/checkout@v4 + + - name: "Get runner ip" + run: | + echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV + echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV + + - run: echo "runner IP is ${{ env.RUNNER_IP }}" + + - name: "Install dnsmasq" + run: | + sudo apt-get update + sudo apt-get install -y dnsmasq + sudo systemctl disable systemd-resolved + sudo systemctl stop systemd-resolved + # sudo chmod -R 777 /etc/resolv.conf + # sudo echo "nameserver 8.8.8.8" > /etc/resolv.conf + sudo mkdir -p dnsmasq + sudo cp .github/dnsmasq.conf dnsmasq/ + sudo chmod -R 777 dnsmasq/dnsmasq.conf + sudo sed -i "s/RUNNER_IP/$RUNNER_IP/g" dnsmasq/dnsmasq.conf + sudo echo "address=/$WCCE_FQDN/$RUNNER_IP" >> dnsmasq/dnsmasq.conf + sudo echo "address=/$WCCE_ADS_DOMAIN/$RUNNER_IP" >> dnsmasq/dnsmasq.conf + sudo echo "address=/$WES_HOST/$RUNNER_IP" >> dnsmasq/dnsmasq.conf + cat dnsmasq/dnsmasq.conf + sudo cp dnsmasq/dnsmasq.conf /etc/ + sudo sed -i "s/ --local-service/ /g" /etc/init.d/dnsmasq + sudo systemctl enable dnsmasq + sudo systemctl start dnsmasq + env: + RUNNER_IP: ${{ env.RUNNER_IP }} + WCCE_ADS_DOMAIN: ${{ secrets.WCCE_ADS_DOMAIN }} + WCCE_FQDN: ${{ secrets.WCCE_FQDN }} + WES_HOST: ${{ secrets.WES_HOST }} + + - name: "Test dns resulution" + run: | + host $WCCE_ADS_DOMAIN ${{ env.RUNNER_IP }} + host $WCCE_FQDN ${{ env.RUNNER_IP }} + host $WES_HOST 127.0.0.1 + env: + WCCE_ADS_DOMAIN: ${{ secrets.WCCE_ADS_DOMAIN }} + WCCE_FQDN: ${{ secrets.WCCE_FQDN }} + WES_HOST: ${{ secrets.WES_HOST }} + + - name: Retrieve Version from version.py + run: | + echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV + + - run: echo "Latest tag is ${{ env.TAG_NAME }}" + + - name: update version number in spec file + run: | + # sudo sed -i "s/Source0:.*/Source0: %{name}-%{version}.tar.gz/g" examples/install_scripts/rpm/acme2certifier.spec + sudo sed -i "s/__version__/${{ env.TAG_NAME }}/g" examples/install_scripts/rpm/acme2certifier.spec + cat examples/install_scripts/rpm/acme2certifier.spec + + - name: build RPM package + id: rpm + uses: grindsa/rpmbuild@alma9 + with: + spec_file: "examples/install_scripts/rpm/acme2certifier.spec" + + - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" + + - name: "Setup environment for alma installation" + run: | + docker network create acme + sudo mkdir -p data + sudo chmod -R 777 data + sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data + sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data + + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + + - name: "Create letsencrypt and lego folder" + run: | + mkdir certbot + mkdir lego + mkdir acme-sh + + - name: "Ssh environment on ramdisk " + run: | + sudo mkdir -p /tmp/rd + sudo mount -t tmpfs -o size=5M none /tmp/rd + sudo echo "$SSH_KEY" > /tmp/rd/ak.tmp + sudo chmod 600 /tmp/rd/ak.tmp + sudo echo "$KNOWN_HOSTS" > /tmp/rd/known_hosts + env: + SSH_KEY: ${{ secrets.WCCE_SSH_ACCESS_KEY }} + KNOWN_HOSTS: ${{ secrets.WCCE_SSH_KNOWN_HOSTS }} + + - name: "Establish SSH connection" + run: sudo ssh $SSH_USER@$SSH_HOST -fN -i /tmp/rd/ak.tmp -p $SSH_PORT -o UserKnownHostsFile=/tmp/rd/known_hosts -L 445:$WCCE_HOST:445 -L 88:$WCCE_HOST:88 -L 443:$WES_IP:443 -g + env: + SSH_USER: ${{ secrets.WCCE_SSH_USER }} + SSH_HOST: ${{ secrets.WCCE_SSH_HOST }} + SSH_PORT: ${{ secrets.WCCE_SSH_PORT }} + WCCE_HOST: ${{ secrets.WCCE_HOST }} + WES_IP: ${{ secrets.WES_IP }} + CMP_HOST: ${{ secrets.CMP_HOST }} + + - name: "Sleep for 5s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 5s + + - name: "NTLM - Prepare acme_srv.cfg with ms_wcce_ca_handler" + run: | + mkdir -p data/acme_ca + sudo touch data/acme_ca/ca_certs.pem + sudo chmod 777 data/acme_ca/ca_certs.pem + sudo echo "$WCCE_CA_BUNDLE" > data/acme_ca/ca_certs.pem + sudo touch data/acme_ca/acme_srv.cfg + sudo chmod 777 data/acme_ca/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/acme_srv.cfg + sudo echo "handler_file: /opt/acme2certifier/examples/ca_handler/mswcce_ca_handler.py" >> data/acme_srv.cfg + sudo echo "host: $RUNNER_IP" >> data/acme_srv.cfg + sudo echo "user: $WCCE_USER" >> data/acme_srv.cfg + sudo echo "password: $WCCE_PASSWORD" >> data/acme_srv.cfg + sudo echo "template: $WCCE_TEMPLATE" >> data/acme_srv.cfg + sudo echo "ca_name: $WCCE_CA_NAME" >> data/acme_srv.cfg + sudo echo "target_domain: $WCCE_ADS_DOMAIN" >> data/acme_srv.cfg + sudo echo "ca_bundle: /opt/acme2certifier/volume/acme_ca/ca_certs.pem" >> data/acme_srv.cfg + sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout: 40/g" data/acme_srv.cfg + env: + RUNNER_IP: ${{ env.RUNNER_IP }} + WCCE_USER: ${{ secrets.WCCE_USER }} + WCCE_PASSWORD: ${{ secrets.WCCE_PASSWORD }} + WCCE_TEMPLATE: ${{ secrets.WCCE_TEMPLATE }} + WCCE_CA_NAME: ${{ secrets.WCCE_CA_NAME }} + WCCE_ADS_DOMAIN: ${{ secrets.WCCE_ADS_DOMAIN }} + WCCE_CA_BUNDLE: ${{ secrets.WCCE_CA_BUNDLE }} + + - name: "NTLM - Prepare Almalinux instance" + run: | + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + docker run -d -id --privileged --network acme --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd + + - name: "NTLM - Execute install scipt" + run: | + docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh + + - name: "NTLM - Sleep for 5s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 5s + + - name: "NTLM - Test http://acme-srv/directory is accessable " + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "NTLM - Prepare acme.sh container" + run: | + docker run --rm -id -v "$(pwd)/acme-sh":/acme.sh --network acme --name=acme-sh neilpang/acme.sh:latest daemon + + - name: "NTLM - Register certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot register --agree-tos -m 'certbot@example.com' --server http://acme-srv --no-eff-email + + - name: "NTLM - Enroll certbot" + run: | + docker run -i --rm --name certbot --network acme -v $PWD/certbot:/etc/letsencrypt/ certbot/certbot certonly --server http://acme-srv --standalone --preferred-challenges http -d certbot.acme --cert-name certbot + sudo openssl verify -CAfile data/acme_ca/ca_certs.pem certbot/live/certbot/cert.pem + + - name: "NTLM - Enroll acme.sh" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force + openssl verify -CAfile data/acme_ca/ca_certs.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + + - name: "NTLM - Enroll lego" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + sudo openssl verify -CAfile data/acme_ca/ca_certs.pem lego/certificates/lego.acme.crt + + - name: "KRB - Setup a2c with ms_wcce_ca_handler (Kerboros)" + run: | + mkdir -p data/acme_ca + sudo touch data/acme_ca/ca_certs.pem + sudo chmod 777 data/acme_ca/ca_certs.pem + sudo echo "$WCCE_CA_BUNDLE" > data/acme_ca/ca_certs.pem + sudo touch data/acme_ca/acme_srv.cfg + sudo chmod 777 data/acme_ca/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/acme_srv.cfg + sudo echo "handler_file: /opt/acme2certifier/examples/ca_handler/mswcce_ca_handler.py" >> data/acme_srv.cfg + sudo echo "host: $WCCE_FQDN" >> data/acme_srv.cfg + sudo echo "user: $WCCE_USER" >> data/acme_srv.cfg + sudo echo "password: $WCCE_PASSWORD" >> data/acme_srv.cfg + sudo echo "template: $WCCE_TEMPLATE" >> data/acme_srv.cfg + sudo echo "ca_name: $WCCE_CA_NAME" >> data/acme_srv.cfg + sudo echo "target_domain: $WCCE_ADS_DOMAIN" >> data/acme_srv.cfg + sudo echo "domain_controller: $RUNNER_IP" >> data/acme_srv.cfg + sudo echo "ca_bundle: /opt/acme2certifier/volume/acme_ca/ca_certs.pem" >> data/acme_srv.cfg + sudo echo "use_kerberos: True" >> data/acme_srv.cfg + sudo sed -i "s/tnauthlist_support: False/tnauthlist_support: False\nheader_info_list: [\"HTTP_USER_AGENT\"]/g" data/acme_srv.cfg + sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout: 40/g" data/acme_srv.cfg + env: + RUNNER_IP: ${{ env.RUNNER_IP }} + WCCE_USER: ${{ secrets.WCCE_USER }} + WCCE_PASSWORD: ${{ secrets.WCCE_PASSWORD }} + WCCE_TEMPLATE: ${{ secrets.WCCE_TEMPLATE }} + WCCE_CA_NAME: ${{ secrets.WCCE_CA_NAME }} + WCCE_ADS_DOMAIN: ${{ secrets.WCCE_ADS_DOMAIN }} + WCCE_CA_BUNDLE: ${{ secrets.WCCE_CA_BUNDLE }} + WCCE_FQDN: ${{ secrets.WCCE_FQDN }} + + - name: "KRB - Reconfigure a2c " + run: | + docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart + + - name: "KRB - Sleep for 5s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 5s + + - name: "KRB - Test http://acme-srv/directory is accessable " + run: docker run -i --rm --network acme curlimages/curl -f http://acme-srv/directory + + - name: "KRB - Enroll lego with template in acme_srv.cfg (WebServer)" + run: | + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.acme --http run + sudo openssl verify -CAfile data/acme_ca/ca_certs.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Server" + + - name: "KRB - Enroll acme.sh with template in acme_srv.cfg (WebServer)" + run: | + docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --issue -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure --force + openssl verify -CAfile data/acme_ca/ca_certs.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Server" + + - name: "KRB - Enroll lego with template submitted in command line (WebServerModified)" + run: | + sudo rm -rf lego/ + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network acme goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent template=WebServerModified --key-type=rsa2048 -d lego.acme --http run + sudo openssl verify -CAfile data/acme_ca/ca_certs.pem lego/certificates/lego.acme.crt + sudo openssl x509 -in lego/certificates/lego.acme.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Client" + + - name: "KRB - Enroll acme.sh with template submitted in command line (WebServerModified)" + run: | + sudo rm -rf acme-sh/ + docker restart acme-sh + docker exec -i acme-sh acme.sh --server http://acme-srv --accountemail 'acme-sh@example.com' --keylength 2048 --issue -d acme-sh.acme --alpn --standalone --useragent template=WebServerModified --debug 3 --output-insecure --force + openssl verify -CAfile data/acme_ca/ca_certs.pem acme-sh/acme-sh.acme/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Client" + + - name: "[ * ] collecting test logs" + if: ${{ failure() }} + run: | + mkdir -p ${{ github.workspace }}/artifact/upload + docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier + sudo rm -rf data/*.rpm + sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + sudo cp -rp dnsmasq/ ${{ github.workspace }}/artifact/dnsmasq/ + # docker exec acme-srv cat /etc/nginx/nginx.conf.orig > ${{ github.workspace }}/artifact/data/nginx.conf.orig + # docker exec acme-srv cat /etc/nginx/nginx.conf > ${{ github.workspace }}/artifact/data/nginx.conf + docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh dnsmasq + + - name: "[ * ] uploading artificates" + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: mswcce_handler_tests_rpm-rh${{ matrix.rhversion }}.tar.gz + path: ${{ github.workspace }}/artifact/upload/ + + mscertsrv_handler_tests_rpm: + name: "mscertsrv_handler_tests_rpm" + runs-on: ubuntu-latest + needs: mswcce_handler_tests_rpm + strategy: + # max-parallel: 1 + fail-fast: false + matrix: + rhversion: [8, 9] + steps: + - name: "checkout GIT" + uses: actions/checkout@v4 + + - name: "create folders and networks" + run: | + docker network create local + mkdir lego + mkdir acme-sh + mkdir certbot + + - name: "Get runner ip" + run: | + echo RUNNER_IP=$(ip addr show eth0 | grep -i "inet " | cut -d ' ' -f 6 | cut -d '/' -f 1) >> $GITHUB_ENV + echo RUNNER_PATH=$(pwd | sed 's_/_\\/_g') >> $GITHUB_ENV + + - run: echo "runner IP is ${{ env.RUNNER_IP }}" + + - name: "Prepare ssh environment on ramdisk " + run: | + sudo mkdir -p /tmp/rd + sudo mount -t tmpfs -o size=5M none /tmp/rd + sudo echo "$SSH_KEY" > /tmp/rd/ak.tmp + sudo chmod 600 /tmp/rd/ak.tmp + sudo echo "$KNOWN_HOSTS" > /tmp/rd/known_hosts + env: + SSH_KEY: ${{ secrets.WCCE_SSH_ACCESS_KEY }} + KNOWN_HOSTS: ${{ secrets.WCCE_SSH_KNOWN_HOSTS }} + + - name: "Setup ssh forwarder" + run: | + docker run -d --rm --network local --name=$WCCE_FQDN_WOTLD -e "MAPPINGS=445:$WCCE_HOST:445; 443:$WCCE_HOST:443; 88:$WCCE_HOST:88" -e "SSH_HOST=$SSH_HOST" -e "SSH_PORT=$SSH_PORT" -e "SSH_USER=$SSH_USER" -p 443:443 -p 445:445 -p 88:88 -v "/tmp/rd/ak.tmp:/ssh_key:ro" davidlor/ssh-port-forward-client:dev + env: + SSH_USER: ${{ secrets.WCCE_SSH_USER }} + SSH_HOST: ${{ secrets.WCCE_SSH_HOST }} + SSH_PORT: ${{ secrets.WCCE_SSH_PORT }} + WCCE_HOST: ${{ secrets.WCCE_HOST }} + WCCE_FQDN_WOTLD: ${{ secrets.WCCE_FQDN_WOTLD }} + + - name: "Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "Test conection to mscertsrv via ssh tunnel" + run: | + docker run -i --rm --network local curlimages/curl --insecure -f https://$WCCE_FQDN + env: + WCCE_FQDN: ${{ secrets.WCCE_FQDN }} + + + - name: Retrieve Version from version.py + run: | + echo TAG_NAME=$(cat acme_srv/version.py | grep -i __version__ | head -n 1 | sed 's/__version__ = //g' | sed s/\'//g) >> $GITHUB_ENV + + - run: echo "Latest tag is ${{ env.TAG_NAME }}" + + - name: update version number in spec file + run: | + # sudo sed -i "s/Source0:.*/Source0: %{name}-%{version}.tar.gz/g" examples/install_scripts/rpm/acme2certifier.spec + sudo sed -i "s/__version__/${{ env.TAG_NAME }}/g" examples/install_scripts/rpm/acme2certifier.spec + cat examples/install_scripts/rpm/acme2certifier.spec + + - name: build RPM package + id: rpm + uses: grindsa/rpmbuild@alma9 + with: + spec_file: "examples/install_scripts/rpm/acme2certifier.spec" + + - run: echo "path is ${{ steps.rpm.outputs.rpm_dir_path }}" + + - name: "Setup environment for alma installation" + run: | + docker network create acme + sudo mkdir -p data + sudo chmod -R 777 data + sudo cp ${{ steps.rpm.outputs.rpm_dir_path }}noarch/acme2certifier-${{ env.TAG_NAME }}-1.0.noarch.rpm data + sudo cp examples/Docker/almalinux-systemd/rpm_tester.sh data + + - name: "Retrieve rpms from SBOM repo" + run: | + git clone https://$GH_SBOM_USER:$GH_SBOM_TOKEN@github.com/$GH_SBOM_USER/sbom /tmp/sbom + cp /tmp/sbom/rpm-repo/RPMs/rhel${{ matrix.rhversion }}/*.rpm data + env: + GH_SBOM_USER: ${{ secrets.GH_SBOM_USER }} + GH_SBOM_TOKEN: ${{ secrets.GH_SBOM_TOKEN }} + + - name: "NTLM - Prepare Almalinux instance" + run: | + sudo cp examples/Docker/almalinux-systemd/Dockerfile data + sudo sed -i "s/FROM almalinux:9/FROM almalinux:${{ matrix.rhversion }}/g" data/Dockerfile + cat data/Dockerfile | docker build -t almalinux-systemd -f - . --no-cache + docker run -d -id --privileged --network local --name=acme-srv -v "$(pwd)/data":/tmp/acme2certifier almalinux-systemd + + - name: "KRB - Setup a2c with mscertsrv_ca_handler using kerberos" + run: | + mkdir -p data/acme_ca + sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem + sudo touch data/acme_srv.cfg + sudo chmod 777 data/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/acme_srv.cfg + sudo echo "handler_file: /opt/acme2certifier/examples/ca_handler/mscertsrv_ca_handler.py" >> data/acme_srv.cfg + sudo echo "host: $WCCE_FQDN" >> data/acme_srv.cfg + sudo echo "user: $WES_USER" >> data/acme_srv.cfg + sudo echo "password: $WES_PASSWORD" >> data/acme_srv.cfg + sudo echo "auth_method: gssapi" >> data/acme_srv.cfg + sudo echo "template: $WES_TEMPLATE" >> data/acme_srv.cfg + sudo echo "ca_bundle: volume/acme_ca/ca_certs.pem" >> data/acme_srv.cfg + sudo echo "krb5_config: volume/acme_ca/krb5.conf" >> data/acme_srv.cfg + sudo echo "verify: False" >> data/acme_srv.cfg + sudo echo "request_timeout: 30" >> data/acme_srv.cfg + sudo sed -i "s/tnauthlist_support: False/tnauthlist_support: False\nheader_info_list: [\"HTTP_USER_AGENT\"]/g" data/acme_srv.cfg + sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout: 40/g" data/acme_srv.cfg + + sudo touch data/acme_ca/krb5.conf + sudo chmod 777 data/acme_ca/krb5.conf + cat < data/acme_ca/krb5.conf + $WES_KRB5_CONF + EOF + + env: + WES_HOST: ${{ secrets.WES_HOST }} + WES_USER: ${{ secrets.WES_USER }} + WES_PASSWORD: ${{ secrets.WES_PASSWORD }} + WES_AUTHMETHOD: ${{ secrets.WES_AUTHMETHOD }} + WES_TEMPLATE: ${{ secrets.WES_TEMPLATE }} + WCCE_FQDN: ${{ secrets.WCCE_FQDN }} + WES_KRB5_CONF: ${{ secrets.WES_KRB5_CONF }} + + - name: "KRB - Execute install scipt" + run: | + docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh + docker exec acme-srv yum install -y krb5-libs + + - name: "KRB - Sleep for 10s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 10s + + - name: "KRB - Enroll acme.sh with template in acme_srv.cfg (WebServer)" + run: | + sudo rm -rf acme-sh/ + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network local --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' -d acme-sh.local --alpn --standalone --debug 3 --output-insecure + openssl verify -CAfile data/acme_ca/ca_certs.pem acme-sh/acme-sh.local_ecc/acme-sh.local.cer + openssl x509 -in acme-sh/acme-sh.local_ecc/acme-sh.local.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Server" + + - name: "KRB - Enroll lego with template in acme_srv.cfg (WebServer)" + run: | + sudo rm -rf lego/ + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network local goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.local --http run + sudo openssl verify -CAfile data/acme_ca/ca_certs.pem lego/certificates/lego.local.crt + sudo openssl x509 -in lego/certificates/lego.local.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Server" + + - name: "KRB - Enroll acme.sh with template submitted in command line (WebServerModified)" + run: | + sudo rm -rf acme-sh/ + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network local --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' -d acme-sh.local --alpn --standalone --useragent template=WebServerModified --keylength 2048 --debug 3 --output-insecure + openssl verify -CAfile data/acme_ca/ca_certs.pem acme-sh/acme-sh.local/acme-sh.local.cer + openssl x509 -in acme-sh/acme-sh.local/acme-sh.local.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Client" + + - name: "KRB - Enroll lego with template submitted in command line (WebServerModified)" + run: | + sudo rm -rf lego/ + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network local goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent template=WebServerModified --key-type=rsa2048 -d lego.local --http run + sudo openssl verify -CAfile data/acme_ca/ca_certs.pem lego/certificates/lego.local.crt + sudo openssl x509 -in lego/certificates/lego.local.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Client" + + - name: "NTLM - Setup a2c with mscertsrv_ca_handler" + run: | + mkdir -p data/acme_ca + sudo cp test/ca/certsrv_ca_certs.pem data/acme_ca/ca_certs.pem + sudo touch data/acme_srv.cfg + sudo chmod 777 data/acme_srv.cfg + sudo head -n -8 .github/openssl_ca_handler.py_acme_srv_default_handler.cfg > data/acme_srv.cfg + sudo echo "handler_file: /opt/acme2certifier/examples/ca_handler/mscertsrv_ca_handler.py" >> data/acme_srv.cfg + sudo echo "host: $WCCE_FQDN" >> data/acme_srv.cfg + sudo echo "user: $WES_USER" >> data/acme_srv.cfg + sudo echo "password: $WES_PASSWORD" >> data/acme_srv.cfg + sudo echo "auth_method: $WES_AUTHMETHOD" >> data/acme_srv.cfg + sudo echo "template: $WES_TEMPLATE" >> data/acme_srv.cfg + sudo echo "ca_bundle: volume/acme_ca/ca_certs.pem" >> data/acme_srv.cfg + sudo echo "verify: False" >> data/acme_srv.cfg + sudo echo "request_timeout: 30" >> data/acme_srv.cfg + sudo sed -i "s/tnauthlist_support: False/tnauthlist_support: False\nheader_info_list: [\"HTTP_USER_AGENT\"]/g" data/acme_srv.cfg + sudo sed -i "s/revocation_reason_check_disable: False/revocation_reason_check_disable: False\nenrollment_timeout: 40/g" data/acme_srv.cfg + env: + WES_HOST: ${{ secrets.WES_HOST }} + WES_USER: ${{ secrets.WES_USER }} + WES_PASSWORD: ${{ secrets.WES_PASSWORD }} + WES_AUTHMETHOD: ${{ secrets.WES_AUTHMETHOD }} + WES_TEMPLATE: ${{ secrets.WES_TEMPLATE }} + WCCE_FQDN: ${{ secrets.WCCE_FQDN }} + + - name: "NTLM - Reconfigure a2c " + run: | + docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart + + - name: "NTLM - Sleep for 5s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 5s + + - name: "NTLM - Enroll acme.sh with template in acme_srv.cfg (WebServer)" + run: | + sudo rm -rf acme-sh/ + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network local --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' -d acme-sh.local --alpn --standalone --debug 3 --output-insecure + openssl verify -CAfile data/acme_ca/ca_certs.pem acme-sh/acme-sh.local_ecc/acme-sh.local.cer + openssl x509 -in acme-sh/acme-sh.local_ecc/acme-sh.local.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Server" + + - name: "NTLM - Enroll lego with template in acme_srv.cfg (WebServer)" + run: | + sudo rm -rf lego/ + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network local goacme/lego -s http://acme-srv -a --email "lego@example.com" -d lego.local --http run + sudo openssl verify -CAfile data/acme_ca/ca_certs.pem lego/certificates/lego.local.crt + sudo openssl x509 -in lego/certificates/lego.local.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Server" + + - name: "NTLM - Enroll acme.sh with template submitted in command line (WebServerModified)" + run: | + sudo rm -rf acme-sh/ + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network local --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' -d acme-sh.local --alpn --standalone --useragent template=WebServerModified --keylength 2048 --debug 3 --output-insecure + openssl verify -CAfile data/acme_ca/ca_certs.pem acme-sh/acme-sh.local/acme-sh.local.cer + openssl x509 -in acme-sh/acme-sh.local/acme-sh.local.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Client" + + - name: "NTLM - Enroll lego with template submitted in command line (WebServerModified)" + run: | + sudo rm -rf lego/ + docker run -i -v $PWD/lego:/.lego/ --rm --name lego --network local goacme/lego -s http://acme-srv -a --email "lego@example.com" --user-agent template=WebServerModified --key-type=rsa2048 -d lego.local --http run + sudo openssl verify -CAfile data/acme_ca/ca_certs.pem lego/certificates/lego.local.crt + sudo openssl x509 -in lego/certificates/lego.local.crt -ext extendedKeyUsage -noout | grep -i "TLS Web Client" + + - name: "NTLM - Setup a2c with mscertsrv_ca_handler with allowed_domainlist configuration" + run: | + sudo sed -i "s/challenge_validation_disable: False/challenge_validation_disable: True/g" data/acme_srv.cfg + sudo echo "allowed_domainlist: [\"*.acme\", \"foo1.bar\", \"*.bar.local\"]" >> data/acme_srv.cfg + + - name: "NTLM - Reconfigure a2c " + run: | + docker exec acme-srv sh /tmp/acme2certifier/rpm_tester.sh restart + + - name: "NTLM - Sleep for 5s" + uses: juliangruber/sleep-action@v2.0.3 + with: + time: 5s + + - name: "NTLM - Test http://acme-srv/directory is accessable" + run: docker run -i --rm --network local curlimages/curl -f http://acme-srv/directory + + - name: "NTLM - Enroll acme.sh with fqdn not part of allowed_domainlist (should fail)" + id: acmefail02 + continue-on-error: true + run: | + sudo rm -rf acme-sh/ + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network local --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' -d acme-sh.local --alpn --standalone --debug 3 --output-insecure + + - name: "NTLM - Check result " + if: steps.acmefail02.outcome != 'failure' + run: | + echo "acmefail outcome is ${{steps.acmefail02.outcome }}" + exit 1 + + - name: "NTLM - Enroll acme.sh with fqdn part of allowed_domainlist" + run: | + sudo rm -rf acme-sh/ + docker run --rm -i -v "$(pwd)/acme-sh":/acme.sh --network local --name=acme-sh neilpang/acme.sh:latest --issue --server http://acme-srv --accountemail 'acme-sh@example.com' -d acme-sh.acme --alpn --standalone --debug 3 --output-insecure + openssl verify -CAfile data/acme_ca/ca_certs.pem acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer + openssl x509 -in acme-sh/acme-sh.acme_ecc/acme-sh.acme.cer -ext extendedKeyUsage -noout | grep -i "TLS Web Server" + + - name: "[ * ] collecting test logs" + if: ${{ failure() }} + run: | + mkdir -p ${{ github.workspace }}/artifact/upload + docker exec acme-srv tar cvfz /tmp/acme2certifier/a2c.tgz /opt/acme2certifier + sudo rm -rf data/*.rpm + sudo cp -rp data/ ${{ github.workspace }}/artifact/data/ + sudo cp -rp acme-sh/ ${{ github.workspace }}/artifact/acme-sh/ + docker exec acme-srv ls -la /tmp > ${{ github.workspace }}/artifact/data/tmp_list + docker exec acme-srv ls -la /tmp + docker exec acme-srv cat /var/log/messages > ${{ github.workspace }}/artifact/acme-srv.log + sudo tar -C ${{ github.workspace }}/artifact/ -cvzf ${{ github.workspace }}/artifact/upload/artifact.tar.gz data acme-srv.log acme-sh + + - name: "[ * ] uploading artificates" + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: mscertsrv_handler_tests_rpm-rh${{ matrix.rhversion }}.tar.gz + path: ${{ github.workspace }}/artifact/upload/ \ No newline at end of file diff --git a/docs/mscertsrv.md b/docs/mscertsrv.md index 5d919188..81347fe2 100644 --- a/docs/mscertsrv.md +++ b/docs/mscertsrv.md @@ -2,11 +2,11 @@ # CA handler for Microsoft Certification Authority Web Enrollment Service -This CA handler uses Microsofts [Certification Authority Web Enrollment service](https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-r2-and-2012/hh831649(v=ws.11)) for certificate enrollment and the python library [magnuswatn](https://github.com/magnuswatn/)/[certsrv](https://github.com/magnuswatn/certsrv) for communication with the enrollment service. +This CA handler uses Microsofts [Certification Authority Web Enrollment service](https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-r2-and-2012/hh831649(v=ws.11)) for certificate enrollment and modified version of the python library [magnuswatn](https://github.com/magnuswatn/)/[certsrv](https://github.com/magnuswatn/certsrv) for communication with the enrollment service. When using the handler please be aware of the following limitations: -- Authentication towards Web Enrollment Service is limited to "basic" or "ntlm". There is currently no support for ClientAuth +- Authentication towards Web Enrollment Service is limited to "basic" "ntlm" or "gssapi" Kkerberos). There is currently no support for ClientAuth - Communication is limited to https - Revocation operations are not supported @@ -16,6 +16,7 @@ When using the handler please be aware of the following limitations: 2. You need to have a set of credentials with permissions to access the service and enrollment templates 3. Authentication method (basic or ntlm) to the service must be configured correctly. 4. (optional): In case you are installing from RPM and plan to use ntlm as authentication scheme you need two additonal python modules [python3-request-ntlm](https://pypi.org/project/requests_ntlm/) and [python3-ntlm-auth](https://pypi.org/project/ntlm-auth/) which are neither part of Standard nor the EPEL repo. If you have no clue from where to get these packaages feel free to use the ones being part of [the a2c github repository](https://github.com/grindsa/sbom/tree/main/rpm-repo/RPMs) +5. (optional): In case you are installing from RPM and plan to use gssapi as authentication scheme you need two additonal python modules [python3-request-gssapi](https://pypi.org/project/requests-gssapi/) and [gssapi](https://pypi.org/project/gssapi/). If you have no clue from where to get these packaages feel free to use the ones being part of [the a2c github repository](https://github.com/grindsa/sbom/tree/main/rpm-repo/RPMs) It is helpful to verify the service access before starting the configuration of acme2certifier @@ -31,6 +32,14 @@ root@rlh:~# curl -I --ntlm --user : -k https:///certsrv/ root@rlh:~# curl -I --user : -k https:///certsrv/ ``` +- service access by using gssapi authentication + +```bash +root@rlh:~# export KRB5_CONFIG=/krb5.conf +root@rlh:~# kinit +root@rlh:~# curl --negotiate -u: : -k https:///certsrv/ +``` + Access to the service is possible if you see the status code 200 returned as part of the response ```bash @@ -69,6 +78,8 @@ password: ca_bundle: auth_method: template: +allowed_domainlist: ["example.com", "*.example2.com"] +krb5_config: /krb5.conf ``` - host - hostname of the system providing the Web enrollment service @@ -78,7 +89,8 @@ template: - password - password - password_variable - *optional* - name of the environment variable containing the password used for service access (a configured `password` parameter in acme_srv.cfg takes precedence) - ca_bundle - CA certificate bundle in pem format needed to validate the server certificate -- auth_method - authentication method (either "basic" or "ntlm") +- auth_method - authentication method (either "basic", "ntlm" or "gssapi") +- krb5_config - *optional* - path to individual krb5.conf - template - certificate template used for enrollment - allowed_domainlist - *optional* - list of domain-names allowed for enrollment in json format example: ["bar.local$, bar.foo.local] From 1a716f360748703acaa45dcb8902a6fa5154db7f Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 11 May 2024 12:54:11 +0200 Subject: [PATCH 201/460] [fix] unittests --- examples/ca_handler/mscertsrv_ca_handler.py | 1 + test/test_msca_handler.py | 93 ++++++++++++++++----- 2 files changed, 71 insertions(+), 23 deletions(-) diff --git a/examples/ca_handler/mscertsrv_ca_handler.py b/examples/ca_handler/mscertsrv_ca_handler.py index 7cd7afbe..917b9cec 100644 --- a/examples/ca_handler/mscertsrv_ca_handler.py +++ b/examples/ca_handler/mscertsrv_ca_handler.py @@ -136,6 +136,7 @@ def _config_parameters_load(self, config_dic: Dict[str, str]): self.ca_bundle = config_dic['CAhandler']['ca_bundle'] if 'krb5_config' in config_dic['CAhandler']: self.krb5_config = config_dic['CAhandler']['krb5_config'] + self.verify = config_dic.getboolean('CAhandler', 'verify', fallback=True) if 'allowed_domainlist' in config_dic['CAhandler']: diff --git a/test/test_msca_handler.py b/test/test_msca_handler.py index a52b0c7a..bdf7e6dc 100644 --- a/test/test_msca_handler.py +++ b/test/test_msca_handler.py @@ -7,6 +7,7 @@ import os from unittest.mock import patch, Mock, MagicMock import base64 +import configparser sys.path.insert(0, '.') sys.path.insert(1, '..') @@ -81,7 +82,9 @@ def test_007_config_load(self, mock_load_cfg): @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_008_config_load(self, mock_load_cfg): """ test _config_load cahandler section with unknown values """ - mock_load_cfg.return_value = {'CAhandler': {'foo': 'bar'}} + parser = configparser.ConfigParser() + parser['CAhandler'] = {'foo': 'bar'} + mock_load_cfg.return_value = parser self.cahandler._config_load() self.assertFalse(self.cahandler.host) self.assertFalse(self.cahandler.user) @@ -95,7 +98,9 @@ def test_008_config_load(self, mock_load_cfg): @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_009_config_load(self, mock_load_cfg): """ test _config_load no cahandler section with host value """ - mock_load_cfg.return_value = {'CAhandler': {'host': 'host'}} + parser = configparser.ConfigParser() + parser['CAhandler'] = {'host': 'host'} + mock_load_cfg.return_value = parser self.cahandler._config_load() self.assertEqual('host', self.cahandler.host) self.assertFalse(self.cahandler.user) @@ -109,7 +114,9 @@ def test_009_config_load(self, mock_load_cfg): @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_010_config_load(self, mock_load_cfg): """ test _config_load cahandler section with user values """ - mock_load_cfg.return_value = {'CAhandler': {'user': 'user'}} + parser = configparser.ConfigParser() + parser['CAhandler'] = {'user': 'user'} + mock_load_cfg.return_value = parser self.cahandler._config_load() self.assertFalse(self.cahandler.host) self.assertEqual('user', self.cahandler.user) @@ -123,7 +130,9 @@ def test_010_config_load(self, mock_load_cfg): @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_011_config_load(self, mock_load_cfg): """ test _config_load cahandler section with password values """ - mock_load_cfg.return_value = {'CAhandler': {'password': 'password'}} + parser = configparser.ConfigParser() + parser['CAhandler'] = {'password': 'password'} + mock_load_cfg.return_value = parser self.cahandler._config_load() self.assertFalse(self.cahandler.host) self.assertFalse(self.cahandler.user) @@ -137,7 +146,9 @@ def test_011_config_load(self, mock_load_cfg): @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_012_config_load(self, mock_load_cfg): """ test _config_load cahandler section with authmethod basic """ - mock_load_cfg.return_value = {'CAhandler': {'auth_method': 'basic'}} + parser = configparser.ConfigParser() + parser['CAhandler'] = {'auth_method': 'basic'} + mock_load_cfg.return_value = parser self.cahandler._config_load() self.assertFalse(self.cahandler.host) self.assertFalse(self.cahandler.user) @@ -151,7 +162,9 @@ def test_012_config_load(self, mock_load_cfg): @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_013_config_load(self, mock_load_cfg): """ test _config_load cahandler section with authmethod ntlm """ - mock_load_cfg.return_value = {'CAhandler': {'auth_method': 'ntlm'}} + parser = configparser.ConfigParser() + parser['CAhandler'] = {'auth_method': 'ntlm'} + mock_load_cfg.return_value = parser self.cahandler._config_load() self.assertFalse(self.cahandler.host) self.assertFalse(self.cahandler.user) @@ -165,7 +178,9 @@ def test_013_config_load(self, mock_load_cfg): @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_014_config_load(self, mock_load_cfg): """ test _config_load cahandler section with authmethod unknown """ - mock_load_cfg.return_value = {'CAhandler': {'auth_method': 'unknown'}} + parser = configparser.ConfigParser() + parser['CAhandler'] = {'auth_method': 'unknown'} + mock_load_cfg.return_value = parser self.cahandler._config_load() self.assertFalse(self.cahandler.host) self.assertFalse(self.cahandler.user) @@ -179,7 +194,9 @@ def test_014_config_load(self, mock_load_cfg): @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_015_config_load(self, mock_load_cfg): """ test _config_load cahandler section with ca_bundle value """ - mock_load_cfg.return_value = {'CAhandler': {'ca_bundle': 'ca_bundle'}} + parser = configparser.ConfigParser() + parser['CAhandler'] = {'ca_bundle': 'ca_bundle'} + mock_load_cfg.return_value = parser self.cahandler._config_load() self.assertFalse(self.cahandler.host) self.assertFalse(self.cahandler.user) @@ -193,7 +210,9 @@ def test_015_config_load(self, mock_load_cfg): @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_016_config_load(self, mock_load_cfg): """ test _config_load cahandler section with template value """ - mock_load_cfg.return_value = {'CAhandler': {'template': 'template'}} + parser = configparser.ConfigParser() + parser['CAhandler'] = {'template': 'template'} + mock_load_cfg.return_value = parser self.cahandler._config_load() self.assertFalse(self.cahandler.host) self.assertFalse(self.cahandler.user) @@ -207,7 +226,9 @@ def test_016_config_load(self, mock_load_cfg): @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_017_config_load(self, mock_load_cfg): """ test _config_load cahandler section with template value """ - mock_load_cfg.return_value = {'CAhandler': {'krb5_config': 'krb5_config'}} + parser = configparser.ConfigParser() + parser['CAhandler'] = {'krb5_config': 'krb5_config'} + mock_load_cfg.return_value = parser self.cahandler._config_load() self.assertFalse(self.cahandler.host) self.assertFalse(self.cahandler.user) @@ -222,7 +243,9 @@ def test_017_config_load(self, mock_load_cfg): @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_018_config_load(self, mock_load_cfg): """ test _config_load - load with host variable """ - mock_load_cfg.return_value = {'CAhandler': {'host_variable': 'host_variable'}} + parser = configparser.ConfigParser() + parser['CAhandler'] = {'host_variable': 'host_variable'} + mock_load_cfg.return_value = parser self.cahandler._config_load() self.assertEqual('host', self.cahandler.host) @@ -230,7 +253,9 @@ def test_018_config_load(self, mock_load_cfg): @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_019_config_load(self, mock_load_cfg): """ test _config_load - load with host variable which does not exist """ - mock_load_cfg.return_value = {'CAhandler': {'host_variable': 'doesnotexist'}} + parser = configparser.ConfigParser() + parser['CAhandler'] = {'host_variable': 'doesnotexist'} + mock_load_cfg.return_value = parser with self.assertLogs('test_a2c', level='INFO') as lcm: self.cahandler._config_load() self.assertFalse(self.cahandler.host) @@ -240,7 +265,9 @@ def test_019_config_load(self, mock_load_cfg): @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_020_config_load(self, mock_load_cfg): """ test _config_load - load with host variable which gets overwritten """ - mock_load_cfg.return_value = {'CAhandler': {'host_variable': 'host_variable', 'host': 'host_local'}} + parser = configparser.ConfigParser() + parser['CAhandler'] = {'host_variable': 'host_variable', 'host': 'host_local'} + mock_load_cfg.return_value = parser with self.assertLogs('test_a2c', level='INFO') as lcm: self.cahandler._config_load() self.assertEqual('host_local', self.cahandler.host) @@ -250,7 +277,9 @@ def test_020_config_load(self, mock_load_cfg): @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_021_config_load(self, mock_load_cfg): """ test _config_load - load with user variable """ - mock_load_cfg.return_value = {'CAhandler': {'user_variable': 'user_variable'}} + parser = configparser.ConfigParser() + parser['CAhandler'] = {'user_variable': 'user_variable'} + mock_load_cfg.return_value = parser self.cahandler._config_load() self.assertEqual('user', self.cahandler.user) @@ -258,7 +287,9 @@ def test_021_config_load(self, mock_load_cfg): @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_022_config_load(self, mock_load_cfg): """ test _config_load - load with user variable which does not exist """ - mock_load_cfg.return_value = {'CAhandler': {'user_variable': 'doesnotexist'}} + parser = configparser.ConfigParser() + parser['CAhandler'] = {'user_variable': 'doesnotexist'} + mock_load_cfg.return_value = parser with self.assertLogs('test_a2c', level='INFO') as lcm: self.cahandler._config_load() self.assertFalse(self.cahandler.user) @@ -268,7 +299,9 @@ def test_022_config_load(self, mock_load_cfg): @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_023_config_load(self, mock_load_cfg): """ test _config_load - load with user variable which gets overwritten """ - mock_load_cfg.return_value = {'CAhandler': {'user_variable': 'user_variable', 'user': 'user_local'}} + parser = configparser.ConfigParser() + parser['CAhandler'] = {'user_variable': 'user_variable', 'user': 'user_local'} + mock_load_cfg.return_value = parser with self.assertLogs('test_a2c', level='INFO') as lcm: self.cahandler._config_load() self.assertEqual('user_local', self.cahandler.user) @@ -278,7 +311,9 @@ def test_023_config_load(self, mock_load_cfg): @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_024_config_load(self, mock_load_cfg): """ test _config_load - load with password variable """ - mock_load_cfg.return_value = {'CAhandler': {'password_variable': 'password_variable'}} + parser = configparser.ConfigParser() + parser['CAhandler'] = {'password_variable': 'password_variable'} + mock_load_cfg.return_value = parser self.cahandler._config_load() self.assertEqual('password', self.cahandler.password) @@ -286,7 +321,9 @@ def test_024_config_load(self, mock_load_cfg): @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_025_config_load(self, mock_load_cfg): """ test _config_load - load with password variable which does not exist """ - mock_load_cfg.return_value = {'CAhandler': {'password_variable': 'doesnotexist'}} + parser = configparser.ConfigParser() + parser['CAhandler'] = {'password_variable': 'doesnotexist'} + mock_load_cfg.return_value = parser with self.assertLogs('test_a2c', level='INFO') as lcm: self.cahandler._config_load() self.assertFalse(self.cahandler.password) @@ -297,7 +334,9 @@ def test_025_config_load(self, mock_load_cfg): @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_026_config_load(self, mock_load_cfg): """ test _config_load - load with password variable which gets overwritten """ - mock_load_cfg.return_value = {'CAhandler': {'password_variable': 'password_variable', 'password': 'password_local'}} + parser = configparser.ConfigParser() + parser['CAhandler'] = {'password_variable': 'password_variable', 'password': 'password_local'} + mock_load_cfg.return_value = parser with self.assertLogs('test_a2c', level='INFO') as lcm: self.cahandler._config_load() self.assertEqual('password_local', self.cahandler.password) @@ -309,7 +348,9 @@ def test_026_config_load(self, mock_load_cfg): @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_027_config_load(self, mock_load_cfg, mock_json, mock_chk): """ test _config_load ca_handler configured load proxies """ - mock_load_cfg.return_value = {'DEFAULT': {'proxy_server_list': 'foo'}} + parser = configparser.ConfigParser() + parser['DEFAULT'] = {'proxy_server_list': 'foo'} + mock_load_cfg.return_value = parser mock_json.return_value = 'foo.bar.local' mock_chk.return_value = 'proxy.bar.local' self.cahandler._config_load() @@ -323,8 +364,10 @@ def test_027_config_load(self, mock_load_cfg, mock_json, mock_chk): @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_028_config_load(self, mock_load_cfg, mock_json, mock_chk): """ test _config_load ca_handler configured load proxies failed with exception in json.load """ - mock_load_cfg.return_value = {'DEFAULT': {'proxy_server_list': 'foo'}} + parser = configparser.ConfigParser() + parser['DEFAULT'] = {'proxy_server_list': 'foo'} mock_json.side_effect = Exception('exc_load_config') + mock_load_cfg.return_value = parser mock_chk.side = 'proxy.bar.local' with self.assertLogs('test_a2c', level='INFO') as lcm: self.cahandler._config_load() @@ -337,7 +380,9 @@ def test_028_config_load(self, mock_load_cfg, mock_json, mock_chk): @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_029_config_load(self, mock_load_cfg): """ allowd_domain_list """ - mock_load_cfg.return_value = {'CAhandler': {'allowed_domainlist': '["allowed_domainlist"]'}} + parser = configparser.ConfigParser() + parser['CAhandler'] = {'allowed_domainlist': '["allowed_domainlist"]'} + mock_load_cfg.return_value = parser self.cahandler._config_load() self.assertFalse(self.cahandler.host) self.assertFalse(self.cahandler.user) @@ -351,7 +396,9 @@ def test_029_config_load(self, mock_load_cfg): @patch('examples.ca_handler.mscertsrv_ca_handler.load_config') def test_030_config_load(self, mock_load_cfg): """ allowd_domain_list """ - mock_load_cfg.return_value = {'CAhandler': {'allowed_domainlist': 'wrongstring'}} + parser = configparser.ConfigParser() + parser['CAhandler'] = {'allowed_domainlist': 'wrongstring'} + mock_load_cfg.return_value = parser with self.assertLogs('test_a2c', level='INFO') as lcm: self.cahandler._config_load() self.assertFalse(self.cahandler.host) From 3311b82961febeeeb43b6dd17c0cfc000b3f6f04 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 11 May 2024 13:21:54 +0200 Subject: [PATCH 202/460] [fix] pytest dependencies --- .github/workflows/python-test.yml | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index 06357bb7..dcedc089 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -15,6 +15,7 @@ jobs: strategy: matrix: python_version: ['3.x', '3.12', '3.11', '3.10', '3.9', '3.8'] + name: Python Unittest (${{ matrix.python_version }}) steps: - uses: actions/checkout@v4 @@ -22,11 +23,19 @@ jobs: uses: actions/setup-python@v4 with: python-version: ${{ matrix.python_version }} + + - name: Install components + run: | + sudo DEBIAN_FRONTEND="noninteractive" apt-get install --no-install-recommends -y \ + libkrb5-dev \ + python3-gssapi \ + - name: Install dependencies run: | python -m pip install --upgrade pip pip install pytest if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + - name: cp run: | cp examples/ca_handler/skeleton_ca_handler.py acme_srv/ca_handler.py @@ -34,37 +43,53 @@ jobs: - name: Python test run: | pytest + pylint: runs-on: ubuntu-latest strategy: matrix: - python_version: [3.x, 3.8] + python_version: ['3.x', '3.12', '3.11', '3.10', '3.9', '3.8'] + name: Pylint test (${{ matrix.python_version }}) + steps: - uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python_version }} uses: actions/setup-python@v4 with: python-version: ${{ matrix.python_version }} + + - name: Install components + run: | + sudo DEBIAN_FRONTEND="noninteractive" apt-get install --no-install-recommends -y \ + libkrb5-dev \ + python3-gssapi \ + - name: Install dependencies run: | python -m pip install --upgrade pip pip install pylint pylint-exit if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + - name: cp run: | cp examples/ca_handler/skeleton_ca_handler.py acme_srv/ca_handler.py cp examples/db_handler/wsgi_handler.py acme_srv/db_handler.py cp examples/acme_srv.cfg acme_srv/ + - name: "Pylint folder: acme" run: | pylint --rcfile=".github/pylintrc" acme_srv/ || pylint-exit $? + - name: "Pylint folder: tools" run: | pylint --rcfile=".github/pylintrc" tools/*.py || pylint-exit $? + - name: "Pylint folder: examples/db_handler" run: | pylint --rcfile=".github/pylintrc" examples/db_handler/*.py || pylint-exit $? + - name: "Pylint folder: examples/ca_handler" run: | pylint --rcfile=".github/pylintrc" examples/ca_handler/*.py || pylint-exit $? From d5ef7180344e242aff84c690d25e050169fef16b Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 11 May 2024 13:31:06 +0200 Subject: [PATCH 203/460] [fix] soap-server --- examples/Docker/soap-srv/Dockerfile | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/examples/Docker/soap-srv/Dockerfile b/examples/Docker/soap-srv/Dockerfile index 604d7d63..3bb53542 100644 --- a/examples/Docker/soap-srv/Dockerfile +++ b/examples/Docker/soap-srv/Dockerfile @@ -1,7 +1,20 @@ FROM ubuntu:22.04 LABEL maintainer="grindelsack@gmail.com" -RUN DEBIAN_FRONTEND="noninteractive" apt-get update && apt-get -y install --no-install-recommends tzdata && apt-get install -y --no-install-recommends python3-pip curl && rm -rf /var/lib/apt/lists/* +RUN apt-get update && \ + DEBIAN_FRONTEND="noninteractive" apt-get -y install --no-install-recommends tzdata && \ + DEBIAN_FRONTEND="noninteractive" apt-get install --no-install-recommends -y \ + python3-pip \ + apache2 \ + apache2-data \ + libapache2-mod-wsgi-py3 \ + curl \ + krb5-user \ + libgssapi-krb5-2 \ + libkrb5-3 \ + python3-gssapi \ + && rm -rf /var/lib/apt/lists/* + # install python requirements COPY requirements.txt /tmp/requirements.txt From 3d04ad5297d89b38c9b8f9a2177500ca0bcf8c76 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 11 May 2024 13:47:16 +0200 Subject: [PATCH 204/460] [fix] manuell installation procedure --- docs/install_apache2_wsgi.md | 2 +- docs/install_nginx_wsgi_ub22.md | 2 +- examples/install_scripts/a2c-ubuntu22-apache2.sh | 2 +- examples/install_scripts/a2c-ubuntu22-nginx.sh | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/install_apache2_wsgi.md b/docs/install_apache2_wsgi.md index 30182d00..f79aec31 100644 --- a/docs/install_apache2_wsgi.md +++ b/docs/install_apache2_wsgi.md @@ -5,7 +5,7 @@ A [readymade shell script](../examples/install_scripts/a2c-ubuntu22-apache2.sh) performing the below tasks will can be found in `examples/install_scripts` directory. 1. Install apache2 and the corresponding wsgi module -$ sudo apt-get install -y apache2 libapache2-mod-wsgi-py3 python3-pip apache2-data +$ sudo apt-get install -y apache2 libapache2-mod-wsgi-py3 python3-pip apache2-data curl krb5-user libgssapi-krb5-2 libkrb5-3 python3-gssapi 2. check if the wsgi module is activated in your apache configuration diff --git a/docs/install_nginx_wsgi_ub22.md b/docs/install_nginx_wsgi_ub22.md index 2712e9a6..a37f5219 100644 --- a/docs/install_nginx_wsgi_ub22.md +++ b/docs/install_nginx_wsgi_ub22.md @@ -7,7 +7,7 @@ A [readymade shell script](../examples/install_scripts/a2c-ubuntu22-nginx.sh) pe 1. Install nginx and the corresponding wsgi module ```bash -$ sudo apt-get install -y python3-pip nginx uwsgi uwsgi-plugin-python3 curl +$ sudo apt-get install -y python3-pip nginx uwsgi uwsgi-plugin-python3 curl krb5-user libgssapi-krb5-2 libkrb5-3 python3-gssapi ``` 2. download the acme2certifier from [Github](https://github.com/grindsa/acme2certifier/archive/refs/heads/master.tar.gz) and unpack it. diff --git a/examples/install_scripts/a2c-ubuntu22-apache2.sh b/examples/install_scripts/a2c-ubuntu22-apache2.sh index 10303212..fe50a492 100644 --- a/examples/install_scripts/a2c-ubuntu22-apache2.sh +++ b/examples/install_scripts/a2c-ubuntu22-apache2.sh @@ -7,7 +7,7 @@ # 1 install needed packages sudo apt-get update -sudo apt-get install -y apache2 libapache2-mod-wsgi-py3 python3-pip apache2-data +sudo apt-get install -y apache2 libapache2-mod-wsgi-py3 python3-pip apache2-data curl krb5-user libgssapi-krb5-2 libkrb5-3 python3-gssapi # 2 check if mod wsgi got activated apache2ctl -M | grep -i wsgi diff --git a/examples/install_scripts/a2c-ubuntu22-nginx.sh b/examples/install_scripts/a2c-ubuntu22-nginx.sh index 3a40b397..bb314378 100644 --- a/examples/install_scripts/a2c-ubuntu22-nginx.sh +++ b/examples/install_scripts/a2c-ubuntu22-nginx.sh @@ -8,7 +8,7 @@ # 1 install needed packages echo "## Install missing packages" sudo apt-get update -sudo apt-get install -y python3-pip nginx uwsgi uwsgi-plugin-python3 curl +sudo apt-get install -y python3-pip nginx uwsgi uwsgi-plugin-python3 curl krb5-user libgssapi-krb5-2 libkrb5-3 python3-gssapi # 3 install needed python modules echo "## Install missing pythom modules" From e3ef0fa50c2c8d69263f07a0f17aa46d61772144 Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 11 May 2024 16:12:08 +0200 Subject: [PATCH 205/460] [wf] max-parallel: 1 in msca, nclm and proxy workflow --- .github/workflows/ca_handler_tests_msca.yml | 8 ++++---- .github/workflows/ca_handler_tests_nclm.yml | 2 ++ .github/workflows/proxy-test.yml | 2 ++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ca_handler_tests_msca.yml b/.github/workflows/ca_handler_tests_msca.yml index 340d4cb7..0cb00565 100644 --- a/.github/workflows/ca_handler_tests_msca.yml +++ b/.github/workflows/ca_handler_tests_msca.yml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest strategy: fail-fast: false - max-parallel: 2 + max-parallel: 1 matrix: websrv: ['apache2', 'nginx'] dbhandler: ['wsgi', 'django'] @@ -289,7 +289,7 @@ jobs: needs: mswcce_handler_tests strategy: fail-fast: false - max-parallel: 2 + max-parallel: 1 matrix: websrv: ['apache2', 'nginx'] dbhandler: ['wsgi', 'django'] @@ -583,7 +583,7 @@ jobs: name: "mswcce_handler_tests_rpm" runs-on: ubuntu-latest strategy: - # max-parallel: 1 + max-parallel: 1 fail-fast: false matrix: rhversion: [8, 9] @@ -867,7 +867,7 @@ jobs: runs-on: ubuntu-latest needs: mswcce_handler_tests_rpm strategy: - # max-parallel: 1 + max-parallel: 1 fail-fast: false matrix: rhversion: [8, 9] diff --git a/.github/workflows/ca_handler_tests_nclm.yml b/.github/workflows/ca_handler_tests_nclm.yml index 9ca5adfb..062698a0 100644 --- a/.github/workflows/ca_handler_tests_nclm.yml +++ b/.github/workflows/ca_handler_tests_nclm.yml @@ -14,6 +14,7 @@ jobs: runs-on: ubuntu-latest strategy: fail-fast: false + max-parallel: 1 matrix: websrv: ['apache2', 'nginx'] dbhandler: ['wsgi', 'django'] @@ -162,6 +163,7 @@ jobs: runs-on: ubuntu-latest strategy: fail-fast: false + max-parallel: 1 matrix: rhversion: [8, 9] steps: diff --git a/.github/workflows/proxy-test.yml b/.github/workflows/proxy-test.yml index 1ca326eb..a3040dc7 100644 --- a/.github/workflows/proxy-test.yml +++ b/.github/workflows/proxy-test.yml @@ -15,6 +15,7 @@ jobs: strategy: fail-fast: false matrix: + max-parallel: 1 websrv: ['apache2'] dbhandler: ['wsgi', 'django'] @@ -355,6 +356,7 @@ jobs: strategy: fail-fast: false matrix: + max-parallel: 1 rhversion: [8, 9] steps: From ac3d4d5bce576cf7423cabeb478ad101f14df71c Mon Sep 17 00:00:00 2001 From: grindsa Date: Sat, 11 May 2024 16:39:28 +0200 Subject: [PATCH 206/460] [feat] allowed_domainlist in mswcce_ca_handler.py --- docs/mswcce.md | 2 + examples/ca_handler/mswcce_ca_handler.py | 74 ++++++++------ test/test_mswcce_ca_handler.py | 117 ++++++++++++++++++----- 3 files changed, 139 insertions(+), 54 deletions(-) diff --git a/docs/mswcce.md b/docs/mswcce.md index ae2e37b5..4b1ffd0b 100644 --- a/docs/mswcce.md +++ b/docs/mswcce.md @@ -38,6 +38,7 @@ ca_name: ca_bundle: template: