예제 #1
0
def get_csr_from_certmonger(nickname):
    """
    Get the csr for the provided nickname by asking certmonger.

    Returns the csr in ASCII format without the header/footer in a single line
    or None if not found.
    """
    criteria = {
        'cert-database': paths.PKI_TOMCAT_ALIAS_DIR,
        'cert-nickname': nickname,
    }

    id = certmonger.get_request_id(criteria)
    if id:
        csr = certmonger.get_request_value(id, "csr")
        if csr:
            try:
                # Make sure the value can be parsed as valid CSR
                csr_obj = crypto_x509.load_pem_x509_csr(
                    csr.encode('ascii'), default_backend())
                val = base64.b64encode(csr_obj.public_bytes(x509.Encoding.DER))
                return val.decode('ascii')
            except Exception as e:
                # Fallthrough and return None
                logger.debug("Unable to get CSR from certmonger: %s", e)
    return None
예제 #2
0
    def renew(self):
        ca = cainstance.CAInstance(api.env.realm)
        if not ca.is_configured():
            raise admintool.ScriptError("CA is not configured on this system")

        criteria = {
            'cert-database': paths.PKI_TOMCAT_ALIAS_DIR,
            'cert-nickname': self.cert_nickname,
            'ca-name': 'dogtag-ipa-ca-renew-agent',
        }
        self.request_id = certmonger.get_request_id(criteria)
        if self.request_id is None:
            raise admintool.ScriptError(
                "CA certificate is not tracked by certmonger")
        self.log.debug(
            "Found certmonger request id %r", self.request_id)

        db = certs.CertDB(api.env.realm, nssdir=paths.PKI_TOMCAT_ALIAS_DIR)
        cert = db.get_cert_from_db(self.cert_nickname, pem=False)

        options = self.options
        if options.external_cert_files:
            return self.renew_external_step_2(ca, cert)

        if options.self_signed is not None:
            self_signed = options.self_signed
        else:
            self_signed = x509.is_self_signed(cert, x509.DER)

        if self_signed:
            return self.renew_self_signed(ca)
        else:
            return self.renew_external_step_1(ca)
예제 #3
0
    def check_dates(self):
        """Check validity dates"""
        # TODO: make this configurable
        threshold = 7  # days

        requests = self.get_requests()

        now = datetime.datetime.utcnow()

        for request in requests:
            request_id = certmonger.get_request_id(request)

            if request_id is None:
                # The missing tracking is reported in check_tracking()
                continue
            nickname = request.get('cert-nickname')
            rawcert = certmonger.get_request_value(request_id, 'cert')
            cert = load_pem_certificate(str(rawcert))
            diff = cert.not_valid_after - now
            if diff.days < 0:  # TODO: this is false-positive generator
                self.failure("Certificate %s is expired" % nickname)
            elif diff.days < threshold:
                self.failure("Certificate %s is expiring soon" % nickname)
            elif cert.not_valid_before > now:
                self.failure("Certificate %s is not valid yet" % nickname)
예제 #4
0
    def check_tracking(self):
        """Compare expected vs actual tracking configuration"""
        requests = self.get_requests()
        cm = certmonger._certmonger()

        ids = []
        all_requests = cm.obj_if.get_requests()
        for req in all_requests:
            request = certmonger._cm_dbus_object(cm.bus, cm, req,
                                                 certmonger.DBUS_CM_REQUEST_IF,
                                                 certmonger.DBUS_CM_IF, True)
            id = request.prop_if.Get(certmonger.DBUS_CM_REQUEST_IF, 'nickname')
            ids.append(str(id))

        for request in requests:
            request_id = certmonger.get_request_id(request)
            try:
                if request_id is not None:
                    ids.remove(request_id)
            except ValueError as e:
                self.failure('Failure trying to remove % from '
                             'list: %s' % (request_id, e))

            if request_id is None:
                self.failure('Missing tracking for %s' % request)

        if ids:
            self.warning('Unknown certmonger ids: %s' % ','.join(ids))
