Exemplo n.º 1
0
def expired_ipa_certs(now):
    """
    Determine which IPA certs are expired, or close to expiry.

    Return a list of (IPACertType, cert) pairs.

    """
    certs = []

    # IPA RA
    cert = x509.load_certificate_from_file(paths.RA_AGENT_PEM)
    if cert.not_valid_after <= now:
        certs.append((IPACertType.IPARA, cert))

    # Apache HTTPD
    cert = x509.load_certificate_from_file(paths.HTTPD_CERT_FILE)
    if cert.not_valid_after <= now:
        certs.append((IPACertType.HTTPS, cert))

    # LDAPS
    ds_dbdir = dsinstance.config_dirname(realm_to_serverid(api.env.realm))
    db = NSSDatabase(nssdir=ds_dbdir)
    cert = db.get_cert('Server-Cert')
    if cert.not_valid_after <= now:
        certs.append((IPACertType.LDAPS, cert))

    # KDC
    cert = x509.load_certificate_from_file(paths.KDC_CERT)
    if cert.not_valid_after <= now:
        certs.append((IPACertType.KDC, cert))

    return certs
Exemplo n.º 2
0
    def __create_kra_agent(self):
        """
        Create KRA agent, assign a certificate, and add the user to
        the appropriate groups for accessing KRA services.
        """
        conn = api.Backend.ldap2

        # get RA agent certificate
        cert = x509.load_certificate_from_file(paths.RA_AGENT_PEM)

        # create ipakra user with RA agent certificate
        entry = conn.make_entry(KRA_AGENT_DN,
                                objectClass=[
                                    'top', 'person', 'organizationalPerson',
                                    'inetOrgPerson', 'cmsuser'
                                ],
                                uid=["ipakra"],
                                sn=["IPA KRA User"],
                                cn=["IPA KRA User"],
                                usertype=["undefined"],
                                userCertificate=[cert],
                                description=[
                                    '2;%s;%s;%s' %
                                    (cert.serial_number, self.ca_subject,
                                     DN(('CN', 'IPA RA'), self.subject_base))
                                ])
        conn.add_entry(entry)

        # add ipakra user to Data Recovery Manager Agents group
        group_dn = DN(('cn', 'Data Recovery Manager Agents'), ('ou', 'groups'),
                      KRA_BASEDN)
        conn.add_entry_to_group(KRA_AGENT_DN, group_dn, 'uniqueMember')
Exemplo n.º 3
0
def check_ra_cert(config_data, cert_name='ipaCert'):
    from freeipa_health_checker import ldap_helper

    nssdb_dir = config_data['ck_ra_cert']['nssdb_dir']
    pem_dir = config_data['ck_ra_cert']['pem_dir']

    if os.path.exists(nssdb_dir):
        cert_data = commands_helper.get_cert(nssdb_dir, cert_name)
        cert = parser.nssdb_cert_to_basecertificate(cert_data)
        certificate = parser.BaseCertificate(serial_number=cert.serial_number)

        cert_serialnumber = certificate.serial_number
        cert_derdata = cert.der_data

        logger.info(messages.ra_cert_from(cert_name, nssdb_dir))

    elif os.path.exists(pem_dir):
        from ipalib import x509
        certificate = x509.load_certificate_from_file(pem_dir)

        cert_serialnumber = certificate.serial_number
        cert_derdata = certificate.der_data

        logger.info(messages.ra_cert_from(cert_name, pem_dir))

    ldap_serialnumber, usercertificate = ldap_helper.get_ra_cert()

    certificates_are_same = usercertificate == cert_derdata
    logger.info(messages.certificate_der_data_are_equal(certificates_are_same))

    return cert_serialnumber, ldap_serialnumber
Exemplo n.º 4
0
    def install(self):
        print("Installing CA certificate, please wait")

        options = self.options
        cert_filename = self.args[1]

        try:
            cert = x509.load_certificate_from_file(cert_filename)
        except IOError as e:
            raise admintool.ScriptError("Can't open \"%s\": %s" %
                                        (cert_filename, e))
        except (TypeError, ValueError) as e:
            raise admintool.ScriptError("Not a valid certificate: %s" % e)

        nickname = options.nickname or str(DN(cert.subject))

        ca_certs = certstore.get_ca_certs_nss(api.Backend.ldap2,
                                              api.env.basedn, api.env.realm,
                                              False)

        with certs.NSSDatabase() as tmpdb:
            tmpdb.create_db()
            tmpdb.add_cert(cert, nickname, EXTERNAL_CA_TRUST_FLAGS)
            for ca_cert, ca_nickname, ca_trust_flags in ca_certs:
                tmpdb.add_cert(ca_cert, ca_nickname, ca_trust_flags)

            try:
                tmpdb.verify_ca_cert_validity(nickname)
            except ValueError as e:
                raise admintool.ScriptError(
                    "Not a valid CA certificate: %s (visit "
                    "http://www.freeipa.org/page/Troubleshooting for "
                    "troubleshooting guide)" % e)

        trust_flags = options.trust_flags.split(',')
        if (set(options.trust_flags) - set(',CPTcgpuw')
                or len(trust_flags) not in [3, 4]):
            raise admintool.ScriptError("Invalid trust flags")

        extra_flags = trust_flags[3:]
        extra_usages = set()
        if extra_flags:
            if 'C' in extra_flags[0]:
                extra_usages.add(x509.EKU_PKINIT_KDC)
            if 'T' in extra_flags[0]:
                extra_usages.add(x509.EKU_PKINIT_CLIENT_AUTH)

        trust_flags = parse_trust_flags(','.join(trust_flags[:3]))
        trust_flags = TrustFlags(trust_flags.has_key, trust_flags.trusted,
                                 trust_flags.ca,
                                 trust_flags.usages | extra_usages)

        try:
            certstore.put_ca_cert_nss(api.Backend.ldap2, api.env.basedn, cert,
                                      nickname, trust_flags)
        except ValueError as e:
            raise admintool.ScriptError(
                "Failed to install the certificate: %s" % e)

        print("CA certificate successfully installed")
Exemplo n.º 5
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()
Exemplo n.º 6
0
def expired_ipa_certs(now):
    """
    Determine which IPA certs are expired, or close to expiry.

    Return a list of (IPACertType, cert) pairs.

    """
    certs = []
    non_renewed = []

    # IPA RA
    cert = x509.load_certificate_from_file(paths.RA_AGENT_PEM)
    if cert.not_valid_after <= now:
        certs.append((IPACertType.IPARA, cert))

    # Apache HTTPD
    cert = x509.load_certificate_from_file(paths.HTTPD_CERT_FILE)
    if cert.not_valid_after <= now:
        if not is_ipa_issued_cert(api, cert):
            non_renewed.append((IPACertType.HTTPS, cert))
        else:
            certs.append((IPACertType.HTTPS, cert))

    # LDAPS
    serverid = realm_to_serverid(api.env.realm)
    ds = dsinstance.DsInstance(realm_name=api.env.realm)
    ds_dbdir = dsinstance.config_dirname(serverid)
    ds_nickname = ds.get_server_cert_nickname(serverid)
    db = NSSDatabase(nssdir=ds_dbdir)
    cert = db.get_cert(ds_nickname)
    if cert.not_valid_after <= now:
        if not is_ipa_issued_cert(api, cert):
            non_renewed.append((IPACertType.LDAPS, cert))
        else:
            certs.append((IPACertType.LDAPS, cert))

    # KDC
    cert = x509.load_certificate_from_file(paths.KDC_CERT)
    if cert.not_valid_after <= now:
        if not is_ipa_issued_cert(api, cert):
            non_renewed.append((IPACertType.HTTPS, cert))
        else:
            certs.append((IPACertType.KDC, cert))

    return certs, non_renewed
