Esempio n. 1
0
File: cli.py Progetto: Netflix/lemur
def query(fqdns, issuer, owner, expired):
    """Prints certificates that match the query params."""
    table = []

    q = database.session_query(Certificate)
    if issuer:
        sub_query = database.session_query(Authority.id) \
            .filter(Authority.name.ilike('%{0}%'.format(issuer))) \
            .subquery()

        q = q.filter(
            or_(
                Certificate.issuer.ilike('%{0}%'.format(issuer)),
                Certificate.authority_id.in_(sub_query)
            )
        )
    if owner:
        q = q.filter(Certificate.owner.ilike('%{0}%'.format(owner)))

    if not expired:
        q = q.filter(Certificate.expired == False)  # noqa

    if fqdns:
        for f in fqdns.split(','):
            q = q.filter(
                or_(
                    Certificate.cn.ilike('%{0}%'.format(f)),
                    Certificate.domains.any(Domain.name.ilike('%{0}%'.format(f)))
                )
            )

    for c in q.all():
        table.append([c.id, c.name, c.owner, c.issuer])

    print(tabulate(table, headers=['Id', 'Name', 'Owner', 'Issuer'], tablefmt='csv'))
Esempio n. 2
0
def render(args):
    """
    Helper that paginates and filters data when requested
    through the REST Api

    :param args:
    :return:
    """
    query = database.session_query(Log)

    filt = args.pop('filter')

    if filt:
        terms = filt.split(';')

        if 'certificate.name' in terms:
            sub_query = database.session_query(Certificate.id)\
                .filter(Certificate.name.ilike('%{0}%'.format(terms[1])))

            query = query.filter(Log.certificate_id.in_(sub_query))

        elif 'user.email' in terms:
            sub_query = database.session_query(User.id)\
                .filter(User.email.ilike('%{0}%'.format(terms[1])))

            query = query.filter(Log.user_id.in_(sub_query))

        else:
            query = database.filter(query, Log, terms)

    return database.sort_and_page(query, Log, args)
Esempio n. 3
0
def render(args):
    sort_by = args.pop('sort_by')
    sort_dir = args.pop('sort_dir')
    page = args.pop('page')
    count = args.pop('count')
    filt = args.pop('filter')
    certificate_id = args.pop('certificate_id', None)

    if certificate_id:
        query = database.session_query(Notification).join(Certificate, Notification.certificate)
        query = query.filter(Certificate.id == certificate_id)
    else:
        query = database.session_query(Notification)

    if filt:
        terms = filt.split(';')
        if terms[0] == 'active' and terms[1] == 'false':
            query = query.filter(Notification.active == False)  # noqa
        elif terms[0] == 'active' and terms[1] == 'true':
            query = query.filter(Notification.active == True)  # noqa
        else:
            query = database.filter(query, Notification, terms)

    query = database.find_all(query, Notification, args)

    if sort_by and sort_dir:
        query = database.sort(query, Notification, sort_by, sort_dir)

    return database.paginate(query, page, count)
Esempio n. 4
0
def render(args):
    sort_by = args.pop("sort_by")
    sort_dir = args.pop("sort_dir")
    page = args.pop("page")
    count = args.pop("count")
    filt = args.pop("filter")
    certificate_id = args.pop("certificate_id", None)

    if certificate_id:
        query = database.session_query(Notification).join(Certificate, Notification.certificate)
        query = query.filter(Certificate.id == certificate_id)
    else:
        query = database.session_query(Notification)

    if filt:
        terms = filt.split(";")
        if terms[0] == "active" and terms[1] == "false":
            query = query.filter(Notification.active == False)  # noqa
        elif terms[0] == "active" and terms[1] == "true":
            query = query.filter(Notification.active == True)  # noqa
        else:
            query = database.filter(query, Notification, terms)

    query = database.find_all(query, Notification, args)

    if sort_by and sort_dir:
        query = database.sort(query, Notification, sort_by, sort_dir)

    return database.paginate(query, page, count)
Esempio n. 5
0
def render(args):
    """
    Helper that helps us render the REST Api responses.
    :param args:
    :return:
    """
    query = database.session_query(Authority)
    filt = args.pop('filter')

    if filt:
        terms = filt.split(';')
        if 'active' in filt:
            query = query.filter(Authority.active == truthiness(terms[1]))
        elif 'cn' in filt:
            term = '%{0}%'.format(terms[1])
            sub_query = database.session_query(Certificate.root_authority_id) \
                .filter(Certificate.cn.ilike(term)) \
                .subquery()

            query = query.filter(Authority.id.in_(sub_query))
        else:
            query = database.filter(query, Authority, terms)

    # we make sure that a user can only use an authority they either own are a member of - admins can see all
    if not args['user'].is_admin:
        authority_ids = []
        for authority in args['user'].authorities:
            authority_ids.append(authority.id)

        for role in args['user'].roles:
            for authority in role.authorities:
                authority_ids.append(authority.id)
        query = query.filter(Authority.id.in_(authority_ids))

    return database.sort_and_page(query, Authority, args)