예제 #5
0
    def renew(self):
        ca = cainstance.CAInstance(api.env.realm)
        if not ca.is_configured():
            raise admintool.ScriptError("CA is not configured on this system")

        criteria = {
            'cert-database': paths.PKI_TOMCAT_ALIAS_DIR,
            'cert-nickname': self.cert_nickname,
            'ca-name': 'dogtag-ipa-ca-renew-agent',
        }
        self.request_id = certmonger.get_request_id(criteria)
        if self.request_id is None:
            raise admintool.ScriptError(
                "CA certificate is not tracked by certmonger")
        self.log.debug(
            "Found certmonger request id %r", self.request_id)

        db = certs.CertDB(api.env.realm, nssdir=paths.PKI_TOMCAT_ALIAS_DIR)
        cert = db.get_cert_from_db(self.cert_nickname, pem=False)

        options = self.options
        if options.external_cert_files:
            return self.renew_external_step_2(ca, cert)

        if options.self_signed is not None:
            self_signed = options.self_signed
        else:
            self_signed = x509.is_self_signed(cert, x509.DER)

        if self_signed:
            return self.renew_self_signed(ca)
        else:
            return self.renew_external_step_1(ca)
예제 #6
0
 def _get_ca_request_id(self, ca_name):
     """Lookup tracking request for IPA CA, using given ca-name."""
     criteria = {
         'cert-database': paths.PKI_TOMCAT_ALIAS_DIR,
         'cert-nickname': self.cert_nickname,
         'ca-name': ca_name,
     }
     return certmonger.get_request_id(criteria)
예제 #7
0
 def _get_ca_request_id(self, ca_name):
     """Lookup tracking request for IPA CA, using given ca-name."""
     criteria = {
         'cert-database': paths.PKI_TOMCAT_ALIAS_DIR,
         'cert-nickname': self.cert_nickname,
         'ca-name': ca_name,
     }
     return certmonger.get_request_id(criteria)
예제 #8
0
    def compare_requests(self):
        """
        Compare cert serial numbers to their request

        The CA subsystem certificates are renewed using the certmonger
        CA dogtag-ipa-ca-renew-agent. This renews by serial number,
        sending CS a request like:
            GET /ca/ee/ca/profileSubmit?profileId=caServerCert&serial_num=5&
                renewal=true&xml=true&requestor_name=IPA

        CS uses the existing cert to generate and return a new one.

        Double-check that the cert in that request entry,
           dn: cn=<serial#>,ou=ca,ou=requests,o=ipaca
        """
        if not self.ca.is_configured():
            self.failure('Skipping request compare because CA not installed')
            return

        requests = self.get_requests()

        for request in requests:
            if request.get('ca-name') != 'dogtag-ipa-ca-renew-agent':
                continue
            request_id = certmonger.get_request_id(request)
            serial = int(certmonger.get_request_value(request_id, 'serial'),
                         16)
            template_subject = DN(
                certmonger.get_request_value(request_id, 'template-subject'))

            dn = DN(('cn', serial), ('ou', 'ca'), ('ou', 'requests'),
                    ('o', 'ipaca'))

            try:
                entries = self.conn.get_entries(dn, self.conn.SCOPE_SUBTREE)
            except errors.NotFound:
                self.failure('Unable to find request for serial %s' % serial)
            except Exception as e:
                self.failure('Failed to load request for serial %s' % serial)
            else:
                s = entries[0].get('extdata-req--005fsubject--005fname')
                if s is None:
                    continue
                subject_der = base64.b64decode(s[0])
                subject = DN(der_to_subject(subject_der))
                subject = DN(der_to_subject(subject_der))

                logger.debug('CS template %s, CM subject %s, serial %s',
                             subject, template_subject, serial)

                if ((subject != template_subject)
                        and (subject != template_subject.x500_text())):
                    self.failure('Subject %s and template subject %s '
                                 'do not match for serial %s' %
                                 (subject, template_subject, serial))
