Ejemplo n.º 1
0
    def renew(self):
        ca = cainstance.CAInstance(api.env.realm, certs.NSS_DIR)
        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)
Ejemplo n.º 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")

        self.request_id = self._get_ca_request_id(RENEWAL_CA_NAME)
        if self.request_id is None:
            # if external CA renewal was interrupted, the request may have
            # been left with the "dogtag-ipa-ca-renew-agent-reuse" CA;
            # look for it too
            self.request_id = self._get_ca_request_id(RENEWAL_REUSE_CA_NAME)
            if self.request_id is None:
                raise admintool.ScriptError(
                    "CA certificate is not tracked by certmonger")
        logger.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)

        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 = cert.is_self_signed()

        if self_signed:
            return self.renew_self_signed(ca)
        else:
            return self.renew_external_step_1(ca)
Ejemplo n.º 3
0
    def __upload_ca_cert(self):
        """
        Upload the CA certificate from the NSS database to the LDAP directory.
        """

        dirname = config_dirname(self.serverid)
        dsdb = certs.CertDB(self.realm, nssdir=dirname,
                            subject_base=self.subject_base)
        trust_flags = dict(reversed(dsdb.list_certs()))

        ldap_uri = ipaldap.get_ldap_uri(self.fqdn)
        conn = ipaldap.LDAPClient(ldap_uri)
        conn.simple_bind(bind_dn=ipaldap.DIRMAN_DN,
                         bind_password=self.dm_password)

        nicknames = dsdb.find_root_cert(self.cacert_name)[:-1]
        for nickname in nicknames:
            cert = dsdb.get_cert_from_db(nickname, pem=False)
            certstore.put_ca_cert_nss(conn, self.suffix, cert, nickname,
                                      trust_flags[nickname])

        nickname = self.cacert_name
        cert = dsdb.get_cert_from_db(nickname, pem=False)
        certstore.put_ca_cert_nss(conn, self.suffix, cert, nickname,
                                  trust_flags[nickname],
                                  config_ipa=self.ca_is_configured,
                                  config_compat=self.master_fqdn is None)

        conn.unbind()
Ejemplo n.º 4
0
    def migrate_to_mod_ssl(self):
        """For upgrades only, migrate from mod_nss to mod_ssl"""
        db = certs.CertDB(api.env.realm, nssdir=paths.HTTPD_ALIAS_DIR)
        nickname = self.get_mod_nss_nickname()
        with tempfile.NamedTemporaryFile() as temp:
            pk12_password = ipautil.ipa_generate_password()
            pk12_pwdfile = ipautil.write_tmp_file(pk12_password)
            db.export_pkcs12(temp.name, pk12_pwdfile.name, nickname)
            certs.install_pem_from_p12(temp.name, pk12_password,
                                       paths.HTTPD_CERT_FILE)
            certs.install_key_from_p12(temp.name, pk12_password,
                                       paths.HTTPD_KEY_FILE)

        self.backup_ssl_conf()
        self.configure_mod_ssl_certs()
        self.set_mod_ssl_protocol()
        self.set_mod_ssl_logdir()
        self.__add_include()

        self.cert = x509.load_certificate_from_file(paths.HTTPD_CERT_FILE)

        if self.ca_is_configured:
            db.untrack_server_cert(nickname)
            self.start_tracking_certificates()

        # remove nickname and CA certs from NSS db

        self.disable_nss_conf()
Ejemplo n.º 5
0
    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:
                    # FIXME: is this a warning, skip?
                    print("%s not found, assuming 3rd party" % nickname)
                    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 %s. Got %s expected %s' %
                    (nickname, flags, expected))
                continue
            else:
                yield Result(self, constants.SUCCESS, key=nickname)

        for nickname in expected_trust:
            yield Result(self,
                         constants.ERROR,
                         key=nickname,
                         msg='Certificate %s missing while verifying trust' %
                         nickname)
Ejemplo n.º 6
0
 def stop_tracking_certificates(self, serverid=None):
     if serverid is None:
         serverid = self.get_state("serverid")
     if not serverid is None:
         # drop the trailing / off the config_dirname so the directory
         # will match what is in certmonger
         dirname = config_dirname(serverid)[:-1]
         dsdb = certs.CertDB(self.realm, nssdir=dirname)
         dsdb.untrack_server_cert(self.nickname)