Esempio n. 6
0
def render(args):
    """
    Helper function that allows use to render our REST Api.

    :param args:
    :return:
    """
    query = database.session_query(Certificate)

    time_range = args.pop("time_range")
    destination_id = args.pop("destination_id")
    notification_id = args.pop("notification_id", None)
    show = args.pop("show")
    # owner = args.pop('owner')
    # creator = args.pop('creator')  # TODO we should enabling filtering by owner

    filt = args.pop("filter")

    if filt:
        terms = filt.split(";")
        if "issuer" in terms:
            # we can't rely on issuer being correct in the cert directly so we combine queries
            sub_query = (
                database.session_query(Authority.id).filter(Authority.name.ilike("%{0}%".format(terms[1]))).subquery()
            )

            query = query.filter(
                or_(Certificate.issuer.ilike("%{0}%".format(terms[1])), Certificate.authority_id.in_(sub_query))
            )
            return database.sort_and_page(query, Certificate, args)

        if "destination" in terms:
            query = query.filter(Certificate.destinations.any(Destination.id == terms[1]))
        elif "active" in filt:  # this is really weird but strcmp seems to not work here??
            query = query.filter(Certificate.active == terms[1])
        else:
            query = database.filter(query, Certificate, terms)

    if show:
        sub_query = database.session_query(Role.name).filter(Role.user_id == g.user.id).subquery()
        query = query.filter(or_(Certificate.user_id == g.user.id, Certificate.owner.in_(sub_query)))

    if destination_id:
        query = query.filter(Certificate.destinations.any(Destination.id == destination_id))

    if notification_id:
        query = query.filter(Certificate.notifications.any(Notification.id == notification_id))

    if time_range:
        to = arrow.now().replace(weeks=+time_range).format("YYYY-MM-DD")
        now = arrow.now().format("YYYY-MM-DD")
        query = query.filter(Certificate.not_after <= to).filter(Certificate.not_after >= now)

    return database.sort_and_page(query, Certificate, args)
Esempio n. 7
0
def render(args):
    filt = args.pop('filter')
    certificate_id = args.pop('certificate_id', None)

    if certificate_id:
        query = database.session_query(Source).join(Certificate, Source.certificate)
        query = query.filter(Certificate.id == certificate_id)
    else:
        query = database.session_query(Source)

    if filt:
        terms = filt.split(';')
        query = database.filter(query, Source, terms)

    return database.sort_and_page(query, Source, args)
Esempio n. 8
0
def render(args):
    """
    Helper to parse REST Api requests

    :param args:
    :return:
    """
    query = database.session_query(Domain).join(Certificate, Domain.certificate)

    sort_by = args.pop('sort_by')
    sort_dir = args.pop('sort_dir')
    page = args.pop('page')
    count = args.pop('count')
    filt = args.pop('filter')
    certificate_id = args.pop('certificate_id', None)

    if filt:
        terms = filt.split(';')
        query = database.filter(query, Domain, terms)

    if certificate_id:
        query = query.filter(Certificate.id == certificate_id)

    query = database.find_all(query, Domain, args)

    if sort_by and sort_dir:
        query = database.sort(query, Domain, sort_by, sort_dir)

    return database.paginate(query, page, count)
Esempio n. 9
0
def render(args):
    """
    Helper that filters subsets of roles depending on the parameters
    passed to the REST Api

    :param args:
    :return:
    """
    query = database.session_query(Role)
    filt = args.pop('filter')
    user_id = args.pop('user_id', None)
    authority_id = args.pop('authority_id', None)

    if user_id:
        query = query.filter(Role.users.any(User.id == user_id))

    if authority_id:
        query = query.filter(Role.authority_id == authority_id)

    # we make sure that user can see the role - admins can see all
    if not g.current_user.is_admin:
        ids = []
        for role in g.current_user.roles:
            ids.append(role.id)
        query = query.filter(Role.id.in_(ids))

    if filt:
        terms = filt.split(';')
        query = database.filter(query, Role, terms)

    return database.sort_and_page(query, Role, args)
