Ejemplo n.º 1
0
    def forward(self, *keys, **options):
        filename = None
        if 'certificate_out' in options:
            filename = options.pop('certificate_out')
            try:
                util.check_writable_file(filename)
            except errors.FileError as e:
                raise errors.ValidationError(name='certificate-out',
                                             error=str(e))

        result = super(WithCertOutArgs, self).forward(*keys, **options)

        if filename:
            # if result certificate / certificate_chain not present in result,
            # it means Dogtag did not provide it (probably due to LWCA key
            # replication lag or failure.  The server transmits a warning
            # message in this case, which the client automatically prints.
            # So in this section we just ignore it and move on.
            certs = None
            if options.get('chain', False):
                if 'certificate_chain' in result['result']:
                    certs = result['result']['certificate_chain']
            else:
                if 'certificate' in result['result']:
                    certs = [base64.b64decode(result['result']['certificate'])]
            if certs:
                x509.write_certificate_list(
                    (x509.load_der_x509_certificate(cert) for cert in certs),
                    filename)

        return result
Ejemplo n.º 2
0
 def _install_pkinit_ca_bundle(self):
     ca_certs = certstore.get_ca_certs(self.api.Backend.ldap2,
                                       self.api.env.basedn,
                                       self.api.env.realm,
                                       False)
     ca_certs = [c for c, _n, t, _u in ca_certs if t is not False]
     x509.write_certificate_list(ca_certs, paths.CACERT_PEM)
Ejemplo n.º 3
0
 def _install_pkinit_ca_bundle(self):
     ca_certs = certstore.get_ca_certs(self.api.Backend.ldap2,
                                       self.api.env.basedn,
                                       self.api.env.realm,
                                       False)
     ca_certs = [c for c, _n, t, _u in ca_certs if t is not False]
     x509.write_certificate_list(ca_certs, paths.CACERT_PEM, mode=0o644)
Ejemplo n.º 4
0
 def __publish_ca_cert(self):
     ca_subject = self.cert.issuer
     certlist = x509.load_certificate_list_from_file(paths.IPA_CA_CRT)
     ca_certs = [c for c in certlist if c.subject == ca_subject]
     if not ca_certs:
         raise RuntimeError("HTTPD cert was issued by an unknown CA.")
     # at this time we can assume any CA cert will be valid since this is
     # only run during installation
     x509.write_certificate_list(certlist, paths.CA_CRT)
Ejemplo n.º 5
0
 def __publish_ca_cert(self):
     ca_subject = self.cert.issuer
     certlist = x509.load_certificate_list_from_file(paths.IPA_CA_CRT)
     ca_certs = [c for c in certlist if c.subject == ca_subject]
     if not ca_certs:
         raise RuntimeError("HTTPD cert was issued by an unknown CA.")
     # at this time we can assume any CA cert will be valid since this is
     # only run during installation
     x509.write_certificate_list(certlist, paths.CA_CRT, mode=0o644)
Ejemplo n.º 6
0
 def forward(self, *keys, **options):
     if "out" in options:
         util.check_writable_file(options["out"])
         result = super(service_show, self).forward(*keys, **options)
         if "usercertificate" in result["result"]:
             x509.write_certificate_list(result["result"]["usercertificate"], options["out"])
             result["summary"] = _("Certificate(s) stored in file '%(file)s'") % dict(file=options["out"])
             return result
         else:
             raise errors.NoCertificateError(entry=keys[-1])
     else:
         return super(service_show, self).forward(*keys, **options)
Ejemplo n.º 7
0
def install_ca_cert(ldap, base_dn, realm, cafile):
    try:
        try:
            certs = certstore.get_ca_certs(ldap, base_dn, realm, False)
        except errors.NotFound:
            shutil.copy(cafile, constants.CACERT)
        else:
            certs = [c[0] for c in certs if c[2] is not False]
            x509.write_certificate_list(certs, constants.CACERT)

        os.chmod(constants.CACERT, 0444)
    except Exception, e:
        print "error copying files: " + str(e)
        sys.exit(1)
Ejemplo n.º 8
0
 def forward(self, *keys, **options):
     if 'out' in options:
         util.check_writable_file(options['out'])
         result = super(user_show, self).forward(*keys, **options)
         if 'usercertificate' in result['result']:
             x509.write_certificate_list(
                 result['result']['usercertificate'], options['out'])
             result['summary'] = (
                 _('Certificate(s) stored in file \'%(file)s\'') %
                 dict(file=options['out']))
             return result
         else:
             raise errors.NoCertificateError(entry=keys[-1])
     else:
         return super(user_show, self).forward(*keys, **options)
