def check(self):
        expected_trust = {
            'ocspSigningCert cert-pki-ca': 'u,u,u',
            'subsystemCert cert-pki-ca': 'u,u,u',
            'auditSigningCert cert-pki-ca': 'u,u,Pu',
            'Server-Cert cert-pki-ca': 'u,u,u',
        }
        kra = krainstance.KRAInstance(api.env.realm)
        if kra.is_installed():
            kra_trust = {
                'transportCert cert-pki-kra': 'u,u,u',
                'storageCert cert-pki-kra': 'u,u,u',
                'auditSigningCert cert-pki-kra': 'u,u,Pu',
            }
            expected_trust.update(kra_trust)

        if not self.ca.is_configured():
            logger.debug('CA is not configured, skipping NSS trust check')
            return

        db = certs.CertDB(api.env.realm, paths.PKI_TOMCAT_ALIAS_DIR)
        for nickname, _trust_flags in db.list_certs():
            flags = certdb.unparse_trust_flags(_trust_flags)
            if nickname.startswith('caSigningCert cert-pki-ca'):
                expected = 'CTu,Cu,Cu'
            else:
                try:
                    expected = expected_trust[nickname]
                except KeyError:
                    logger.debug("%s not found in %s, assuming 3rd party" %
                                 (nickname, paths.PKI_TOMCAT_ALIAS_DIR))
                    continue
            try:
                expected_trust.pop(nickname)
            except KeyError:
                pass
            if flags != expected:
                yield Result(
                    self,
                    constants.ERROR,
                    key=nickname,
                    expected=expected,
                    got=flags,
                    nickname=nickname,
                    dbdir=paths.PKI_TOMCAT_ALIAS_DIR,
                    msg='Incorrect NSS trust for {nickname} in {dbdir}. '
                    'Got {got} expected {expected}.')
                continue
            else:
                yield Result(self, constants.SUCCESS, key=nickname)

        for nickname in expected_trust:
            yield Result(
                self,
                constants.ERROR,
                key=nickname,
                nickname=nickname,
                dbdir=paths.PKI_TOMCAT_ALIAS_DIR,
                msg='Certificate {nickname} missing from {dbdir} while '
                'verifying trust')
Esempio n. 2
0
def install_check(api, replica_config, options):
    if replica_config is not None and not replica_config.setup_kra:
        return

    kra = krainstance.KRAInstance(api.env.realm)
    if kra.is_installed():
        raise RuntimeError("KRA is already installed.")

    if not options.setup_ca:
        if cainstance.is_ca_installed_locally():
            if api.env.dogtag_version >= 10:
                # correct dogtag version of CA installed
                pass
            else:
                raise RuntimeError(
                    "Dogtag must be version 10.2 or above to install KRA")
        else:
            raise RuntimeError(
                "Dogtag CA is not installed.  Please install the CA first")

    if replica_config is not None:
        if not api.Command.kra_is_enabled()['result']:
            raise RuntimeError(
                "KRA is not installed on the master system. Please use "
                "'ipa-kra-install' command to install the first instance.")
Esempio n. 3
0
def install(api, replica_config, options, custodia):
    if replica_config is None:
        if not options.setup_kra:
            return
        realm_name = api.env.realm
        dm_password = options.dm_password
        host_name = api.env.host
        subject_base = dsinstance.DsInstance().find_subject_base()

        pkcs12_info = None
        master_host = None
        promote = False
    else:
        if not replica_config.setup_kra:
            return
        krafile = os.path.join(replica_config.dir, 'kracert.p12')
        with ipautil.private_ccache():
            ccache = os.environ['KRB5CCNAME']
            kinit_keytab(
                'host/{env.host}@{env.realm}'.format(env=api.env),
                paths.KRB5_KEYTAB,
                ccache)
            custodia.get_kra_keys(
                krafile,
                replica_config.dirman_password)

        realm_name = replica_config.realm_name
        dm_password = replica_config.dirman_password
        host_name = replica_config.host_name
        subject_base = replica_config.subject_base

        pkcs12_info = (krafile,)
        master_host = replica_config.kra_host_name
        promote = True

    ca_subject = ca.lookup_ca_subject(api, subject_base)

    kra = krainstance.KRAInstance(realm_name)
    kra.configure_instance(
        realm_name, host_name, dm_password, dm_password,
        subject_base=subject_base,
        ca_subject=ca_subject,
        pkcs12_info=pkcs12_info,
        master_host=master_host,
        promote=promote,
        pki_config_override=options.pki_config_override,
    )

    _service.print_msg("Restarting the directory server")
    ds = dsinstance.DsInstance()
    ds.restart()
    kra.enable_client_auth_to_db()

    # Restart apache for new proxy config file
    services.knownservices.httpd.restart(capture_output=True)
    # Restarted named to restore bind-dyndb-ldap operation, see
    # https://pagure.io/freeipa/issue/5813
    named = services.knownservices.named  # alias for current named
    if named.is_running():
        named.restart(capture_output=True)