Ejemplo n.º 7
0
 def start_tracking_certificates(self):
     db = certs.CertDB(self.realm, nssdir=paths.HTTPD_ALIAS_DIR)
     nickname = self.get_mod_nss_nickname()
     if db.is_ipa_issued_cert(api, nickname):
         db.track_server_cert(nickname, self.principal, db.passwd_fname,
                              'restart_httpd')
     else:
         logger.debug(
             "Will not track HTTP server cert %s as it is not "
             "issued by IPA", nickname)
Ejemplo n.º 8
0
    def install_kdc_cert(self):
        ca_cert_file = paths.CA_BUNDLE_PEM
        pkcs12_file, pin, ca_cert = installutils.load_pkcs12(
            cert_files=self.args,
            key_password=self.options.pin,
            key_nickname=self.options.cert_name,
            ca_cert_files=[ca_cert_file],
            realm_name=api.env.realm)

        cdb = certs.CertDB(api.env.realm, nssdir=paths.IPA_NSSDB_DIR)

        # Check that the ca_cert is known and trusted
        with tempfile.NamedTemporaryFile() as temp:
            certs.install_pem_from_p12(pkcs12_file.name, pin, temp.name)

            kdc_cert = x509.load_certificate_from_file(temp.name)
            ca_certs = x509.load_certificate_list_from_file(ca_cert_file)

            try:
                verify_kdc_cert_validity(kdc_cert, ca_certs, api.env.realm)
            except ValueError as e:
                raise admintool.ScriptError(
                    "Peer's certificate issuer is not trusted (%s). "
                    "Please run ipa-cacert-manage install and ipa-certupdate "
                    "to install the CA certificate." % str(e))

        try:
            ca_enabled = api.Command.ca_is_enabled()['result']
            if ca_enabled:
                certmonger.stop_tracking(certfile=paths.KDC_CERT)

            certs.install_pem_from_p12(pkcs12_file.name, pin, paths.KDC_CERT)
            certs.install_key_from_p12(pkcs12_file.name, pin, paths.KDC_KEY)

            if ca_enabled:
                # Start tracking only if the cert was issued by IPA CA
                # Retrieve IPA CA
                ipa_ca_cert = cdb.get_cert_from_db(get_ca_nickname(
                    api.env.realm),
                                                   pem=False)
                # And compare with the CA which signed this certificate
                if ca_cert == ipa_ca_cert:
                    certmonger.start_tracking((paths.KDC_CERT, paths.KDC_KEY),
                                              storage='FILE',
                                              profile='KDCs_PKINIT_Certs')
        except RuntimeError as e:
            raise admintool.ScriptError(str(e))

        krb = krbinstance.KrbInstance()
        krb.init_info(
            realm_name=api.env.realm,
            host_name=api.env.host,
        )
        krb.pkinit_enable()
Ejemplo n.º 9
0
 def start_tracking_certificates(self, serverid):
     nickname = self.get_server_cert_nickname(serverid)
     dirname = config_dirname(serverid)[:-1]
     dsdb = certs.CertDB(self.realm, nssdir=dirname)
     if dsdb.is_ipa_issued_cert(api, nickname):
         dsdb.track_server_cert(nickname, self.principal, dsdb.passwd_fname,
                                'restart_dirsrv %s' % serverid)
     else:
         logger.debug(
             "Will not track DS server certificate %s as it is "
             "not issued by IPA", nickname)
Ejemplo n.º 10
0
    def export_ra_pkcs12(self):
        agent_fd, agent_name = tempfile.mkstemp()
        os.write(agent_fd, self.dirman_password)
        os.close(agent_fd)

        try:
            db = certs.CertDB(api.env.realm, host_name=api.env.host)

            if db.has_nickname("ipaCert"):
                pkcs12_fname = os.path.join(self.dir, "ra.p12")
                db.export_pkcs12(pkcs12_fname, agent_name, "ipaCert")
        finally:
            os.remove(agent_name)
Ejemplo n.º 11
0
    def __import_ca_certs(self):
        dirname = config_dirname(self.serverid)
        dsdb = certs.CertDB(self.realm, nssdir=dirname,
                            subject_base=self.subject_base)

        ldap_uri = ipaldap.get_ldap_uri(self.fqdn)
        conn = ipaldap.LDAPClient(ldap_uri)
        conn.simple_bind(bind_dn=ipaldap.DIRMAN_DN,
                         bind_password=self.dm_password)

        self.import_ca_certs(dsdb, self.ca_is_configured, conn)

        conn.unbind()
Ejemplo n.º 12
0
    def __setup_pkinit(self):
        ca_db = certs.CertDB(self.realm,
                             host_name=self.fqdn,
                             subject_base=self.subject_base)

        if self.pkcs12_info:
            ca_db.install_pem_from_p12(self.pkcs12_info[0],
                                       self.pkcs12_info[1], paths.KDC_PEM)
        else:
            raise RuntimeError("PKI not supported yet\n")

        # Finally copy the cacert in the krb directory so we don't
        # have any selinux issues with the file context
        shutil.copyfile(CACERT, paths.CACERT_PEM)