Ejemplo n.º 9
0
def install_ca_cert(ldap, base_dn, realm, cafile, destfile=paths.IPA_CA_CRT):
    try:
        try:
            certs = certstore.get_ca_certs(ldap, base_dn, realm, False)
        except errors.NotFound:
            try:
                shutil.copy(cafile, destfile)
            except shutil.Error:
                # cafile == IPA_CA_CRT
                pass
        else:
            certs = [c[0] for c in certs if c[2] is not False]
            x509.write_certificate_list(certs, destfile, mode=0o644)
    except Exception as e:
        raise ScriptError("error copying files: " + str(e))
    return destfile
Ejemplo n.º 10
0
def install_ca_cert(ldap, base_dn, realm, cafile, destfile=paths.IPA_CA_CRT):
    try:
        try:
            certs = certstore.get_ca_certs(ldap, base_dn, realm, False)
        except errors.NotFound:
            try:
                shutil.copy(cafile, destfile)
            except shutil.Error:
                # cafile == IPA_CA_CRT
                pass
        else:
            certs = [c[0] for c in certs if c[2] is not False]
            x509.write_certificate_list(certs, destfile, mode=0o644)
    except Exception as e:
        raise ScriptError("error copying files: " + str(e))
    return destfile
Ejemplo n.º 11
0
 def forward(self, *keys, **options):
     if 'out' in options:
         util.check_writable_file(options['out'])
         result = super(service_show, self).forward(*keys, **options)
         if 'usercertificate' in result['result']:
             certs = (x509.load_der_x509_certificate(c)
                      for c in result['result']['usercertificate'])
             x509.write_certificate_list(certs, options['out'])
             result['summary'] = (
                 _('Certificate(s) stored in file \'%(file)s\'')
                 % dict(file=options['out'])
             )
             return result
         else:
             raise errors.NoCertificateError(entry=keys[-1])
     else:
         return super(service_show, self).forward(*keys, **options)
Ejemplo n.º 12
0
Archivo: ca.py Proyecto: xxblx/freeipa
    def forward(self, *keys, **options):
        filename = None
        if 'certificate_out' in options:
            filename = options.pop('certificate_out')
            try:
                util.check_writable_file(filename)
            except errors.FileError as e:
                raise errors.ValidationError(name='certificate-out',
                                             error=str(e))

        result = super(WithCertOutArgs, self).forward(*keys, **options)
        if filename:
            if options.get('chain', False):
                certs = result['result']['certificate_chain']
            else:
                certs = [base64.b64decode(result['result']['certificate'])]
            certs = (x509.load_der_x509_certificate(cert) for cert in certs)
            x509.write_certificate_list(certs, filename)

        return result
Ejemplo n.º 13
0
    def forward(self, *keys, **options):
        filename = None
        if 'certificate_out' in options:
            filename = options.pop('certificate_out')
            try:
                util.check_writable_file(filename)
            except errors.FileError as e:
                raise errors.ValidationError(name='certificate-out',
                                             error=str(e))

        result = super(WithCertOutArgs, self).forward(*keys, **options)
        if filename:
            if options.get('chain', False):
                certs = result['result']['certificate_chain']
            else:
                certs = [base64.b64decode(result['result']['certificate'])]
            certs = (x509.load_der_x509_certificate(cert) for cert in certs)
            x509.write_certificate_list(certs, filename)

        return result
Ejemplo n.º 14
0
    def forward(self, *args, **options):
        if 'certificate_out' in options:
            certificate_out = options.pop('certificate_out')
            try:
                util.check_writable_file(certificate_out)
            except errors.FileError as e:
                raise errors.ValidationError(name='certificate-out',
                                             error=str(e))
        else:
            certificate_out = None

        result = super(CertRetrieveOverride, self).forward(*args, **options)

        if certificate_out is not None:
            if options.get('chain', False):
                certs = result['result']['certificate_chain']
            else:
                certs = [base64.b64decode(result['result']['certificate'])]
            certs = (x509.load_der_x509_certificate(cert) for cert in certs)
            x509.write_certificate_list(certs, certificate_out)

        return result