Esempio n. 4
0
def install(api, replica_config, options):
    if replica_config is None:
        if not options.setup_kra:
            return
        realm_name = api.env.realm
        dm_password = options.dm_password
        host_name = api.env.host
        subject_base = dsinstance.DsInstance().find_subject_base()

        pkcs12_info = None
        master_host = None
        promote = False
    else:
        if not replica_config.setup_kra:
            return
        krafile = os.path.join(replica_config.dir, 'kracert.p12')
        if options.promote:
            with ipautil.private_ccache():
                ccache = os.environ['KRB5CCNAME']
                kinit_keytab('host/{env.host}@{env.realm}'.format(env=api.env),
                             paths.KRB5_KEYTAB, ccache)
                custodia = custodiainstance.CustodiaInstance(
                    replica_config.host_name, replica_config.realm_name)
                custodia.get_kra_keys(replica_config.kra_host_name, krafile,
                                      replica_config.dirman_password)
        else:
            cafile = os.path.join(replica_config.dir, 'cacert.p12')
            if not os.path.isfile(cafile):
                raise RuntimeError(
                    "Unable to clone KRA."
                    "  cacert.p12 file not found in replica file")
            shutil.copy(cafile, krafile)

        realm_name = replica_config.realm_name
        dm_password = replica_config.dirman_password
        host_name = replica_config.host_name
        subject_base = replica_config.subject_base

        pkcs12_info = (krafile, )
        master_host = replica_config.kra_host_name
        promote = options.promote

    kra = krainstance.KRAInstance(realm_name)
    kra.configure_instance(realm_name,
                           host_name,
                           dm_password,
                           dm_password,
                           subject_base=subject_base,
                           pkcs12_info=pkcs12_info,
                           master_host=master_host,
                           promote=promote)

    _service.print_msg("Restarting the directory server")
    ds = dsinstance.DsInstance()
    ds.restart()
    kra.enable_client_auth_to_db()

    # Restart apache for new proxy config file
    services.knownservices.httpd.restart(capture_output=True)
Esempio n. 5
0
def install(api, replica_config, options):
    if replica_config is None:
        realm_name = api.env.realm
        dm_password = options.dm_password
        host_name = api.env.host
        subject_base = dsinstance.DsInstance().find_subject_base()

        pkcs12_info = None
        master_host = None
        ra_only = False
        promote = False
    else:
        krafile = os.path.join(replica_config.dir, 'kracert.p12')
        if options.promote:
            custodia = custodiainstance.CustodiaInstance(
                replica_config.host_name, replica_config.realm_name)
            custodia.get_kra_keys(replica_config.kra_host_name, krafile,
                                  replica_config.dirman_password)
        else:
            cafile = os.path.join(replica_config.dir, 'cacert.p12')
            if not ipautil.file_exists(cafile):
                raise RuntimeError(
                    "Unable to clone KRA."
                    "  cacert.p12 file not found in replica file")
            shutil.copy(cafile, krafile)

        realm_name = replica_config.realm_name
        dm_password = replica_config.dirman_password
        host_name = replica_config.host_name
        subject_base = replica_config.subject_base

        pkcs12_info = (krafile, )
        master_host = replica_config.kra_host_name
        ra_only = not replica_config.setup_kra
        promote = options.promote

    kra = krainstance.KRAInstance(realm_name)
    kra.configure_instance(realm_name,
                           host_name,
                           dm_password,
                           dm_password,
                           subject_base=subject_base,
                           pkcs12_info=pkcs12_info,
                           master_host=master_host,
                           ra_only=ra_only,
                           promote=promote)

    _service.print_msg("Restarting the directory server")
    ds = dsinstance.DsInstance()
    ds.restart()

    if not ra_only:
        kra.enable_client_auth_to_db(paths.KRA_CS_CFG_PATH)

        # Restart apache for new proxy config file
        services.knownservices.httpd.restart(capture_output=True)
Esempio n. 6
0
    def validate_options(self, needs_root=True):
        super(KRAUninstaller, self).validate_options(needs_root=True)

        if self.args:
            self.option_parser.error("Too many parameters provided.")

        _kra = krainstance.KRAInstance(api)
        if not _kra.is_installed():
            self.option_parser.error(
                "Cannot uninstall.  There is no KRA installed on this system.")
Esempio n. 7
0
    def check(self):
        if not self.ca.is_configured():
            logger.debug('CA is not configured, skipping KRA Agent check')
            return

        kra = krainstance.KRAInstance(api.env.realm)
        if not kra.is_installed():
            logger.debug('KRA is not installed, skipping KRA Agent check')
            return

        base_dn = DN('uid=ipakra,ou=people,o=kra,o=ipaca')
        yield from check_agent(self, base_dn, 'KRA')
Esempio n. 8
0
def uninstall_check(options):
    """IPA needs to be running so pkidestroy can unregister KRA"""
    kra = krainstance.KRAInstance(api.env.realm)
    if not kra.is_installed():
        return

    result = ipautil.run([paths.IPACTL, 'status'], raiseonerr=False)

    if result.returncode not in [0, 4]:
        try:
            ipautil.run([paths.IPACTL, 'start'])
        except Exception:
            logger.info("Re-starting IPA failed, continuing uninstall")