예제 #9
0
def get_pkinit_request_ca():
    """
    Return the certmonger CA name which is serving the PKINIT certificate
    request. If the certificate is not tracked by Certmonger, return None
    """
    pkinit_request_id = certmonger.get_request_id(
        {'cert-file': paths.KDC_CERT})

    if pkinit_request_id is None:
        return

    return certmonger.get_request_value(pkinit_request_id, 'ca-name')
예제 #10
0
def get_pkinit_request_ca():
    """
    Return the certmonger CA name which is serving the PKINIT certificate
    request. If the certificate is not tracked by Certmonger, return None
    """
    pkinit_request_id = certmonger.get_request_id(
        {'cert-file': paths.KDC_CERT})

    if pkinit_request_id is None:
        return

    return certmonger.get_request_value(pkinit_request_id, 'ca-name')
예제 #11
0
    def check(self):
        requests = get_expected_requests(self.ca, self.ds, self.serverid)
        cm = certmonger._certmonger()

        ids = []
        all_requests = cm.obj_if.get_requests()
        for req in all_requests:
            request = certmonger._cm_dbus_object(cm.bus, cm, req,
                                                 certmonger.DBUS_CM_REQUEST_IF,
                                                 certmonger.DBUS_CM_IF, True)
            id = request.prop_if.Get(certmonger.DBUS_CM_REQUEST_IF, 'nickname')
            ids.append(str(id))

        for request in requests:
            request_id = certmonger.get_request_id(request)
            try:
                if request_id is not None:
                    # Tracking found, move onto the next
                    ids.remove(request_id)
                    yield Result(self, constants.SUCCESS, key=request_id)
                    continue
            except ValueError as e:
                # A request was found but the id isn't in the
                # list from certmonger!?
                yield Result(self,
                             constants.ERROR,
                             key=request_id,
                             error=str(e),
                             msg='Found request id {key} but it is not tracked'
                             'by certmonger!?: {error}')
                continue

            # The criteria was not met
            if request_id is None:
                flatten = ', '.join("{!s}={!s}".format(key, val)
                                    for (key, val) in request.items())
                yield Result(self,
                             constants.ERROR,
                             key=flatten,
                             msg='Expected certmonger tracking is missing for '
                             '{key}. Automated renewal will not happen '
                             'for this certificate')
                continue

        # Report any unknown certmonger requests as warnings
        if ids:
            for id in ids:
                yield Result(self,
                             constants.WARNING,
                             key=id,
                             msg='certmonger tracking request {key} found and '
                             'is not expected on an IPA master.')
예제 #12
0
def update_server(certs):
    instance = '-'.join(api.env.realm.split('.'))
    update_db(paths.ETC_DIRSRV_SLAPD_INSTANCE_TEMPLATE % instance, certs)
    if services.knownservices.dirsrv.is_running():
        services.knownservices.dirsrv.restart(instance)

    if services.knownservices.httpd.is_running():
        services.knownservices.httpd.restart()

    criteria = {
        'cert-database': paths.PKI_TOMCAT_ALIAS_DIR,
        'cert-nickname': IPA_CA_NICKNAME,
        'ca-name': RENEWAL_CA_NAME,
    }
    request_id = certmonger.get_request_id(criteria)
    if request_id is not None:
        timeout = api.env.startup_timeout + 60

        # The dogtag-ipa-ca-renew-agent-reuse Certmonger CA never
        # actually renews the certificate; it only pulls it from the
        # ca_renewal LDAP cert store.
        #
        # Why is this needed?  If the CA cert gets renewed long
        # before its notAfter (expiry) date (e.g. to switch from
        # self-signed to external, or to switch to new external CA),
        # then the other (i.e. not caRenewalMaster) CA replicas will
        # not promptly pick up the new CA cert.  So we make
        # ipa-certupdate always check for an updated CA cert.
        #
        logger.debug("resubmitting certmonger request '%s'", request_id)
        certmonger.resubmit_request(
            request_id, ca='dogtag-ipa-ca-renew-agent-reuse', profile='')
        try:
            state = certmonger.wait_for_request(request_id, timeout)
        except RuntimeError:
            raise admintool.ScriptError(
                "Resubmitting certmonger request '%s' timed out, "
                "please check the request manually" % request_id)
        ca_error = certmonger.get_request_value(request_id, 'ca-error')
        if state != 'MONITORING' or ca_error:
            raise admintool.ScriptError(
                "Error resubmitting certmonger request '%s', "
                "please check the request manually" % request_id)

        logger.debug("modifying certmonger request '%s'", request_id)
        certmonger.modify(request_id, ca='dogtag-ipa-ca-renew-agent')

    update_file(paths.CA_CRT, certs)
    update_file(paths.CACERT_PEM, certs)