Esempio n. 10
0
def render(args):
    """
    Helper that helps us render the REST Api responses.
    :param args:
    :return:
    """
    query = database.session_query(Endpoint)
    filt = args.pop('filter')

    if filt:
        terms = filt.split(';')
        if 'active' in filt:  # this is really weird but strcmp seems to not work here??
            query = query.filter(Endpoint.active == terms[1])
        elif 'port' in filt:
            if terms[1] != 'null':  # ng-table adds 'null' if a number is removed
                query = query.filter(Endpoint.port == terms[1])
        elif 'ciphers' in filt:
            query = query.filter(
                Cipher.name == terms[1]
            )
        else:
            query = database.filter(query, Endpoint, terms)

    # we make sure that a user can only use an endpoint they either own are are a member of - admins can see all
    if not g.current_user.is_admin:
        endpoint_ids = []
        for role in g.current_user.roles:
            for endpoint in role.endpoints:
                endpoint_ids.append(endpoint.id)
        query = query.filter(Endpoint.id.in_(endpoint_ids))

    return database.sort_and_page(query, Endpoint, args)
Esempio n. 11
0
def render(args):
    """
    Helper that helps us render the REST Api responses.
    :param args:
    :return:
    """
    query = database.session_query(Authority)
    sort_by = args.pop('sort_by')
    sort_dir = args.pop('sort_dir')
    page = args.pop('page')
    count = args.pop('count')
    filt = args.pop('filter')

    if filt:
        terms = filt.split(';')
        if 'active' in filt:  # this is really weird but strcmp seems to not work here??
            query = query.filter(Authority.active == terms[1])
        else:
            query = database.filter(query, Authority, terms)

    # we make sure that a user can only use an authority they either own are are a member of - admins can see all
    if not g.current_user.is_admin:
        authority_ids = []
        for role in g.current_user.roles:
            if role.authority:
                authority_ids.append(role.authority.id)
        query = query.filter(Authority.id.in_(authority_ids))

    query = database.find_all(query, Authority, args)

    if sort_by and sort_dir:
        query = database.sort(query, Authority, sort_by, sort_dir)

    return database.paginate(query, page, count)
Esempio n. 12
0
def render(args):
    filt = args.pop("filter")
    certificate_id = args.pop("certificate_id", None)

    if certificate_id:
        query = database.session_query(Source).join(Certificate,
                                                    Source.certificate)
        query = query.filter(Certificate.id == certificate_id)
    else:
        query = database.session_query(Source)

    if filt:
        terms = filt.split(";")
        query = database.filter(query, Source, terms)

    return database.sort_and_page(query, Source, args)
Esempio n. 13
0
def get_unresolved_pending_certs():
    """
    Retrieve a list of unresolved pending certs given a list of ids
    Filters out non-existing pending certs
    """
    query = database.session_query(PendingCertificate).filter(PendingCertificate.resolved.is_(False))
    return database.find_all(query, PendingCertificate, {}).all()
Esempio n. 14
0
def render(args):
    """
    Helper that helps us render the REST Api responses.
    :param args:
    :return:
    """
    query = database.session_query(Authority)
    sort_by = args.pop('sort_by')
    sort_dir = args.pop('sort_dir')
    page = args.pop('page')
    count = args.pop('count')
    filt = args.pop('filter')

    if filt:
        terms = filt.split(';')
        if 'active' in filt:  # this is really weird but strcmp seems to not work here??
            query = query.filter(Authority.active == terms[1])
        else:
            query = database.filter(query, Authority, terms)

    # we make sure that a user can only use an authority they either own are are a member of - admins can see all
    if not g.current_user.is_admin:
        authority_ids = []
        for role in g.current_user.roles:
            if role.authority:
                authority_ids.append(role.authority.id)
        query = query.filter(Authority.id.in_(authority_ids))

    query = database.find_all(query, Authority, args)

    if sort_by and sort_dir:
        query = database.sort(query, Authority, sort_by, sort_dir)

    return database.paginate(query, page, count)
Esempio n. 15
0
def _find_superseded(cert):
    """
    Here we try to fetch any domain in the certificate to see if we can resolve it
    and to try and see if it is currently serving the certificate we are
    alerting on.

    :param domains:
    :return:
    """
    query = database.session_query(Certificate)
    ss_list = []

    # determine what is current host at our domains
    for domain in cert.domains:
        dups = _get_domain_certificate(domain.name)
        for c in dups:
            if c.body != cert.body:
                ss_list.append(dups)

        current_app.logger.info("Trying to resolve {0}".format(domain.name))

    # look for other certificates that may not be hosted but cover the same domains
    query = query.filter(Certificate.domains.any(Domain.name.in_([x.name for x in cert.domains])))
    query = query.filter(Certificate.active == True)  # noqa
    query = query.filter(Certificate.not_after >= arrow.utcnow().format('YYYY-MM-DD'))
    query = query.filter(Certificate.body != cert.body)
    ss_list.extend(query.all())
    return ss_list