Esempio n. 9
0
def install(api, replica_config, options):
    subject = dsinstance.DsInstance().find_subject_base()
    if replica_config is None:
        kra = krainstance.KRAInstance(api.env.realm)
        kra.configure_instance(api.env.realm,
                               api.env.host,
                               options.dm_password,
                               options.dm_password,
                               subject_base=subject)
    else:
        if options.promote:
            ca_data = (os.path.join(replica_config.dir, 'kracert.p12'),
                       replica_config.dirman_password)

            custodia = custodiainstance.CustodiaInstance(
                replica_config.host_name, replica_config.realm_name)
            custodia.get_kra_keys(replica_config.kra_host_name, ca_data[0],
                                  ca_data[1])

            kra = krainstance.KRAInstance(replica_config.realm_name)
            kra.configure_replica(replica_config.host_name,
                                  replica_config.kra_host_name,
                                  replica_config.dirman_password,
                                  kra_cert_bundle=ca_data)
            return

        else:
            kra = krainstance.install_replica_kra(replica_config)

    service.print_msg("Restarting the directory server")
    ds = dsinstance.DsInstance()
    ds.restart()

    kra.ldap_enable('KRA', api.env.host, options.dm_password, api.env.basedn)

    kra.enable_client_auth_to_db(paths.KRA_CS_CFG_PATH)

    # Restart apache for new proxy config file
    services.knownservices.httpd.restart(capture_output=True)
Esempio n. 10
0
def uninstall(standalone):
    kra = krainstance.KRAInstance(api.env.realm)

    if standalone:
        try:
            kra.admin_conn.delete_entry(DN(('cn', 'KRA'), ('cn', api.env.host),
                                           ('cn', 'masters'), ('cn', 'ipa'),
                                           ('cn', 'etc'), api.env.basedn))
        except errors.NotFound:
            pass

    kra.stop_tracking_certificates(stop_certmonger=not standalone)
    if kra.is_installed():
        kra.uninstall()
Esempio n. 11
0
    def execute(self, **options):
        kra = krainstance.KRAInstance(self.api.env.realm)
        if not kra.is_installed():
            return False, []

        cert = x509.load_certificate_from_file(paths.RA_AGENT_PEM)
        entry = self.api.Backend.ldap2.get_entry(krainstance.KRA_AGENT_DN)

        # check description attribute
        description_values = entry.get('description', [])
        if len(description_values) < 1:
            # missing 'description' attribute is unexpected, but we can
            # add it
            do_fix = True
        else:
            # There should only be one value, so we will take the first value.
            # But ignore the serial number when comparing, just in case.
            description = description_values[0]
            parts = description.split(';', 2)  # see below for syntax

            if len(parts) < 3:
                do_fix = True  # syntax error (not expected)
            elif parts[2] != '{};{}'.format(DN(cert.issuer), DN(cert.subject)):
                # issuer/subject does not match cert.  THIS is the condition
                # caused by issue 8084, which we want to fix.
                do_fix = True
            else:
                do_fix = False  # everything is fine

        if do_fix:
            # If other replicas have a different iteration of the IPA RA
            # cert (e.g. renewal was triggered prematurely on some master
            # and not on others) then authentication on those replicas will
            # fail.  But the 'description' attribute needed fixing because
            # the issuer value was wrong, meaning authentication was broken
            # on ALL replicas.  So even for the corner case where different
            # replicas have different IPA RA certs, updating the attribute
            # will at least mean THIS replica can authenticate to the KRA.

            logger.debug("Fixing KRA user entry 'description' attribute")
            entry['description'] = [
                '2;{};{};{}'.format(
                    cert.serial_number,
                    DN(cert.issuer),
                    DN(cert.subject)
                )
            ]
            self.api.Backend.ldap2.update_entry(entry)

        return False, []  # don't restart DS; no LDAP updates to perform
Esempio n. 12
0
    def run(self):
        super(KRAUninstaller, self).run()
        dogtag_constants = dogtag.configured_constants()

        kra_instance = krainstance.KRAInstance(
            api.env.realm, dogtag_constants=dogtag_constants)
        kra_instance.stop_tracking_certificates()
        if kra_instance.is_installed():
            kra_instance.uninstall()

        # Update config file
        parser = RawConfigParser()
        parser.read(paths.IPA_DEFAULT_CONF)
        parser.set('global', 'enable_kra', 'False')

        with open(paths.IPA_DEFAULT_CONF, 'w') as f:
            parser.write(f)
Esempio n. 13
0
def install_check(api, replica_config, options):
    if replica_config is not None and not replica_config.setup_kra:
        return

    kra = krainstance.KRAInstance(api.env.realm)
    if kra.is_installed():
        raise RuntimeError("KRA is already installed.")

    if not options.setup_ca:
        if cainstance.is_ca_installed_locally():
            if api.env.dogtag_version >= 10:
                # correct dogtag version of CA installed
                pass
            else:
                raise RuntimeError(
                    "Dogtag must be version 10.2 or above to install KRA")
        else:
            raise RuntimeError(
                "Dogtag CA is not installed.  Please install the CA first")

    if replica_config is not None:
        if not api.Command.kra_is_enabled()['result']:
            raise RuntimeError(
                "KRA is not installed on the master system. Please use "
                "'ipa-kra-install' command to install the first instance.")

        if options.promote:
            return

        with certdb.NSSDatabase() as tmpdb:
            pw = ipautil.write_tmp_file(ipautil.ipa_generate_password())
            tmpdb.create_db(pw.name)
            tmpdb.import_pkcs12(replica_config.dir + "/cacert.p12", pw.name,
                                replica_config.dirman_password)
            kra_cert_nicknames = [
                "storageCert cert-pki-kra", "transportCert cert-pki-kra",
                "auditSigningCert cert-pki-kra"
            ]
            if not all(
                    tmpdb.has_nickname(nickname)
                    for nickname in kra_cert_nicknames):
                raise RuntimeError("Missing KRA certificates, please create a "
                                   "new replica file.")