Exemplo n.º 7
0
    def check_ra_cert(self):
        """Check the RA certificate subject & blob against LDAP"""
        if not self.ca.is_configured():
            self.failure('Skipping RA check because CA not installed')
            return

        if not self.conn:
            self.failure('Skipping RA check because no LDAP connection')
            return

        cert = x509.load_certificate_from_file(paths.RA_AGENT_PEM)

        serial_number = cert.serial_number
        subject = DN(cert.subject)
        issuer = DN(cert.issuer)
        description = '2;%d;%s;%s' % (serial_number, issuer, subject)

        logger.debug('RA agent description should be %s', description)

        db_filter = ldap2.ldap2.combine_filters([
            ldap2.ldap2.make_filter({'objectClass': 'inetOrgPerson'}),
            ldap2.ldap2.make_filter(
                {'description': ';%s;%s' % (issuer, subject)},
                exact=False,
                trailing_wildcard=False),
        ], ldap2.ldap2.MATCH_ALL)

        base_dn = DN(('o', 'ipaca'))
        try:
            entries = self.conn.get_entries(base_dn, self.conn.SCOPE_SUBTREE,
                                            db_filter)
        except errors.NotFound:
            self.failure('RA agent certificate not found in LDAP')
            return
        except Exception as e:
            self.failure('RA agent check failed %s' % e)
            return
        else:
            if len(entries) != 1:
                self.failure('Too many RA agent entries found')
            entry = entries[0]
            ra_desc = entry.get('description')[0]
            ra_certs = entry.get('usercertificate')
            if ra_desc != description:
                self.failure('RA agent description does not match '
                             '%s in LDAP and %s expected' %
                             (ra_desc, description))
            found = False
            for check in ra_certs:
                if isinstance(check, str):
                    check = load_der_certificate(check)
                if check == cert:
                    found = True
                    break
            if not found:
                self.failure('RA agent certificate not found in LDAP')
Exemplo n.º 8
0
    def install(self):
        print("Installing CA certificate, please wait")

        options = self.options
        cert_filename = self.args[1]

        nss_cert = None
        try:
            try:
                nss_cert = x509.load_certificate_from_file(cert_filename)
            except IOError as e:
                raise admintool.ScriptError(
                    "Can't open \"%s\": %s" % (cert_filename, e))
            except (TypeError, NSPRError, ValueError) as e:
                raise admintool.ScriptError("Not a valid certificate: %s" % e)
            subject = nss_cert.subject
            cert = nss_cert.der_data
        finally:
            del nss_cert

        nickname = options.nickname or str(subject)

        ca_certs = certstore.get_ca_certs_nss(api.Backend.ldap2,
                                              api.env.basedn,
                                              api.env.realm,
                                              False)

        with certs.NSSDatabase() as tmpdb:
            pw = ipautil.write_tmp_file(ipautil.ipa_generate_password())
            tmpdb.create_db(pw.name)
            tmpdb.add_cert(cert, nickname, 'C,,')
            for ca_cert, ca_nickname, ca_trust_flags in ca_certs:
                tmpdb.add_cert(ca_cert, ca_nickname, ca_trust_flags)

            try:
                tmpdb.verify_ca_cert_validity(nickname)
            except ValueError as e:
                raise admintool.ScriptError(
                    "Not a valid CA certificate: %s (visit "
                    "http://www.freeipa.org/page/Troubleshooting for "
                    "troubleshooting guide)" % e)

        trust_flags = options.trust_flags
        if ((set(trust_flags) - set(',CPTcgpuw')) or
            len(trust_flags.split(',')) != 3):
            raise admintool.ScriptError("Invalid trust flags")

        try:
            certstore.put_ca_cert_nss(
                api.Backend.ldap2, api.env.basedn, cert, nickname, trust_flags)
        except ValueError as e:
            raise admintool.ScriptError(
                "Failed to install the certificate: %s" % e)

        print("CA certificate successfully installed")
Exemplo n.º 9
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()
Exemplo n.º 10
0
    def install(self):
        print("Installing CA certificate, please wait")

        options = self.options
        cert_filename = self.args[1]

        nss_cert = None
        try:
            try:
                nss_cert = x509.load_certificate_from_file(cert_filename)
            except IOError as e:
                raise admintool.ScriptError("Can't open \"%s\": %s" %
                                            (cert_filename, e))
            except (TypeError, NSPRError, ValueError) as e:
                raise admintool.ScriptError("Not a valid certificate: %s" % e)
            subject = nss_cert.subject
            cert = nss_cert.der_data
        finally:
            del nss_cert

        nickname = options.nickname or str(subject)

        ca_certs = certstore.get_ca_certs_nss(api.Backend.ldap2,
                                              api.env.basedn, api.env.realm,
                                              False)

        with certs.NSSDatabase() as tmpdb:
            pw = ipautil.write_tmp_file(ipautil.ipa_generate_password())
            tmpdb.create_db(pw.name)
            tmpdb.add_cert(cert, nickname, 'C,,')
            for ca_cert, ca_nickname, ca_trust_flags in ca_certs:
                tmpdb.add_cert(ca_cert, ca_nickname, ca_trust_flags)

            try:
                tmpdb.verify_ca_cert_validity(nickname)
            except ValueError as e:
                raise admintool.ScriptError(
                    "Not a valid CA certificate: %s (visit "
                    "http://www.freeipa.org/page/Troubleshooting for "
                    "troubleshooting guide)" % e)

        trust_flags = options.trust_flags
        if ((set(trust_flags) - set(',CPTcgpuw'))
                or len(trust_flags.split(',')) != 3):
            raise admintool.ScriptError("Invalid trust flags")

        try:
            certstore.put_ca_cert_nss(api.Backend.ldap2, api.env.basedn, cert,
                                      nickname, trust_flags)
        except ValueError as e:
            raise admintool.ScriptError(
                "Failed to install the certificate: %s" % e)

        print("CA certificate successfully installed")
Exemplo n.º 11
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()
Exemplo n.º 12
0
def check_renewed_ipa_certs(certs):
    """
    Check whether all expected IPA-specific certs (extra_certs) were renewed
    successfully.

    For now this subroutine just checks that the files that we expect
    ``pki-server cert-fix`` to have written do exist and contain an X.509
    certificate.

    Return ``True`` if everything seems to be as expected, otherwise ``False``.

    """
    for _certtype, oldcert in certs:
        cert_path = RENEWED_CERT_PATH_TEMPLATE.format(oldcert.serial_number)
        try:
            x509.load_certificate_from_file(cert_path)
        except (IOError, ValueError):
            return False

    return True