Ejemplo n.º 13
0
    def add_ca_cert(self, cacert_fname, cacert_name=''):
        """Add a CA certificate to the directory server cert db.  We
        first have to shut down the directory server in case it has
        opened the cert db read-only.  Then we use the CertDB class
        to add the CA cert.  We have to provide a nickname, and we
        do not use 'IPA CA' since that's the default, so
        we use 'Imported CA' if none specified.  Then we restart
        the server."""
        # first make sure we have a valid cacert_fname
        try:
            if not os.access(cacert_fname, os.R_OK):
                root_logger.critical(
                    "The given CA cert file named [%s] could not be read" %
                    cacert_fname)
                return False
        except OSError as e:
            root_logger.critical(
                "The given CA cert file named [%s] could not be read: %s" %
                (cacert_fname, str(e)))
            return False
        # ok - ca cert file can be read
        # shutdown the server
        self.stop()

        dirname = config_dirname(installutils.realm_to_serverid(self.realm))
        certdb = certs.CertDB(
            self.realm,
            nssdir=dirname,
            subject_base=self.subject_base,
            ca_subject=self.ca_subject,
        )
        if not cacert_name or len(cacert_name) == 0:
            cacert_name = "Imported CA"
        # we can't pass in the nickname, so we set the instance variable
        certdb.cacert_name = cacert_name
        status = True
        try:
            certdb.load_cacert(cacert_fname, 'C,,')
        except ipautil.CalledProcessError as e:
            root_logger.critical(
                "Error importing CA cert file named [%s]: %s" %
                (cacert_fname, str(e)))
            status = False
        # restart the directory server
        self.start()

        return status
Ejemplo n.º 14
0
    def __upload_ca_cert(self):
        """
        Upload the CA certificate from the NSS database to the LDAP directory.
        """

        dirname = config_dirname(self.serverid)
        dsdb = certs.CertDB(self.realm,
                            nssdir=dirname,
                            subject_base=self.subject_base)
        trust_flags = dict(reversed(dsdb.list_certs()))

        ldap_uri = ipaldap.get_ldap_uri(self.fqdn)
        conn = ipaldap.LDAPClient(ldap_uri)
        conn.simple_bind(bind_dn=ipaldap.DIRMAN_DN,
                         bind_password=self.dm_password)

        nicknames = dsdb.find_root_cert(self.cacert_name)[:-1]
        for nickname in nicknames:
            cert = dsdb.get_cert_from_db(nickname)
            certstore.put_ca_cert_nss(conn, self.suffix, cert, nickname,
                                      trust_flags[nickname])

        nickname = self.cacert_name
        cert = dsdb.get_cert_from_db(nickname)
        cacert_flags = trust_flags[nickname]
        if self.setup_pkinit:
            cacert_flags = TrustFlags(
                cacert_flags.has_key,
                cacert_flags.trusted,
                cacert_flags.ca,
                (cacert_flags.usages
                 | {x509.EKU_PKINIT_CLIENT_AUTH, x509.EKU_PKINIT_KDC}),
            )
        certstore.put_ca_cert_nss(conn,
                                  self.suffix,
                                  cert,
                                  nickname,
                                  cacert_flags,
                                  config_ipa=self.ca_is_configured,
                                  config_compat=self.master_fqdn is None)

        conn.unbind()
Ejemplo n.º 15
0
    def execute(self, **options):
        ldap = self.obj.backend
        (cdn, ipa_config) = ldap.get_ipa_config()
        subject_base = ipa_config.get('ipacertificatesubjectbase', [None])[0]
        dirname = config_dirname(realm_to_serverid(api.env.realm))
        certdb = certs.CertDB(api.env.realm, nssdir=dirname, subject_base=subject_base)

        dercert = certdb.get_cert_from_db(certdb.cacert_name, pem=False)

        updates = {}
        dn = DN(('cn', 'CACert'), ('cn', 'ipa'), ('cn','etc'), api.env.basedn)

        cacrt_entry = ['objectclass:nsContainer',
                       'objectclass:pkiCA',
                       'cn:CAcert',
                       'cACertificate;binary:%s' % dercert,
                      ]
        updates[dn] = {'dn': dn, 'default': cacrt_entry}

        return (False, True, [updates])
