Пример #1
0
def install_plugins(app):
    """
    Installs new issuers that are not currently bundled with Lemur.

    :param app:
    :return:
    """
    from lemur.plugins import plugins
    from lemur.plugins.base import register
    # entry_points={
    #    'lemur.plugins': [
    #         'verisign = lemur_verisign.plugin:VerisignPlugin'
    #     ],
    # },
    for ep in pkg_resources.iter_entry_points('lemur.plugins'):
        try:
            plugin = ep.load()
        except Exception:
            import traceback
            app.logger.error("Failed to load plugin %r:\n%s\n" % (ep.name, traceback.format_exc()))
        else:
            register(plugin)

    # ensure that we have some way to notify
    with app.app_context():
        try:
            slug = app.config.get("LEMUR_DEFAULT_NOTIFICATION_PLUGIN", "email-notification")
            plugins.get(slug)
        except KeyError:
            raise Exception("Unable to location notification plugin: {slug}. Ensure that LEMUR_DEFAULT_NOTIFICATION_PLUGIN is set to a valid and installed notification plugin.".format(slug=slug))
Пример #2
0
def install_plugins(app):
    """
    Installs new issuers that are not currently bundled with Lemur.

    :param app:
    :return:
    """
    from lemur.plugins import plugins
    from lemur.plugins.base import register
    # entry_points={
    #    'lemur.plugins': [
    #         'verisign = lemur_verisign.plugin:VerisignPlugin'
    #     ],
    # },
    for ep in pkg_resources.iter_entry_points('lemur.plugins'):
        try:
            plugin = ep.load()
        except Exception:
            import traceback
            app.logger.error("Failed to load plugin %r:\n%s\n" %
                             (ep.name, traceback.format_exc()))
        else:
            register(plugin)

    # ensure that we have some way to notify
    with app.app_context():
        try:
            slug = app.config.get("LEMUR_DEFAULT_NOTIFICATION_PLUGIN",
                                  "email-notification")
            plugins.get(slug)
        except KeyError:
            raise Exception(
                "Unable to location notification plugin: {slug}. Ensure that LEMUR_DEFAULT_NOTIFICATION_PLUGIN is set to a valid and installed notification plugin."
                .format(slug=slug))
Пример #3
0
def publish_verisign_units():
    """
    Simple function that queries verisign for API units and posts the mertics to
    Atlas API for other teams to consume.
    :return:
    """
    from lemur.plugins import plugins
    v = plugins.get('verisign-issuer')
    units = v.get_available_units()

    metrics = {}
    for item in units:
        if item['@type'] in metrics.keys():
            metrics[item['@type']] += int(item['@remaining'])
        else:
            metrics.update({item['@type']: int(item['@remaining'])})

    for name, value in metrics.items():
        metric = [
            {
                "timestamp": 1321351651,
                "type": "GAUGE",
                "name": "Symantec {0} Unit Count".format(name),
                "tags": {},
                "value": value
            }
        ]

        requests.post('http://localhost:8078/metrics', data=json.dumps(metric))
Пример #4
0
def send_rotation_notification(certificate, notification_plugin=None):
    """
    Sends a report to certificate owners when their certificate has been
    rotated.

    :param certificate:
    :param notification_plugin:
    :return:
    """
    status = FAILURE_METRIC_STATUS
    if not notification_plugin:
        notification_plugin = plugins.get(current_app.config.get('LEMUR_DEFAULT_NOTIFICATION_PLUGIN'))

    data = certificate_notification_output_schema.dump(certificate).data

    try:
        notification_plugin.send('rotation', data, [data['owner']])
        status = SUCCESS_METRIC_STATUS
    except Exception as e:
        current_app.logger.error('Unable to send notification to {}.'.format(data['owner']), exc_info=True)
        sentry.captureException()

    metrics.send('notification', 'counter', 1, metric_tags={'status': status, 'event_type': 'rotation'})

    if status == SUCCESS_METRIC_STATUS:
        return True