Esempio n. 16
0
def render(args):
    """
    Helper that paginates and filters data when requested
    through the REST Api

    :param args:
    :return:
    """
    query = database.session_query(User)

    sort_by = args.pop('sort_by')
    sort_dir = args.pop('sort_dir')
    page = args.pop('page')
    count = args.pop('count')
    filt = args.pop('filter')

    if filt:
        terms = filt.split(';')
        query = database.filter(query, User, terms)

    query = database.find_all(query, User, args)

    if sort_by and sort_dir:
        query = database.sort(query, User, sort_by, sort_dir)

    return database.paginate(query, page, count)
Esempio n. 17
0
def render(args):
    """
    Helper that helps us render the REST Api responses.
    :param args:
    :return:
    """
    query = database.session_query(Authority)
    filt = args.pop('filter')

    if filt:
        terms = filt.split(';')
        if 'active' in filt:  # this is really weird but strcmp seems to not work here??
            query = query.filter(Authority.active == terms[1])
        else:
            query = database.filter(query, Authority, terms)

    # we make sure that a user can only use an authority they either own are are a member of - admins can see all
    if not g.current_user.is_admin:
        authority_ids = []
        for authority in g.current_user.authorities:
            authority_ids.append(authority.id)

        for role in g.current_user.roles:
            for authority in role.authorities:
                authority_ids.append(authority.id)
        query = query.filter(Authority.id.in_(authority_ids))

    return database.sort_and_page(query, Authority, args)
Esempio n. 18
0
def create(**kwargs):
    """
    Creates a new certificate.
    """
    try:
        cert_body, private_key, cert_chain, external_id, csr = mint(**kwargs)
    except Exception:
        log_data = {
            "message": "Exception minting certificate",
            "issuer": kwargs["authority"].name,
            "cn": kwargs["common_name"],
        }
        current_app.logger.error(log_data, exc_info=True)
        capture_exception()
        raise
    kwargs["body"] = cert_body
    kwargs["private_key"] = private_key
    kwargs["chain"] = cert_chain
    kwargs["external_id"] = external_id
    kwargs["csr"] = csr

    roles = create_certificate_roles(**kwargs)

    if kwargs.get("roles"):
        kwargs["roles"] += roles
    else:
        kwargs["roles"] = roles

    if cert_body:
        cert = Certificate(**kwargs)
        kwargs["creator"].certificates.append(cert)
    else:
        # ACME path
        cert = PendingCertificate(**kwargs)
        kwargs["creator"].pending_certificates.append(cert)

    cert.authority = kwargs["authority"]

    database.commit()

    if isinstance(cert, Certificate):
        certificate_issued.send(certificate=cert, authority=cert.authority)
        metrics.send(
            "certificate_issued",
            "counter",
            1,
            metric_tags=dict(owner=cert.owner, issuer=cert.issuer),
        )

    if isinstance(cert, PendingCertificate):
        # We need to refresh the pending certificate to avoid "Instance is not bound to a Session; "
        # "attribute refresh operation cannot proceed"
        pending_cert = database.session_query(PendingCertificate).get(cert.id)
        from lemur.common.celery import fetch_acme_cert

        if not current_app.config.get("ACME_DISABLE_AUTORESOLVE", False):
            fetch_acme_cert.apply_async((pending_cert.id,), countdown=5)

    return cert
Esempio n. 19
0
def get_all():
    """
    Retrieves all notification currently known by Lemur.

    :return:
    """
    query = database.session_query(Notification)
    return database.find_all(query, Notification, {}).all()
Esempio n. 20
0
def get_all():
    """
    Retrieves all destination currently known by Lemur.

    :return:
    """
    query = database.session_query(Destination)
    return database.find_all(query, Destination, {}).all()
Esempio n. 21
0
def get_all():
    """
    Fetches all domains

    :return:
    """
    query = database.session_query(Domain)
    return database.find_all(query, Domain, {}).all()
Esempio n. 22
0
def get_all():
    """
    Retrieve all users from the database.

    :return:
    """
    query = database.session_query(User)
    return database.find_all(query, User, {}).all()
Esempio n. 23
0
def get_all():
    """
    Retrieves all destination currently known by Lemur.

    :return:
    """
    query = database.session_query(Destination)
    return database.find_all(query, Destination, {}).all()
Esempio n. 24
0
def get_unresolved_pending_certs():
    """
    Retrieve a list of unresolved pending certs given a list of ids
    Filters out non-existing pending certs
    """
    query = database.session_query(PendingCertificate).filter(
        PendingCertificate.resolved.is_(False))
    return database.find_all(query, PendingCertificate, {}).all()
Esempio n. 25
0
def get_all():
    """
    Retrieve all logs from the database.

    :return:
    """
    query = database.session_query(Log)
    return database.find_all(query, Log, {}).all()