Ejemplo n.º 16
0
    def import_cert(self, dirname, pkcs12_passwd, old_cert, principal, command):
        pkcs12_file, pin, ca_cert = installutils.load_pkcs12(
            cert_files=self.args,
            key_password=pkcs12_passwd,
            key_nickname=self.options.cert_name,
            ca_cert_files=[paths.IPA_CA_CRT],
            host_name=api.env.host)

        dirname = os.path.normpath(dirname)
        cdb = certs.CertDB(api.env.realm, nssdir=dirname)

        # Check that the ca_cert is known and trusted
        self.check_chain(pkcs12_file.name, pin, cdb)

        try:
            ca_enabled = api.Command.ca_is_enabled()['result']
            if ca_enabled:
                cdb.untrack_server_cert(old_cert)

            cdb.delete_cert(old_cert)
            prevs = cdb.find_server_certs()
            cdb.import_pkcs12(pkcs12_file.name, pin)
            news = cdb.find_server_certs()
            server_certs = [item for item in news if item not in prevs]
            server_cert = server_certs[0][0]

            if ca_enabled:
                # Start tracking only if the cert was issued by IPA CA
                # Retrieve IPA CA
                ipa_ca_cert = cdb.get_cert_from_db(
                    get_ca_nickname(api.env.realm))
                # And compare with the CA which signed this certificate
                if ca_cert == ipa_ca_cert:
                    cdb.track_server_cert(server_cert,
                                          principal,
                                          cdb.passwd_fname,
                                          command)
        except RuntimeError as e:
            raise admintool.ScriptError(str(e))

        return server_cert
Ejemplo n.º 17
0
    def renew_self_signed(self, ca):
        print("Renewing CA certificate, please wait")

        msg = "You cannot specify {} when renewing a self-signed CA"
        if self.options.external_ca_type:
            raise admintool.ScriptError(msg.format("--external-ca-type"))
        if self.options.external_ca_profile:
            raise admintool.ScriptError(msg.format("--external-ca-profile"))

        try:
            ca.set_renewal_master()
        except errors.NotFound:
            raise admintool.ScriptError("CA renewal master not found")

        self.resubmit_request()

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

        print("CA certificate successfully renewed")
Ejemplo n.º 18
0
    def export_certdb(self, fname, passwd_fname):
        """Export a cert database

        :param fname: The file to export to (relative to the info directory)
        :param passwd_fname: File that holds the cert DB password
        """
        hostname = self.replica_fqdn
        subject_base = self.subject_base
        ca_subject = ca.lookup_ca_subject(api, subject_base)
        nickname = "Server-Cert"

        try:
            db = certs.CertDB(api.env.realm,
                              nssdir=self.dir,
                              host_name=api.env.host,
                              subject_base=subject_base,
                              ca_subject=ca_subject)
            db.create_passwd_file()
            db.create_from_cacert()
            db.create_server_cert(nickname, hostname)

            pkcs12_fname = os.path.join(self.dir, fname + ".p12")

            try:
                db.export_pkcs12(pkcs12_fname, passwd_fname, nickname)
            except ipautil.CalledProcessError as e:
                logger.info("error exporting Server certificate: %s", e)
                installutils.remove_file(pkcs12_fname)
                installutils.remove_file(passwd_fname)

            self.remove_info_file("cert8.db")
            self.remove_info_file("key3.db")
            self.remove_info_file("secmod.db")
            self.remove_info_file("noise.txt")

            orig_filename = passwd_fname + ".orig"
            if ipautil.file_exists(orig_filename):
                installutils.remove_file(orig_filename)
        except errors.CertificateOperationError as e:
            raise admintool.ScriptError(str(e))
Ejemplo n.º 19
0
    def __get_ds_cert(self):
        nssdb_dir = config_dirname(self.serverid)
        db = certs.CertDB(
            self.realm,
            nssdir=nssdb_dir,
            subject_base=self.subject_base,
            ca_subject=self.ca_subject,
        )
        db.create_from_cacert()
        db.request_service_cert(self.nickname, self.principal, self.fqdn)
        db.create_pin_file()

        # Connect to self over ldapi as Directory Manager and configure SSL
        ldap_uri = ipaldap.get_ldap_uri(protocol='ldapi', realm=self.realm)
        conn = ipaldap.LDAPClient(ldap_uri)
        conn.external_bind()

        mod = [(ldap.MOD_REPLACE, "nsSSLClientAuth", "allowed"),
               (ldap.MOD_REPLACE, "nsSSL3Ciphers", "default"),
               (ldap.MOD_REPLACE, "allowWeakCipher", "off")]
        conn.modify_s(DN(('cn', 'encryption'), ('cn', 'config')), mod)

        mod = [(ldap.MOD_ADD, "nsslapd-security", "on")]
        conn.modify_s(DN(('cn', 'config')), mod)

        entry = conn.make_entry(
            DN(('cn', 'RSA'), ('cn', 'encryption'), ('cn', 'config')),
            objectclass=["top", "nsEncryptionModule"],
            cn=["RSA"],
            nsSSLPersonalitySSL=[self.nickname],
            nsSSLToken=["internal (software)"],
            nsSSLActivation=["on"],
        )
        conn.add_entry(entry)

        conn.unbind()

        # check for open secure port 636 from now on
        self.open_ports.append(636)