Пример #5
0
def send_rotation_notification(certificate, notification_plugin=None):
    """
    Sends a report to certificate owners when their certificate has been
    rotated.

    :param certificate:
    :param notification_plugin:
    :return:
    """
    status = FAILURE_METRIC_STATUS
    if not notification_plugin:
        notification_plugin = plugins.get(
            current_app.config.get('LEMUR_DEFAULT_NOTIFICATION_PLUGIN'))

    data = certificate_notification_output_schema.dump(certificate).data

    try:
        notification_plugin.send('rotation', data, [data['owner']])
        status = SUCCESS_METRIC_STATUS
    except Exception as e:
        sentry.captureException()

    metrics.send('notification',
                 'counter',
                 1,
                 metric_tags={
                     'status': status,
                     'event_type': 'rotation'
                 })

    if status == SUCCESS_METRIC_STATUS:
        return True
Пример #6
0
 def get_object(self, data, many=False):
     try:
         data['plugin_object'] = plugins.get(data['slug'])
         return data
     except Exception:
         raise ValidationError('Unable to find plugin: {0}'.format(
             data['slug']))
Пример #7
0
def send_pending_failure_notification(pending_cert,
                                      notify_owner=True,
                                      notify_security=True,
                                      notification_plugin=None):
    """
    Sends a report to certificate owners when their pending certificate failed to be created.

    :param pending_cert:
    :param notification_plugin:
    :return:
    """
    status = FAILURE_METRIC_STATUS

    if not notification_plugin:
        notification_plugin = plugins.get(
            current_app.config.get("LEMUR_DEFAULT_NOTIFICATION_PLUGIN",
                                   "email-notification"))

    data = pending_certificate_output_schema.dump(pending_cert).data
    data["security_email"] = current_app.config.get(
        "LEMUR_SECURITY_TEAM_EMAIL")

    if notify_owner:
        try:
            notification_plugin.send("failed", data, [data["owner"]],
                                     pending_cert)
            status = SUCCESS_METRIC_STATUS
        except Exception as e:
            current_app.logger.error(
                "Unable to send pending failure notification to {}.".format(
                    data["owner"]),
                exc_info=True,
            )
            sentry.captureException()

    if notify_security:
        try:
            notification_plugin.send("failed", data, data["security_email"],
                                     pending_cert)
            status = SUCCESS_METRIC_STATUS
        except Exception as e:
            current_app.logger.error(
                "Unable to send pending failure notification to "
                "{}.".format(data["security_email"]),
                exc_info=True,
            )
            sentry.captureException()

    metrics.send(
        "notification",
        "counter",
        1,
        metric_tags={
            "status": status,
            "event_type": "rotation"
        },
    )

    if status == SUCCESS_METRIC_STATUS:
        return True
Пример #8
0
def publish_verisign_units():
    """
    Simple function that queries verisign for API units and posts the mertics to
    Atlas API for other teams to consume.
    :return:
    """
    from lemur.plugins import plugins
    v = plugins.get('verisign-issuer')
    units = v.get_available_units()

    metrics = {}
    for item in units:
        if item['@type'] in metrics.keys():
            metrics[item['@type']] += int(item['@remaining'])
        else:
            metrics.update({item['@type']: int(item['@remaining'])})

    for name, value in metrics.items():
        metric = [{
            "timestamp": 1321351651,
            "type": "GAUGE",
            "name": "Symantec {0} Unit Count".format(name),
            "tags": {},
            "value": value
        }]

        requests.post('http://localhost:8078/metrics', data=json.dumps(metric))