Esempio n. 26
0
def get_all():
    """
    Retrieves all notification currently known by Lemur.

    :return:
    """
    query = database.session_query(Notification)
    return database.find_all(query, Notification, {}).all()
Esempio n. 27
0
def get_all():
    """
    Retrieve all logs from the database.

    :return:
    """
    query = database.session_query(Log)
    return database.find_all(query, Log, {}).all()
Esempio n. 28
0
def get_all():
    """
    Retrieves all source currently known by Lemur.

    :return:
    """
    query = database.session_query(Source)
    return database.find_all(query, Source, {}).all()
Esempio n. 29
0
def get_all():
    """
    Retrieve all users from the database.

    :return:
    """
    query = database.session_query(User)
    return database.find_all(query, User, {}).all()
Esempio n. 30
0
def get_all():
    """
    Fetches all domains

    :return:
    """
    query = database.session_query(Domain)
    return database.find_all(query, Domain, {}).all()
Esempio n. 31
0
def get_all():
    """
    Retrieves all source currently known by Lemur.

    :return:
    """
    query = database.session_query(Source)
    return database.find_all(query, Source, {}).all()
Esempio n. 32
0
def get_all():
    """
    Get all endpoints that are currently in Lemur.

    :rtype : List
    :return:
    """
    query = database.session_query(Endpoint)
    return database.find_all(query, Endpoint, {}).all()
Esempio n. 33
0
def fqdns(**kwargs):
    """
    Returns an FQDN report.
    :return:
    """
    query = database.session_query(Certificate)
    query = filter_by_deployment(query, deployment=kwargs.get("deployed"))
    query = filter_by_validity(query, validity=kwargs.get("validity"))
    return query
Esempio n. 34
0
def fqdns(**kwargs):
    """
    Returns an FQDN report.
    :return:
    """
    query = database.session_query(Certificate)
    query = filter_by_deployment(query, deployment=kwargs.get('deployed'))
    query = filter_by_validity(query, validity=kwargs.get('validity'))
    return query
Esempio n. 35
0
def render(args):
    """
    Helper that helps us render the REST Api responses.
    :param args:
    :return:
    """
    query = database.session_query(DnsProvider)

    return database.sort_and_page(query, DnsProvider, args)
Esempio n. 36
0
def get_all():
    """
    Get all authorities that are currently in Lemur.

    :rtype : List
    :return:
    """
    query = database.session_query(Authority)
    return database.find_all(query, Authority, {}).all()
Esempio n. 37
0
def get_all():
    """
    Get all endpoints that are currently in Lemur.

    :rtype : List
    :return:
    """
    query = database.session_query(Endpoint)
    return database.find_all(query, Endpoint, {}).all()
Esempio n. 38
0
def get_all():
    """
    Get all authorities that are currently in Lemur.

    :rtype : List
    :return:
    """
    query = database.session_query(Authority)
    return database.find_all(query, Authority, {}).all()
Esempio n. 39
0
def get_certificates():
    """
    Finds all certificates that are eligible for notifications.
    :return:
    """
    return database.session_query(Certificate)\
        .options(joinedload('notifications'))\
        .filter(Certificate.notify == True)\
        .filter(Certificate.expired == False)\
        .filter(Certificate.notifications.any()).all()  # noqa
Esempio n. 40
0
def render(args):
    filt = args.pop('filter')
    certificate_id = args.pop('certificate_id', None)

    if certificate_id:
        query = database.session_query(Notification).join(
            Certificate, Notification.certificate)
        query = query.filter(Certificate.id == certificate_id)
    else:
        query = database.session_query(Notification)

    if filt:
        terms = filt.split(';')
        if terms[0] == 'active':
            query = query.filter(Notification.active == truthiness(terms[1]))
        else:
            query = database.filter(query, Notification, terms)

    return database.sort_and_page(query, Notification, args)
Esempio n. 41
0
def render(args):
    filt = args.pop('filter')
    certificate_id = args.pop('certificate_id', None)

    if certificate_id:
        query = database.session_query(Notification).join(Certificate, Notification.certificate)
        query = query.filter(Certificate.id == certificate_id)
    else:
        query = database.session_query(Notification)

    if filt:
        terms = filt.split(';')
        if terms[0] == 'active' and terms[1] == 'false':
            query = query.filter(Notification.active == False)  # noqa
        elif terms[0] == 'active' and terms[1] == 'true':
            query = query.filter(Notification.active == True)  # noqa
        else:
            query = database.filter(query, Notification, terms)

    return database.sort_and_page(query, Notification, args)