예제 #13
0
def update_server(certs):
    instance = '-'.join(api.env.realm.split('.'))
    update_db(paths.ETC_DIRSRV_SLAPD_INSTANCE_TEMPLATE % instance, certs)
    if services.knownservices.dirsrv.is_running():
        services.knownservices.dirsrv.restart(instance)

    if services.knownservices.httpd.is_running():
        services.knownservices.httpd.restart()

    criteria = {
        'cert-database': paths.PKI_TOMCAT_ALIAS_DIR,
        'cert-nickname': IPA_CA_NICKNAME,
        'ca-name': RENEWAL_CA_NAME,
    }
    request_id = certmonger.get_request_id(criteria)
    if request_id is not None:
        timeout = api.env.startup_timeout + 60

        # The dogtag-ipa-ca-renew-agent-reuse Certmonger CA never
        # actually renews the certificate; it only pulls it from the
        # ca_renewal LDAP cert store.
        #
        # Why is this needed?  If the CA cert gets renewed long
        # before its notAfter (expiry) date (e.g. to switch from
        # self-signed to external, or to switch to new external CA),
        # then the other (i.e. not caRenewalMaster) CA replicas will
        # not promptly pick up the new CA cert.  So we make
        # ipa-certupdate always check for an updated CA cert.
        #
        logger.debug("resubmitting certmonger request '%s'", request_id)
        certmonger.resubmit_request(
            request_id, ca='dogtag-ipa-ca-renew-agent-reuse', profile='')
        try:
            state = certmonger.wait_for_request(request_id, timeout)
        except RuntimeError:
            raise admintool.ScriptError(
                "Resubmitting certmonger request '%s' timed out, "
                "please check the request manually" % request_id)
        ca_error = certmonger.get_request_value(request_id, 'ca-error')
        if state != 'MONITORING' or ca_error:
            raise admintool.ScriptError(
                "Error resubmitting certmonger request '%s', "
                "please check the request manually" % request_id)

        logger.debug("modifying certmonger request '%s'", request_id)
        certmonger.modify(request_id, ca='dogtag-ipa-ca-renew-agent')

    update_file(paths.CA_CRT, certs)
    update_file(paths.CACERT_PEM, certs)
예제 #14
0
    def check(self):
        requests = get_expected_requests(self.ca, self.ds, self.serverid)
        cm = certmonger._certmonger()

        ids = []
        all_requests = cm.obj_if.get_requests()
        for req in all_requests:
            request = certmonger._cm_dbus_object(cm.bus, cm, req,
                                                 certmonger.DBUS_CM_REQUEST_IF,
                                                 certmonger.DBUS_CM_IF, True)
            id = request.prop_if.Get(certmonger.DBUS_CM_REQUEST_IF, 'nickname')
            ids.append(str(id))

        for request in requests:
            request_id = certmonger.get_request_id(request)
            try:
                if request_id is not None:
                    # Tracking found, move onto the next
                    ids.remove(request_id)
                    yield Result(self, constants.SUCCESS, key=request_id)
                    continue
            except ValueError as e:
                # A request was found but the id isn't in the
                # list from certmonger!?
                yield Result(self,
                             constants.ERROR,
                             key=request_id,
                             msg='Request id %s is not tracked: %s' %
                             (request_id, e))
                continue

            # The criteria was not met
            if request_id is None:
                flatten = ', '.join("{!s}={!s}".format(key, val)
                                    for (key, val) in request.items())
                yield Result(self,
                             constants.ERROR,
                             key=flatten,
                             msg='Missing tracking for %s' % flatten)
                continue

        # Report any unknown certmonger requests as warnings
        if ids:
            for id in ids:
                yield Result(self,
                             constants.WARNING,
                             key=id,
                             msg='Unknown certmonger id %s' % id)