Esempio n. 14
0
    def _run(self):
        super(KRAInstaller, self).run()
        print dedent(self.INSTALLER_START_MESSAGE)

        subject = dsinstance.DsInstance().find_subject_base()
        if not self.installing_replica:
            kra = krainstance.KRAInstance(
                api.env.realm, dogtag_constants=dogtag.install_constants)

            kra.configure_instance(api.env.host,
                                   api.env.domain,
                                   self.options.password,
                                   self.options.password,
                                   subject_base=subject)
        else:
            replica_config = create_replica_config(self.options.password,
                                                   self.replica_file,
                                                   self.options)

            if not read_replica_info_kra_enabled(replica_config.dir):
                raise admintool.ScriptError(
                    "Either KRA is not installed on the master system or "
                    "your replica file is out of date")

            kra = krainstance.install_replica_kra(replica_config)
            service.print_msg("Restarting the directory server")

            ds = dsinstance.DsInstance()
            ds.restart()

        kra.enable_client_auth_to_db(kra.dogtag_constants.KRA_CS_CFG_PATH)

        # Restart apache for new proxy config file
        services.knownservices.httpd.restart(capture_output=True)

        # Update config file
        parser = RawConfigParser()
        parser.read(paths.IPA_DEFAULT_CONF)
        parser.set('global', 'enable_kra', 'True')

        with open(paths.IPA_DEFAULT_CONF, 'w') as f:
            parser.write(f)
Esempio n. 15
0
def uninstall():
    kra = krainstance.KRAInstance(api.env.realm)
    kra.stop_tracking_certificates()
    if kra.is_installed():
        kra.uninstall()
Esempio n. 16
0
def get_expected_requests(ca, ds, serverid):
    """Provide the expected certmonger tracking request data

       This list is based in part on certificate_renewal_update() in
       ipaserver/install/server/upgrade.py and various
       start_tracking_certificates() methods in *instance.py.

       The list is filtered depending on whether a CA is running
       and the certificates have been issued by IPA.

      :param ca: the CAInstance
      :param ds: the DSInstance
      :param serverid: the DS serverid name
    """
    template = paths.CERTMONGER_COMMAND_TEMPLATE

    if api.Command.ca_is_enabled()['result']:
        requests = [
            {
                'cert-file': paths.RA_AGENT_PEM,
                'key-file': paths.RA_AGENT_KEY,
                'ca-name': RENEWAL_CA_NAME,
                'cert-presave-command': template % 'renew_ra_cert_pre',
                'cert-postsave-command': template % 'renew_ra_cert',
            },
        ]
    else:
        requests = []

    if ca.is_configured():
        dogtag_reqs = ca.tracking_reqs.items()
        kra = krainstance.KRAInstance(api.env.realm)
        if kra.is_installed():
            dogtag_reqs = itertools.chain(dogtag_reqs,
                                          kra.tracking_reqs.items())
        for nick, profile in dogtag_reqs:
            req = {
                'cert-database':
                paths.PKI_TOMCAT_ALIAS_DIR,
                'cert-nickname':
                nick,
                'ca-name':
                RENEWAL_CA_NAME,
                'cert-presave-command':
                template % 'stop_pkicad',
                'cert-postsave-command':
                (template % 'renew_ca_cert "{}"'.format(nick)),
                'template-profile':
                profile,
            }
            requests.append(req)
    else:
        logger.debug('CA is not configured, skipping CA tracking')

    cert = x509.load_certificate_from_file(paths.HTTPD_CERT_FILE)
    issued = is_ipa_issued_cert(api, cert)
    if issued is None:
        logger.debug('Unable to determine if \'%s\' was issued by IPA '
                     'because no LDAP connection, assuming yes.')
    if issued or issued is None:
        requests.append({
            'cert-file': paths.HTTPD_CERT_FILE,
            'key-file': paths.HTTPD_KEY_FILE,
            'ca-name': 'IPA',
            'cert-postsave-command': template % 'restart_httpd',
        })
    else:
        logger.debug(
            'HTTP cert not issued by IPA, \'%s\', skip tracking '
            'check', DN(cert.issuer))

    # Check the ldap server cert if issued by IPA
    ds_nickname = ds.get_server_cert_nickname(serverid)
    ds_db_dirname = dsinstance.config_dirname(serverid)
    ds_db = certs.CertDB(api.env.realm, nssdir=ds_db_dirname)
    connected = api.Backend.ldap2.isconnected()
    if not connected:
        logger.debug('Unable to determine if \'%s\' was issued by IPA '
                     'because no LDAP connection, assuming yes.')
    if not connected or ds_db.is_ipa_issued_cert(api, ds_nickname):
        requests.append({
            'cert-database':
            ds_db_dirname[:-1],
            'cert-nickname':
            ds_nickname,
            'ca-name':
            'IPA',
            'cert-postsave-command':
            '%s %s' % (template % 'restart_dirsrv', serverid),
        })
    else:
        logger.debug('DS cert is not issued by IPA, skip tracking check')

    # Check if pkinit is enabled
    if os.path.exists(paths.KDC_CERT):
        pkinit_request_ca = krbinstance.get_pkinit_request_ca()
        requests.append({
            'cert-file': paths.KDC_CERT,
            'key-file': paths.KDC_KEY,
            'ca-name': pkinit_request_ca,
            'cert-postsave-command': template % 'renew_kdc_cert',
        })
    else:
        logger.debug('No KDC pkinit certificate')

    return requests
