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')
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.")
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)
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)
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)
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.")
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')
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")
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)
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()
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
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)
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.")
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)
def uninstall(): kra = krainstance.KRAInstance(api.env.realm) kra.stop_tracking_certificates() if kra.is_installed(): kra.uninstall()
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
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()
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))
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
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()
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)