Esempio n. 42
0
def expire(ttl):
    """
    Removed all endpoints that have not been recently updated.
    """
    now = arrow.utcnow()
    expiration = now - timedelta(hours=ttl)
    endpoints = database.session_query(Endpoint).filter(cast(Endpoint.last_updated, ArrowType) <= expiration)

    for endpoint in endpoints:
        database.delete(endpoint)
        metrics.send('endpoint_expired', 'counter', 1)
Esempio n. 43
0
def query_name(certificate_name, args):
    """
    Helper function that queries for a certificate by name

    :param args:
    :return:
    """
    query = database.session_query(Certificate)
    query = query.filter(Certificate.name == certificate_name)
    result = database.sort_and_page(query, Certificate, args)
    return result
Esempio n. 44
0
def is_domain_sensitive(name):
    """
    Return True if domain is marked sensitive

    :param name:
    :return:
    """
    query = database.session_query(Domain)

    query = query.filter(and_(Domain.sensitive, Domain.name == name))

    return database.find_all(query, Domain, {}).all()
Esempio n. 45
0
def create(**kwargs):
    """
    Creates a new certificate.
    """
    try:
        cert_body, private_key, cert_chain, external_id, csr = mint(**kwargs)
    except Exception:
        current_app.logger.error("Exception minting certificate",
                                 exc_info=True)
        sentry.captureException()
        raise
    kwargs['body'] = cert_body
    kwargs['private_key'] = private_key
    kwargs['chain'] = cert_chain
    kwargs['external_id'] = external_id
    kwargs['csr'] = csr

    roles = create_certificate_roles(**kwargs)

    if kwargs.get('roles'):
        kwargs['roles'] += roles
    else:
        kwargs['roles'] = roles

    if cert_body:
        cert = Certificate(**kwargs)
        kwargs['creator'].certificates.append(cert)
    else:
        cert = PendingCertificate(**kwargs)
        kwargs['creator'].pending_certificates.append(cert)

    cert.authority = kwargs['authority']

    database.commit()

    if isinstance(cert, Certificate):
        certificate_issued.send(certificate=cert, authority=cert.authority)
        metrics.send('certificate_issued',
                     'counter',
                     1,
                     metric_tags=dict(owner=cert.owner, issuer=cert.issuer))

    if isinstance(cert, PendingCertificate):
        # We need to refresh the pending certificate to avoid "Instance is not bound to a Session; "
        # "attribute refresh operation cannot proceed"
        pending_cert = database.session_query(PendingCertificate).get(cert.id)
        from lemur.common.celery import fetch_acme_cert
        if not current_app.config.get("ACME_DISABLE_AUTORESOLVE", False):
            fetch_acme_cert.apply_async((pending_cert.id, ), countdown=5)

    return cert
Esempio n. 46
0
def render(args):
    """
    Helper that helps us render the REST Api responses.
    :param args:
    :return:
    """
    query = database.session_query(Authority)

    filt = args.pop("filter")

    if filt:
        terms = filt.split(";")
        if "active" in filt:
            query = query.filter(Authority.active == truthiness(terms[1]))
        elif "cn" in filt:
            term = "%{0}%".format(terms[1])
            sub_query = (
                database.session_query(Certificate.root_authority_id)
                .filter(Certificate.cn.ilike(term))
                .subquery()
            )

            query = query.filter(Authority.id.in_(sub_query))
        else:
            query = database.filter(query, Authority, terms)

    # we make sure that a user can only use an authority they either own are a member of - admins can see all
    if not args["user"].is_admin:
        authority_ids = []
        for authority in args["user"].authorities:
            authority_ids.append(authority.id)

        for role in args["user"].roles:
            for authority in role.authorities:
                authority_ids.append(authority.id)
        query = query.filter(Authority.id.in_(authority_ids))

    return database.sort_and_page(query, Authority, args)
Esempio n. 47
0
def get_by_attributes(conditions):
    """
    Retrieves certificate(s) by conditions given in a hash of given key=>value pairs.
    :param serial:
    :return:
    """
    # Ensure that each of the given conditions corresponds to actual columns
    # if not, silently remove it
    for attr in conditions.keys():
        if attr not in Certificate.__table__.columns:
            conditions.pop(attr)

    query = database.session_query(Certificate)
    return database.find_all(query, Certificate, conditions).all()
Esempio n. 48
0
def get_by_attributes(conditions):
    """
    Retrieves certificate(s) by conditions given in a hash of given key=>value pairs.
    :param serial:
    :return:
    """
    # Ensure that each of the given conditions corresponds to actual columns
    # if not, silently remove it
    for attr in conditions.keys():
        if attr not in Certificate.__table__.columns:
            conditions.pop(attr)

    query = database.session_query(Certificate)
    return database.find_all(query, Certificate, conditions).all()