Exemplo n.º 13
0
 def start_tracking_certificates(self):
     cert = x509.load_certificate_from_file(paths.HTTPD_CERT_FILE)
     if certs.is_ipa_issued_cert(api, cert):
         request_id = certmonger.start_tracking(
             certpath=(paths.HTTPD_CERT_FILE, paths.HTTPD_KEY_FILE),
             post_command='restart_httpd', storage='FILE'
         )
         subject = str(DN(cert.subject))
         certmonger.add_principal(request_id, self.principal)
         certmonger.add_subject(request_id, subject)
     else:
         logger.debug("Will not track HTTP server cert %s as it is not "
                      "issued by IPA", cert.subject)
Exemplo n.º 14
0
 def start_tracking_certificates(self):
     cert = x509.load_certificate_from_file(paths.HTTPD_CERT_FILE)
     if certs.is_ipa_issued_cert(api, cert):
         request_id = certmonger.start_tracking(
             certpath=(paths.HTTPD_CERT_FILE, paths.HTTPD_KEY_FILE),
             post_command='restart_httpd',
             storage='FILE')
         subject = str(DN(cert.subject))
         certmonger.add_principal(request_id, self.principal)
         certmonger.add_subject(request_id, subject)
     else:
         logger.debug(
             "Will not track HTTP server cert %s as it is not "
             "issued by IPA", cert.subject)
Exemplo n.º 15
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
Exemplo n.º 16
0
    def install(self):
        print("Installing CA certificate, please wait")

        options = self.options
        cert_filename = self.args[1]

        try:
            cert_obj = x509.load_certificate_from_file(cert_filename)
        except IOError as e:
            raise admintool.ScriptError(
                "Can't open \"%s\": %s" % (cert_filename, e))
        except (TypeError, ValueError) as e:
            raise admintool.ScriptError("Not a valid certificate: %s" % e)
        cert = cert_obj.public_bytes(serialization.Encoding.DER)

        nickname = options.nickname or str(DN(cert_obj.subject))

        ca_certs = certstore.get_ca_certs_nss(api.Backend.ldap2,
                                              api.env.basedn,
                                              api.env.realm,
                                              False)

        with certs.NSSDatabase() as tmpdb:
            tmpdb.create_db()
            tmpdb.add_cert(cert, nickname, 'C,,')
            for ca_cert, ca_nickname, ca_trust_flags in ca_certs:
                tmpdb.add_cert(ca_cert, ca_nickname, ca_trust_flags)

            try:
                tmpdb.verify_ca_cert_validity(nickname)
            except ValueError as e:
                raise admintool.ScriptError(
                    "Not a valid CA certificate: %s (visit "
                    "http://www.freeipa.org/page/Troubleshooting for "
                    "troubleshooting guide)" % e)

        trust_flags = options.trust_flags
        if ((set(trust_flags) - set(',CPTcgpuw')) or
            len(trust_flags.split(',')) != 3):
            raise admintool.ScriptError("Invalid trust flags")

        try:
            certstore.put_ca_cert_nss(
                api.Backend.ldap2, api.env.basedn, cert, nickname, trust_flags)
        except ValueError as e:
            raise admintool.ScriptError(
                "Failed to install the certificate: %s" % e)

        print("CA certificate successfully installed")
Exemplo n.º 17
0
    def load_cert(self, domain):
        """Load cert from cache

        :param domain: IPA domain
        :return: cryptography.x509.Certificate or None
        """
        filename = self._get_filename(domain)
        try:
            try:
                return x509.load_certificate_from_file(filename)
            except EnvironmentError as e:
                if e.errno != errno.ENOENT:
                    raise
        except Exception:
            logger.warning("Failed to load %s", filename, exc_info=True)
Exemplo n.º 18
0
    def install(self):
        print "Installing CA certificate, please wait"

        options = self.options
        cert_filename = self.args[1]

        nss_cert = None
        try:
            try:
                nss_cert = x509.load_certificate_from_file(cert_filename)
            except IOError, e:
                raise admintool.ScriptError(
                    "Can't open \"%s\": %s" % (cert_filename, e))
            except (TypeError, NSPRError), e:
                raise admintool.ScriptError("Not a valid certificate: %s" % e)
Exemplo n.º 19
0
    def load_cert(self, domain):
        """Load cert from cache

        :param domain: IPA domain
        :return: cryptography.x509.Certificate or None
        """
        filename = self._get_filename(domain)
        try:
            try:
                return x509.load_certificate_from_file(filename)
            except EnvironmentError as e:
                if e.errno != errno.ENOENT:
                    raise
        except Exception:
            logger.warning("Failed to load %s", filename, exc_info=True)
Exemplo n.º 20
0
    def install(self):
        print "Installing CA certificate, please wait"

        options = self.options
        cert_filename = self.args[1]

        nss_cert = None
        try:
            try:
                nss_cert = x509.load_certificate_from_file(cert_filename)
            except IOError, e:
                raise admintool.ScriptError("Can't open \"%s\": %s" %
                                            (cert_filename, e))
            except (TypeError, NSPRError), e:
                raise admintool.ScriptError("Not a valid certificate: %s" % e)
Exemplo n.º 21
0
 def start_tracking_certificates(self):
     key_passwd_file = paths.HTTPD_PASSWD_FILE_FMT.format(host=api.env.host)
     cert = x509.load_certificate_from_file(paths.HTTPD_CERT_FILE)
     if certs.is_ipa_issued_cert(api, cert):
         request_id = certmonger.start_tracking(
             certpath=(paths.HTTPD_CERT_FILE, paths.HTTPD_KEY_FILE),
             post_command='restart_httpd', storage='FILE',
             profile=dogtag.DEFAULT_PROFILE,
             pinfile=key_passwd_file,
             dns=[self.fqdn, f'{IPA_CA_RECORD}.{api.env.domain}'],
         )
         subject = str(DN(cert.subject))
         certmonger.add_principal(request_id, self.principal)
         certmonger.add_subject(request_id, subject)
     else:
         logger.debug("Will not track HTTP server cert %s as it is not "
                      "issued by IPA", cert.subject)
Exemplo n.º 22
0
    def __parse_crt_or_pem_cert(self, row):
        from ipalib import x509

        cert = None
        try:
            cert = x509.load_certificate_from_file(row['path'])
        except IOError:
            self.logger.error(messages.cert_not_in_path("", row['path']))
            return None

        trust_flags = None
        cert_name = row.get('name')

        if cert_name:
            trust_flags = commands_helper.get_certs_trust_flags(
                row['path'], cert_name)

        return parser.certdb_to_basecertificate(cert, cert_name, trust_flags)