Пример #9
0
def send_pending_failure_notification(pending_cert,
                                      notify_owner=True,
                                      notify_security=True,
                                      notification_plugin=None):
    """
    Sends a report to certificate owners when their pending certificate failed to be created.

    :param pending_cert:
    :param notification_plugin:
    :return:
    """
    status = FAILURE_METRIC_STATUS

    if not notification_plugin:
        notification_plugin = plugins.get(
            current_app.config.get('LEMUR_DEFAULT_NOTIFICATION_PLUGIN',
                                   'email-notification'))

    data = pending_certificate_output_schema.dump(pending_cert).data
    data["security_email"] = current_app.config.get(
        'LEMUR_SECURITY_TEAM_EMAIL')

    if notify_owner:
        try:
            notification_plugin.send('failed', data, [data['owner']],
                                     pending_cert)
            status = SUCCESS_METRIC_STATUS
        except Exception as e:
            current_app.logger.error(
                'Unable to send pending failure notification to {}.'.format(
                    data['owner']),
                exc_info=True)
            sentry.captureException()

    if notify_security:
        try:
            notification_plugin.send('failed', data, data["security_email"],
                                     pending_cert)
            status = SUCCESS_METRIC_STATUS
        except Exception as e:
            current_app.logger.error(
                'Unable to send pending failure notification to '
                '{}.'.format(data['security_email']),
                exc_info=True)
            sentry.captureException()

    metrics.send('notification',
                 'counter',
                 1,
                 metric_tags={
                     'status': status,
                     'event_type': 'rotation'
                 })

    if status == SUCCESS_METRIC_STATUS:
        return True
Пример #10
0
def publish_unapproved_verisign_certificates():
    """
    Query the Verisign for any certificates that need to be approved.
    :return:
    """
    from lemur.plugins import plugins
    from lemur.extensions import metrics
    v = plugins.get('verisign-issuer')
    certs = v.get_pending_certificates()
    metrics.send('pending_certificates', 'gauge', certs)
Пример #11
0
def publish_unapproved_verisign_certificates():
    """
    Query the Verisign for any certificates that need to be approved.
    :return:
    """
    from lemur.plugins import plugins
    from lemur.extensions import metrics
    v = plugins.get('verisign-issuer')
    certs = v.get_pending_certificates()
    metrics.send('pending_certificates', 'gauge', certs)
Пример #12
0
    def get_object(self, data, many=False):
        try:
            data["plugin_object"] = plugins.get(data["slug"])
        except KeyError as e:
            raise ValidationError(
                "Unable to find plugin. Slug: {0} Reason: {1}".format(
                    data["slug"], e))

        plugin_options_validated = []

        # parse any sub-plugins
        for option in data.get("plugin_options", []):
            server_options_user_value = None
            if not option:
                continue  # Angular sometimes generates empty option objects.
            try:
                option_name = option["name"]
                option_value = option.get("value", "")
            except KeyError as e:
                raise ValidationError(
                    f"Unable to get plugin options. Slug: {data['slug']} Option: {option!r}"
                )
            if "plugin" in option.get("type", []):
                # for plugins, sub-plugin options are validated in a recursive call to schema.load() below
                sub_data, errors = PluginInputSchema().load(option_value)
                if errors:
                    raise ValidationError(
                        f"Unable to load plugin options. Slug: {data['slug']} Option {option_name}"
                    )
                option["value"] = sub_data
                plugin_options_validated.append(option)
            elif data["plugin_object"]:
                # validate user inputs for sub-plugin options and only accept "value" field from user
                try:
                    # Run regex validation rule on user input
                    data["plugin_object"].validate_option_value(
                        option_name, option_value)

                    # Only accept the "value" field from the user - keep server default options for all other fields
                    server_options_with_user_value = data[
                        "plugin_object"].get_server_options(option_name)
                    if server_options_with_user_value is None:  # no server options discovered
                        plugin_options_validated.append(option)
                        continue
                    server_options_with_user_value["value"] = option_value
                    plugin_options_validated.append(
                        server_options_with_user_value)

                except (ValueError, ValidationError) as e:
                    raise ValidationError(
                        f"Unable to validate plugin options. Slug: {data['slug']} Option {option_name}: {e}"
                    )

        data["plugin_options"] = plugin_options_validated
        return data