Ejemplo n.º 20
0
    def replace_key_cert_files(self,
                               cert,
                               key,
                               cert_fname,
                               key_fname,
                               ca_cert,
                               passwd_fname=None,
                               profile=None,
                               cmgr_post_command=None):
        try:
            ca_enabled = api.Command.ca_is_enabled()['result']
            if ca_enabled:
                certmonger.stop_tracking(certfile=cert_fname)

            pkey_passwd = None
            if passwd_fname is not None:
                with open(passwd_fname, 'rb') as f:
                    pkey_passwd = f.read()

            x509.write_certificate(cert, cert_fname)
            x509.write_pem_private_key(key, key_fname, pkey_passwd)

            if ca_enabled:
                # Start tracking only if the cert was issued by IPA CA
                # Retrieve IPA CA
                cdb = certs.CertDB(api.env.realm, nssdir=paths.IPA_NSSDB_DIR)
                ipa_ca_cert = cdb.get_cert_from_db(
                    get_ca_nickname(api.env.realm))
                # And compare with the CA which signed this certificate
                if ca_cert == ipa_ca_cert:
                    req_id = certmonger.start_tracking(
                        (cert_fname, key_fname),
                        pinfile=passwd_fname,
                        storage='FILE',
                        post_command=cmgr_post_command)
                    return req_id
        except RuntimeError as e:
            raise admintool.ScriptError(str(e))
        return None
Ejemplo n.º 21
0
    def check_cs_cfg(self):
        """Compare cert blob in NSS database to that stored in CS.cfg"""
        if not self.ca.is_configured():
            logger.debug("No CA configured, skipping CS config check")
            return

        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'
        }

        db = certs.CertDB(api.env.realm, paths.PKI_TOMCAT_ALIAS_DIR)
        for nickname, _trust_flags in db.list_certs():
            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:
                self.failure('Certificate %s not found in %s' %
                             (blobs[nickname], paths.CA_CS_CFG_PATH))
                continue
            cert = db.get_cert_from_db(nickname)
            if isinstance(cert, string_types):
                pem = cert
                pem = pem.replace('\r\n', '')
            else:
                pem = cert.public_bytes(Encoding.PEM).decode()
                pem = pem.replace('\n', '')
            pem = pem.replace('-----BEGIN CERTIFICATE-----', '')
            pem = pem.replace('-----END CERTIFICATE-----', '')

            # TODO: Handle multi-valued certs.
            if pem.strip() != val:
                self.failure('Certificate %s does not match %s' %
                             (blobs[nickname], paths.CA_CS_CFG_PATH))
Ejemplo n.º 22
0
    def import_cert(self, dirname, pkcs12_passwd, old_cert, principal,
                    command):
        pkcs12_file, pin, ca_cert = installutils.load_pkcs12(
            cert_files=self.args,
            key_password=pkcs12_passwd,
            key_nickname=self.options.cert_name,
            ca_cert_files=[CACERT],
            host_name=api.env.host)

        cdb = certs.CertDB(api.env.realm, nssdir=dirname)
        try:
            ca_enabled = api.Command.ca_is_enabled()['result']
            if ca_enabled:
                cdb.untrack_server_cert(old_cert)

            cdb.delete_cert(old_cert)
            cdb.import_pkcs12(pkcs12_file.name, pin)
            server_cert = cdb.find_server_certs()[0][0]

            if ca_enabled:
                cdb.track_server_cert(server_cert, principal, cdb.passwd_fname,
                                      command)
        except RuntimeError, e:
            raise admintool.ScriptError(str(e))
