def sync(source, user, ttl_hours=2): try: new_certs, updated_certs, updated_certs_by_hash = sync_certificates( source, user) metrics.send("sync.updated_certs_by_hash", "gauge", updated_certs_by_hash, metric_tags={"source": source.label}) new_endpoints, updated_endpoints, updated_endpoints_by_hash = sync_endpoints( source) metrics.send("sync.updated_endpoints_by_hash", "gauge", updated_endpoints_by_hash, metric_tags={"source": source.label}) expired_endpoints = expire_endpoints(source, ttl_hours) source.last_run = arrow.utcnow() database.update(source) return { "endpoints": (new_endpoints, updated_endpoints, expired_endpoints), "certificates": (new_certs, updated_certs), } except Exception as e: # noqa current_app.logger.warning( f"Sync source '{source.label}' aborted: {e}") capture_exception() raise e
def create(**kwargs): """ Creates a new certificate. """ from lemur.notifications import service as notification_service cert, private_key, cert_chain = mint(kwargs) cert.owner = kwargs['owner'] database.create(cert) cert.description = kwargs['description'] g.user.certificates.append(cert) database.update(g.user) # do this after the certificate has already been created because if it fails to upload to the third party # we do not want to lose the certificate information. database.update_list(cert, 'destinations', Destination, kwargs.get('destinations')) database.update_list(cert, 'replaces', Certificate, kwargs['replacements']) database.update_list(cert, 'notifications', Notification, kwargs.get('notifications')) # create default notifications for this certificate if none are provided notifications = cert.notifications if not kwargs.get('notifications'): notification_name = "DEFAULT_{0}".format(cert.owner.split('@')[0].upper()) notifications += notification_service.create_default_expiration_notifications(notification_name, [cert.owner]) notification_name = 'DEFAULT_SECURITY' notifications += notification_service.create_default_expiration_notifications(notification_name, current_app.config.get('LEMUR_SECURITY_TEAM_EMAIL')) cert.notifications = notifications database.update(cert) return cert
def increment_attempt(pending_certificate): """ Increments pending certificate attempt counter and updates it in the database. """ pending_certificate.number_attempts += 1 database.update(pending_certificate) return pending_certificate.number_attempts
def create(kwargs): """ Create a new authority. :return: """ issuer = plugins.get(kwargs.get('pluginName')) kwargs['creator'] = g.current_user.email cert_body, intermediate, issuer_roles = issuer.create_authority(kwargs) cert = Certificate(cert_body, chain=intermediate) cert.owner = kwargs['ownerEmail'] if kwargs['caType'] == 'subca': cert.description = "This is the ROOT certificate for the {0} sub certificate authority the parent \ authority is {1}.".format( kwargs.get('caName'), kwargs.get('caParent')) else: cert.description = "This is the ROOT certificate for the {0} certificate authority.".format( kwargs.get('caName')) cert.user = g.current_user cert.notifications = notification_service.create_default_expiration_notifications( 'DEFAULT_SECURITY', current_app.config.get('LEMUR_SECURITY_TEAM_EMAIL')) # we create and attach any roles that the issuer gives us role_objs = [] for r in issuer_roles: role = role_service.create( r['name'], password=r['password'], description="{0} auto generated role".format( kwargs.get('pluginName')), username=r['username']) # the user creating the authority should be able to administer it if role.username == 'admin': g.current_user.roles.append(role) role_objs.append(role) authority = Authority(kwargs.get('caName'), kwargs['ownerEmail'], kwargs['pluginName'], cert_body, description=kwargs['caDescription'], chain=intermediate, roles=role_objs) database.update(cert) authority = database.create(authority) g.current_user.authorities.append(authority) return authority
def cleanup_after_revoke(certificate): """ Perform the needed cleanup for a revoked certificate. This includes - 1. Disabling notification 2. Disabling auto-rotation 3. Update certificate status to 'revoked' 4. Remove from AWS :param certificate: Certificate object to modify and update in DB :return: None """ certificate.notify = False certificate.rotation = False certificate.status = 'revoked' error_message = "" for destination in list(certificate.destinations): try: remove_from_destination(certificate, destination) certificate.destinations.remove(destination) except Exception as e: # This cleanup is the best-effort since certificate is already revoked at this point. # We will capture the exception and move on to the next destination sentry.captureException() error_message = error_message + f"Failed to remove destination: {destination.label}. {str(e)}. " database.update(certificate) return error_message
def update(endpoint_id, **kwargs): endpoint = database.get(Endpoint, endpoint_id) endpoint.policy = kwargs["policy"] endpoint.certificate = kwargs["certificate"] endpoint.source = kwargs["source"] endpoint.certificate_path = kwargs.get("certificate_path") endpoint.registry_type = kwargs.get("registry_type") existing_alias = {} for e in endpoint.aliases: existing_alias[e.alias] = e endpoint.aliases = [] if "aliases" in kwargs: for name in kwargs["aliases"]: if name in existing_alias: endpoint.aliases.append(existing_alias[name]) else: endpoint.aliases.append(EndpointDnsAlias(alias=name)) endpoint.last_updated = arrow.utcnow() metrics.send( "endpoint_updated", "counter", 1, metric_tags={"source": endpoint.source.label, "type": endpoint.type} ) database.update(endpoint) return endpoint
def create(**kwargs): """ Creates a new certificate. """ from lemur.notifications import service as notification_service cert, private_key, cert_chain = mint(kwargs) cert.owner = kwargs["owner"] database.create(cert) cert.description = kwargs["description"] g.user.certificates.append(cert) database.update(g.user) # do this after the certificate has already been created because if it fails to upload to the third party # we do not want to lose the certificate information. database.update_list(cert, "destinations", Destination, kwargs.get("destinations")) database.update_list(cert, "notifications", Notification, kwargs.get("notifications")) # create default notifications for this certificate if none are provided notifications = [] if not kwargs.get("notifications"): notification_name = "DEFAULT_{0}".format(cert.owner.split("@")[0].upper()) notifications += notification_service.create_default_expiration_notifications(notification_name, [cert.owner]) notification_name = "DEFAULT_SECURITY" notifications += notification_service.create_default_expiration_notifications( notification_name, current_app.config.get("LEMUR_SECURITY_TEAM_EMAIL") ) cert.notifications = notifications database.update(cert) return cert
def mint(issuer_options): """ Minting is slightly different for each authority. Support for multiple authorities is handled by individual plugins. :param issuer_options: """ authority = issuer_options['authority'] issuer = plugins.get(authority.plugin_name) # allow the CSR to be specified by the user if not issuer_options.get('csr'): csr, private_key = create_csr(issuer_options) else: csr = str(issuer_options.get('csr')) private_key = None issuer_options['creator'] = g.user.email cert_body, cert_chain = issuer.create_certificate(csr, issuer_options) cert = Certificate(cert_body, private_key, cert_chain) cert.user = g.user cert.authority = authority database.update(cert) return cert, private_key, cert_chain,
def mint(issuer_options): """ Minting is slightly different for each authority. Support for multiple authorities is handled by individual plugins. :param issuer_options: """ authority = issuer_options['authority'] issuer = plugins.get(authority.plugin_name) # allow the CSR to be specified by the user if not issuer_options.get('csr'): csr, private_key = create_csr(issuer_options) else: csr = issuer_options.get('csr') private_key = None issuer_options['creator'] = g.user.email cert_body, cert_chain = issuer.create_certificate(csr, issuer_options) cert = Certificate(cert_body, private_key, cert_chain) cert.user = g.user cert.authority = authority database.update(cert) return cert, private_key, cert_chain,
def update(endpoint_id, **kwargs): endpoint = database.get(Endpoint, endpoint_id) endpoint.policy = kwargs['policy'] endpoint.certificate = kwargs['certificate'] database.update(endpoint) return endpoint
def set_domains(dns_provider, domains): """ Increments pending certificate attempt counter and updates it in the database. """ dns_provider.domains = domains database.update(dns_provider) return dns_provider
def check_revoked(): """ Function attempts to update Lemur's internal cache with revoked certificates. This is called periodically by Lemur. It checks both CRLs and OCSP to see if a certificate is revoked. If Lemur is unable encounters an issue with verification it marks the certificate status as `unknown`. """ for cert in get_all_certs(): try: if cert.chain: status = verify_string(cert.body, cert.chain) else: status = verify_string(cert.body, "") if status is None: cert.status = 'unknown' else: cert.status = 'valid' if status else 'revoked' except Exception as e: sentry.captureException() current_app.logger.exception(e) cert.status = 'unknown' database.update(cert)
def create_certificate(pending_certificate, certificate, user): """ Create and store a certificate with pending certificate's info :arg pending_certificate: PendingCertificate which will populate the certificate :arg certificate: dict from Authority, which contains the body, chain and external id :arg user: User that called this function, used as 'creator' of the certificate if it does not have an owner """ certificate["owner"] = pending_certificate.owner data, errors = CertificateUploadInputSchema().load(certificate) if errors: raise Exception( "Unable to create certificate: {reasons}".format(reasons=errors)) data.update(vars(pending_certificate)) # Copy relationships, vars doesn't copy this without explicit fields data["notifications"] = list(pending_certificate.notifications) data["destinations"] = list(pending_certificate.destinations) data["sources"] = list(pending_certificate.sources) data["roles"] = list(pending_certificate.roles) data["replaces"] = list(pending_certificate.replaces) data["rotation_policy"] = pending_certificate.rotation_policy # Replace external id and chain with the one fetched from source data["external_id"] = certificate["external_id"] data["chain"] = certificate["chain"] creator = user_service.get_by_email(pending_certificate.owner) if not creator: # Owner of the pending certificate is not the creator, so use the current user who called # this as the creator (usually lemur) creator = user if pending_certificate.rename: # If generating name from certificate, remove the one from pending certificate del data["name"] data["creator"] = creator cert = certificate_service.import_certificate(**data) database.update(cert) metrics.send("certificate_issued", "counter", 1, metric_tags=dict(owner=cert.owner, issuer=cert.issuer)) log_service.audit_log( "certificate_from_pending_certificate", cert.name, f"Created from the pending certificate {pending_certificate.name}") log_data = { "function": "lemur.certificates.service.create", "owner": cert.owner, "name": cert.name, "serial": cert.serial, "issuer": cert.issuer, "not_after": cert.not_after.format('YYYY-MM-DD HH:mm:ss'), "not_before": cert.not_before.format('YYYY-MM-DD HH:mm:ss'), "sans": cert.san, } current_app.logger.info(log_data) return cert
def sync(source, user): new_certs, updated_certs = sync_certificates(source, user) new_endpoints, updated_endpoints = sync_endpoints(source) source.last_run = arrow.utcnow() database.update(source) return {'endpoints': (new_endpoints, updated_endpoints), 'certificates': (new_certs, updated_certs)}
def sync(source, user): new, updated = sync_certificates(source, user) new, updated = sync_endpoints(source) source.last_run = arrow.utcnow() database.update(source) return {'endpoints': (new, updated), 'certificates': (new, updated)}
def certificate_update(certificate, source): for s in certificate.sources: if s.label == source.label: break else: certificate.sources.append(source) sync_update_destination(certificate, source) database.update(certificate)
def update(endpoint_id, **kwargs): endpoint = database.get(Endpoint, endpoint_id) endpoint.policy = kwargs['policy'] endpoint.certificate = kwargs['certificate'] endpoint.source = kwargs['source'] metrics.send('endpoint_added', 'counter', 1) database.update(endpoint) return endpoint
def update(endpoint_id, **kwargs): endpoint = database.get(Endpoint, endpoint_id) endpoint.policy = kwargs['policy'] endpoint.certificate = kwargs['certificate'] endpoint.source = kwargs['source'] endpoint.last_updated = arrow.utcnow() metrics.send('endpoint_updated', 'counter', 1, metric_tags={'source': endpoint.source.label}) database.update(endpoint) return endpoint
def create(kwargs): """ Create a new authority. :rtype : Authority :return: """ issuer = plugins.get(kwargs.get('pluginName')) kwargs['creator'] = g.current_user.email cert_body, intermediate, issuer_roles = issuer.create_authority(kwargs) cert = Certificate(cert_body, chain=intermediate) cert.owner = kwargs['ownerEmail'] cert.description = "This is the ROOT certificate for the {0} certificate authority".format(kwargs.get('caName')) cert.user = g.current_user cert.notifications = notification_service.create_default_expiration_notifications( 'DEFAULT_SECURITY', current_app.config.get('LEMUR_SECURITY_TEAM_EMAIL') ) # we create and attach any roles that the issuer gives us role_objs = [] for r in issuer_roles: role = role_service.create( r['name'], password=r['password'], description="{0} auto generated role".format(kwargs.get('pluginName')), username=r['username']) # the user creating the authority should be able to administer it if role.username == 'admin': g.current_user.roles.append(role) role_objs.append(role) authority = Authority( kwargs.get('caName'), kwargs['ownerEmail'], kwargs['pluginName'], cert_body, description=kwargs['caDescription'], chain=intermediate, roles=role_objs ) database.update(cert) authority = database.create(authority) g.current_user.authorities.append(authority) return authority
def rotate_certificate(endpoint, new_cert): """Rotates a certificate on a given endpoint.""" try: endpoint.source.plugin.update_endpoint(endpoint, new_cert) endpoint.certificate = new_cert database.update(endpoint) metrics.send('certificate_rotate_success', 'counter', 1, metric_tags={'endpoint': endpoint.name, 'source': endpoint.source.label}) except Exception as e: metrics.send('certificate_rotate_failure', 'counter', 1, metric_tags={'endpoint': endpoint.name}) current_app.logger.exception(e) raise e
def sync(source, user): new_certs, updated_certs = sync_certificates(source, user) new_endpoints, updated_endpoints = sync_endpoints(source) source.last_run = arrow.utcnow() database.update(source) return { "endpoints": (new_endpoints, updated_endpoints), "certificates": (new_certs, updated_certs), }
def increment_attempt(pending_certificate): """ Increments pending certificate attempt counter and updates it in the database. """ pending_certificate.number_attempts += 1 database.update(pending_certificate) log_service.audit_log("increment_attempt_pending_certificate", pending_certificate.name, "Incremented attempts for the pending certificate") return pending_certificate.number_attempts
def run(self, elb_list, chain_path, cert_name, cert_prefix, description): for e in open(elb_list, 'r').readlines(): elb_name, account_id, region, from_port, to_port, protocol = e.strip().split(',') if cert_name: arn = "arn:aws:iam::{0}:server-certificate/{1}".format(account_id, cert_name) else: # if no cert name is provided we need to discover it listeners = elb.get_listeners(account_id, region, elb_name) # get the listener we care about for listener in listeners: if listener[0] == int(from_port) and listener[1] == int(to_port): arn = listener[4] name = get_name_from_arn(arn) certificate = cert_service.get_by_name(name) break else: sys.stdout.write("[-] Could not find ELB {0}".format(elb_name)) continue if not certificate: sys.stdout.write("[-] Could not find certificate {0} in Lemur".format(name)) continue dests = [] for d in certificate.destinations: dests.append({'id': d.id}) nots = [] for n in certificate.notifications: nots.append({'id': n.id}) new_certificate = database.clone(certificate) if cert_prefix: new_certificate.name = "{0}-{1}".format(cert_prefix, new_certificate.name) new_certificate.chain = open(chain_path, 'r').read() new_certificate.description = "{0} - {1}".format(new_certificate.description, description) new_certificate = database.create(new_certificate) database.update_list(new_certificate, 'destinations', Destination, dests) database.update_list(new_certificate, 'notifications', Notification, nots) database.update(new_certificate) arn = new_certificate.get_arn(account_id) elb.update_listeners(account_id, region, elb_name, [(from_port, to_port, protocol, arn)], [from_port]) sys.stdout.write("[+] Updated {0} to use {1}\n".format(elb_name, new_certificate.name))
def remove_source_association(certificate, source): certificate.sources.remove(source) database.update(certificate) metrics.send( "delete_certificate_source_association", "counter", 1, metric_tags={"status": SUCCESS_METRIC_STATUS, "source": source.label, "certificate": certificate.name} )
def rotate_certificate(endpoint, new_cert): """ Rotates a certificate on a given endpoint. :param endpoint: :param new_cert: :return: """ # ensure that certificate is available for rotation endpoint.source.plugin.update_endpoint(endpoint, new_cert) endpoint.certificate = new_cert database.update(endpoint)
def set_third_party(role_id, third_party_status=False): """ Sets a role to be a third party role. A user should pretty much never call this directly. :param role_id: :param third_party_status: :return: """ role = get(role_id) role.third_party = third_party_status database.update(role) return role
def cancel(pending_certificate, **kwargs): """ Cancel a pending certificate. A check should be done prior to this function to decide to revoke the certificate or just abort cancelling. Args: pending_certificate: PendingCertificate to be cancelled Returns: the pending certificate if successful, raises Exception if there was an issue """ plugin = plugins.get(pending_certificate.authority.plugin_name) plugin.cancel_ordered_certificate(pending_certificate, **kwargs) pending_certificate.status = 'Cancelled' database.update(pending_certificate) return pending_certificate
def update(domain_id, name, sensitive): """ Update an existing domain :param domain_id: :param name: :param sensitive: :return: """ domain = get(domain_id) domain.name = name domain.sensitive = sensitive database.update(domain)
def update(endpoint_id, **kwargs): endpoint = database.get(Endpoint, endpoint_id) endpoint.policy = kwargs["policy"] endpoint.certificate = kwargs["certificate"] endpoint.source = kwargs["source"] endpoint.last_updated = arrow.utcnow() metrics.send("endpoint_updated", "counter", 1, metric_tags={"source": endpoint.source.label}) database.update(endpoint) return endpoint
def certificate_create(certificate, source): data, errors = CertificateUploadInputSchema().load(certificate) if errors: raise Exception( "Unable to import certificate: {reasons}".format(reasons=errors)) cert = cert_service.import_certificate(**data) cert.description = "This certificate was automatically discovered by Lemur" cert.sources.append(source) sync_update_destination(cert, source) database.update(cert) return cert
def create_certificate(pending_certificate, certificate, user): """ Create and store a certificate with pending certificate's info Args: pending_certificate: PendingCertificate which will populate the certificate certificate: dict from Authority, which contains the body, chain and external id user: User that called this function, used as 'creator' of the certificate if it does not have an owner """ # check if the pending_certificate already has been resolved, in that case return # existing certificate maybe_resolved_cert = get(pending_certificate.id) if maybe_resolved_cert and maybe_resolved_cert.resolved and maybe_resolved_cert.resolved_cert_id: current_app.logger.warning( "Trying to resolve an already resolved certificate, returning existing resolved certificate" ) return certificate_service.get(maybe_resolved_cert.resolved_cert_id) certificate["owner"] = pending_certificate.owner data, errors = CertificateUploadInputSchema().load(certificate) if errors: raise Exception( "Unable to create certificate: {reasons}".format(reasons=errors)) data.update(vars(pending_certificate)) # Copy relationships, vars doesn't copy this without explicit fields data["notifications"] = list(pending_certificate.notifications) data["destinations"] = list(pending_certificate.destinations) data["sources"] = list(pending_certificate.sources) data["roles"] = list(pending_certificate.roles) data["replaces"] = list(pending_certificate.replaces) data["rotation_policy"] = pending_certificate.rotation_policy data["authority"] = pending_certificate.authority # Replace external id and chain with the one fetched from source data["external_id"] = certificate["external_id"] data["chain"] = certificate["chain"] creator = user_service.get_by_email(pending_certificate.owner) if not creator: # Owner of the pending certificate is not the creator, so use the current user who called # this as the creator (usually lemur) creator = user if pending_certificate.rename: # If generating name from certificate, remove the one from pending certificate del data["name"] data["creator"] = creator cert = certificate_service.import_certificate(**data) database.update(cert) return cert
def certificate_create(certificate, source): data, errors = CertificateUploadInputSchema().load(certificate) if errors: raise Exception("Unable to import certificate: {reasons}".format(reasons=errors)) data['creator'] = certificate['creator'] cert = certificate_service.import_certificate(**data) cert.description = "This certificate was automatically discovered by Lemur" cert.sources.append(source) sync_update_destination(cert, source) database.update(cert) return cert
def check_revoked(): """ Function attempts to update Lemur's internal cache with revoked certificates. This is called periodically by Lemur. It checks both CRLs and OCSP to see if a certificate is revoked. If Lemur is unable encounters an issue with verification it marks the certificate status as `unknown`. """ log_data = { "function": f"{__name__}.{sys._getframe().f_code.co_name}", "message": "Checking for revoked Certificates" } certs = get_all_valid_certs( current_app.config.get("SUPPORTED_REVOCATION_AUTHORITY_PLUGINS", [])) for cert in certs: try: if cert.chain: status = verify_string(cert.body, cert.chain) elif cert.issuer == '<selfsigned>': status = True else: status = verify_string(cert.body, "") cert.status = "valid" if status else "revoked" if cert.status == "revoked": log_data["valid"] = cert.status log_data["certificate_name"] = cert.name log_data["certificate_id"] = cert.id metrics.send( "certificate_revoked", "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) except Exception as e: sentry.captureException() current_app.logger.exception(e) cert.status = "unknown" database.update(cert)
def certificate_create(certificate, source): data, errors = CertificateUploadInputSchema().load(certificate) if errors: current_app.logger.error(f"Unable to import certificate: {errors}") return data["creator"] = certificate["creator"] cert = certificate_service.import_certificate(**data) cert.description = "This certificate was automatically discovered by Lemur" cert.sources.append(source) sync_update_destination(cert, source) database.update(cert) return cert
def backfill_signing_algo(): """ Will attempt to backfill the signing_algorithm column :return: """ from cryptography import x509 from cryptography.hazmat.backends import default_backend from lemur.certificates.models import get_signing_algorithm for c in cert_service.get_all_certs(): cert = x509.load_pem_x509_certificate(str(c.body), default_backend()) c.signing_algorithm = get_signing_algorithm(cert) c.signing_algorithm database.update(c) print(c.signing_algorithm)
def update(role_id, name, description, users): """ Update a role :param role_id: :param name: :param description: :param users: :return: """ role = get(role_id) role.name = name role.description = description role.users = users database.update(role) return role
def upload(**kwargs): """ Allows for pre-made certificates to be imported into Lemur. """ roles = create_certificate_roles(**kwargs) if kwargs.get('roles'): kwargs['roles'] += roles else: kwargs['roles'] = roles if kwargs.get('private_key'): private_key = kwargs['private_key'] if not isinstance(private_key, bytes): kwargs['private_key'] = private_key.encode('utf-8') cert = Certificate(**kwargs) cert = database.create(cert) kwargs['creator'].certificates.append(cert) cert = database.update(cert) certificate_imported.send(certificate=cert, authority=cert.authority) return cert
def update(cert_id, owner, description, active, destinations, notifications): """ Updates a certificate. :param cert_id: :param owner: :param active: :return: """ from lemur.notifications import service as notification_service cert = get(cert_id) cert.active = active cert.description = description # we might have to create new notifications if the owner changes new_notifications = [] # get existing names to remove notification_name = "DEFAULT_{0}".format(cert.owner.split("@")[0].upper()) for n in notifications: if notification_name not in n.label: new_notifications.append(n) notification_name = "DEFAULT_{0}".format(owner.split("@")[0].upper()) new_notifications += notification_service.create_default_expiration_notifications(notification_name, owner) cert.notifications = new_notifications database.update_list(cert, "destinations", Destination, destinations) cert.owner = owner return database.update(cert)
def sync(labels=None, type=None): for source in database.get_all(Source, True, field='active'): # we should be able to specify, individual sources to sync if labels: if source.label not in labels: continue if type == 'endpoints': sync_endpoints(source) elif type == 'certificates': sync_certificates(source) else: sync_certificates(source) sync_endpoints(source) source.last_run = datetime.datetime.utcnow() database.update(source)
def update(pending_cert_id, **kwargs): """ Updates a pending certificate. The allowed fields are validated by PendingCertificateEditInputSchema. """ pending_cert = get(pending_cert_id) for key, value in kwargs.items(): setattr(pending_cert, key, value) return database.update(pending_cert)
def upload(**kwargs): """ Allows for pre-made certificates to be imported into Lemur. """ roles = create_certificate_roles(**kwargs) if kwargs.get('roles'): kwargs['roles'] += roles else: kwargs['roles'] = roles cert = Certificate(**kwargs) cert = database.create(cert) g.user.certificates.append(cert) database.update(cert) return cert
def check_revoked(): """ Function attempts to update Lemur's internal cache with revoked certificates. This is called periodically by Lemur. It checks both CRLs and OCSP to see if a certificate is revoked. If Lemur is unable encounters an issue with verification it marks the certificate status as `unknown`. """ for cert in cert_service.get_all_certs(): try: if cert.chain: status = verify_string(cert.body, cert.chain) else: status = verify_string(cert.body, "") cert.status = 'valid' if status else 'invalid' except Exception as e: cert.status = 'unknown' database.update(cert)
def update(cert_id, **kwargs): """ Updates a certificate :param cert_id: :return: """ cert = get(cert_id) for key, value in kwargs.items(): setattr(cert, key, value) return database.update(cert)
def create_certificate(pending_certificate, certificate, user): """ Create and store a certificate with pending certificate's info Args: pending_certificate: PendingCertificate which will populate the certificate certificate: dict from Authority, which contains the body, chain and external id user: User that called this function, used as 'creator' of the certificate if it does not have an owner """ certificate['owner'] = pending_certificate.owner data, errors = CertificateUploadInputSchema().load(certificate) if errors: raise Exception("Unable to create certificate: {reasons}".format(reasons=errors)) data.update(vars(pending_certificate)) # Copy relationships, vars doesn't copy this without explicit fields data['notifications'] = list(pending_certificate.notifications) data['destinations'] = list(pending_certificate.destinations) data['sources'] = list(pending_certificate.sources) data['roles'] = list(pending_certificate.roles) data['replaces'] = list(pending_certificate.replaces) data['rotation_policy'] = pending_certificate.rotation_policy # Replace external id and chain with the one fetched from source data['external_id'] = certificate['external_id'] data['chain'] = certificate['chain'] creator = user_service.get_by_email(pending_certificate.owner) if not creator: # Owner of the pending certificate is not the creator, so use the current user who called # this as the creator (usually lemur) creator = user if pending_certificate.rename: # If generating name from certificate, remove the one from pending certificate del data['name'] data['creator'] = creator cert = certificate_service.import_certificate(**data) database.update(cert) return cert
def mint(issuer_options): """ Minting is slightly different for each authority. Support for multiple authorities is handled by individual plugins. :param issuer_options: """ authority = issuer_options["authority"] issuer = plugins.get(authority.plugin_name) csr, private_key = create_csr(issuer_options) issuer_options["creator"] = g.user.email cert_body, cert_chain = issuer.create_certificate(csr, issuer_options) cert = Certificate(cert_body, private_key, cert_chain) cert.user = g.user cert.authority = authority database.update(cert) return cert, private_key, cert_chain
def update(policy_id, **kwargs): """ Updates a policy. :param policy_id: :param kwargs: :return: """ policy = get(policy_id) for key, value in kwargs.items(): setattr(policy, key, value) return database.update(policy)
def upload(**kwargs): """ Allows for pre-made certificates to be imported into Lemur. """ from lemur.notifications import service as notification_service cert = Certificate( kwargs.get('public_cert'), kwargs.get('private_key'), kwargs.get('intermediate_cert'), ) # we override the generated name if one is provided if kwargs.get('name'): cert.name = kwargs['name'] cert.description = kwargs.get('description') cert.owner = kwargs['owner'] cert = database.create(cert) g.user.certificates.append(cert) database.update_list(cert, 'destinations', Destination, kwargs['destinations']) database.update_list(cert, 'notifications', Notification, kwargs['notifications']) database.update_list(cert, 'replaces', Certificate, kwargs['replacements']) # create default notifications for this certificate if none are provided notifications = [] if not kwargs.get('notifications'): notification_name = "DEFAULT_{0}".format(cert.owner.split('@')[0].upper()) notifications += notification_service.create_default_expiration_notifications(notification_name, [cert.owner]) notification_name = 'DEFAULT_SECURITY' notifications += notification_service.create_default_expiration_notifications(notification_name, current_app.config.get('LEMUR_SECURITY_TEAM_EMAIL')) cert.notifications = notifications database.update(cert) return cert
def create(**kwargs): """ Creates a new certificate. """ from lemur.notifications import service as notification_service cert, private_key, cert_chain = mint(kwargs) cert.owner = kwargs['owner'] # we override the generated name if one is provided if kwargs.get('name'): cert.name = kwargs['name'] database.create(cert) cert.description = kwargs.get('description') g.user.certificates.append(cert) database.update(g.user) # do this after the certificate has already been created because if it fails to upload to the third party # we do not want to lose the certificate information. database.update_list(cert, 'destinations', Destination, kwargs['destinations']) database.update_list(cert, 'replaces', Certificate, kwargs['replacements']) database.update_list(cert, 'notifications', Notification, kwargs['notifications']) # create default notifications for this certificate if none are provided notifications = cert.notifications if not kwargs.get('notifications'): notification_name = "DEFAULT_{0}".format(cert.owner.split('@')[0].upper()) notifications += notification_service.create_default_expiration_notifications(notification_name, [cert.owner]) notification_name = 'DEFAULT_SECURITY' notifications += notification_service.create_default_expiration_notifications(notification_name, current_app.config.get('LEMUR_SECURITY_TEAM_EMAIL')) cert.notifications = notifications database.update(cert) metrics.send('certificate_issued', 'counter', 1, metric_tags=dict(owner=cert.owner, issuer=cert.issuer)) return cert
def upload(**kwargs): """ Allows for pre-made certificates to be imported into Lemur. """ from lemur.notifications import service as notification_service cert = Certificate(kwargs.get("public_cert"), kwargs.get("private_key"), kwargs.get("intermediate_cert")) # we override the generated name if one is provided if kwargs.get("name"): cert.name = kwargs["name"] cert.description = kwargs.get("description") cert.owner = kwargs["owner"] cert = database.create(cert) g.user.certificates.append(cert) database.update_list(cert, "destinations", Destination, kwargs.get("destinations")) database.update_list(cert, "notifications", Notification, kwargs.get("notifications")) # create default notifications for this certificate if none are provided notifications = [] if not kwargs.get("notifications"): notification_name = "DEFAULT_{0}".format(cert.owner.split("@")[0].upper()) notifications += notification_service.create_default_expiration_notifications(notification_name, [cert.owner]) notification_name = "DEFAULT_SECURITY" notifications += notification_service.create_default_expiration_notifications( notification_name, current_app.config.get("LEMUR_SECURITY_TEAM_EMAIL") ) cert.notifications = notifications database.update(cert) return cert
def update(source_id, label, options, description): """ Updates an existing source. :param source_id: Lemur assigned ID :param label: Source common name :rtype : Source :return: """ source = get(source_id) source.label = label source.options = options source.description = description return database.update(source)