Пример #13
0
def send_security_expiration_summary(exclude=None):
    """
    Sends a report to the security team with a summary of all expiring certificates.
    All expiring certificates are included here, regardless of notification configuration.
    Certificates with notifications disabled are omitted.

    :param exclude:
    :return:
    """
    function = f"{__name__}.{sys._getframe().f_code.co_name}"
    status = FAILURE_METRIC_STATUS
    notification_plugin = plugins.get(
        current_app.config.get("LEMUR_DEFAULT_NOTIFICATION_PLUGIN", "email-notification")
    )
    notification_type = "expiration_summary"
    log_data = {
        "function": function,
        "message": "Sending expiration summary notification for to security team",
        "notification_type": notification_type,
        "notification_plugin": notification_plugin.slug,
    }

    intervals_and_certs = get_eligible_security_summary_certs(exclude)
    security_email = current_app.config.get("LEMUR_SECURITY_TEAM_EMAIL")

    try:
        current_app.logger.debug(log_data)

        message_data = []

        for interval, certs in intervals_and_certs.items():
            cert_data = []
            for certificate in certs:
                cert_data.append(certificate_notification_output_schema.dump(certificate).data)
            interval_data = {"interval": interval, "certificates": cert_data}
            message_data.append(interval_data)

        notification_plugin.send(notification_type, message_data, security_email, None)
        status = SUCCESS_METRIC_STATUS
    except Exception:
        log_data["message"] = f"Unable to send {notification_type} notification for certificates " \
                              f"{intervals_and_certs} to targets {security_email}"
        current_app.logger.error(log_data, exc_info=True)
        sentry.captureException()

    metrics.send(
        "notification",
        "counter",
        1,
        metric_tags={"status": status, "event_type": notification_type, "plugin": notification_plugin.slug},
    )

    if status == SUCCESS_METRIC_STATUS:
        return True
Пример #14
0
def send_default_notification(notification_type,
                              data,
                              targets,
                              notification_options=None,
                              **kwargs):
    """
    Sends a report to the specified target via the default notification plugin. Applicable for any notification_type.
    At present, "default" means email, as the other notification plugins do not support dynamically configured targets.

    :param notification_type:
    :param data:
    :param targets:
    :param notification_options:
    :return:
    """
    function = f"{__name__}.{sys._getframe().f_code.co_name}"
    status = FAILURE_METRIC_STATUS
    notification_plugin = plugins.get(
        current_app.config.get("LEMUR_DEFAULT_NOTIFICATION_PLUGIN",
                               "email-notification"))
    log_data = {
        "function": function,
        "message":
        f"Sending {notification_type} notification for certificate data {data} to targets {targets}",
        "notification_type": notification_type,
        "notification_plugin": notification_plugin.slug,
    }

    try:
        current_app.logger.debug(log_data)
        # we need the notification.options here because the email templates utilize the interval/unit info
        notification_plugin.send(notification_type, data, targets,
                                 notification_options, **kwargs)
        status = SUCCESS_METRIC_STATUS
    except Exception as e:
        log_data["message"] = f"Unable to send {notification_type} notification for certificate data {data} " \
                              f"to targets {targets}"
        current_app.logger.error(log_data, exc_info=True)
        capture_exception()

    metrics.send(
        "notification",
        "counter",
        1,
        metric_tags={
            "status": status,
            "event_type": notification_type,
            "plugin": notification_plugin.slug
        },
    )

    if status == SUCCESS_METRIC_STATUS:
        return True
Пример #15
0
    def get_object(self, data, many=False):
        try:
            data['plugin_object'] = plugins.get(data['slug'])

            # parse any sub-plugins
            for option in data.get('plugin_options', []):
                if 'plugin' in option.get('type', []):
                    sub_data, errors = PluginInputSchema().load(option['value'])
                    option['value'] = sub_data

            return data
        except Exception as e:
            raise ValidationError('Unable to find plugin. Slug: {0} Reason: {1}'.format(data['slug'], e))