Ejemplo n.º 23
0
    def __enable_ssl(self):
        dirname = config_dirname(self.serverid)
        dsdb = certs.CertDB(self.realm, nssdir=dirname, subject_base=self.subject_base)
        if self.pkcs12_info:
            if self.ca_is_configured:
                trust_flags = 'CT,C,C'
            else:
                trust_flags = None
            dsdb.create_from_pkcs12(self.pkcs12_info[0], self.pkcs12_info[1],
                                    ca_file=self.ca_file,
                                    trust_flags=trust_flags)
            server_certs = dsdb.find_server_certs()
            if len(server_certs) == 0:
                raise RuntimeError("Could not find a suitable server cert in import in %s" % self.pkcs12_info[0])

            # We only handle one server cert
            self.nickname = server_certs[0][0]
            self.dercert = dsdb.get_cert_from_db(self.nickname, pem=False)

            if self.ca_is_configured:
                dsdb.track_server_cert(
                    self.nickname, self.principal, dsdb.passwd_fname,
                    'restart_dirsrv %s' % self.serverid)
        else:
            cadb = certs.CertDB(self.realm, host_name=self.fqdn, subject_base=self.subject_base)

            # FIXME, need to set this nickname in the RA plugin
            cadb.export_ca_cert('ipaCert', False)
            dsdb.create_from_cacert(cadb.cacert_fname, passwd=None)
            ca_args = ['/usr/libexec/certmonger/dogtag-submit',
                       '--ee-url', 'https://%s:8443/ca/ee/ca' % self.fqdn,
                       '--dbdir', paths.HTTPD_ALIAS_DIR,
                       '--nickname', 'ipaCert',
                       '--sslpinfile', paths.ALIAS_PWDFILE_TXT,
                       '--agent-submit']
            helper = " ".join(ca_args)
            prev_helper = certmonger.modify_ca_helper('IPA', helper)
            try:
                cmd = 'restart_dirsrv %s' % self.serverid
                certmonger.request_and_wait_for_cert(
                    nssdb=dirname,
                    nickname=self.nickname,
                    principal=self.principal,
                    passwd_fname=dsdb.passwd_fname,
                    subject=str(DN(('CN', self.fqdn), self.subject_base)),
                    ca='IPA',
                    profile=dogtag.DEFAULT_PROFILE,
                    dns=[self.fqdn],
                    post_command=cmd)
            finally:
                certmonger.modify_ca_helper('IPA', prev_helper)

            self.dercert = dsdb.get_cert_from_db(self.nickname, pem=False)
            dsdb.create_pin_file()

        self.cacert_name = dsdb.cacert_name

        ldap_uri = ipaldap.get_ldap_uri(self.fqdn)
        conn = ipaldap.LDAPClient(ldap_uri)
        conn.simple_bind(bind_dn=ipaldap.DIRMAN_DN,
                         bind_password=self.dm_password)

        mod = [(ldap.MOD_REPLACE, "nsSSLClientAuth", "allowed"),
               (ldap.MOD_REPLACE, "nsSSL3Ciphers", "default"),
               (ldap.MOD_REPLACE, "allowWeakCipher", "off")]
        conn.modify_s(DN(('cn', 'encryption'), ('cn', 'config')), mod)

        mod = [(ldap.MOD_ADD, "nsslapd-security", "on")]
        conn.modify_s(DN(('cn', 'config')), mod)

        entry = conn.make_entry(
            DN(('cn', 'RSA'), ('cn', 'encryption'), ('cn', 'config')),
            objectclass=["top", "nsEncryptionModule"],
            cn=["RSA"],
            nsSSLPersonalitySSL=[self.nickname],
            nsSSLToken=["internal (software)"],
            nsSSLActivation=["on"],
        )
        conn.add_entry(entry)

        conn.unbind()

        # check for open secure port 636 from now on
        self.open_ports.append(636)
Ejemplo n.º 24
0
 def start_tracking_certificates(self, serverid):
     dirname = config_dirname(serverid)[:-1]
     dsdb = certs.CertDB(self.realm, nssdir=dirname)
     dsdb.track_server_cert(self.nickname, self.principal,
                            dsdb.passwd_fname,
                            'restart_dirsrv %s' % serverid)
Ejemplo n.º 25
0
 def start_tracking_certificates(self):
     db = certs.CertDB(self.realm)
     db.track_server_cert(self.cert_nickname, self.principal,
                          db.passwd_fname, 'restart_httpd')
Ejemplo n.º 26
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
Ejemplo n.º 27
0
 def stop_tracking_certificates(self):
     db = certs.CertDB(api.env.realm)
     db.untrack_server_cert(self.cert_nickname)