Esempio n. 17
0
    def run(self):
        super(KRAInstaller, self).run()

        # Verify DM password. This has to be called after ask_for_options(),
        # so it can't be placed in validate_options().
        try:
            installutils.validate_dm_password_ldap(self.options.password)
        except ValueError:
            raise admintool.ScriptError(
                "Directory Manager password is invalid")

        if not cainstance.is_ca_installed_locally():
            raise RuntimeError("Dogtag CA is not installed. "
                               "Please install the CA first")

        # check if KRA is not already installed
        _kra = krainstance.KRAInstance(api)
        if _kra.is_installed():
            raise admintool.ScriptError("KRA already installed")

        # this check can be done only when CA is installed
        self.installing_replica = dogtaginstance.is_installing_replica("KRA")
        self.options.promote = False

        if self.installing_replica:
            domain_level = dsinstance.get_domain_level(api)
            if domain_level > DOMAIN_LEVEL_0:
                self.options.promote = True
            elif not self.args:
                raise RuntimeError("A replica file is required.")

        if self.args and (not self.installing_replica or self.options.promote):
            raise RuntimeError("Too many parameters provided. "
                               "No replica file is required.")

        self.options.dm_password = self.options.password
        self.options.setup_ca = False
        self.options.setup_kra = True

        api.Backend.ldap2.connect()

        config = None
        if self.installing_replica:
            if self.options.promote:
                config = ReplicaConfig()
                config.kra_host_name = None
                config.realm_name = api.env.realm
                config.host_name = api.env.host
                config.domain_name = api.env.domain
                config.dirman_password = self.options.password
                config.ca_ds_port = 389
                config.top_dir = tempfile.mkdtemp("ipa")
                config.dir = config.top_dir
            else:
                config = create_replica_config(
                    self.options.password,
                    self.replica_file,
                    self.options)
                config.kra_host_name = config.master_host_name

            config.setup_kra = True

            if config.subject_base is None:
                attrs = api.Backend.ldap2.get_ipa_config()
                config.subject_base = attrs.get('ipacertificatesubjectbase')[0]

            if config.kra_host_name is None:
                config.kra_host_name = service.find_providing_server(
                    'KRA', api.Backend.ldap2, api.env.ca_host)

        try:
            kra.install_check(api, config, self.options)
        except RuntimeError as e:
            raise admintool.ScriptError(str(e))

        print(dedent(self.INSTALLER_START_MESSAGE))

        try:
            kra.install(api, config, self.options)
        except:
            self.log.error(dedent(self.FAIL_MESSAGE))
            raise

        api.Backend.ldap2.disconnect()
