Merge branch 'master' into url_context_path

This commit is contained in:
Hossein Shafagh 2020-10-23 14:13:25 -07:00 committed by GitHub
commit 2b7cb0d44f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 123 additions and 17 deletions

View File

@ -735,3 +735,45 @@ def automatically_enable_autorotate():
}) })
cert.rotation = True cert.rotation = True
database.update(cert) database.update(cert)
@manager.command
def deactivate_entrust_certificates():
"""
Attempt to deactivate test certificates issued by Entrust
"""
log_data = {
"function": f"{__name__}.{sys._getframe().f_code.co_name}",
"message": "Deactivating Entrust certificates"
}
certificates = get_all_valid_certs(['entrust-issuer'])
entrust_plugin = plugins.get('entrust-issuer')
for cert in certificates:
try:
response = entrust_plugin.deactivate_certificate(cert)
if response == 200:
cert.status = "revoked"
else:
cert.status = "unknown"
log_data["valid"] = cert.status
log_data["certificate_name"] = cert.name
log_data["certificate_id"] = cert.id
metrics.send(
"certificate_deactivate",
"counter",
1,
metric_tags={"status": log_data["valid"],
"certificate_name": log_data["certificate_name"],
"certificate_id": log_data["certificate_id"]},
)
current_app.logger.info(log_data)
database.update(cert)
except Exception as e:
current_app.logger.info(log_data)
sentry.captureException()
current_app.logger.exception(e)

View File

@ -105,7 +105,7 @@ def get_all_certs():
def get_all_valid_certs(authority_plugin_name): def get_all_valid_certs(authority_plugin_name):
""" """
Retrieves all valid (not expired) certificates within Lemur, for the given authority plugin names Retrieves all valid (not expired & not revoked) certificates within Lemur, for the given authority plugin names
ignored if no authority_plugin_name provided. ignored if no authority_plugin_name provided.
Note that depending on the DB size retrieving all certificates might an expensive operation Note that depending on the DB size retrieving all certificates might an expensive operation
@ -116,11 +116,12 @@ def get_all_valid_certs(authority_plugin_name):
return ( return (
Certificate.query.outerjoin(Authority, Authority.id == Certificate.authority_id).filter( Certificate.query.outerjoin(Authority, Authority.id == Certificate.authority_id).filter(
Certificate.not_after > arrow.now().format("YYYY-MM-DD")).filter( Certificate.not_after > arrow.now().format("YYYY-MM-DD")).filter(
Authority.plugin_name.in_(authority_plugin_name)).all() Authority.plugin_name.in_(authority_plugin_name)).filter(Certificate.revoked.is_(False)).all()
) )
else: else:
return ( return (
Certificate.query.filter(Certificate.not_after > arrow.now().format("YYYY-MM-DD")).all() Certificate.query.filter(Certificate.not_after > arrow.now().format("YYYY-MM-DD")).filter(
Certificate.revoked.is_(False)).all()
) )
@ -359,7 +360,12 @@ def create(**kwargs):
try: try:
cert_body, private_key, cert_chain, external_id, csr = mint(**kwargs) cert_body, private_key, cert_chain, external_id, csr = mint(**kwargs)
except Exception: except Exception:
current_app.logger.error("Exception minting certificate", exc_info=True) log_data = {
"message": "Exception minting certificate",
"issuer": kwargs["authority"].name,
"cn": kwargs["common_name"],
}
current_app.logger.error(log_data, exc_info=True)
sentry.captureException() sentry.captureException()
raise raise
kwargs["body"] = cert_body kwargs["body"] = cert_body

View File

@ -759,7 +759,7 @@ def check_revoked():
log_data = { log_data = {
"function": function, "function": function,
"message": "check if any certificates are revoked revoked", "message": "check if any valid certificate is revoked",
"task_id": task_id, "task_id": task_id,
} }
@ -842,3 +842,39 @@ def enable_autorotate_for_certs_attached_to_endpoint():
cli_certificate.automatically_enable_autorotate() cli_certificate.automatically_enable_autorotate()
metrics.send(f"{function}.success", "counter", 1) metrics.send(f"{function}.success", "counter", 1)
return log_data return log_data
@celery.task(soft_time_limit=3600)
def deactivate_entrust_test_certificates():
"""
This celery task attempts to deactivate all not yet deactivated Entrust certificates, and should only run in TEST
:return:
"""
function = f"{__name__}.{sys._getframe().f_code.co_name}"
task_id = None
if celery.current_task:
task_id = celery.current_task.request.id
log_data = {
"function": function,
"message": "deactivate entrust certificates",
"task_id": task_id,
}
if task_id and is_task_active(function, task_id, None):
log_data["message"] = "Skipping task: Task is already active"
current_app.logger.debug(log_data)
return
current_app.logger.debug(log_data)
try:
cli_certificate.deactivate_entrust_certificates()
except SoftTimeLimitExceeded:
log_data["message"] = "Time limit exceeded."
current_app.logger.error(log_data)
sentry.captureException()
metrics.send("celery.timeout", "counter", 1, metric_tags={"function": function})
return
metrics.send(f"{function}.success", "counter", 1)
return log_data

View File