예제 #15
0
    def update_server(self, certs):
        instance = '-'.join(api.env.realm.split('.'))
        self.update_db(paths.ETC_DIRSRV_SLAPD_INSTANCE_TEMPLATE % instance,
                       certs)
        if services.knownservices.dirsrv.is_running():
            services.knownservices.dirsrv.restart(instance)

        self.update_db(paths.HTTPD_ALIAS_DIR, certs)
        if services.knownservices.httpd.is_running():
            services.knownservices.httpd.restart()

        criteria = {
            'cert-database': paths.PKI_TOMCAT_ALIAS_DIR,
            'cert-nickname': IPA_CA_NICKNAME,
            'ca-name': RENEWAL_CA_NAME
        }
        request_id = certmonger.get_request_id(criteria)
        if request_id is not None:
            timeout = api.env.startup_timeout + 60

            logger.debug("resubmitting certmonger request '%s'", request_id)
            certmonger.resubmit_request(request_id,
                                        ca='dogtag-ipa-ca-renew-agent-reuse',
                                        profile='')
            try:
                state = certmonger.wait_for_request(request_id, timeout)
            except RuntimeError:
                raise admintool.ScriptError(
                    "Resubmitting certmonger request '%s' timed out, "
                    "please check the request manually" % request_id)
            ca_error = certmonger.get_request_value(request_id, 'ca-error')
            if state != 'MONITORING' or ca_error:
                raise admintool.ScriptError(
                    "Error resubmitting certmonger request '%s', "
                    "please check the request manually" % request_id)

            logger.debug("modifying certmonger request '%s'", request_id)
            certmonger.modify(request_id, ca='dogtag-ipa-ca-renew-agent')

        self.update_file(paths.CA_CRT, certs)
        self.update_file(paths.CACERT_PEM, certs)
예제 #16
0
    def update_server(self, certs):
        instance = '-'.join(api.env.realm.split('.'))
        self.update_db(
            paths.ETC_DIRSRV_SLAPD_INSTANCE_TEMPLATE % instance, certs)
        if services.knownservices.dirsrv.is_running():
            services.knownservices.dirsrv.restart(instance)

        self.update_db(paths.HTTPD_ALIAS_DIR, certs)
        if services.knownservices.httpd.is_running():
            services.knownservices.httpd.restart()

        criteria = {
            'cert-database': paths.PKI_TOMCAT_ALIAS_DIR,
            'cert-nickname': IPA_CA_NICKNAME,
            'ca-name': RENEWAL_CA_NAME
        }
        request_id = certmonger.get_request_id(criteria)
        if request_id is not None:
            timeout = api.env.startup_timeout + 60

            logger.debug("resubmitting certmonger request '%s'", request_id)
            certmonger.resubmit_request(
                request_id, ca='dogtag-ipa-ca-renew-agent-reuse', profile='')
            try:
                state = certmonger.wait_for_request(request_id, timeout)
            except RuntimeError:
                raise admintool.ScriptError(
                    "Resubmitting certmonger request '%s' timed out, "
                    "please check the request manually" % request_id)
            ca_error = certmonger.get_request_value(request_id, 'ca-error')
            if state != 'MONITORING' or ca_error:
                raise admintool.ScriptError(
                    "Error resubmitting certmonger request '%s', "
                    "please check the request manually" % request_id)

            logger.debug("modifying certmonger request '%s'", request_id)
            certmonger.modify(request_id, ca='dogtag-ipa-ca-renew-agent')

        self.update_file(paths.CA_CRT, certs)
        self.update_file(paths.CACERT_PEM, certs)