Пример #16
0
    def get_object(self, data, many=False):
        try:
            data['plugin_object'] = plugins.get(data['slug'])

            # parse any sub-plugins
            for option in data.get('plugin_options', []):
                if 'plugin' in option.get('type', []):
                    sub_data, errors = PluginInputSchema().load(option['value'])
                    option['value'] = sub_data

            return data
        except Exception as e:
            raise ValidationError('Unable to find plugin. Slug: {0} Reason: {1}'.format(data['slug'], e))
Пример #17
0
def send_rotation_notification(certificate, notification_plugin=None):
    """
    Sends a report to certificate owners when their certificate has been
    rotated.

    :param certificate:
    :param notification_plugin:
    :return:
    """
    function = f"{__name__}.{sys._getframe().f_code.co_name}"
    log_data = {
        "function": function,
        "message": f"Sending rotation notification for certificate {certificate.name}",
        "notification_type": "rotation",
        "certificate_name": certificate.name,
        "certificate_owner": certificate.owner,
    }
    status = FAILURE_METRIC_STATUS
    if not notification_plugin:
        notification_plugin = plugins.get(
            current_app.config.get("LEMUR_DEFAULT_NOTIFICATION_PLUGIN", "email-notification")
        )

    data = certificate_notification_output_schema.dump(certificate).data

    try:
        notification_plugin.send("rotation", data, [data["owner"]], [])
        status = SUCCESS_METRIC_STATUS
    except Exception as e:
        log_data["message"] = f"Unable to send rotation notification for certificate {certificate.name} " \
                              f"to owner {data['owner']}"
        current_app.logger.error(log_data, exc_info=True)
        sentry.captureException()

    metrics.send(
        "notification",
        "counter",
        1,
        metric_tags={"status": status, "event_type": "rotation"},
    )

    if status == SUCCESS_METRIC_STATUS:
        return True
Пример #18
0
def send_rotation_notification(certificate, notification_plugin=None):
    """
    Sends a report to certificate owners when their certificate as been
    rotated.

    :param certificate:
    :return:
    """
    if not notification_plugin:
        notification_plugin = plugins.get(current_app.config.get('LEMUR_DEFAULT_NOTIFICATION_PLUGIN'))

    data = certificate_notification_output_schema.dump(certificate).data

    try:
        notification_plugin.send('rotation', data, [data['owner']])
        metrics.send('rotation_notification_sent', 'counter', 1)
        return True
    except Exception as e:
        metrics.send('rotation_notification_failure', 'counter', 1)
        current_app.logger.exception(e)
Пример #19
0
def send_pending_failure_notification(pending_cert, notify_owner=True, notify_security=True, notification_plugin=None):
    """
    Sends a report to certificate owners when their pending certificate failed to be created.

    :param pending_cert:
    :param notification_plugin:
    :return:
    """
    status = FAILURE_METRIC_STATUS

    if not notification_plugin:
        notification_plugin = plugins.get(
            current_app.config.get('LEMUR_DEFAULT_NOTIFICATION_PLUGIN', 'email-notification')
        )

    data = pending_certificate_output_schema.dump(pending_cert).data
    data["security_email"] = current_app.config.get('LEMUR_SECURITY_TEAM_EMAIL')

    if notify_owner:
        try:
            notification_plugin.send('failed', data, [data['owner']], pending_cert)
            status = SUCCESS_METRIC_STATUS
        except Exception as e:
            current_app.logger.error('Unable to send pending failure notification to {}.'.format(data['owner']),
                                     exc_info=True)
            sentry.captureException()

    if notify_security:
        try:
            notification_plugin.send('failed', data, data["security_email"], pending_cert)
            status = SUCCESS_METRIC_STATUS
        except Exception as e:
            current_app.logger.error('Unable to send pending failure notification to '
                                     '{}.'.format(data['security_email']),
                                     exc_info=True)
            sentry.captureException()

    metrics.send('notification', 'counter', 1, metric_tags={'status': status, 'event_type': 'rotation'})

    if status == SUCCESS_METRIC_STATUS:
        return True