@ -37,7 +37,13 @@ def log_status_code(r, *args, **kwargs):
:param kwargs: :param kwargs:
:return: :return:
""" """
log_data = {
"reason": (r.reason if r.reason else ""),
"status_code": r.status_code,
"url": (r.url if r.url else ""),
}
metrics.send("digicert_status_code_{}".format(r.status_code), "counter", 1) metrics.send("digicert_status_code_{}".format(r.status_code), "counter", 1)
current_app.logger.info(log_data)
def signature_hash(signing_algorithm): def signature_hash(signing_algorithm):
@ -171,7 +177,7 @@ def map_cis_fields(options, csr):
"csr": csr, "csr": csr,
"signature_hash": signature_hash(options.get("signing_algorithm")), "signature_hash": signature_hash(options.get("signing_algorithm")),
"validity": { "validity": {
"valid_to": validity_end.format("YYYY-MM-DDTHH:MM") + "Z" "valid_to": validity_end.format("YYYY-MM-DDTHH:mm:ss") + "Z"
}, },
"organization": { "organization": {
"name": options["organization"], "name": options["organization"],
@ -204,7 +210,7 @@ def handle_response(response):
:return: :return:
""" """
if response.status_code > 399: if response.status_code > 399:
raise Exception(response.json()["errors"][0]["message"]) raise Exception("DigiCert rejected request with the error:" + response.json()["errors"][0]["message"])
return response.json() return response.json()
@ -215,10 +221,17 @@ def handle_cis_response(response):
:param response: :param response:
:return: :return:
""" """
if response.status_code > 399: if response.status_code == 404:
raise Exception(response.text) raise Exception("DigiCert: order not in issued state")
elif response.status_code == 406:
raise Exception("DigiCert: wrong header request format")
elif response.status_code > 399:
raise Exception("DigiCert rejected request with the error:" + response.text)
return response.json() if response.url.endswith("download"):
return response.content
else:
return response.json()
@retry(stop_max_attempt_number=10, wait_fixed=10000) @retry(stop_max_attempt_number=10, wait_fixed=10000)
@ -238,11 +251,9 @@ def get_cis_certificate(session, base_url, order_id):
certificate_url = "{0}/platform/cis/certificate/{1}/download".format(base_url, order_id) certificate_url = "{0}/platform/cis/certificate/{1}/download".format(base_url, order_id)
session.headers.update({"Accept": "application/x-pkcs7-certificates"}) session.headers.update({"Accept": "application/x-pkcs7-certificates"})
response = session.get(certificate_url) response = session.get(certificate_url)
response_content = handle_cis_response(response)
if response.status_code == 404: cert_chain_pem = convert_pkcs7_bytes_to_pem(response_content)
raise Exception("Order not in issued state.")
cert_chain_pem = convert_pkcs7_bytes_to_pem(response.content)
if len(cert_chain_pem) < 3: if len(cert_chain_pem) < 3:
raise Exception("Missing the certificate chain") raise Exception("Missing the certificate chain")
return cert_chain_pem return cert_chain_pem

View File

@ -123,7 +123,7 @@ def test_map_cis_fields_with_validity_years(mock_current_app, authority):
"signature_hash": "sha256", "signature_hash": "sha256",
"organization": {"name": "Example, Inc."}, "organization": {"name": "Example, Inc."},
"validity": { "validity": {
"valid_to": arrow.get(2018, 11, 3).format("YYYY-MM-DDTHH:MM") + "Z" "valid_to": arrow.get(2018, 11, 3).format("YYYY-MM-DDTHH:mm:ss") + "Z"
}, },
"profile_name": None, "profile_name": None,
} }
@ -159,7 +159,7 @@ def test_map_cis_fields_with_validity_end_and_start(mock_current_app, app, autho
"signature_hash": "sha256", "signature_hash": "sha256",
"organization": {"name": "Example, Inc."}, "organization": {"name": "Example, Inc."},
"validity": { "validity": {
"valid_to": arrow.get(2017, 5, 7).format("YYYY-MM-DDTHH:MM") + "Z" "valid_to": arrow.get(2017, 5, 7).format("YYYY-MM-DDTHH:mm:ss") + "Z"
}, },
"profile_name": None, "profile_name": None,
} }

View File

@ -20,7 +20,13 @@ def log_status_code(r, *args, **kwargs):
:param kwargs: :param kwargs:
:return: :return:
""" """
log_data = {
"reason": (r.reason if r.reason else ""),
"status_code": r.status_code,
"url": (r.url if r.url else ""),
}
metrics.send(f"entrust_status_code_{r.status_code}", "counter", 1) metrics.send(f"entrust_status_code_{r.status_code}", "counter", 1)
current_app.logger.info(log_data)
def determine_end_date(end_date): def determine_end_date(end_date):
@ -109,7 +115,12 @@ def handle_response(my_response):
"response": d "response": d
} }
current_app.logger.info(log_data) current_app.logger.info(log_data)
return d if d == {'response': 'No detailed message'}:
# status if no data
return s
else:
# return data from the response
return d
class EntrustIssuerPlugin(IssuerPlugin): class EntrustIssuerPlugin(IssuerPlugin):