Ejemplo n.º 15
0
    def forward(self, *args, **options):
        if 'certificate_out' in options:
            certificate_out = options.pop('certificate_out')
            try:
                util.check_writable_file(certificate_out)
            except errors.FileError as e:
                raise errors.ValidationError(name='certificate-out',
                                             error=str(e))
        else:
            certificate_out = None

        result = super(CertRetrieveOverride, self).forward(*args, **options)

        if certificate_out is not None:
            if options.get('chain', False):
                certs = result['result']['certificate_chain']
            else:
                certs = [result['result']['certificate']]
            certs = (x509.load_der_x509_certificate(base64.b64decode(cert))
                     for cert in certs)
            x509.write_certificate_list(certs, certificate_out)

        return result
Ejemplo n.º 16
0
def update_file(filename, certs, mode=0o644):
    certs = (c[0] for c in certs if c[2] is not False)
    try:
        x509.write_certificate_list(certs, filename, mode=mode)
    except Exception as e:
        logger.error("failed to update %s: %s", filename, e)
Ejemplo n.º 17
0
def main():
    module = AnsibleModule(
        argument_spec = dict(
            servers=dict(required=True, type='list'),
            domain=dict(required=True),
            realm=dict(required=True),
            hostname=dict(required=True),
            basedn=dict(required=True),
            principal=dict(required=False),
            subject_base=dict(required=True),
            ca_enabled=dict(required=True, type='bool'),
            mkhomedir=dict(required=False, type='bool'),
            on_master=dict(required=False, type='bool'),
        ),
        supports_check_mode = True,
    )

    module._ansible_debug = True
    servers = module.params.get('servers')
    realm = module.params.get('realm')
    hostname = module.params.get('hostname')
    basedn = module.params.get('basedn')
    domain = module.params.get('domain')
    principal = module.params.get('principal')
    subject_base = module.params.get('subject_base')
    ca_enabled = module.params.get('ca_enabled')
    mkhomedir = module.params.get('mkhomedir')
    on_master = module.params.get('on_master')

    fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE)
    statestore = sysrestore.StateFile(paths.IPA_CLIENT_SYSRESTORE)

    ###########################################################################

    os.environ['KRB5CCNAME'] = CCACHE_FILE
    
    class Object(object):
        pass
    options = Object()
    options.dns_updates = False
    options.all_ip_addresses = False
    options.ip_addresses = None
    options.request_cert = False
    options.hostname = hostname
    options.preserve_sssd = False
    options.on_master = False
    options.conf_ssh = True
    options.conf_sshd = True
    options.conf_sudo = True
    options.primary = False
    options.permit = False
    options.krb5_offline_passwords = False
    options.create_sshfp = True

    ##########################################################################

    # Create IPA NSS database
    try:
        create_ipa_nssdb()
    except ipautil.CalledProcessError as e:
        module.fail_json(msg="Failed to create IPA NSS database: %s" % e)

    # Get CA certificates from the certificate store
    try:
        ca_certs = get_certs_from_ldap(servers[0], basedn, realm,
                                       ca_enabled)
    except errors.NoCertificateError:
        if ca_enabled:
            ca_subject = DN(('CN', 'Certificate Authority'), subject_base)
        else:
            ca_subject = None
        ca_certs = certstore.make_compat_ca_certs(ca_certs, realm,
                                                  ca_subject)
    ca_certs_trust = [(c, n, certstore.key_policy_to_trust_flags(t, True, u))
                      for (c, n, t, u) in ca_certs]

    if hasattr(paths, "KDC_CA_BUNDLE_PEM"):
        x509.write_certificate_list(
            [c for c, n, t, u in ca_certs if t is not False],
            paths.KDC_CA_BUNDLE_PEM)
    if hasattr(paths, "CA_BUNDLE_PEM"):
        x509.write_certificate_list(
            [c for c, n, t, u in ca_certs if t is not False],
            paths.CA_BUNDLE_PEM)

    # Add the CA certificates to the IPA NSS database
    module.debug("Adding CA certificates to the IPA NSS database.")
    ipa_db = certdb.NSSDatabase(paths.IPA_NSSDB_DIR)
    for cert, nickname, trust_flags in ca_certs_trust:
        try:
            ipa_db.add_cert(cert, nickname, trust_flags)
        except CalledProcessError as e:
            module.fail_json(msg="Failed to add %s to the IPA NSS database." % nickname)

    # Add the CA certificates to the platform-dependant systemwide CA store
    tasks.insert_ca_certs_into_systemwide_ca_store(ca_certs)

    if not on_master:
        client_dns(servers[0], hostname, options)
        configure_certmonger(fstore, subject_base, realm, hostname,
                             options, ca_enabled)

    if hasattr(paths, "SSH_CONFIG_DIR"):
        ssh_config_dir = paths.SSH_CONFIG_DIR
    else:
        ssh_config_dir = services.knownservices.sshd.get_config_dir()
    update_ssh_keys(hostname, ssh_config_dir, options.create_sshfp)

    try:
        os.remove(CCACHE_FILE)
    except Exception:
        pass

    ##########################################################################

    # Name Server Caching Daemon. Disable for SSSD, use otherwise
    # (if installed)
    nscd = services.knownservices.nscd
    if nscd.is_installed():
        save_state(nscd, statestore)

        try:
            nscd_service_action = 'stop'
            nscd.stop()
        except Exception:
            module.warn("Failed to %s the %s daemon" %
                        (nscd_service_action, nscd.service_name))

        try:
            nscd.disable()
        except Exception:
            module.warn("Failed to disable %s daemon. Disable it manually." %
                        nscd.service_name)

    nslcd = services.knownservices.nslcd
    if nslcd.is_installed():
        save_state(nslcd, statestore)

    retcode, conf = (0, None)

    ##########################################################################

    # Modify nsswitch/pam stack
    tasks.modify_nsswitch_pam_stack(sssd=True,
                                    mkhomedir=mkhomedir,
                                    statestore=statestore)

    module.log("SSSD enabled")

    argspec = inspect.getargspec(services.service)
    if len(argspec.args) > 1:
        sssd = services.service('sssd', api)
    else:
        sssd = services.service('sssd')
    try:
        sssd.restart()
    except CalledProcessError:
        module.warn("SSSD service restart was unsuccessful.")

    try:
        sssd.enable()
    except CalledProcessError as e:
        module.warn(
            "Failed to enable automatic startup of the SSSD daemon: "
            "%s", e)

    if configure_openldap_conf(fstore, basedn, servers):
        module.log("Configured /etc/openldap/ldap.conf")
    else:
        module.log("Failed to configure /etc/openldap/ldap.conf")

    # Check that nss is working properly
    if not on_master:
        user = principal
        if user is None or user == "":
            user = "******" % domain
            module.log("Principal is not set when enrolling with OTP"
                       "; using principal '%s' for 'getent passwd'" % user)
        elif '@' not in user:
            user = "******" % (user, domain)
        n = 0
        found = False
        # Loop for up to 10 seconds to see if nss is working properly.
        # It can sometimes take a few seconds to connect to the remote
        # provider.
        # Particulary, SSSD might take longer than 6-8 seconds.
        while n < 10 and not found:
            try:
                ipautil.run(["getent", "passwd", user])
                found = True
            except Exception as e:
                time.sleep(1)
                n = n + 1

        if not found:
            module.fail_json(msg="Unable to find '%s' user with 'getent "
                             "passwd %s'!" % (user.split("@")[0], user))
            if conf:
                module.log("Recognized configuration: %s" % conf)
            else:
                module.fail_json(msg=
                                 "Unable to reliably detect "
                                 "configuration. Check NSS setup manually.")

            try:
                hardcode_ldap_server(servers)
            except Exception as e:
                module.fail_json(msg="Adding hardcoded server name to "
                                 "/etc/ldap.conf failed: %s" % str(e))

    ##########################################################################

    module.exit_json(changed=True,
                     ca_enabled_ra=ca_enabled)