Пример #20
0
def send_rotation_notification(certificate, notification_plugin=None):
    """
    Sends a report to certificate owners when their certificate as been
    rotated.

    :param certificate:
    :return:
    """
    if not notification_plugin:
        notification_plugin = plugins.get(current_app.config.get('LEMUR_DEFAULT_NOTIFICATION_PLUGIN'))

    data = certificate_notification_output_schema.dump(certificate).data

    try:
        notification_plugin.send('rotation', data, [data['owner']])
        metrics.send('rotation_notification_sent', 'counter', 1)
        return True
    except Exception as e:
        sentry.captureException()
        metrics.send('rotation_notification_failure', 'counter', 1)
        current_app.logger.exception(e)
Пример #21
0
def send_rotation_notification(certificate, notification_plugin=None):
    """
    Sends a report to certificate owners when their certificate has been
    rotated.

    :param certificate:
    :param notification_plugin:
    :return:
    """
    status = FAILURE_METRIC_STATUS
    if not notification_plugin:
        notification_plugin = plugins.get(
            current_app.config.get("LEMUR_DEFAULT_NOTIFICATION_PLUGIN"))

    data = certificate_notification_output_schema.dump(certificate).data

    try:
        notification_plugin.send("rotation", data, [data["owner"]])
        status = SUCCESS_METRIC_STATUS
    except Exception as e:
        current_app.logger.error("Unable to send notification to {}.".format(
            data["owner"]),
                                 exc_info=True)
        sentry.captureException()

    metrics.send(
        "notification",
        "counter",
        1,
        metric_tags={
            "status": status,
            "event_type": "rotation"
        },
    )

    if status == SUCCESS_METRIC_STATUS:
        return True
Пример #22
0
 def get_object(self, data, many=False):
     try:
         data['plugin_object'] = plugins.get(data['slug'])
         return data
     except Exception:
         raise ValidationError('Unable to find plugin: {0}'.format(data['slug']))
Пример #23
0
    def post(self, certificate_id):
        """
        .. http:post:: /certificates/1/export

           Export a certificate

           **Example request**:

           .. sourcecode:: http

              PUT /certificates/1/export HTTP/1.1
              Host: example.com
              Accept: application/json, text/javascript

              {
                "export": {
                    "plugin": {
                        "pluginOptions": [{
                            "available": ["Java Key Store (JKS)"],
                            "required": true,
                            "type": "select",
                            "name": "type",
                            "helpMessage": "Choose the format you wish to export",
                            "value": "Java Key Store (JKS)"
                        }, {
                            "required": false,
                            "type": "str",
                            "name": "passphrase",
                            "validation": "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[$@$!%*#?&])[A-Za-z\\d$@$!%*#?&]{8,}$",
                            "helpMessage": "If no passphrase is given one will be generated for you, we highly recommend this. Minimum length is 8."
                        }, {
                            "required": false,
                            "type": "str",
                            "name": "alias",
                            "helpMessage": "Enter the alias you wish to use for the keystore."
                        }],
                        "version": "unknown",
                        "description": "Attempts to generate a JKS keystore or truststore",
                        "title": "Java",
                        "author": "Kevin Glisson",
                        "type": "export",
                        "slug": "java-export"
                    }
                }
              }


           **Example response**:

           .. sourcecode:: http

              HTTP/1.1 200 OK
              Vary: Accept
              Content-Type: text/javascript

              {
                "data": "base64encodedstring",
                "passphrase": "UAWOHW#&@_%!tnwmxh832025",
                "extension": "jks"
              }

           :reqheader Authorization: OAuth token to authenticate
           :statuscode 200: no error
           :statuscode 403: unauthenticated
        """
        self.reqparse.add_argument('export', type=dict, required=True, location='json')
        args = self.reqparse.parse_args()

        cert = service.get(certificate_id)
        role = role_service.get_by_name(cert.owner)

        permission = UpdateCertificatePermission(certificate_id, getattr(role, 'name', None))

        plugin = plugins.get(args['export']['plugin']['slug'])
        if plugin.requires_key:
            if permission.can():
                extension, passphrase, data = plugin.export(cert.body, cert.chain, cert.private_key, args['export']['plugin']['pluginOptions'])
            else:
                return dict(message='You are not authorized to export this certificate'), 403
        else:
            extension, passphrase, data = plugin.export(cert.body, cert.chain, cert.private_key, args['export']['plugin']['pluginOptions'])

        # we take a hit in message size when b64 encoding
        return dict(extension=extension, passphrase=passphrase, data=base64.b64encode(data))