예제 #17
0
    def check(self):
        # For simplicity use the expected certmonger tracking for the
        # list of certificates to check because it already filters out
        # based on whether the CA system is configure and whether the
        # certificates were issued by IPA.
        if not self.ca.is_configured():
            logger.debug('CA is not configured, skipping revocation check')
            return
        requests = get_expected_requests(self.ca, self.ds, self.serverid)
        for request in requests:
            id = certmonger.get_request_id(request)
            if request.get('cert-file') is not None:
                certfile = request.get('cert-file')
                try:
                    cert = x509.load_certificate_from_file(certfile)
                except Exception as e:
                    yield Result(self,
                                 constants.ERROR,
                                 key=id,
                                 certfile=certfile,
                                 error=str(e),
                                 msg='Unable to open cert file {certfile}: '
                                 '{error}')
                    continue
            elif request.get('cert-database') is not None:
                nickname = request.get('cert-nickname')
                dbdir = request.get('cert-database')
                try:
                    db = certdb.NSSDatabase(dbdir)
                except Exception as e:
                    yield Result(self,
                                 constants.ERROR,
                                 key=id,
                                 dbdir=dbdir,
                                 error=str(e),
                                 msg='Unable to open NSS database {dbdir}: '
                                 '{error}')
                    continue
                try:
                    cert = db.get_cert(nickname)
                except Exception as e:
                    yield Result(self,
                                 constants.ERROR,
                                 key=id,
                                 dbdir=dbdir,
                                 nickname=nickname,
                                 error=str(e),
                                 msg='Unable to retrieve certificate '
                                 '\'{nickname}\' from {dbdir}: {error}')
                    continue
            else:
                yield Result(self,
                             constants.ERROR,
                             key=id,
                             msg='Unable to to identify certificate storage '
                             'type for request {key}')
                continue

            issued = is_ipa_issued_cert(api, cert)
            if issued is False:
                logger.debug('\'%s\' was not issued by IPA, skipping',
                             DN(cert.subject))
                continue
            if issued is None:
                logger.debug('LDAP is down, skipping \'%s\'', DN(cert.subject))
                continue

            # Now we have the cert either way, check the recovation
            try:
                result = api.Command.cert_show(cert.serial_number, all=True)
            except Exception as e:
                yield Result(self,
                             constants.ERROR,
                             key=id,
                             serial=cert.serial_number,
                             error=str(e),
                             msg='Request for certificate serial number '
                             '{serial} in request {key} failed: {error}')
                continue

            try:
                if result['result']['revoked']:
                    reason = result['result']['revocation_reason']
                    reason_txt = self.revocation_reason[reason]
                    yield Result(self,
                                 constants.ERROR,
                                 revocation_reason=reason_txt,
                                 key=id,
                                 msg='Certificate tracked by {key} is revoked '
                                 '{revocation_reason}')
                else:
                    yield Result(self, constants.SUCCESS, key=id)
            except Exception as e:
                yield Result(self,
                             constants.ERROR,
                             key=id,
                             error=str(e),
                             msg='Unable to determine revocation '
                             'status for {key}: {error}')