Exemplo n.º 23
0
    def __create_kra_agent(self):
        """
        Create KRA agent, assign a certificate, and add the user to
        the appropriate groups for accessing KRA services.
        """

        # get RA agent certificate
        cert = x509.load_certificate_from_file(paths.RA_AGENT_PEM)
        cert_data = cert.public_bytes(serialization.Encoding.DER)

        # connect to KRA database
        server_id = installutils.realm_to_serverid(api.env.realm)
        dogtag_uri = 'ldapi://%%2fvar%%2frun%%2fslapd-%s.socket' % server_id
        conn = ldap2.ldap2(api, ldap_uri=dogtag_uri)
        conn.connect(autobind=True)

        # create ipakra user with RA agent certificate
        user_dn = DN(('uid', "ipakra"), ('ou', 'people'), self.basedn)
        entry = conn.make_entry(
            user_dn,
            objectClass=[
                'top', 'person', 'organizationalPerson', 'inetOrgPerson',
                'cmsuser'
            ],
            uid=["ipakra"],
            sn=["IPA KRA User"],
            cn=["IPA KRA User"],
            usertype=["undefined"],
            userCertificate=[cert_data],
            description=[
                '2;%s;%s;%s' % (cert.serial_number, DN(
                    self.subject), DN(('CN', 'IPA RA'), self.subject_base))
            ])
        conn.add_entry(entry)

        # add ipakra user to Data Recovery Manager Agents group
        group_dn = DN(('cn', 'Data Recovery Manager Agents'), ('ou', 'groups'),
                      self.basedn)
        conn.add_entry_to_group(user_dn, group_dn, 'uniqueMember')

        conn.disconnect()
Exemplo n.º 24
0
def install_ipa_certs(subject_base, ca_subject_dn, certs):
    """Print details and install renewed IPA certificates."""
    for certtype, oldcert in certs:
        cert_path = "/etc/pki/pki-tomcat/certs/{}-renewed.crt" \
            .format(oldcert.serial_number)
        cert = x509.load_certificate_from_file(cert_path)
        print_cert_info("Renewed IPA", certtype.value, cert)

        if certtype is IPACertType.IPARA:
            shutil.copyfile(cert_path, paths.RA_AGENT_PEM)
            cainstance.update_people_entry(cert)
            replicate_cert(subject_base, ca_subject_dn, cert)
        elif certtype is IPACertType.HTTPS:
            shutil.copyfile(cert_path, paths.HTTPD_CERT_FILE)
        elif certtype is IPACertType.LDAPS:
            ds_dbdir = dsinstance.config_dirname(
                realm_to_serverid(api.env.realm))
            db = NSSDatabase(nssdir=ds_dbdir)
            db.delete_cert('Server-Cert')
            db.import_pem_cert('Server-Cert', EMPTY_TRUST_FLAGS, cert_path)
        elif certtype is IPACertType.KDC:
            shutil.copyfile(cert_path, paths.KDC_CERT)
Exemplo n.º 25
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)

            passwd_fname = paths.HTTPD_PASSWD_FILE_FMT.format(
                            host=api.env.host)
            with open(passwd_fname, 'wb') as passwd_file:
                os.fchmod(passwd_file.fileno(), 0o600)
                passwd_file.write(
                    ipautil.ipa_generate_password().encode('utf-8'))

            certs.install_key_from_p12(temp.name,
                                       pk12_password,
                                       paths.HTTPD_KEY_FILE,
                                       out_passwd_fname=passwd_fname)

        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()
Exemplo n.º 26
0
    def __create_kra_agent(self):
        """
        Create KRA agent, assign a certificate, and add the user to
        the appropriate groups for accessing KRA services.
        """

        # get RA agent certificate
        cert = x509.load_certificate_from_file(paths.RA_AGENT_PEM)

        # connect to KRA database
        conn = ldap2.ldap2(api)
        conn.connect(autobind=True)

        # create ipakra user with RA agent certificate
        user_dn = DN(('uid', "ipakra"), ('ou', 'people'), self.basedn)
        entry = conn.make_entry(
            user_dn,
            objectClass=[
                'top', 'person', 'organizationalPerson', 'inetOrgPerson',
                'cmsuser'
            ],
            uid=["ipakra"],
            sn=["IPA KRA User"],
            cn=["IPA KRA User"],
            usertype=["undefined"],
            userCertificate=[cert],
            description=[
                '2;%s;%s;%s' % (cert.serial_number, DN(
                    self.subject), DN(('CN', 'IPA RA'), self.subject_base))
            ])
        conn.add_entry(entry)

        # add ipakra user to Data Recovery Manager Agents group
        group_dn = DN(('cn', 'Data Recovery Manager Agents'), ('ou', 'groups'),
                      self.basedn)
        conn.add_entry_to_group(user_dn, group_dn, 'uniqueMember')

        conn.disconnect()
Exemplo n.º 27
0
    def load_pkcs12(self, ca_chain_fname=paths.IPA_CA_CRT, **kwargs):
        # Note that the "installutils.load_pkcs12" is quite a complex function
        # which performs some checking based on its kwargs:
        #       host_name performs NSSDatabase.verify_server_cert_validity()
        #       realm performs NSSDatabase.verify_kdc_cert_validity()
        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_chain_fname],
            **kwargs)

        # 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)
            cert = x509.load_certificate_from_file(temp.name)

        with tempfile.NamedTemporaryFile("rb") as temp:
            certs.install_key_from_p12(pkcs12_file.name, pin, temp.name)
            key = x509.load_pem_private_key(
                temp.read(), None, backend=x509.default_backend())

        return cert, key, ca_cert
Exemplo n.º 28
0
    def load_pkcs12(self, ca_chain_fname=paths.IPA_CA_CRT, **kwargs):
        # Note that the "installutils.load_pkcs12" is quite a complex function
        # which performs some checking based on its kwargs:
        #       host_name performs NSSDatabase.verify_server_cert_validity()
        #       realm performs NSSDatabase.verify_kdc_cert_validity()
        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_chain_fname],
            **kwargs)

        # 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)
            cert = x509.load_certificate_from_file(temp.name)

        with tempfile.NamedTemporaryFile("rb") as temp:
            certs.install_key_from_p12(pkcs12_file.name, pin, temp.name)
            key = x509.load_pem_private_key(
                temp.read(), None, backend=x509.default_backend())

        return cert, key, ca_cert
Exemplo n.º 29
0
def install_ipa_certs(subject_base, ca_subject_dn, certs):
    """Print details and install renewed IPA certificates."""
    for certtype, oldcert in certs:
        cert_path = RENEWED_CERT_PATH_TEMPLATE.format(oldcert.serial_number)
        cert = x509.load_certificate_from_file(cert_path)
        print_cert_info("Renewed IPA", certtype.value, cert)

        if certtype is IPACertType.IPARA:
            shutil.copyfile(cert_path, paths.RA_AGENT_PEM)
            cainstance.update_people_entry(cert)
            replicate_cert(subject_base, ca_subject_dn, cert)
        elif certtype is IPACertType.HTTPS:
            shutil.copyfile(cert_path, paths.HTTPD_CERT_FILE)
        elif certtype is IPACertType.LDAPS:
            serverid = realm_to_serverid(api.env.realm)
            ds = dsinstance.DsInstance(realm_name=api.env.realm)
            ds_dbdir = dsinstance.config_dirname(serverid)
            db = NSSDatabase(nssdir=ds_dbdir)
            ds_nickname = ds.get_server_cert_nickname(serverid)
            db.delete_cert(ds_nickname)
            db.import_pem_cert(ds_nickname, EMPTY_TRUST_FLAGS, cert_path)
        elif certtype is IPACertType.KDC:
            shutil.copyfile(cert_path, paths.KDC_CERT)