Пример #24
0
def upload_acme_token_s3(token, token_name, prefix, account_number,
                         bucket_name):
    """
    This method serves for testing the upload_acme_token to S3, fetching the token to verify it, and then deleting it.
    It mainly serves for testing purposes.
    :param token:
    :param token_name:
    :param prefix:
    :param account_number:
    :param bucket_name:
    :return:
    """
    additional_options = [
        {
            "name": "bucket",
            "value": bucket_name,
            "type": "str",
            "required": True,
            "validation": r"[0-9a-z.-]{3,63}",
            "helpMessage": "Must be a valid S3 bucket name!",
        },
        {
            "name":
            "accountNumber",
            "type":
            "str",
            "value":
            account_number,
            "required":
            True,
            "validation":
            r"[0-9]{12}",
            "helpMessage":
            "A valid AWS account number with permission to access S3",
        },
        {
            "name": "region",
            "type": "str",
            "default": "us-east-1",
            "required": False,
            "helpMessage": "Region bucket exists",
            "available": ["us-east-1", "us-west-2", "eu-west-1"],
        },
        {
            "name": "encrypt",
            "type": "bool",
            "value": False,
            "required": False,
            "helpMessage": "Enable server side encryption",
            "default": True,
        },
        {
            "name": "prefix",
            "type": "str",
            "value": prefix,
            "required": False,
            "helpMessage": "Must be a valid S3 object prefix!",
        },
    ]

    p = plugins.get("aws-s3")
    p.upload_acme_token(token_name, token, additional_options)

    if not prefix.endswith("/"):
        prefix + "/"

    token_res = s3.get(bucket_name,
                       prefix + token_name,
                       account_number=account_number)
    assert (token_res == token)
    s3.delete(bucket_name, prefix + token_name, account_number=account_number)
Пример #25
0
 def get_object(self, data, many=False):
     if many:
         return [plugins.get(plugin['slug']) for plugin in data]
     else:
         return plugins.get(data['slug'])