예제 #18
0
    def check(self):
        fqdn = socket.getfqdn()
        requests = get_expected_requests(self.ca, self.ds, self.serverid)

        for request in requests:
            request_id = certmonger.get_request_id(request)
            if request_id is None:
                yield Result(self,
                             constants.ERROR,
                             key=request_id,
                             msg='Found request id {key} but it is not tracked'
                             'by certmonger!?')
                continue

            ca_name = certmonger.get_request_value(request_id, 'ca-name')
            if ca_name != 'IPA':
                logger.debug('Skipping request %s with CA %s', request_id,
                             ca_name)
                continue
            profile = certmonger.get_request_value(request_id,
                                                   'template_profile')
            if profile != 'caIPAserviceCert':
                logger.debug('Skipping request %s with profile %s', request_id,
                             profile)
                continue

            certfile = None
            if request.get('cert-file') is not None:
                certfile = request.get('cert-file')
                try:
                    cert = x509.load_certificate_from_file(certfile)
                except Exception as e:
                    yield Result(self,
                                 constants.ERROR,
                                 key=request_id,
                                 certfile=certfile,
                                 error=str(e),
                                 msg='Unable to open cert file {certfile}: '
                                 '{error}')
                    continue
            elif request.get('cert-database') is not None:
                nickname = request.get('cert-nickname')
                dbdir = request.get('cert-database')
                try:
                    db = certdb.NSSDatabase(dbdir)
                except Exception as e:
                    yield Result(self,
                                 constants.ERROR,
                                 key=request_id,
                                 dbdir=dbdir,
                                 error=str(e),
                                 msg='Unable to open NSS database {dbdir}: '
                                 '{error}')
                    continue
                try:
                    cert = db.get_cert(nickname)
                except Exception as e:
                    yield Result(self,
                                 constants.ERROR,
                                 key=id,
                                 dbdir=dbdir,
                                 nickname=nickname,
                                 error=str(e),
                                 msg='Unable to retrieve certificate '
                                 '\'{nickname}\' from {dbdir}: {error}')
                    continue

            hostlist = [fqdn]
            if self.ca.is_configured() and certfile == paths.HTTPD_CERT_FILE:
                hostlist.append(f'{IPA_CA_RECORD}.{api.env.domain}')
            error = False
            for host in hostlist:
                if host not in cert.san_a_label_dns_names:
                    error = True
                    yield Result(self,
                                 constants.ERROR,
                                 key=request_id,
                                 hostname=host,
                                 san=cert.san_a_label_dns_names,
                                 ca=ca_name,
                                 profile=profile,
                                 msg='Certificate request id {key} with '
                                 'profile {profile} for CA {ca} does not '
                                 'have a DNS SAN {san} matching name '
                                 '{hostname}')
            if not error:
                yield Result(self,
                             constants.SUCCESS,
                             key=request_id,
                             hostname=hostlist,
                             san=cert.san_a_label_dns_names,
                             ca=ca_name,
                             profile=profile)
예제 #19
0
    def execute(self, **options):
        ca = cainstance.CAInstance(self.api.env.realm, certs.NSS_DIR)
        if not ca.is_configured():
            self.debug("CA is not configured on this host")
            return False, []

        ldap = self.api.Backend.ldap2
        base_dn = DN(('cn', 'masters'), ('cn', 'ipa'), ('cn', 'etc'),
                     self.api.env.basedn)
        dn = DN(('cn', 'CA'), ('cn', self.api.env.host), base_dn)
        filter = '(&(cn=CA)(ipaConfigString=caRenewalMaster))'
        try:
            entries = ldap.get_entries(base_dn=base_dn,
                                       filter=filter,
                                       attrs_list=[])
        except errors.NotFound:
            pass
        else:
            self.debug("found CA renewal master %s", entries[0].dn[1].value)

            master = False
            updates = []

            for entry in entries:
                if entry.dn == dn:
                    master = True
                    continue

                updates.append({
                    'dn':
                    entry.dn,
                    'updates': [
                        dict(action='remove',
                             attr='ipaConfigString',
                             value='caRenewalMaster')
                    ],
                })

            if master:
                return False, updates
            else:
                return False, []

        criteria = {
            'cert-database': paths.HTTPD_ALIAS_DIR,
            'cert-nickname': 'ipaCert',
        }
        request_id = certmonger.get_request_id(criteria)
        if request_id is not None:
            self.debug("found certmonger request for ipaCert")

            ca_name = certmonger.get_request_value(request_id, 'ca-name')
            if ca_name is None:
                self.warning(
                    "certmonger request for ipaCert is missing ca_name, "
                    "assuming local CA is renewal slave")
                return False, []
            ca_name = ca_name.strip()

            if ca_name == 'dogtag-ipa-renew-agent':
                pass
            elif ca_name == 'dogtag-ipa-retrieve-agent-submit':
                return False, []
            elif ca_name == 'dogtag-ipa-ca-renew-agent':
                return False, []
            else:
                self.warning(
                    "certmonger request for ipaCert has unknown ca_name '%s', "
                    "assuming local CA is renewal slave", ca_name)
                return False, []
        else:
            self.debug("certmonger request for ipaCert not found")

            config = installutils.get_directive(paths.CA_CS_CFG_PATH,
                                                'subsystem.select', '=')

            if config == 'New':
                pass
            elif config == 'Clone':
                return False, []
            else:
                self.warning(
                    "CS.cfg has unknown subsystem.select value '%s', "
                    "assuming local CA is renewal slave", config)
                return (False, False, [])

        update = {
            'dn':
            dn,
            'updates': [
                dict(action='add',
                     attr='ipaConfigString',
                     value='caRenewalMaster')
            ],
        }

        return False, [update]