Esempio n. 18
0
    def check(self):
        if not self.ca.is_configured():
            logger.debug('CA is not configured, skipping connectivity check')
            return

        def match_ldap_nss_cert(plugin, ldap, db, cert_dn, attr, cert_nick):
            try:
                entry = ldap.get_entry(cert_dn)
            except errors.NotFound:
                yield Result(plugin,
                             constants.ERROR,
                             msg='%s entry not found in LDAP' % cert_dn)
                return False
            try:
                nsscert = db.get_cert_from_db(cert_nick)
            except Exception as e:
                yield Result(plugin,
                             constants.ERROR,
                             error=str(e),
                             msg=('Unable to load %s certificate:'
                                  '{error}' % cert_nick))
                return False
            cert_matched = any(cert == nsscert for cert in entry[attr])
            if not cert_matched:
                yield Result(plugin,
                             constants.ERROR,
                             key=cert_nick,
                             nickname=cert_nick,
                             dbdir=db.secdir,
                             msg=('{nickname} certificate in NSS DB {dbdir} '
                                  'does not match entry in LDAP'))
                return False
            return True

        def match_ldap_nss_certs_by_subject(plugin, ldap, db, dn,
                                            expected_nicks_subjects):
            entries = ldap.get_entries(dn)
            all_ok = True
            for nick, subject in expected_nicks_subjects.items():
                cert = db.get_cert_from_db(nick)
                ok = any(cert in entry["userCertificate"]
                         and subject == entry["subjectName"][0]
                         for entry in entries if "userCertificate" in entry)
                if not ok:
                    all_ok = False
                    yield Result(plugin,
                                 constants.ERROR,
                                 key=nick,
                                 nickname=nick,
                                 dbdir=db.secdir,
                                 msg=('{nickname} certificate in NSS DB '
                                      '{dbdir} does not match entry in LDAP'))
            return all_ok

        db = certs.CertDB(api.env.realm, paths.PKI_TOMCAT_ALIAS_DIR)
        dn = DN('uid=pkidbuser,ou=people,o=ipaca')
        subsystem_nick = 'subsystemCert cert-pki-ca'
        subsystem_ok = yield from match_ldap_nss_cert(self, self.conn, db, dn,
                                                      'userCertificate',
                                                      subsystem_nick)
        dn = DN('cn=%s IPA CA' % api.env.realm,
                'cn=certificates,cn=ipa,cn=etc', api.env.basedn)
        casigning_nick = 'caSigningCert cert-pki-ca'
        casigning_ok = yield from match_ldap_nss_cert(self, self.conn, db, dn,
                                                      'CACertificate',
                                                      casigning_nick)

        expected_nicks_subjects = {
            'ocspSigningCert cert-pki-ca':
            'CN=OCSP Subsystem,O=%s' % api.env.realm,
            'subsystemCert cert-pki-ca':
            'CN=CA Subsystem,O=%s' % api.env.realm,
            'auditSigningCert cert-pki-ca':
            'CN=CA Audit,O=%s' % api.env.realm,
            'Server-Cert cert-pki-ca':
            'CN=%s,O=%s' % (api.env.host, api.env.realm),
        }

        kra = krainstance.KRAInstance(api.env.realm)
        if kra.is_installed():
            kra_expected_nicks_subjects = {
                'transportCert cert-pki-kra':
                'CN=KRA Transport Certificate,O=%s' % api.env.realm,
                'storageCert cert-pki-kra':
                'CN=KRA Storage Certificate,O=%s' % api.env.realm,
                'auditSigningCert cert-pki-kra':
                'CN=KRA Audit,O=%s' % api.env.realm,
            }
            expected_nicks_subjects.update(kra_expected_nicks_subjects)

        ipaca_basedn = DN('ou=certificateRepository,ou=ca,o=ipaca')
        ipaca_certs_ok = yield from match_ldap_nss_certs_by_subject(
            self, self.conn, db, ipaca_basedn, expected_nicks_subjects)

        if subsystem_ok:
            yield Result(self, constants.SUCCESS, key=subsystem_nick)
        if casigning_ok:
            yield Result(self, constants.SUCCESS, key=casigning_nick)
        if ipaca_certs_ok:
            yield Result(self, constants.SUCCESS, key=str(ipaca_basedn))