Ejemplo n.º 18
0
def load_external_cert(files, ca_subject):
    """
    Load and verify external CA certificate chain from multiple files.

    The files are accepted in PEM and DER certificate and PKCS#7 certificate
    chain formats.

    :param files: Names of files to import
    :param ca_subject: IPA CA subject DN
    :returns: Temporary file with the IPA CA certificate and temporary file
        with the external CA certificate chain
    """
    with certs.NSSDatabase() as nssdb:
        nssdb.create_db()

        try:
            nssdb.import_files(files)
        except RuntimeError as e:
            raise ScriptError(str(e))

        ca_subject = DN(ca_subject)
        ca_nickname = None
        cache = {}
        for nickname, _trust_flags in nssdb.list_certs():
            cert = nssdb.get_cert(nickname)
            subject = DN(cert.subject)
            issuer = DN(cert.issuer)

            cache[nickname] = (cert, subject, issuer)
            if subject == ca_subject:
                ca_nickname = nickname
            nssdb.trust_root_cert(nickname, EXTERNAL_CA_TRUST_FLAGS)

        if ca_nickname is None:
            raise ScriptError(
                "IPA CA certificate with subject '%s' "
                "was not found in %s." % (ca_subject, (",".join(files))))

        trust_chain = list(reversed(nssdb.get_trust_chain(ca_nickname)))
        ca_cert_chain = []
        for nickname in trust_chain:
            cert, subject, issuer = cache[nickname]
            ca_cert_chain.append(cert)
            if subject == issuer:
                break
        else:
            raise ScriptError(
                "CA certificate chain in %s is incomplete: "
                "missing certificate with subject '%s'" %
                (", ".join(files), issuer))

        for nickname in trust_chain:
            try:
                nssdb.verify_ca_cert_validity(nickname)
            except ValueError as e:
                cert, subject, issuer = cache[nickname]
                raise ScriptError(
                    "CA certificate %s in %s is not valid: %s" %
                    (subject, ", ".join(files), e))

    cert_file = tempfile.NamedTemporaryFile()
    cert_file.write(ca_cert_chain[0].public_bytes(x509.Encoding.PEM) + b'\n')
    cert_file.flush()

    ca_file = tempfile.NamedTemporaryFile()
    x509.write_certificate_list(
        ca_cert_chain[1:],
        ca_file.name,
        mode=0o644
    )
    ca_file.flush()

    return cert_file, ca_file