Ejemplo n.º 28
0
def install_check(standalone, replica_config, options):
    global external_cert_file
    global external_ca_file

    realm_name = options.realm_name
    host_name = options.host_name

    if replica_config is None:
        options._subject_base = options.subject_base
        options._ca_subject = options.ca_subject
    else:
        # during replica install, this gets invoked before local DS is
        # available, so use the remote api.
        _api = api if standalone else options._remote_api

        # for replica-install the knobs cannot be written, hence leading '_'
        options._subject_base = str(replica_config.subject_base)
        options._ca_subject = lookup_ca_subject(_api, options._subject_base)

    if replica_config is not None and not replica_config.setup_ca:
        return

    if replica_config is not None:
        if standalone and api.env.ra_plugin == 'selfsign':
            raise ScriptError('A selfsign CA can not be added')

        if standalone and not options.skip_conncheck:
            principal = options.principal
            replica_conn_check(replica_config.ca_host_name,
                               host_name,
                               realm_name,
                               True,
                               replica_config.ca_ds_port,
                               options.admin_password,
                               principal=principal,
                               ca_cert_file=options.ca_cert_file)

        if options.skip_schema_check:
            logger.info("Skipping CA DS schema check")

        return

    if standalone:
        if api.Command.ca_is_enabled()['result']:
            raise ScriptError(
                "One or more CA masters are already present in IPA realm "
                "'%s'.\nIf you wish to replicate CA to this host, please "
                "re-run 'ipa-ca-install'\nwith a replica file generated on "
                "an existing CA master as argument." % realm_name)

    if options.external_cert_files:
        if not cainstance.is_step_one_done():
            # This can happen if someone passes external_ca_file without
            # already having done the first stage of the CA install.
            raise ScriptError(
                "CA is not installed yet. To install with an external CA "
                "is a two-stage process.\nFirst run the installer with "
                "--external-ca.")

        external_cert_file, external_ca_file = installutils.load_external_cert(
            options.external_cert_files, options._ca_subject)
    elif options.external_ca:
        if cainstance.is_step_one_done():
            raise ScriptError(
                "CA is already installed.\nRun the installer with "
                "--external-cert-file.")
        if os.path.isfile(paths.ROOT_IPA_CSR):
            raise ScriptError(
                "CA CSR file %s already exists.\nIn order to continue "
                "remove the file and run the installer again." %
                paths.ROOT_IPA_CSR)

        if not options.external_ca_type:
            options.external_ca_type = x509.ExternalCAType.GENERIC.value

        if options.external_ca_profile is not None:
            # check that profile is valid for the external ca type
            if options.external_ca_type \
                    not in options.external_ca_profile.valid_for:
                raise ScriptError(
                    "External CA profile specification '{}' "
                    "cannot be used with external CA type '{}'.".format(
                        options.external_ca_profile.unparsed_input,
                        options.external_ca_type))

    if not options.external_cert_files:
        if not cainstance.check_ports():
            print("IPA requires ports 8080 and 8443 for PKI, but one or more "
                  "are currently in use.")
            raise ScriptError("Aborting installation")

    if standalone:
        dirname = dsinstance.config_dirname(
            ipaldap.realm_to_serverid(realm_name))
        cadb = certs.CertDB(realm_name,
                            nssdir=paths.PKI_TOMCAT_ALIAS_DIR,
                            subject_base=options._subject_base)
        dsdb = certs.CertDB(realm_name,
                            nssdir=dirname,
                            subject_base=options._subject_base)

        # Check that we can add our CA cert to DS and PKI NSS databases
        for db in (cadb, dsdb):
            if not db.exists():
                continue
            for nickname, _trust_flags in db.list_certs():
                if nickname == certdb.get_ca_nickname(realm_name):
                    raise ScriptError(
                        "Certificate with nickname %s is present in %s, "
                        "cannot continue." % (nickname, db.secdir))

                cert = db.get_cert_from_db(nickname)
                if not cert:
                    continue
                subject = DN(cert.subject)
                if subject == DN(options._ca_subject):
                    raise ScriptError(
                        "Certificate with subject %s is present in %s, "
                        "cannot continue." % (subject, db.secdir))