Exemplo n.º 30
0
    def __create_kra_agent(self):
        """
        Create KRA agent, assign a certificate, and add the user to
        the appropriate groups for accessing KRA services.
        """

        # get RA agent certificate
        cert = x509.load_certificate_from_file(paths.RA_AGENT_PEM)
        cert_data = cert.public_bytes(serialization.Encoding.DER)

        # connect to KRA database
        conn = ldap2.ldap2(api)
        conn.connect(autobind=True)

        # create ipakra user with RA agent certificate
        user_dn = DN(('uid', "ipakra"), ('ou', 'people'), self.basedn)
        entry = conn.make_entry(
            user_dn,
            objectClass=['top', 'person', 'organizationalPerson',
                         'inetOrgPerson', 'cmsuser'],
            uid=["ipakra"],
            sn=["IPA KRA User"],
            cn=["IPA KRA User"],
            usertype=["undefined"],
            userCertificate=[cert_data],
            description=['2;%s;%s;%s' % (
                cert.serial_number,
                DN(self.subject),
                DN(('CN', 'IPA RA'), self.subject_base))])
        conn.add_entry(entry)

        # add ipakra user to Data Recovery Manager Agents group
        group_dn = DN(('cn', 'Data Recovery Manager Agents'), ('ou', 'groups'),
                self.basedn)
        conn.add_entry_to_group(user_dn, group_dn, 'uniqueMember')

        conn.disconnect()
Exemplo n.º 31
0
    def check(self):
        if not self.ca.is_configured():
            logger.debug('CA is not configured, skipping RA Agent check')
            return

        try:
            cert = x509.load_certificate_from_file(paths.RA_AGENT_PEM)
        except Exception as e:
            yield Result(self,
                         constants.ERROR,
                         error=str(e),
                         msg='Unable to load RA cert: {error}')
            return

        serial_number = cert.serial_number
        subject = DN(cert.subject)
        issuer = DN(cert.issuer)
        description = '2;%d;%s;%s' % (serial_number, issuer, subject)

        logger.debug('RA agent description should be %s', description)

        db_filter = ldap2.ldap2.combine_filters([
            ldap2.ldap2.make_filter({'objectClass': 'inetOrgPerson'}),
            ldap2.ldap2.make_filter({'sn': 'ipara'}),
            ldap2.ldap2.make_filter(
                {'description': ';%s;%s' % (issuer, subject)},
                exact=False,
                trailing_wildcard=False),
        ], ldap2.ldap2.MATCH_ALL)

        base_dn = DN(('o', 'ipaca'))
        try:
            entries = self.conn.get_entries(base_dn, self.conn.SCOPE_SUBTREE,
                                            db_filter)
        except errors.NotFound:
            yield Result(self,
                         constants.ERROR,
                         description=description,
                         msg='RA agent not found in LDAP')
            return
        except Exception as e:
            yield Result(self,
                         constants.ERROR,
                         error=str(e),
                         msg='Retrieving RA agent from LDAP failed {error}')
            return
        else:
            logger.debug('RA agent description is %s', description)
            if len(entries) != 1:
                yield Result(self,
                             constants.ERROR,
                             found=len(entries),
                             msg='Too many RA agent entries found, {found}')
                return
            entry = entries[0]
            raw_desc = entry.get('description')
            if raw_desc is None:
                yield Result(self,
                             constants.ERROR,
                             msg='RA agent is missing the description '
                             'attribute or it is not readable')
                return
            ra_desc = raw_desc[0]
            ra_certs = entry.get('usercertificate')
            if ra_desc != description:
                yield Result(self,
                             constants.ERROR,
                             expected=description,
                             got=ra_desc,
                             msg='RA agent description does not match. Found '
                             '{got} in LDAP and expected {expected}')
                return
            found = False
            for candidate in ra_certs:
                if candidate == cert:
                    found = True
                    break
            if not found:
                yield Result(self,
                             constants.ERROR,
                             certfile=paths.RA_AGENT_PEM,
                             dn=str(entry.dn),
                             msg='RA agent certificate in {certfile} not '
                             'found in LDAP userCertificate attribute '
                             'for the entry {dn}')
            yield Result(self, constants.SUCCESS)
Exemplo n.º 32
0
def replicate_dogtag_certs(subject_base, ca_subject_dn, certs):
    for certid, _oldcert in certs:
        cert_path = "/etc/pki/pki-tomcat/certs/{}.crt".format(certid)
        cert = x509.load_certificate_from_file(cert_path)
        print_cert_info("Renewed Dogtag", certid, cert)
        replicate_cert(subject_base, ca_subject_dn, cert)
Exemplo n.º 33
0
    def renew_external_step_2(self, ca, old_cert):
        print("Importing the renewed CA certificate, please wait")

        options = self.options
        conn = api.Backend.ldap2
        cert_file, ca_file = installutils.load_external_cert(
            options.external_cert_files, x509.subject_base())

        nss_cert = None
        nss.nss_init(paths.PKI_TOMCAT_ALIAS_DIR)
        try:
            nss_cert = x509.load_certificate(old_cert, x509.DER)
            subject = nss_cert.subject
            der_subject = x509.get_der_subject(old_cert, x509.DER)
            #pylint: disable=E1101
            pkinfo = nss_cert.subject_public_key_info.format()
            #pylint: enable=E1101

            nss_cert = x509.load_certificate_from_file(cert_file.name)
            cert = nss_cert.der_data
            if nss_cert.subject != subject:
                raise admintool.ScriptError(
                    "Subject name mismatch (visit "
                    "http://www.freeipa.org/page/Troubleshooting for "
                    "troubleshooting guide)")
            if x509.get_der_subject(cert, x509.DER) != der_subject:
                raise admintool.ScriptError(
                    "Subject name encoding mismatch (visit "
                    "http://www.freeipa.org/page/Troubleshooting for "
                    "troubleshooting guide)")
            #pylint: disable=E1101
            if nss_cert.subject_public_key_info.format() != pkinfo:
                raise admintool.ScriptError(
                    "Subject public key info mismatch (visit "
                    "http://www.freeipa.org/page/Troubleshooting for "
                    "troubleshooting guide)")
            #pylint: enable=E1101
        finally:
            del nss_cert
            nss.nss_shutdown()

        with certs.NSSDatabase() as tmpdb:
            pw = ipautil.write_tmp_file(ipautil.ipa_generate_password())
            tmpdb.create_db(pw.name)
            tmpdb.add_cert(old_cert, 'IPA CA', 'C,,')

            try:
                tmpdb.add_cert(cert, 'IPA CA', 'C,,')
            except ipautil.CalledProcessError as e:
                raise admintool.ScriptError(
                    "Not compatible with the current CA certificate: %s" % e)

            ca_certs = x509.load_certificate_list_from_file(ca_file.name)
            for ca_cert in ca_certs:
                tmpdb.add_cert(ca_cert.der_data, str(ca_cert.subject), 'C,,')
            del ca_certs
            del ca_cert

            try:
                tmpdb.verify_ca_cert_validity('IPA CA')
            except ValueError as e:
                raise admintool.ScriptError(
                    "Not a valid CA certificate: %s (visit "
                    "http://www.freeipa.org/page/Troubleshooting for "
                    "troubleshooting guide)" % e)

            trust_chain = tmpdb.get_trust_chain('IPA CA')[:-1]
            for nickname in trust_chain:
                try:
                    ca_cert = tmpdb.get_cert(nickname)
                except RuntimeError:
                    break
                certstore.put_ca_cert_nss(conn, api.env.basedn, ca_cert,
                                          nickname, ',,')

        dn = DN(('cn', self.cert_nickname), ('cn', 'ca_renewal'),
                ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn)
        try:
            entry = conn.get_entry(dn, ['usercertificate'])
            entry['usercertificate'] = [cert]
            conn.update_entry(entry)
        except errors.NotFound:
            entry = conn.make_entry(
                dn,
                objectclass=['top', 'pkiuser', 'nscontainer'],
                cn=[self.cert_nickname],
                usercertificate=[cert])
            conn.add_entry(entry)
        except errors.EmptyModlist:
            pass

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

        self.resubmit_request(ca, 'ipaRetrieval')

        print("CA certificate successfully renewed")