Ejemplo n.º 19
0
def load_external_cert(files, ca_subject):
    """
    Load and verify external CA certificate chain from multiple files.

    The files are accepted in PEM and DER certificate and PKCS#7 certificate
    chain formats.

    :param files: Names of files to import
    :param ca_subject: IPA CA subject DN
    :returns: Temporary file with the IPA CA certificate and temporary file
        with the external CA certificate chain
    """
    with certs.NSSDatabase() as nssdb:
        nssdb.create_db()

        try:
            nssdb.import_files(files)
        except RuntimeError as e:
            raise ScriptError(str(e))

        ca_subject = DN(ca_subject)
        ca_nickname = None
        cache = {}
        for nickname, _trust_flags in nssdb.list_certs():
            cert = nssdb.get_cert(nickname)
            subject = DN(cert.subject)
            issuer = DN(cert.issuer)

            cache[nickname] = (cert, subject, issuer)
            if subject == ca_subject:
                ca_nickname = nickname
            nssdb.trust_root_cert(nickname, EXTERNAL_CA_TRUST_FLAGS)

        if ca_nickname is None:
            raise ScriptError(
                "IPA CA certificate with subject '%s' "
                "was not found in %s." % (ca_subject, (",".join(files))))

        trust_chain = list(reversed(nssdb.get_trust_chain(ca_nickname)))
        ca_cert_chain = []
        for nickname in trust_chain:
            cert, subject, issuer = cache[nickname]
            ca_cert_chain.append(cert)
            if subject == issuer:
                break
        else:
            raise ScriptError(
                "CA certificate chain in %s is incomplete: "
                "missing certificate with subject '%s'" %
                (", ".join(files), issuer))

        for nickname in trust_chain:
            try:
                nssdb.verify_ca_cert_validity(nickname)
            except ValueError as e:
                raise ScriptError(
                    "CA certificate %s in %s is not valid: %s" %
                    (subject, ", ".join(files), e))

    cert_file = tempfile.NamedTemporaryFile()
    cert_file.write(ca_cert_chain[0].public_bytes(x509.Encoding.PEM) + b'\n')
    cert_file.flush()

    ca_file = tempfile.NamedTemporaryFile()
    x509.write_certificate_list(
        ca_cert_chain[1:],
        ca_file.name,
        mode=0o644
    )
    ca_file.flush()

    return cert_file, ca_file
Ejemplo n.º 20
0
 def update_file(self, filename, certs, mode=0444):
     certs = (c[0] for c in certs if c[2] is not False)
     try:
         x509.write_certificate_list(certs, filename)
     except Exception, e:
         self.log.error("failed to update %s: %s", filename, e)
Ejemplo n.º 21
0
def update_file(filename, certs, mode=0o644):
    certs = (c[0] for c in certs if c[2] is not False)
    try:
        x509.write_certificate_list(certs, filename, mode=mode)
    except Exception as e:
        logger.error("failed to update %s: %s", filename, e)