Пример #26
0
    def post(self, certificate_id):
        """
        .. http:post:: /certificates/1/export

           Export a certificate

           **Example request**:

           .. sourcecode:: http

              PUT /certificates/1/export HTTP/1.1
              Host: example.com
              Accept: application/json, text/javascript

              {
                "export": {
                    "plugin": {
                        "pluginOptions": [{
                            "available": ["Java Key Store (JKS)"],
                            "required": true,
                            "type": "select",
                            "name": "type",
                            "helpMessage": "Choose the format you wish to export",
                            "value": "Java Key Store (JKS)"
                        }, {
                            "required": false,
                            "type": "str",
                            "name": "passphrase",
                            "validation": "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[$@$!%*#?&])[A-Za-z\\d$@$!%*#?&]{8,}$",
                            "helpMessage": "If no passphrase is given one will be generated for you, we highly recommend this. Minimum length is 8."
                        }, {
                            "required": false,
                            "type": "str",
                            "name": "alias",
                            "helpMessage": "Enter the alias you wish to use for the keystore."
                        }],
                        "version": "unknown",
                        "description": "Attempts to generate a JKS keystore or truststore",
                        "title": "Java",
                        "author": "Kevin Glisson",
                        "type": "export",
                        "slug": "java-export"
                    }
                }
              }


           **Example response**:

           .. sourcecode:: http

              HTTP/1.1 200 OK
              Vary: Accept
              Content-Type: text/javascript

              {
                "data": "base64encodedstring",
                "passphrase": "UAWOHW#&@_%!tnwmxh832025",
                "extension": "jks"
              }

           :reqheader Authorization: OAuth token to authenticate
           :statuscode 200: no error
           :statuscode 403: unauthenticated
        """
        self.reqparse.add_argument('export',
                                   type=dict,
                                   required=True,
                                   location='json')
        args = self.reqparse.parse_args()

        cert = service.get(certificate_id)
        role = role_service.get_by_name(cert.owner)

        permission = UpdateCertificatePermission(certificate_id,
                                                 getattr(role, 'name', None))

        plugin = plugins.get(args['export']['plugin']['slug'])
        if plugin.requires_key:
            if permission.can():
                extension, passphrase, data = plugin.export(
                    cert.body, cert.chain, cert.private_key,
                    args['export']['plugin']['pluginOptions'])
            else:
                return dict(
                    message='You are not authorized to export this certificate'
                ), 403
        else:
            extension, passphrase, data = plugin.export(
                cert.body, cert.chain, cert.private_key,
                args['export']['plugin']['pluginOptions'])

        # we take a hit in message size when b64 encoding
        return dict(extension=extension,
                    passphrase=passphrase,
                    data=base64.b64encode(data))
Пример #27
0
 def get_object(self, data, many=False):
     data['plugin_object'] = plugins.get(data['slug'])
     return data
Пример #28
0
 def get_object(self, data, many=False):
     data['plugin_object'] = plugins.get(data['slug'])
     return data
Пример #29
0
def send_pending_failure_notification(
    pending_cert, notify_owner=True, notify_security=True, notification_plugin=None
):
    """
    Sends a report to certificate owners when their pending certificate failed to be created.

    :param pending_cert:
    :param notification_plugin:
    :return:
    """
    function = f"{__name__}.{sys._getframe().f_code.co_name}"
    log_data = {
        "function": function,
        "message": f"Sending pending failure notification for pending certificate {pending_cert}",
        "notification_type": "failed",
        "certificate_name": pending_cert.name,
        "certificate_owner": pending_cert.owner,
    }
    status = FAILURE_METRIC_STATUS

    if not notification_plugin:
        notification_plugin = plugins.get(
            current_app.config.get(
                "LEMUR_DEFAULT_NOTIFICATION_PLUGIN", "email-notification"
            )
        )

    data = pending_certificate_output_schema.dump(pending_cert).data
    data["security_email"] = current_app.config.get("LEMUR_SECURITY_TEAM_EMAIL")

    if notify_owner:
        try:
            notification_plugin.send("failed", data, [data["owner"]], pending_cert)
            status = SUCCESS_METRIC_STATUS
        except Exception as e:
            log_data["recipient"] = data["owner"]
            log_data["message"] = f"Unable to send pending failure notification for certificate {pending_cert.name} " \
                                  f"to owner {pending_cert.owner}"
            current_app.logger.error(log_data, exc_info=True)
            sentry.captureException()

    if notify_security:
        try:
            notification_plugin.send(
                "failed", data, data["security_email"], pending_cert
            )
            status = SUCCESS_METRIC_STATUS
        except Exception as e:
            log_data["recipient"] = data["security_email"]
            log_data["message"] = f"Unable to send pending failure notification for certificate {pending_cert.name} " \
                                  f"to security email {pending_cert.owner}"
            current_app.logger.error(log_data, exc_info=True)
            sentry.captureException()

    metrics.send(
        "notification",
        "counter",
        1,
        metric_tags={"status": status, "event_type": "failed"},
    )

    if status == SUCCESS_METRIC_STATUS:
        return True