Exemplo n.º 34
0
    def __setup_ssl(self):
        key_passwd_file = paths.HTTPD_PASSWD_FILE_FMT.format(host=api.env.host)
        with open(key_passwd_file, 'wb') as f:
            os.fchmod(f.fileno(), 0o600)
            pkey_passwd = ipautil.ipa_generate_password().encode('utf-8')
            f.write(pkey_passwd)

        if self.pkcs12_info:
            p12_certs, p12_priv_keys = certs.pkcs12_to_certkeys(
                *self.pkcs12_info)
            keys_dict = {
                k.public_key().public_numbers(): k
                for k in p12_priv_keys
            }
            certs_keys = [
                (c, keys_dict.get(c.public_key().public_numbers()))
                for c in p12_certs
            ]
            server_certs_keys = [
                (c, k) for c, k in certs_keys if k is not None
            ]

            if not server_certs_keys:
                raise RuntimeError(
                    "Could not find a suitable server cert in import in %s"
                    % self.pkcs12_info[0]
                )

            # We only handle one server cert
            self.cert = server_certs_keys[0][0]
            x509.write_certificate(self.cert, paths.HTTPD_CERT_FILE)
            x509.write_pem_private_key(
                server_certs_keys[0][1],
                paths.HTTPD_KEY_FILE,
                passwd=pkey_passwd
            )

            if self.ca_is_configured:
                self.start_tracking_certificates()

            self.add_cert_to_service()

        else:
            if not self.promote:
                ca_args = [
                    paths.CERTMONGER_DOGTAG_SUBMIT,
                    '--ee-url', 'https://%s:8443/ca/ee/ca' % self.fqdn,
                    '--certfile', paths.RA_AGENT_PEM,
                    '--keyfile', paths.RA_AGENT_KEY,
                    '--cafile', paths.IPA_CA_CRT,
                    '--agent-submit'
                ]
                helper = " ".join(ca_args)
                prev_helper = certmonger.modify_ca_helper('IPA', helper)
            else:
                prev_helper = None
            try:
                certmonger.request_and_wait_for_cert(
                    certpath=(paths.HTTPD_CERT_FILE, paths.HTTPD_KEY_FILE),
                    principal=self.principal,
                    subject=str(DN(('CN', self.fqdn), self.subject_base)),
                    ca='IPA',
                    profile=dogtag.DEFAULT_PROFILE,
                    dns=[self.fqdn],
                    post_command='restart_httpd',
                    storage='FILE',
                    passwd_fname=key_passwd_file
                )
            finally:
                if prev_helper is not None:
                    certmonger.modify_ca_helper('IPA', prev_helper)
            self.cert = x509.load_certificate_from_file(
                paths.HTTPD_CERT_FILE
            )

            if prev_helper is not None:
                self.add_cert_to_service()

            with open(paths.HTTPD_KEY_FILE, 'rb') as f:
                priv_key = x509.load_pem_private_key(
                    f.read(), pkey_passwd, backend=x509.default_backend())

            # Verify we have a valid server cert
            if (priv_key.public_key().public_numbers()
                    != self.cert.public_key().public_numbers()):
                raise RuntimeError(
                    "The public key of the issued HTTPD service certificate "
                    "does not match its private key.")

        sysupgrade.set_upgrade_state('ssl.conf', 'migrated_to_mod_ssl', True)
Exemplo n.º 35
0
    def install(self):
        print("Installing CA certificate, please wait")

        options = self.options
        cert_filename = self.args[1]

        try:
            cert_obj = x509.load_certificate_from_file(cert_filename)
        except IOError as e:
            raise admintool.ScriptError(
                "Can't open \"%s\": %s" % (cert_filename, e))
        except (TypeError, ValueError) as e:
            raise admintool.ScriptError("Not a valid certificate: %s" % e)
        cert = cert_obj.public_bytes(serialization.Encoding.DER)

        nickname = options.nickname or str(DN(cert_obj.subject))

        ca_certs = certstore.get_ca_certs_nss(api.Backend.ldap2,
                                              api.env.basedn,
                                              api.env.realm,
                                              False)

        with certs.NSSDatabase() as tmpdb:
            tmpdb.create_db()
            tmpdb.add_cert(cert, nickname, EXTERNAL_CA_TRUST_FLAGS)
            for ca_cert, ca_nickname, ca_trust_flags in ca_certs:
                tmpdb.add_cert(ca_cert, ca_nickname, ca_trust_flags)

            try:
                tmpdb.verify_ca_cert_validity(nickname)
            except ValueError as e:
                raise admintool.ScriptError(
                    "Not a valid CA certificate: %s (visit "
                    "http://www.freeipa.org/page/Troubleshooting for "
                    "troubleshooting guide)" % e)

        trust_flags = options.trust_flags.split(',')
        if (set(options.trust_flags) - set(',CPTcgpuw') or
                len(trust_flags) not in [3, 4]):
            raise admintool.ScriptError("Invalid trust flags")

        extra_flags = trust_flags[3:]
        extra_usages = set()
        if extra_flags:
            if 'C' in extra_flags[0]:
                extra_usages.add(x509.EKU_PKINIT_KDC)
            if 'T' in extra_flags[0]:
                extra_usages.add(x509.EKU_PKINIT_CLIENT_AUTH)

        trust_flags = parse_trust_flags(','.join(trust_flags[:3]))
        trust_flags = TrustFlags(trust_flags.has_key,
                                 trust_flags.trusted,
                                 trust_flags.ca,
                                 trust_flags.usages | extra_usages)

        try:
            certstore.put_ca_cert_nss(
                api.Backend.ldap2, api.env.basedn, cert, nickname, trust_flags)
        except ValueError as e:
            raise admintool.ScriptError(
                "Failed to install the certificate: %s" % e)

        print("CA certificate successfully installed")