Esempio n. 49
0
File: cli.py Progetto: zarfide/lemur
def query(fqdns, issuer, owner, expired):
    """Prints certificates that match the query params."""
    table = []

    q = database.session_query(Certificate)
    if issuer:
        sub_query = (
            database.session_query(Authority.id)
            .filter(Authority.name.ilike("%{0}%".format(issuer)))
            .subquery()
        )

        q = q.filter(
            or_(
                Certificate.issuer.ilike("%{0}%".format(issuer)),
                Certificate.authority_id.in_(sub_query),
            )
        )
    if owner:
        q = q.filter(Certificate.owner.ilike("%{0}%".format(owner)))

    if not expired:
        q = q.filter(Certificate.expired == False)  # noqa

    if fqdns:
        for f in fqdns.split(","):
            q = q.filter(
                or_(
                    Certificate.cn.ilike("%{0}%".format(f)),
                    Certificate.domains.any(Domain.name.ilike("%{0}%".format(f))),
                )
            )

    for c in q.all():
        table.append([c.id, c.name, c.owner, c.issuer])

    print(tabulate(table, headers=["Id", "Name", "Owner", "Issuer"], tablefmt="csv"))
Esempio n. 50
0
def get_pending_certs(pending_ids):
    """
    Retrieve a list of pending certs given a list of ids
    Filters out non-existing pending certs
    """
    pending_certs = []
    if "all" in pending_ids:
        query = database.session_query(PendingCertificate)
        return database.find_all(query, PendingCertificate, {}).all()
    else:
        for pending_id in pending_ids:
            pending_cert = get(pending_id)
            if pending_cert:
                pending_certs.append(pending_cert)
    return pending_certs
Esempio n. 51
0
def render(args):
    sort_by = args.pop('sort_by')
    sort_dir = args.pop('sort_dir')
    page = args.pop('page')
    count = args.pop('count')
    filt = args.pop('filter')
    certificate_id = args.pop('certificate_id', None)

    if certificate_id:
        query = database.session_query(Source).join(Certificate, Source.certificate)
        query = query.filter(Certificate.id == certificate_id)
    else:
        query = database.session_query(Source)

    if filt:
        terms = filt.split(';')
        query = database.filter(query, Source, terms)

    query = database.find_all(query, Source, args)

    if sort_by and sort_dir:
        query = database.sort(query, Source, sort_by, sort_dir)

    return database.paginate(query, page, count)
Esempio n. 52
0
def expire(ttl):
    """
    Removed all endpoints that have not been recently updated.
    """
    print("[+] Staring expiration of old endpoints.")
    now = arrow.utcnow()
    expiration = now - timedelta(hours=ttl)
    endpoints = database.session_query(Endpoint).filter(cast(Endpoint.last_updated, ArrowType) <= expiration)

    for endpoint in endpoints:
        print("[!] Expiring endpoint: {name} Last Updated: {last_updated}".format(name=endpoint.name, last_updated=endpoint.last_updated))
        database.delete(endpoint)
        metrics.send('endpoint_expired', 'counter', 1)

    print("[+] Finished expiration.")
Esempio n. 53
0
def expiring_certificates(**kwargs):
    """
    Returns an Expiring report.
    :return:
    """
    ttl = kwargs.get('ttl', 30)
    now = arrow.utcnow()
    validity_end = now + timedelta(days=ttl)

    query = database.session_query(Certificate)
    query = filter_by_deployment(query, deployment=kwargs.get('deployed'))
    query = filter_by_validity(query, validity='valid')
    query = filter_by_validity_end(query, validity_end=validity_end)

    return query
Esempio n. 54
0
def expiring_certificates(**kwargs):
    """
    Returns an Expiring report.
    :return:
    """
    ttl = kwargs.get("ttl", 30)
    now = arrow.utcnow()
    validity_end = now + timedelta(days=ttl)

    query = database.session_query(Certificate)
    query = filter_by_deployment(query, deployment=kwargs.get("deployed"))
    query = filter_by_validity(query, validity="valid")
    query = filter_by_validity_end(query, validity_end=validity_end)

    return query
Esempio n. 55
0
def get_pending_certs(pending_ids):
    """
    Retrieve a list of pending certs given a list of ids
    Filters out non-existing pending certs
    """
    pending_certs = []
    if 'all' in pending_ids:
        query = database.session_query(PendingCertificate)
        return database.find_all(query, PendingCertificate, {}).all()
    else:
        for pending_id in pending_ids:
            pending_cert = get(pending_id)
            if pending_cert:
                pending_certs.append(pending_cert)
    return pending_certs