Esempio n. 19
0
def get_expected_requests(ca, ds, serverid):
    """Provide the expected certmonger tracking request data

       This list is based in part on certificate_renewal_update() in
       ipaserver/install/server/upgrade.py and various
       start_tracking_certificates() methods in *instance.py.

       The list is filtered depending on whether a CA is running
       and the certificates have been issued by IPA.

      :param ca: the CAInstance
      :param ds: the DSInstance
      :param serverid: the DS serverid name
    """
    template = paths.CERTMONGER_COMMAND_TEMPLATE

    if api.Command.ca_is_enabled()['result']:
        requests = [
            {
                'cert-file': paths.RA_AGENT_PEM,
                'key-file': paths.RA_AGENT_KEY,
                'ca-name': 'dogtag-ipa-ca-renew-agent',
                'cert-presave-command': template % 'renew_ra_cert_pre',
                'cert-postsave-command': template % 'renew_ra_cert',
            },
        ]
    else:
        requests = []

    ca_requests = [
        {
            'cert-database':
            paths.PKI_TOMCAT_ALIAS_DIR,
            'cert-nickname':
            'auditSigningCert cert-pki-ca',
            'ca-name':
            'dogtag-ipa-ca-renew-agent',
            'cert-presave-command':
            template % 'stop_pkicad',
            'cert-postsave-command':
            (template % 'renew_ca_cert "auditSigningCert cert-pki-ca"'),
        },
        {
            'cert-database':
            paths.PKI_TOMCAT_ALIAS_DIR,
            'cert-nickname':
            'ocspSigningCert cert-pki-ca',
            'ca-name':
            'dogtag-ipa-ca-renew-agent',
            'cert-presave-command':
            template % 'stop_pkicad',
            'cert-postsave-command':
            (template % 'renew_ca_cert "ocspSigningCert cert-pki-ca"'),
        },
        {
            'cert-database':
            paths.PKI_TOMCAT_ALIAS_DIR,
            'cert-nickname':
            'subsystemCert cert-pki-ca',
            'ca-name':
            'dogtag-ipa-ca-renew-agent',
            'cert-presave-command':
            template % 'stop_pkicad',
            'cert-postsave-command':
            (template % 'renew_ca_cert "subsystemCert cert-pki-ca"'),
        },
        {
            'cert-database':
            paths.PKI_TOMCAT_ALIAS_DIR,
            'cert-nickname':
            'caSigningCert cert-pki-ca',
            'ca-name':
            'dogtag-ipa-ca-renew-agent',
            'cert-presave-command':
            template % 'stop_pkicad',
            'cert-postsave-command':
            (template % 'renew_ca_cert "caSigningCert cert-pki-ca"'),
            'template-profile':
            None,
        },
        {
            'cert-database':
            paths.PKI_TOMCAT_ALIAS_DIR,
            'cert-nickname':
            'Server-Cert cert-pki-ca',
            'ca-name':
            'dogtag-ipa-ca-renew-agent',
            'cert-presave-command':
            template % 'stop_pkicad',
            'cert-postsave-command':
            (template % 'renew_ca_cert "Server-Cert cert-pki-ca"'),
        },
    ]

    kra_requests = [
        {
            'cert-database':
            paths.PKI_TOMCAT_ALIAS_DIR,
            'cert-nickname':
            'auditSigningCert cert-pki-kra',
            'ca-name':
            'dogtag-ipa-ca-renew-agent',
            'cert-presave-command':
            template % 'stop_pkicad',
            'cert-postsave-command':
            (template % 'renew_ca_cert "auditSigningCert cert-pki-kra"'),
        },
        {
            'cert-database':
            paths.PKI_TOMCAT_ALIAS_DIR,
            'cert-nickname':
            'transportCert cert-pki-kra',
            'ca-name':
            'dogtag-ipa-ca-renew-agent',
            'cert-presave-command':
            template % 'stop_pkicad',
            'cert-postsave-command':
            (template % 'renew_ca_cert "transportCert cert-pki-kra"'),
        },
        {
            'cert-database':
            paths.PKI_TOMCAT_ALIAS_DIR,
            'cert-nickname':
            'storageCert cert-pki-kra',
            'ca-name':
            'dogtag-ipa-ca-renew-agent',
            'cert-presave-command':
            template % 'stop_pkicad',
            'cert-postsave-command':
            (template % 'renew_ca_cert "storageCert cert-pki-kra"'),
        },
    ]

    if ca.is_configured():
        db = certs.CertDB(api.env.realm, paths.PKI_TOMCAT_ALIAS_DIR)
        for nickname, _trust_flags in db.list_certs():
            if nickname.startswith('caSigningCert cert-pki-ca '):
                requests.append({
                    'cert-database':
                    paths.PKI_TOMCAT_ALIAS_DIR,
                    'cert-nickname':
                    nickname,
                    'ca-name':
                    'dogtag-ipa-ca-renew-agent',
                    'cert-presave-command':
                    template % 'stop_pkicad',
                    'cert-postsave-command':
                    (template % ('renew_ca_cert "%s"' % nickname)),
                    'template-profile':
                    'caCACert',
                })
        requests += ca_requests
        kra = krainstance.KRAInstance(api.env.realm)
        if kra.is_installed():
            requests += kra_requests
    else:
        logger.debug('CA is not configured, skipping CA tracking')

    cert = x509.load_certificate_from_file(paths.HTTPD_CERT_FILE)
    issued = is_ipa_issued_cert(api, cert)
    if issued is None:
        logger.debug('Unable to determine if \'%s\' was issued by IPA '
                     'because no LDAP connection, assuming yes.')
    if issued or issued is None:
        requests.append({
            'cert-file': paths.HTTPD_CERT_FILE,
            'key-file': paths.HTTPD_KEY_FILE,
            'ca-name': 'IPA',
            'cert-postsave-command': template % 'restart_httpd',
        })
    else:
        logger.debug(
            'HTTP cert not issued by IPA, \'%s\', skip tracking '
            'check', DN(cert.issuer))

    # Check the ldap server cert if issued by IPA
    ds_nickname = ds.get_server_cert_nickname(serverid)
    ds_db_dirname = dsinstance.config_dirname(serverid)
    ds_db = certs.CertDB(api.env.realm, nssdir=ds_db_dirname)
    connected = api.Backend.ldap2.isconnected()
    if not connected:
        logger.debug('Unable to determine if \'%s\' was issued by IPA '
                     'because no LDAP connection, assuming yes.')
    if not connected or ds_db.is_ipa_issued_cert(api, ds_nickname):
        requests.append({
            'cert-database':
            ds_db_dirname[:-1],
            'cert-nickname':
            ds_nickname,
            'ca-name':
            'IPA',
            'cert-postsave-command':
            '%s %s' % (template % 'restart_dirsrv', serverid),
        })
    else:
        logger.debug(
            'DS cert is not issued by IPA, \'%s\', skip tracking '
            'check', DN(cert.issuer))

    # Check if pkinit is enabled
    if os.path.exists(paths.KDC_CERT):
        pkinit_request_ca = krbinstance.get_pkinit_request_ca()
        cert = x509.load_certificate_from_file(paths.KDC_CERT)
        requests.append({
            'cert-file': paths.KDC_CERT,
            'key-file': paths.KDC_KEY,
            'ca-name': pkinit_request_ca,
            'cert-postsave-command': template % 'renew_kdc_cert',
        })
    else:
        logger.debug('No KDC pkinit certificate')

    return requests