Exemplo n.º 36
0
    def renew_external_step_2(self, ca, old_cert):
        print "Importing the renewed CA certificate, please wait"

        options = self.options
        cert_file, ca_file = installutils.load_external_cert(
            options.external_cert_files, x509.subject_base())

        nss_cert = None
        nss.nss_init(ca.dogtag_constants.ALIAS_DIR)
        try:
            nss_cert = x509.load_certificate(old_cert, x509.DER)
            subject = nss_cert.subject
            der_subject = x509.get_der_subject(old_cert, x509.DER)
            #pylint: disable=E1101
            pkinfo = nss_cert.subject_public_key_info.format()
            #pylint: enable=E1101

            nss_cert = x509.load_certificate_from_file(cert_file.name)
            cert = nss_cert.der_data
            if nss_cert.subject != subject:
                raise admintool.ScriptError(
                    "Subject name mismatch (visit "
                    "http://www.freeipa.org/page/Troubleshooting for "
                    "troubleshooting guide)")
            if x509.get_der_subject(cert, x509.DER) != der_subject:
                raise admintool.ScriptError(
                    "Subject name encoding mismatch (visit "
                    "http://www.freeipa.org/page/Troubleshooting for "
                    "troubleshooting guide)")
            #pylint: disable=E1101
            if nss_cert.subject_public_key_info.format() != pkinfo:
                raise admintool.ScriptError(
                    "Subject public key info mismatch (visit "
                    "http://www.freeipa.org/page/Troubleshooting for "
                    "troubleshooting guide)")
            #pylint: enable=E1101
        finally:
            del nss_cert
            nss.nss_shutdown()

        with certs.NSSDatabase() as tmpdb:
            pw = ipautil.write_tmp_file(ipautil.ipa_generate_password())
            tmpdb.create_db(pw.name)
            tmpdb.add_cert(old_cert, 'IPA CA', 'C,,')

            try:
                tmpdb.add_cert(cert, 'IPA CA', 'C,,')
            except ipautil.CalledProcessError, e:
                raise admintool.ScriptError(
                    "Not compatible with the current CA certificate: %s" % e)

            ca_certs = x509.load_certificate_list_from_file(ca_file.name)
            for ca_cert in ca_certs:
                tmpdb.add_cert(ca_cert.der_data, str(ca_cert.subject), 'C,,')
            del ca_certs
            del ca_cert

            try:
                tmpdb.verify_ca_cert_validity('IPA CA')
            except ValueError, e:
                raise admintool.ScriptError(
                    "Not a valid CA certificate: %s (visit "
                    "http://www.freeipa.org/page/Troubleshooting for "
                    "troubleshooting guide)" % e)
Exemplo n.º 37
0
    def __setup_ssl(self):
        key_passwd_file = paths.HTTPD_PASSWD_FILE_FMT.format(host=api.env.host)
        with open(key_passwd_file, 'wb') as f:
            os.fchmod(f.fileno(), 0o600)
            pkey_passwd = ipautil.ipa_generate_password().encode('utf-8')
            f.write(pkey_passwd)

        if self.pkcs12_info:
            p12_certs, p12_priv_keys = certs.pkcs12_to_certkeys(
                *self.pkcs12_info)
            keys_dict = {
                k.public_key().public_numbers(): k
                for k in p12_priv_keys
            }
            certs_keys = [(c, keys_dict.get(c.public_key().public_numbers()))
                          for c in p12_certs]
            server_certs_keys = [(c, k) for c, k in certs_keys
                                 if k is not None]

            if not server_certs_keys:
                raise RuntimeError(
                    "Could not find a suitable server cert in import in %s" %
                    self.pkcs12_info[0])

            # We only handle one server cert
            self.cert = server_certs_keys[0][0]
            x509.write_certificate(self.cert, paths.HTTPD_CERT_FILE)
            x509.write_pem_private_key(server_certs_keys[0][1],
                                       paths.HTTPD_KEY_FILE,
                                       passwd=pkey_passwd)

            if self.ca_is_configured:
                self.start_tracking_certificates()

            self.add_cert_to_service()

        else:
            if not self.promote:
                ca_args = [
                    paths.CERTMONGER_DOGTAG_SUBMIT, '--ee-url',
                    'https://%s:8443/ca/ee/ca' % self.fqdn, '--certfile',
                    paths.RA_AGENT_PEM, '--keyfile', paths.RA_AGENT_KEY,
                    '--cafile', paths.IPA_CA_CRT, '--agent-submit'
                ]
                helper = " ".join(ca_args)
                prev_helper = certmonger.modify_ca_helper('IPA', helper)
            else:
                prev_helper = None
            try:
                certmonger.request_and_wait_for_cert(
                    certpath=(paths.HTTPD_CERT_FILE, paths.HTTPD_KEY_FILE),
                    principal=self.principal,
                    subject=str(DN(('CN', self.fqdn), self.subject_base)),
                    ca='IPA',
                    profile=dogtag.DEFAULT_PROFILE,
                    dns=[self.fqdn],
                    post_command='restart_httpd',
                    storage='FILE',
                    passwd_fname=key_passwd_file)
            finally:
                if prev_helper is not None:
                    certmonger.modify_ca_helper('IPA', prev_helper)
            self.cert = x509.load_certificate_from_file(paths.HTTPD_CERT_FILE)

            if prev_helper is not None:
                self.add_cert_to_service()

            with open(paths.HTTPD_KEY_FILE, 'rb') as f:
                priv_key = x509.load_pem_private_key(
                    f.read(), pkey_passwd, backend=x509.default_backend())

            # Verify we have a valid server cert
            if (priv_key.public_key().public_numbers() !=
                    self.cert.public_key().public_numbers()):
                raise RuntimeError(
                    "The public key of the issued HTTPD service certificate "
                    "does not match its private key.")

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

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

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

            try:
                if result['result']['revoked']:
                    reason = result['result']['revocation_reason']
                    reason_txt = self.revocation_reason[reason]
                    yield Result(self,
                                 constants.ERROR,
                                 revocation_reason=reason_txt,
                                 key=id,
                                 msg='Certificate tracked by {key} is revoked '
                                 '{revocation_reason}')
                else:
                    yield Result(self, constants.SUCCESS, key=id)
            except Exception as e:
                yield Result(self,
                             constants.ERROR,
                             key=id,
                             error=str(e),
                             msg='Unable to determine revocation '
                             'status for {key}: {error}')