Esempio n. 56
0
def create(**kwargs):
    """
    Creates a new certificate.
    """
    try:
        cert_body, private_key, cert_chain, external_id, csr = mint(**kwargs)
    except Exception:
        current_app.logger.error("Exception minting certificate", exc_info=True)
        sentry.captureException()
        raise
    kwargs['body'] = cert_body
    kwargs['private_key'] = private_key
    kwargs['chain'] = cert_chain
    kwargs['external_id'] = external_id
    kwargs['csr'] = csr

    roles = create_certificate_roles(**kwargs)

    if kwargs.get('roles'):
        kwargs['roles'] += roles
    else:
        kwargs['roles'] = roles

    if cert_body:
        cert = Certificate(**kwargs)
        kwargs['creator'].certificates.append(cert)
    else:
        cert = PendingCertificate(**kwargs)
        kwargs['creator'].pending_certificates.append(cert)

    cert.authority = kwargs['authority']

    database.commit()

    if isinstance(cert, Certificate):
        certificate_issued.send(certificate=cert, authority=cert.authority)
        metrics.send('certificate_issued', 'counter', 1, metric_tags=dict(owner=cert.owner, issuer=cert.issuer))

    if isinstance(cert, PendingCertificate):
        # We need to refresh the pending certificate to avoid "Instance is not bound to a Session; "
        # "attribute refresh operation cannot proceed"
        pending_cert = database.session_query(PendingCertificate).get(cert.id)
        from lemur.common.celery import fetch_acme_cert
        if not current_app.config.get("ACME_DISABLE_AUTORESOLVE", False):
            fetch_acme_cert.apply_async((pending_cert.id,), countdown=5)

    return cert
Esempio n. 57
0
def render(args):
    """
    Helper that paginates and filters data when requested
    through the REST Api

    :param args:
    :return:
    """
    query = database.session_query(Log)

    filt = args.pop('filter')

    if filt:
        terms = filt.split(';')
        query = database.filter(query, Log, terms)

    return database.sort_and_page(query, Log, args)
Esempio n. 58
0
def render(args):
    """
    Helper to parse REST Api requests

    :param args:
    :return:
    """
    query = database.session_query(Domain)
    filt = args.pop('filter')
    certificate_id = args.pop('certificate_id', None)

    if filt:
        terms = filt.split(';')
        query = database.filter(query, Domain, terms)

    if certificate_id:
        query = query.join(Certificate, Domain.certificates)
        query = query.filter(Certificate.id == certificate_id)

    return database.sort_and_page(query, Domain, args)
Esempio n. 59
0
def expire_endpoints(source, ttl_hours):
    now = arrow.utcnow()
    expiration = now - timedelta(hours=ttl_hours)
    endpoints = database.session_query(Endpoint).filter(
        Endpoint.source_id == source.id).filter(
            cast(Endpoint.last_updated, ArrowType) <= expiration)
    expired = 0
    for endpoint in endpoints:
        current_app.logger.debug(
            "Expiring endpoint from source {source}: {name} Last Updated: {last_updated}"
            .format(source=source.label,
                    name=endpoint.name,
                    last_updated=endpoint.last_updated))
        database.delete(endpoint)
        metrics.send("endpoint_expired",
                     "counter",
                     1,
                     metric_tags={"source": source.label})
        expired += 1
    return expired
Esempio n. 60
0
def get_all_valid_certs(authority_plugin_name,
                        paginate=False,
                        page=1,
                        count=1000,
                        created_on_or_before=None):
    """
    Retrieves all valid (not expired & not revoked) certificates within Lemur, for the given authority plugin names
    ignored if no authority_plugin_name provided.

    Note that depending on the DB size retrieving all certificates might an expensive operation
    :param paginate: option to use pagination, for large number of certificates. default to false
    :param page: the page to turn. default to 1
    :param count: number of return certificates per page. default 1000
    :param created_on_or_before: optional Arrow date to select only certificates issued on or before the date

    :return: list of certificates to check for revocation
    """
    assert (page > 0)
    query = database.session_query(
        Certificate) if paginate else Certificate.query

    if authority_plugin_name:
        query = query.outerjoin(Authority, Authority.id == Certificate.authority_id)\
            .filter(Certificate.not_after > arrow.now().format("YYYY-MM-DD"))\
            .filter(Authority.plugin_name.in_(authority_plugin_name))\
            .filter(Certificate.revoked.is_(False))

    else:
        query = query.filter(Certificate.not_after > arrow.now().format("YYYY-MM-DD"))\
            .filter(Certificate.revoked.is_(False))

    if created_on_or_before:
        query = query.filter(Certificate.date_created <=
                             created_on_or_before.format("YYYY-MM-DD"))

    if paginate:
        items = database.paginate(query, page, count)
        return items['items']

    return query.all()