Esempio n. 20
0
    def run(self):
        super(KRAInstaller, self).run()

        # Verify DM password. This has to be called after ask_for_options(),
        # so it can't be placed in validate_options().
        try:
            installutils.validate_dm_password_ldap(self.options.password)
        except ValueError:
            raise admintool.ScriptError(
                "Directory Manager password is invalid")

        if not cainstance.is_ca_installed_locally():
            raise RuntimeError("Dogtag CA is not installed. "
                               "Please install a CA first with the "
                               "`ipa-ca-install` command.")

        # check if KRA is not already installed
        _kra = krainstance.KRAInstance(api)
        if _kra.is_installed():
            raise admintool.ScriptError("KRA already installed")

        # this check can be done only when CA is installed
        self.installing_replica = dogtaginstance.is_installing_replica("KRA")

        if self.installing_replica:
            domain_level = dsinstance.get_domain_level(api)
            if domain_level < DOMAIN_LEVEL_1:
                raise RuntimeError("Unsupported domain level %d." %
                                   domain_level)

        if self.args:
            raise RuntimeError("Too many parameters provided.")

        self.options.dm_password = self.options.password
        self.options.setup_ca = False
        self.options.setup_kra = True

        api.Backend.ldap2.connect()

        if self.installing_replica:
            config = ReplicaConfig()
            config.kra_host_name = None
            config.realm_name = api.env.realm
            config.host_name = api.env.host
            config.domain_name = api.env.domain
            config.dirman_password = self.options.password
            config.ca_ds_port = 389
            config.top_dir = tempfile.mkdtemp("ipa")
            config.dir = config.top_dir

            config.setup_kra = True

            if config.subject_base is None:
                attrs = api.Backend.ldap2.get_ipa_config()
                config.subject_base = attrs.get('ipacertificatesubjectbase')[0]

            if config.kra_host_name is None:
                config.kra_host_name = find_providing_server(
                    'KRA', api.Backend.ldap2, [api.env.ca_host])
                if config.kra_host_name is None:
                    # all CA/KRA servers are down or unreachable.
                    raise admintool.ScriptError(
                        "Failed to find an active KRA server!")
            custodia = custodiainstance.get_custodia_instance(
                config, custodiainstance.CustodiaModes.KRA_PEER)
        else:
            config = None
            custodia = None

        try:
            kra.install_check(api, config, self.options)
        except RuntimeError as e:
            raise admintool.ScriptError(str(e))

        print(dedent(self.INSTALLER_START_MESSAGE))

        try:
            kra.install(api, config, self.options, custodia=custodia)
        except:
            logger.error('%s', dedent(self.FAIL_MESSAGE))
            raise

        # pki-spawn restarts 389-DS, reconnect
        api.Backend.ldap2.close()
        api.Backend.ldap2.connect()

        # Enable configured services and update DNS SRV records
        service.sync_services_state(api.env.host)
        api.Command.dns_update_system_records()
        api.Backend.ldap2.disconnect()
Esempio n. 21
0
    def check(self):
        if not self.ca.is_configured():
            logger.debug("No CA configured, skipping dogtag config check")
            return

        kra = krainstance.KRAInstance(api.env.realm)

        blobs = {
            'auditSigningCert cert-pki-ca': 'ca.audit_signing.cert',
            'ocspSigningCert cert-pki-ca': 'ca.ocsp_signing.cert',
            'caSigningCert cert-pki-ca': 'ca.signing.cert',
            'subsystemCert cert-pki-ca': 'ca.subsystem.cert',
            'Server-Cert cert-pki-ca': 'ca.sslserver.cert'
        }

        # Nicknames to skip because their certs are not in CS.cfg
        skip = []

        if kra.is_installed:
            kra_blobs = {
                'transportCert cert-pki-kra': 'ca.connector.KRA.transportCert',
            }
            blobs.update(kra_blobs)
            skip.append('storageCert cert-pki-kra')
            skip.append('auditSigningCert cert-pki-kra')

        db = certs.CertDB(api.env.realm, paths.PKI_TOMCAT_ALIAS_DIR)
        for nickname, _trust_flags in db.list_certs():
            if nickname in skip:
                logging.debug('Skipping nickname %s because it isn\'t in '
                              'the configuration file')
                continue
            try:
                val = get_directive(paths.CA_CS_CFG_PATH, blobs[nickname], '=')
            except KeyError:
                print("%s not found, assuming 3rd party" % nickname)
                continue
            if val is None:
                yield Result(self,
                             constants.ERROR,
                             key=nickname,
                             configfile=paths.CA_CS_CFG_PATH,
                             msg='Certificate %s not found in %s' %
                             (blobs[nickname], paths.CA_CS_CFG_PATH))
                continue
            cert = db.get_cert_from_db(nickname)
            pem = cert.public_bytes(Encoding.PEM).decode()
            pem = pem.replace('\n', '')
            pem = pem.replace('-----BEGIN CERTIFICATE-----', '')
            pem = pem.replace('-----END CERTIFICATE-----', '')

            if pem.strip() != val:
                yield Result(self,
                             constants.ERROR,
                             key=nickname,
                             directive=blobs[nickname],
                             configfile=paths.CA_CS_CFG_PATH,
                             msg='Certificate \'%s\' does not match the value '
                             'of %s in %s' %
                             (nickname, blobs[nickname], paths.CA_CS_CFG_PATH))
            else:
                yield Result(self,
                             constants.SUCCESS,
                             key=nickname,
                             configfile=paths.CA_CS_CFG_PATH)