Exemplo n.º 39
0
    def renew_external_step_2(self, ca, old_cert):
        print("Importing the renewed CA certificate, please wait")

        options = self.options
        conn = api.Backend.ldap2
        cert_file, ca_file = installutils.load_external_cert(
            options.external_cert_files, x509.subject_base())

        nss_cert = None
        nss.nss_init(paths.PKI_TOMCAT_ALIAS_DIR)
        try:
            nss_cert = x509.load_certificate(old_cert, x509.DER)
            subject = nss_cert.subject
            der_subject = x509.get_der_subject(old_cert, x509.DER)
            #pylint: disable=E1101
            pkinfo = nss_cert.subject_public_key_info.format()
            #pylint: enable=E1101

            nss_cert = x509.load_certificate_from_file(cert_file.name)
            cert = nss_cert.der_data
            if nss_cert.subject != subject:
                raise admintool.ScriptError(
                    "Subject name mismatch (visit "
                    "http://www.freeipa.org/page/Troubleshooting for "
                    "troubleshooting guide)")
            if x509.get_der_subject(cert, x509.DER) != der_subject:
                raise admintool.ScriptError(
                    "Subject name encoding mismatch (visit "
                    "http://www.freeipa.org/page/Troubleshooting for "
                    "troubleshooting guide)")
            #pylint: disable=E1101
            if nss_cert.subject_public_key_info.format() != pkinfo:
                raise admintool.ScriptError(
                    "Subject public key info mismatch (visit "
                    "http://www.freeipa.org/page/Troubleshooting for "
                    "troubleshooting guide)")
            #pylint: enable=E1101
        finally:
            del nss_cert
            nss.nss_shutdown()

        with certs.NSSDatabase() as tmpdb:
            pw = ipautil.write_tmp_file(ipautil.ipa_generate_password())
            tmpdb.create_db(pw.name)
            tmpdb.add_cert(old_cert, 'IPA CA', 'C,,')

            try:
                tmpdb.add_cert(cert, 'IPA CA', 'C,,')
            except ipautil.CalledProcessError as e:
                raise admintool.ScriptError(
                    "Not compatible with the current CA certificate: %s" % e)

            ca_certs = x509.load_certificate_list_from_file(ca_file.name)
            for ca_cert in ca_certs:
                tmpdb.add_cert(ca_cert.der_data, str(ca_cert.subject), 'C,,')
            del ca_certs
            del ca_cert

            try:
                tmpdb.verify_ca_cert_validity('IPA CA')
            except ValueError as e:
                raise admintool.ScriptError(
                    "Not a valid CA certificate: %s (visit "
                    "http://www.freeipa.org/page/Troubleshooting for "
                    "troubleshooting guide)" % e)

            trust_chain = tmpdb.get_trust_chain('IPA CA')[:-1]
            for nickname in trust_chain:
                try:
                    ca_cert = tmpdb.get_cert(nickname)
                except RuntimeError:
                    break
                certstore.put_ca_cert_nss(
                    conn, api.env.basedn, ca_cert, nickname, ',,')

        dn = DN(('cn', self.cert_nickname), ('cn', 'ca_renewal'),
                ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn)
        try:
            entry = conn.get_entry(dn, ['usercertificate'])
            entry['usercertificate'] = [cert]
            conn.update_entry(entry)
        except errors.NotFound:
            entry = conn.make_entry(
                dn,
                objectclass=['top', 'pkiuser', 'nscontainer'],
                cn=[self.cert_nickname],
                usercertificate=[cert])
            conn.add_entry(entry)
        except errors.EmptyModlist:
            pass

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

        self.resubmit_request(ca, 'ipaRetrieval')

        print("CA certificate successfully renewed")
Exemplo n.º 40
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
Exemplo n.º 41
0
    def check(self):
        fqdn = socket.getfqdn()
        requests = get_expected_requests(self.ca, self.ds, self.serverid)

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

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

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

            hostlist = [fqdn]
            if self.ca.is_configured() and certfile == paths.HTTPD_CERT_FILE:
                hostlist.append(f'{IPA_CA_RECORD}.{api.env.domain}')
            error = False
            for host in hostlist:
                if host not in cert.san_a_label_dns_names:
                    error = True
                    yield Result(self,
                                 constants.ERROR,
                                 key=request_id,
                                 hostname=host,
                                 san=cert.san_a_label_dns_names,
                                 ca=ca_name,
                                 profile=profile,
                                 msg='Certificate request id {key} with '
                                 'profile {profile} for CA {ca} does not '
                                 'have a DNS SAN {san} matching name '
                                 '{hostname}')
            if not error:
                yield Result(self,
                             constants.SUCCESS,
                             key=request_id,
                             hostname=hostlist,
                             san=cert.san_a_label_dns_names,
                             ca=ca_name,
                             profile=profile)
Exemplo n.º 42
0
    def check(self):
        cm = certmonger._certmonger()

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

            store = request.prop_if.Get(certmonger.DBUS_CM_REQUEST_IF,
                                        'cert-storage')
            if store == 'FILE':
                certfile = str(
                    request.prop_if.Get(certmonger.DBUS_CM_REQUEST_IF,
                                        'cert-file'))
                try:
                    cert = x509.load_certificate_from_file(certfile)
                except Exception as e:
                    yield Result(self,
                                 constants.ERROR,
                                 key=id,
                                 certfile=certfile,
                                 error=str(e),
                                 msg='Request id {key}: Unable to open cert '
                                 'file \'{certfile}\': {error}')
                    continue
            elif store == 'NSSDB':
                nickname = str(
                    request.prop_if.Get(certmonger.DBUS_CM_REQUEST_IF,
                                        'key_nickname'))
                dbdir = str(
                    request.prop_if.Get(certmonger.DBUS_CM_REQUEST_IF,
                                        'cert_database'))
                try:
                    db = certdb.NSSDatabase(dbdir)
                except Exception as e:
                    yield Result(self,
                                 constants.ERROR,
                                 key=id,
                                 dbdir=dbdir,
                                 error=str(e),
                                 msg='Request id {key}: Unable to open NSS '
                                 'database \'{dbdir}\': {error}')
                    continue

                try:
                    cert = db.get_cert(nickname)
                except Exception as e:
                    yield Result(self,
                                 constants.ERROR,
                                 key=id,
                                 dbdir=dbdir,
                                 nickname=nickname,
                                 error=str(e),
                                 msg='Request id {key}: Unable to retrieve '
                                 'cert \'{nickname}\' from \'{dbdir}\': '
                                 '{error}')
                    continue
            else:
                yield Result(self,
                             constants.ERROR,
                             key=id,
                             store=store,
                             msg='Request id {key}: Unknown certmonger '
                             'storage type: {store}')
                continue

            now = datetime.utcnow()
            notafter = cert.not_valid_after

            if now > notafter:
                yield Result(self,
                             constants.ERROR,
                             key=id,
                             expiration_date=generalized_time(notafter),
                             msg='Request id {key} expired on '
                             '{expiration_date}')
                continue

            delta = notafter - now
            diff = int(delta.total_seconds() / DAY)
            if diff < int(self.config.cert_expiration_days):
                yield Result(self,
                             constants.WARNING,
                             key=id,
                             expiration_date=generalized_time(notafter),
                             days=diff,
                             msg='Request id {key} expires in {days} '
                             'days. certmonger should renew this '
                             'automatically. Watch the status with'
                             'getcert list -i {key}.')
            else:
                yield Result(self, constants.SUCCESS, key=id)