예제 #20
0
    def execute(self, **options):
        ca = cainstance.CAInstance(self.api.env.realm)
        if not ca.is_configured():
            logger.debug("CA is not configured on this host")
            return False, []

        ldap = self.api.Backend.ldap2
        base_dn = DN(self.api.env.container_masters, self.api.env.basedn)
        dn = DN(('cn', 'CA'), ('cn', self.api.env.host), base_dn)
        filter = '(&(cn=CA)(ipaConfigString=caRenewalMaster))'
        try:
            entries = ldap.get_entries(base_dn=base_dn, filter=filter,
                                       attrs_list=[])
        except errors.NotFound:
            pass
        else:
            logger.debug("found CA renewal master %s", entries[0].dn[1].value)

            master = False
            updates = []

            for entry in entries:
                if entry.dn == dn:
                    master = True
                    continue

                updates.append({
                    'dn': entry.dn,
                    'updates': [
                        dict(action='remove', attr='ipaConfigString',
                             value='caRenewalMaster')
                    ],
                })

            if master:
                return False, updates
            else:
                return False, []

        criteria = {
            'cert-file': paths.RA_AGENT_PEM,
        }
        request_id = certmonger.get_request_id(criteria)
        if request_id is not None:
            logger.debug("found certmonger request for RA cert")

            ca_name = certmonger.get_request_value(request_id, 'ca-name')
            if ca_name is None:
                logger.warning(
                    "certmonger request for RA cert is missing ca_name, "
                    "assuming local CA is renewal slave")
                return False, []
            ca_name = ca_name.strip()

            if ca_name == 'dogtag-ipa-renew-agent':
                pass
            elif ca_name == 'dogtag-ipa-retrieve-agent-submit':
                return False, []
            elif ca_name == 'dogtag-ipa-ca-renew-agent':
                return False, []
            else:
                logger.warning(
                    "certmonger request for RA cert has unknown ca_name '%s', "
                    "assuming local CA is renewal slave", ca_name)
                return False, []
        else:
            logger.debug("certmonger request for RA cert not found")

            config = directivesetter.get_directive(
                paths.CA_CS_CFG_PATH, 'subsystem.select', '=')

            if config == 'New':
                pass
            elif config == 'Clone':
                return False, []
            else:
                logger.warning(
                    "CS.cfg has unknown subsystem.select value '%s', "
                    "assuming local CA is renewal slave", config)
                return (False, False, [])

        update = {
                'dn': dn,
                'updates': [
                    dict(action='add', attr='ipaConfigString',
                         value='caRenewalMaster')
                ],
        }

        return False, [update]