Ejemplo n.º 29
0
def install_step_1(standalone, replica_config, options, custodia):
    if replica_config is not None and not replica_config.setup_ca:
        return

    realm_name = options.realm_name
    host_name = options.host_name
    subject_base = options._subject_base
    basedn = ipautil.realm_to_suffix(realm_name)

    ca = cainstance.CAInstance(realm=realm_name,
                               host_name=host_name,
                               custodia=custodia)

    ca.stop('pki-tomcat')

    # This is done within stopped_service context, which restarts CA
    ca.enable_client_auth_to_db()

    # Lightweight CA key retrieval is configured in step 1 instead
    # of CAInstance.configure_instance (which is invoked from step
    # 0) because kadmin_addprinc fails until krb5.conf is installed
    # by krb.create_instance.
    #
    ca.setup_lightweight_ca_key_retrieval()

    serverid = ipaldap.realm_to_serverid(realm_name)

    if standalone and replica_config is None:
        dirname = dsinstance.config_dirname(serverid)

        # Store the new IPA CA cert chain in DS NSS database and LDAP
        cadb = certs.CertDB(realm_name,
                            nssdir=paths.PKI_TOMCAT_ALIAS_DIR,
                            subject_base=subject_base)
        dsdb = certs.CertDB(realm_name,
                            nssdir=dirname,
                            subject_base=subject_base)
        cacert = cadb.get_cert_from_db('caSigningCert cert-pki-ca')
        nickname = certdb.get_ca_nickname(realm_name)
        trust_flags = certdb.IPA_CA_TRUST_FLAGS
        dsdb.add_cert(cacert, nickname, trust_flags)
        certstore.put_ca_cert_nss(api.Backend.ldap2,
                                  api.env.basedn,
                                  cacert,
                                  nickname,
                                  trust_flags,
                                  config_ipa=True,
                                  config_compat=True)

        # Store DS CA cert in Dogtag NSS database
        trust_flags = dict(reversed(dsdb.list_certs()))
        server_certs = dsdb.find_server_certs()
        trust_chain = dsdb.find_root_cert(server_certs[0][0])[:-1]
        nickname = trust_chain[-1]
        cert = dsdb.get_cert_from_db(nickname)
        cadb.add_cert(cert, nickname, trust_flags[nickname])

    installutils.restart_dirsrv()

    ca.start('pki-tomcat')

    if standalone or replica_config is not None:
        # We need to restart apache as we drop a new config file in there
        services.knownservices.httpd.restart(capture_output=True)

    if standalone:
        # Install CA DNS records
        if bindinstance.dns_container_exists(basedn):
            bind = bindinstance.BindInstance()
            bind.update_system_records()
Ejemplo n.º 30
0
    def execute(self, **options):
        db = certs.CertDB(self.api.env.realm, paths.HTTPD_ALIAS_DIR)
        ca_cert = None

        ca_enabled = self.api.Command.ca_is_enabled()['result']
        if ca_enabled:
            ca_nickname = certdb.get_ca_nickname(self.api.env.realm)
        else:
            ca_nickname = None
            server_certs = db.find_server_certs()
            if server_certs:
                ca_chain = db.find_root_cert(server_certs[0][0])[:-1]
                if ca_chain:
                    ca_nickname = ca_chain[-1]

        ldap = self.api.Backend.ldap2

        for nickname, trust_flags in db.list_certs():
            if trust_flags.has_key:
                continue
            if nickname == ca_nickname and ca_enabled:
                trust_flags = certdb.IPA_CA_TRUST_FLAGS
            cert = db.get_cert_from_db(nickname, pem=False)
            trust, _ca, eku = certstore.trust_flags_to_key_policy(trust_flags)

            dn = DN(('cn', nickname), ('cn', 'certificates'), ('cn', 'ipa'),
                    ('cn', 'etc'), self.api.env.basedn)
            entry = ldap.make_entry(dn)

            try:
                certstore.init_ca_entry(entry, cert, nickname, trust, eku)
            except Exception as e:
                self.log.warning("Failed to create entry for %s: %s", nickname,
                                 e)
                continue
            if nickname == ca_nickname:
                ca_cert = cert
                config = entry.setdefault('ipaConfigString', [])
                if ca_enabled:
                    config.append('ipaCa')
                config.append('ipaCa')

            try:
                ldap.add_entry(entry)
            except errors.DuplicateEntry:
                if nickname == ca_nickname and ca_enabled:
                    try:
                        ldap.update_entry(entry)
                    except errors.EmptyModlist:
                        pass

        if ca_cert:
            dn = DN(('cn', 'CACert'), ('cn', 'ipa'), ('cn', 'etc'),
                    self.api.env.basedn)
            try:
                entry = ldap.get_entry(dn)
            except errors.NotFound:
                entry = ldap.make_entry(dn)
                entry['objectclass'] = ['nsContainer', 'pkiCA']
                entry.single_value['cn'] = 'CAcert'
                entry.single_value['cACertificate;binary'] = ca_cert
                ldap.add_entry(entry)
            else:
                if b'' in entry['cACertificate;binary']:
                    entry.single_value['cACertificate;binary'] = ca_cert
                    ldap.update_entry(entry)

        return False, []