Beispiel #1
0
def export_key(args, tmpdir):
    """Export cert and private from PEM files as PKCS#12 file.

    The PKCS#12 file is encrypted with a password.
    """
    pk12file = os.path.join(tmpdir, 'export.p12')

    password = ipautil.ipa_generate_password()
    pk12pwfile = os.path.join(tmpdir, 'passwd')
    with open(pk12pwfile, 'w') as f:
        f.write(password)

    # OpenSSL does not support pkcs12 export of a cert without key
    ipautil.run([
        paths.OPENSSL,
        'pkcs12',
        '-export',
        '-in',
        args.certfile,
        '-out',
        pk12file,
        '-inkey',
        args.keyfile,
        '-password',
        'file:{pk12pwfile}'.format(pk12pwfile=pk12pwfile),
    ])

    with open(pk12file, 'rb') as f:
        p12data = f.read()

    data = {
        'export password': password,
        'pkcs12 data': p12data,
    }
    common.json_dump(data, args.exportfile)
Beispiel #2
0
def export_key(args, tmpdir):
    """Export key and certificate from the NSS DB to a PKCS#12 file.

    The PKCS#12 file is encrypted with a password.
    """
    pk12file = os.path.join(tmpdir, 'export.p12')

    password = ipautil.ipa_generate_password()
    pk12pk12pwfile = os.path.join(tmpdir, 'passwd')
    with open(pk12pk12pwfile, 'w') as f:
        f.write(password)

    nssdb = NSSDatabase(args.nssdb_path)
    nssdb.run_pk12util([
        "-o", pk12file,
        "-n", args.nickname,
        "-k", args.nssdb_pwdfile,
        "-w", pk12pk12pwfile,
    ])

    with open(pk12file, 'rb') as f:
        p12data = f.read()

    data = {
        'export password': password,
        'pkcs12 data': p12data,
    }
    common.json_dump(data, args.exportfile)
Beispiel #3
0
 def __setup_sub_dict(self):
     server_root = find_server_root()
     try:
         idrange_size = self.idmax - self.idstart + 1
     except TypeError:
         idrange_size = None
     self.sub_dict = dict(FQDN=self.fqdn, SERVERID=self.serverid,
                          PASSWORD=self.dm_password,
                          RANDOM_PASSWORD=ipautil.ipa_generate_password(),
                          SUFFIX=self.suffix,
                          REALM=self.realm, USER=DS_USER,
                          SERVER_ROOT=server_root, DOMAIN=self.domain,
                          TIME=int(time.time()), IDSTART=self.idstart,
                          IDMAX=self.idmax, HOST=self.fqdn,
                          ESCAPED_SUFFIX=str(self.suffix),
                          GROUP=DS_GROUP,
                          IDRANGE_SIZE=idrange_size,
                          DOMAIN_LEVEL=self.domainlevel,
                          MAX_DOMAIN_LEVEL=constants.MAX_DOMAIN_LEVEL,
                          MIN_DOMAIN_LEVEL=constants.MIN_DOMAIN_LEVEL,
                          STRIP_ATTRS=" ".join(replication.STRIP_ATTRS),
                          EXCLUDES='(objectclass=*) $ EXCLUDE ' +
                          ' '.join(replication.EXCLUDES),
                          TOTAL_EXCLUDES='(objectclass=*) $ EXCLUDE ' +
                          ' '.join(replication.TOTAL_EXCLUDES),
                      )
Beispiel #4
0
    def migrate_to_mod_ssl(self):
        """For upgrades only, migrate from mod_nss to mod_ssl"""
        db = certs.CertDB(api.env.realm, nssdir=paths.HTTPD_ALIAS_DIR)
        nickname = self.get_mod_nss_nickname()
        with tempfile.NamedTemporaryFile() as temp:
            pk12_password = ipautil.ipa_generate_password()
            pk12_pwdfile = ipautil.write_tmp_file(pk12_password)
            db.export_pkcs12(temp.name, pk12_pwdfile.name, nickname)
            certs.install_pem_from_p12(temp.name, pk12_password,
                                       paths.HTTPD_CERT_FILE)
            certs.install_key_from_p12(temp.name, pk12_password,
                                       paths.HTTPD_KEY_FILE)

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

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

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

        # remove nickname and CA certs from NSS db

        self.disable_nss_conf()
Beispiel #5
0
 def __setup_sub_dict(self):
     server_root = find_server_root()
     try:
         idrange_size = self.idmax - self.idstart + 1
     except TypeError:
         idrange_size = None
     self.sub_dict = dict(
         FQDN=self.fqdn,
         SERVERID=self.serverid,
         PASSWORD=self.dm_password,
         RANDOM_PASSWORD=ipautil.ipa_generate_password(),
         SUFFIX=self.suffix,
         REALM=self.realm,
         USER=DS_USER,
         SERVER_ROOT=server_root,
         DOMAIN=self.domain,
         TIME=int(time.time()),
         IDSTART=self.idstart,
         IDMAX=self.idmax,
         HOST=self.fqdn,
         ESCAPED_SUFFIX=str(self.suffix),
         GROUP=DS_GROUP,
         IDRANGE_SIZE=idrange_size,
         DOMAIN_LEVEL=self.domainlevel,
         MAX_DOMAIN_LEVEL=constants.MAX_DOMAIN_LEVEL,
         MIN_DOMAIN_LEVEL=constants.MIN_DOMAIN_LEVEL,
         STRIP_ATTRS=" ".join(replication.STRIP_ATTRS),
         EXCLUDES='(objectclass=*) $ EXCLUDE ' +
         ' '.join(replication.EXCLUDES),
         TOTAL_EXCLUDES='(objectclass=*) $ EXCLUDE ' +
         ' '.join(replication.TOTAL_EXCLUDES),
     )
Beispiel #6
0
    def check_chain(self, pkcs12_filename, pkcs12_pin, nssdb):
        # create a temp nssdb
        with NSSDatabase() as tempnssdb:
            db_password = ipautil.ipa_generate_password()
            db_pwdfile = ipautil.write_tmp_file(db_password)
            tempnssdb.create_db(db_pwdfile.name)

            # import the PKCS12 file, then delete all CA certificates
            # this leaves only the server certs in the temp db
            tempnssdb.import_pkcs12(
                pkcs12_filename, db_pwdfile.name, pkcs12_pin)
            for nickname, flags in tempnssdb.list_certs():
                if 'u' not in flags:
                    while tempnssdb.has_nickname(nickname):
                        tempnssdb.delete_cert(nickname)

            # import all the CA certs from nssdb into the temp db
            for nickname, flags in nssdb.list_certs():
                if 'u' not in flags:
                    cert = nssdb.get_cert_from_db(nickname)
                    tempnssdb.add_cert(cert, nickname, flags)

            # now get the server certs from tempnssdb and check their validity
            try:
                for nick, flags in tempnssdb.find_server_certs():
                    tempnssdb.verify_server_cert_validity(nick, api.env.host)
            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))
Beispiel #7
0
 def export_key(self):
     tdir = tempfile.mkdtemp(dir=paths.TMP)
     try:
         pk12pwfile = os.path.join(tdir, 'pk12pwfile')
         password = ipautil.ipa_generate_password()
         with open(pk12pwfile, 'w') as f:
             f.write(password)
         pk12file = os.path.join(tdir, 'pk12file')
         nssdb = NSSDatabase(self.nssdb_path)
         nssdb.run_pk12util([
             "-o",
             pk12file,
             "-n",
             self.nickname,
             "-k",
             self.nssdb_pwdfile,
             "-w",
             pk12pwfile,
         ])
         with open(pk12file, 'rb') as f:
             data = f.read()
     finally:
         shutil.rmtree(tdir)
     return json_encode({
         'export password': password,
         'pkcs12 data': b64encode(data).decode('ascii')
     })
    def check_chain(self, pkcs12_filename, pkcs12_pin, nssdb):
        # create a temp nssdb
        with NSSDatabase() as tempnssdb:
            db_password = ipautil.ipa_generate_password()
            db_pwdfile = ipautil.write_tmp_file(db_password)
            tempnssdb.create_db(db_pwdfile.name)

            # import the PKCS12 file, then delete all CA certificates
            # this leaves only the server certs in the temp db
            tempnssdb.import_pkcs12(pkcs12_filename, db_pwdfile.name,
                                    pkcs12_pin)
            for nickname, flags in tempnssdb.list_certs():
                if 'u' not in flags:
                    while tempnssdb.has_nickname(nickname):
                        tempnssdb.delete_cert(nickname)

            # import all the CA certs from nssdb into the temp db
            for nickname, flags in nssdb.list_certs():
                if 'u' not in flags:
                    cert = nssdb.get_cert_from_db(nickname)
                    tempnssdb.add_cert(cert, nickname, flags)

            # now get the server certs from tempnssdb and check their validity
            try:
                for nick, flags in tempnssdb.find_server_certs():
                    tempnssdb.verify_server_cert_validity(nick, api.env.host)
            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))
Beispiel #9
0
def export_key(args, tmpdir):
    """Export key and certificate from the NSS DB to a PKCS#12 file.

    The PKCS#12 file is encrypted with a password.
    """
    pk12file = os.path.join(tmpdir, 'export.p12')

    password = ipautil.ipa_generate_password()
    pk12pk12pwfile = os.path.join(tmpdir, 'passwd')
    with open(pk12pk12pwfile, 'w') as f:
        f.write(password)

    nssdb = NSSDatabase(args.nssdb_path)
    nssdb.run_pk12util([
        "-o",
        pk12file,
        "-n",
        args.nickname,
        "-k",
        args.nssdb_pwdfile,
        "-w",
        pk12pk12pwfile,
    ])

    with open(pk12file, 'rb') as f:
        p12data = f.read()

    data = {
        'export password': password,
        'pkcs12 data': p12data,
    }
    common.json_dump(data, args.exportfile)
Beispiel #10
0
def export_key(args, tmpdir):
    """Export cert and private from PEM files as PKCS#12 file.

    The PKCS#12 file is encrypted with a password.
    """
    pk12file = os.path.join(tmpdir, 'export.p12')

    password = ipautil.ipa_generate_password()
    pk12pwfile = os.path.join(tmpdir, 'passwd')
    with open(pk12pwfile, 'w') as f:
        f.write(password)

    # OpenSSL does not support pkcs12 export of a cert without key
    ipautil.run([
        paths.OPENSSL, 'pkcs12', '-export',
        '-in', args.certfile,
        '-out', pk12file,
        '-inkey', args.keyfile,
        '-password', 'file:{pk12pwfile}'.format(pk12pwfile=pk12pwfile),
    ])

    with open(pk12file, 'rb') as f:
        p12data = f.read()

    data = {
        'export password': password,
        'pkcs12 data': p12data,
    }
    common.json_dump(data, args.exportfile)
Beispiel #11
0
 def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
     assert isinstance(dn, DN)
     if options.get('rename') is not None:
         config = ldap.get_ipa_config()[1]
         if 'ipamaxusernamelength' in config:
             if len(options['rename']) > int(config.get('ipamaxusernamelength')[0]):
                 raise errors.ValidationError(
                     name=self.obj.primary_key.cli_name,
                     error=_('can be at most %(len)d characters') % dict(
                         len = int(config.get('ipamaxusernamelength')[0])
                     )
                 )
     if 'mail' in entry_attrs:
         entry_attrs['mail'] = self.obj._normalize_and_validate_email(entry_attrs['mail'])
     if 'manager' in entry_attrs:
         entry_attrs['manager'] = self.obj._normalize_manager(entry_attrs['manager'])
     validate_nsaccountlock(entry_attrs)
     if 'userpassword' not in entry_attrs and options.get('random'):
         entry_attrs['userpassword'] = ipa_generate_password(user_pwdchars)
         # save the password so it can be displayed in post_callback
         setattr(context, 'randompassword', entry_attrs['userpassword'])
     if 'ipasshpubkey' in entry_attrs:
         if 'objectclass' in entry_attrs:
             obj_classes = entry_attrs['objectclass']
         else:
             (_dn, _entry_attrs) = ldap.get_entry(dn, ['objectclass'])
             obj_classes = entry_attrs['objectclass'] = _entry_attrs['objectclass']
         if 'ipasshuser' not in obj_classes:
             obj_classes.append('ipasshuser')
     return dn
Beispiel #12
0
 def __init__(self,
              subsystem,
              fqdn,
              domain,
              subject_base,
              ca_subject,
              admin_user,
              admin_password,
              dm_password,
              pki_config_override=None):
     self.pki_config_override = pki_config_override
     self.defaults = dict(
         # pretty much static
         ipa_ca_pem_file=paths.IPA_CA_CRT,
         pki_configuration_path=paths.PKI_CONFIGURATION,
         # variable
         ipa_ca_subject=ca_subject,
         ipa_subject_base=subject_base,
         ipa_fqdn=fqdn,
         ipa_ocsp_uri="http://{}.{}/ca/ocsp".format(
             IPA_CA_RECORD, ipautil.format_netloc(domain)),
         ipa_admin_cert_p12=paths.DOGTAG_ADMIN_P12,
         ipa_admin_user=admin_user,
         pki_admin_password=admin_password,
         pki_ds_password=dm_password,
         # Dogtag's pkiparser defines these config vars by default:
         pki_dns_domainname=domain,
         pki_hostname=fqdn,
         pki_subsystem=subsystem.upper(),
         pki_subsystem_type=subsystem.lower(),
         home_dir=os.path.expanduser("~"),
         # for softhsm2 testing
         softhsm2_so=paths.LIBSOFTHSM2_SO,
         # Configure a more secure AJP password by default
         ipa_ajp_secret=ipautil.ipa_generate_password(special=None))
Beispiel #13
0
def load_external_cert(files, subject_base):
    """
    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 subject_base: Subject name base for IPA certificates
    :returns: Temporary file with the IPA CA certificate and temporary file
        with the external CA certificate chain
    """
    with certs.NSSDatabase() as nssdb:
        db_password = ipautil.ipa_generate_password()
        db_pwdfile = ipautil.write_tmp_file(db_password)
        nssdb.create_db(db_pwdfile.name)

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

        ca_subject = DN(('CN', 'Certificate Authority'), subject_base)
        ca_nickname = None
        cache = {}
        for nickname, trust_flags in nssdb.list_certs():
            cert = nssdb.get_cert(nickname, pem=True)

            nss_cert = x509.load_certificate(cert)
            subject = DN(str(nss_cert.subject))
            issuer = DN(str(nss_cert.issuer))
            del nss_cert

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

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

        trust_chain = 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" %
                              (", ".join(files)))

        for nickname in trust_chain:
            try:
                nssdb.verify_ca_cert_validity(nickname)
            except ValueError, e:
                raise ScriptError("CA certificate %s in %s is not valid: %s" %
                                  (subject, ", ".join(files), e))
Beispiel #14
0
 def create_passwd_file(self, passwd=None):
     ipautil.backup_file(self.passwd_fname)
     with open(self.passwd_fname, "w") as f:
         self.set_perms(f)
         if passwd is not None:
             f.write("%s\n" % passwd)
         else:
             f.write(ipautil.ipa_generate_password())
Beispiel #15
0
 def create_passwd_file(self, passwd=None):
     ipautil.backup_file(self.passwd_fname)
     with open(self.passwd_fname, "w") as f:
         self.set_perms(f)
         if passwd is not None:
             f.write("%s\n" % passwd)
         else:
             f.write(ipautil.ipa_generate_password())
Beispiel #16
0
    def secure_ajp_connector(self):
        """ Update AJP connector to use a password protection  """

        server_xml = lxml.etree.parse(paths.PKI_TOMCAT_SERVER_XML)
        doc = server_xml.getroot()

        # no AJP connector means no need to update anything
        connectors = doc.xpath('//Connector[@protocol="AJP/1.3"]')
        if len(connectors) == 0:
            return

        # AJP protocol is at version 1.3. Assume there is only one as
        # Dogtag only provisions one.
        connector = connectors[0]

        # Detect tomcat version and choose the right option name
        # pre-9.0.31.0 uses 'requiredSecret'
        # 9.0.31.0 or later uses 'secret'
        secretattr = 'requiredSecret'
        oldattr = 'requiredSecret'
        if self.__is_newer_tomcat_version('9.0.31.0'):
            secretattr = 'secret'

        rewrite = True
        if secretattr in connector.attrib:
            # secret is already in place
            # Perhaps, we need to synchronize it with Apache configuration
            self.ajp_secret = connector.attrib[secretattr]
            rewrite = False
        else:
            if oldattr in connector.attrib:
                # Sufficiently new Dogtag versions (10.9.0-a2) handle the
                # upgrade for us; we need only to ensure that we're not both
                # attempting to upgrade server.xml at the same time.
                # Hopefully this is guaranteed for us.
                self.ajp_secret = connector.attrib[oldattr]
                connector.attrib[secretattr] = self.ajp_secret
                del connector.attrib[oldattr]
            else:
                # Generate password, don't use special chars to not break XML.
                #
                # If we hit this case, pkispawn was run on an older Dogtag
                # version and we're stuck migrating, choosing a password
                # ourselves. Dogtag can't generate one randomly because a
                # Dogtag administrator might've configured AJP and might
                # not be using IPA.
                #
                # Newer Dogtag versions will generate a random password
                # during pkispawn.
                self.ajp_secret = ipautil.ipa_generate_password(special=None)
                connector.attrib[secretattr] = self.ajp_secret

        if rewrite:
            pent = pwd.getpwnam(constants.PKI_USER)
            with open(paths.PKI_TOMCAT_SERVER_XML, "wb") as fd:
                server_xml.write(fd, pretty_print=True, encoding="utf-8")
                os.fchmod(fd.fileno(), 0o660)
                os.fchown(fd.fileno(), pent.pw_uid, pent.pw_gid)
Beispiel #17
0
    def create_db(self, user=None, group=None, mode=None, backup=False):
        """Create cert DB

        :param user: User owner the secdir
        :param group: Group owner of the secdir
        :param mode: Mode of the secdir
        :param backup: Backup the sedir files
        """
        dirmode = 0o750
        filemode = 0o640
        pwdfilemode = 0o640
        if mode is not None:
            dirmode = mode
            filemode = mode & 0o666
            pwdfilemode = mode & 0o660

        uid = -1
        gid = -1
        if user is not None:
            uid = pwd.getpwnam(user).pw_uid
        if group is not None:
            gid = grp.getgrnam(group).gr_gid

        if backup:
            for filename in NSS_FILES:
                path = os.path.join(self.secdir, filename)
                ipautil.backup_file(path)

        if not os.path.exists(self.secdir):
            os.makedirs(self.secdir, dirmode)

        if not os.path.exists(self.pwd_file):
            # Create the password file for this db
            with io.open(os.open(self.pwd_file, os.O_CREAT | os.O_WRONLY,
                                 pwdfilemode),
                         'w',
                         closefd=True) as f:
                f.write(ipautil.ipa_generate_password())
                f.flush()

        self.run_certutil(["-N", "-f", self.pwd_file])

        # Finally fix up perms
        os.chown(self.secdir, uid, gid)
        os.chmod(self.secdir, dirmode)
        tasks.restore_context(self.secdir)
        for filename in NSS_FILES:
            path = os.path.join(self.secdir, filename)
            if os.path.exists(path):
                if uid != -1 or gid != -1:
                    os.chown(path, uid, gid)
                if path == self.pwd_file:
                    new_mode = pwdfilemode
                else:
                    new_mode = filemode
                os.chmod(path, new_mode)
                tasks.restore_context(path)
Beispiel #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 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")
Beispiel #19
0
    def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys,
                     **options):
        assert isinstance(dn, DN)
        if options.get('rename') is not None:
            config = ldap.get_ipa_config()
            if 'ipamaxusernamelength' in config:
                if len(options['rename']) > int(
                        config.get('ipamaxusernamelength')[0]):
                    raise errors.ValidationError(
                        name=self.obj.primary_key.cli_name,
                        error=_('can be at most %(len)d characters') %
                        dict(len=int(config.get('ipamaxusernamelength')[0])))
        if 'mail' in entry_attrs:
            entry_attrs['mail'] = self.obj.normalize_and_validate_email(
                entry_attrs['mail'])
        if 'manager' in entry_attrs:
            entry_attrs['manager'] = self.obj.normalize_manager(
                entry_attrs['manager'], self.obj.active_container_dn)
        validate_nsaccountlock(entry_attrs)
        if 'userpassword' not in entry_attrs and options.get('random'):
            entry_attrs['userpassword'] = ipa_generate_password(
                baseuser_pwdchars)
            # save the password so it can be displayed in post_callback
            setattr(context, 'randompassword', entry_attrs['userpassword'])
        if ('ipasshpubkey' in entry_attrs or 'ipauserauthtype' in entry_attrs
                or 'userclass' in entry_attrs
                or 'ipatokenradiusconfiglink' in entry_attrs):
            if 'objectclass' in entry_attrs:
                obj_classes = entry_attrs['objectclass']
            else:
                _entry_attrs = ldap.get_entry(dn, ['objectclass'])
                obj_classes = entry_attrs['objectclass'] = _entry_attrs[
                    'objectclass']

            if 'ipasshpubkey' in entry_attrs and 'ipasshuser' not in obj_classes:
                obj_classes.append('ipasshuser')

            if 'ipauserauthtype' in entry_attrs and 'ipauserauthtypeclass' not in obj_classes:
                obj_classes.append('ipauserauthtypeclass')

            if 'userclass' in entry_attrs and 'ipauser' not in obj_classes:
                obj_classes.append('ipauser')

            if 'ipatokenradiusconfiglink' in entry_attrs:
                cl = entry_attrs['ipatokenradiusconfiglink']
                if cl:
                    if 'ipatokenradiusproxyuser' not in obj_classes:
                        obj_classes.append('ipatokenradiusproxyuser')

                    answer = self.api.Object['radiusproxy'].get_dn_if_exists(
                        cl)
                    entry_attrs['ipatokenradiusconfiglink'] = answer

        return dn
Beispiel #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 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")
Beispiel #21
0
    def create_db(self, user=None, group=None, mode=None, backup=False):
        """Create cert DB

        :param user: User owner the secdir
        :param group: Group owner of the secdir
        :param mode: Mode of the secdir
        :param backup: Backup the sedir files
        """
        dirmode = 0o750
        filemode = 0o640
        pwdfilemode = 0o640
        if mode is not None:
            dirmode = mode
            filemode = mode & 0o666
            pwdfilemode = mode & 0o660

        uid = -1
        gid = -1
        if user is not None:
            uid = pwd.getpwnam(user).pw_uid
        if group is not None:
            gid = grp.getgrnam(group).gr_gid

        if backup:
            for filename in NSS_FILES:
                path = os.path.join(self.secdir, filename)
                ipautil.backup_file(path)

        if not os.path.exists(self.secdir):
            os.makedirs(self.secdir, dirmode)

        if not os.path.exists(self.pwd_file):
            # Create the password file for this db
            with io.open(os.open(self.pwd_file,
                                 os.O_CREAT | os.O_WRONLY,
                                 pwdfilemode), 'w', closefd=True) as f:
                f.write(ipautil.ipa_generate_password())
                f.flush()

        self.run_certutil(["-N", "-f", self.pwd_file])

        # Finally fix up perms
        os.chown(self.secdir, uid, gid)
        os.chmod(self.secdir, dirmode)
        for filename in NSS_FILES:
            path = os.path.join(self.secdir, filename)
            if os.path.exists(path):
                os.chown(path, uid, gid)
                if path == self.pwd_file:
                    new_mode = pwdfilemode
                else:
                    new_mode = filemode
                os.chmod(path, new_mode)
Beispiel #22
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()
Beispiel #23
0
    def setup_admin(self):
        self.admin_user = "******" % self.fqdn
        self.admin_password = ipautil.ipa_generate_password()
        self.admin_dn = _person_dn(self.admin_user)

        result = self.create_user(
            uid=self.admin_user,
            cn=self.admin_user,
            sn=self.admin_user,
            user_type='adminType',
            groups=self.admin_groups,
            force=True,
        )
        if result is None:
            return None  # something went wrong
        else:
            self.admin_password = result

        # Now wait until the other server gets replicated this data
        master_conn = ipaldap.LDAPClient.from_hostname_secure(self.master_host)
        logger.debug("Waiting %s seconds for %s to appear on %s",
                     api.env.replication_wait_timeout, self.admin_dn,
                     master_conn)
        deadline = time.time() + api.env.replication_wait_timeout
        while time.time() < deadline:
            time.sleep(1)
            try:
                master_conn.simple_bind(self.admin_dn, self.admin_password)
            except errors.ACIError:
                # user not replicated yet
                pass
            else:
                logger.debug("Successfully logged in as %s", self.admin_dn)
                break
        else:
            logger.error("Unable to log in as %s on %s", self.admin_dn,
                         master_conn)
            logger.info("[hint] tune with replication_wait_timeout")
            raise errors.NotFound(reason="{} did not replicate to {}".format(
                self.admin_dn, master_conn))

        # wait for group membership
        for group_dn in (_group_dn(group) for group in self.admin_groups):
            replication.wait_for_entry(
                master_conn,
                group_dn,
                timeout=api.env.replication_wait_timeout,
                attr='uniqueMember',
                attrvalue=self.admin_dn)
Beispiel #24
0
 def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
     assert isinstance(dn, DN)
     if options.get('ip_address') and dns_container_exists(ldap):
         parts = keys[-1].split('.')
         host = parts[0]
         domain = unicode('.'.join(parts[1:]))
         check_reverse = not options.get('no_reverse', False)
         add_records_for_host_validation('ip_address',
                 DNSName(host),
                 DNSName(domain).make_absolute(),
                 options['ip_address'],
                 check_forward=True,
                 check_reverse=check_reverse)
     if not options.get('force', False) and not 'ip_address' in options:
         util.validate_host_dns(self.log, keys[-1])
     if 'locality' in entry_attrs:
         entry_attrs['l'] = entry_attrs['locality']
     entry_attrs['cn'] = keys[-1]
     entry_attrs['serverhostname'] = keys[-1].split('.', 1)[0]
     if not entry_attrs.get('userpassword', False) and not options.get('random', False):
         entry_attrs['krbprincipalname'] = 'host/%s@%s' % (
             keys[-1], self.api.env.realm
         )
         if 'krbprincipalaux' not in entry_attrs['objectclass']:
             entry_attrs['objectclass'].append('krbprincipalaux')
         if 'krbprincipal' not in entry_attrs['objectclass']:
             entry_attrs['objectclass'].append('krbprincipal')
     else:
         if 'krbprincipalaux' in entry_attrs['objectclass']:
             entry_attrs['objectclass'].remove('krbprincipalaux')
         if 'krbprincipal' in entry_attrs['objectclass']:
             entry_attrs['objectclass'].remove('krbprincipal')
     if options.get('random'):
         entry_attrs['userpassword'] = ipa_generate_password(characters=host_pwd_chars)
         # save the password so it can be displayed in post_callback
         setattr(context, 'randompassword', entry_attrs['userpassword'])
     certs = options.get('usercertificate', [])
     certs_der = map(x509.normalize_certificate, certs)
     for cert in certs_der:
         x509.verify_cert_subject(ldap, keys[-1], cert)
     entry_attrs['usercertificate'] = certs_der
     entry_attrs['managedby'] = dn
     entry_attrs['objectclass'].append('ieee802device')
     entry_attrs['objectclass'].append('ipasshhost')
     update_krbticketflags(ldap, entry_attrs, attrs_list, options, False)
     if 'krbticketflags' in entry_attrs:
         entry_attrs['objectclass'].append('krbticketpolicyaux')
     return dn
Beispiel #25
0
 def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
     assert isinstance(dn, DN)
     if options.get('ip_address') and dns_container_exists(ldap):
         parts = keys[-1].split('.')
         host = parts[0]
         domain = unicode('.'.join(parts[1:]))
         check_reverse = not options.get('no_reverse', False)
         add_records_for_host_validation('ip_address',
                 DNSName(host),
                 DNSName(domain).make_absolute(),
                 options['ip_address'],
                 check_forward=True,
                 check_reverse=check_reverse)
     if not options.get('force', False) and not 'ip_address' in options:
         util.verify_host_resolvable(keys[-1], self.log)
     if 'locality' in entry_attrs:
         entry_attrs['l'] = entry_attrs['locality']
     entry_attrs['cn'] = keys[-1]
     entry_attrs['serverhostname'] = keys[-1].split('.', 1)[0]
     if not entry_attrs.get('userpassword', False) and not options.get('random', False):
         entry_attrs['krbprincipalname'] = 'host/%s@%s' % (
             keys[-1], self.api.env.realm
         )
         if 'krbprincipalaux' not in entry_attrs['objectclass']:
             entry_attrs['objectclass'].append('krbprincipalaux')
         if 'krbprincipal' not in entry_attrs['objectclass']:
             entry_attrs['objectclass'].append('krbprincipal')
     else:
         if 'krbprincipalaux' in entry_attrs['objectclass']:
             entry_attrs['objectclass'].remove('krbprincipalaux')
         if 'krbprincipal' in entry_attrs['objectclass']:
             entry_attrs['objectclass'].remove('krbprincipal')
     if options.get('random'):
         entry_attrs['userpassword'] = ipa_generate_password(characters=host_pwd_chars)
         # save the password so it can be displayed in post_callback
         setattr(context, 'randompassword', entry_attrs['userpassword'])
     certs = options.get('usercertificate', [])
     certs_der = [x509.normalize_certificate(c) for c in certs]
     for cert in certs_der:
         x509.verify_cert_subject(ldap, keys[-1], cert)
     entry_attrs['usercertificate'] = certs_der
     entry_attrs['managedby'] = dn
     entry_attrs['objectclass'].append('ieee802device')
     entry_attrs['objectclass'].append('ipasshhost')
     update_krbticketflags(ldap, entry_attrs, attrs_list, options, False)
     if 'krbticketflags' in entry_attrs:
         entry_attrs['objectclass'].append('krbticketpolicyaux')
     return dn
Beispiel #26
0
    def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
        assert isinstance(dn, DN)
        if options.get('rename') is not None:
            config = ldap.get_ipa_config()[1]
            if 'ipamaxusernamelength' in config:
                if len(options['rename']) > int(config.get('ipamaxusernamelength')[0]):
                    raise errors.ValidationError(
                        name=self.obj.primary_key.cli_name,
                        error=_('can be at most %(len)d characters') % dict(
                            len = int(config.get('ipamaxusernamelength')[0])
                        )
                    )
        if 'mail' in entry_attrs:
            entry_attrs['mail'] = self.obj._normalize_and_validate_email(entry_attrs['mail'])
        if 'manager' in entry_attrs:
            entry_attrs['manager'] = self.obj._normalize_manager(entry_attrs['manager'])
        validate_nsaccountlock(entry_attrs)
        if 'userpassword' not in entry_attrs and options.get('random'):
            entry_attrs['userpassword'] = ipa_generate_password(user_pwdchars)
            # save the password so it can be displayed in post_callback
            setattr(context, 'randompassword', entry_attrs['userpassword'])
        if ('ipasshpubkey' in entry_attrs or 'ipauserauthtype' in entry_attrs
            or 'userclass' in entry_attrs or 'ipatokenradiusconfiglink' in entry_attrs):
            if 'objectclass' in entry_attrs:
                obj_classes = entry_attrs['objectclass']
            else:
                _entry_attrs = ldap.get_entry(dn, ['objectclass'])
                obj_classes = entry_attrs['objectclass'] = _entry_attrs['objectclass']

            if 'ipasshpubkey' in entry_attrs and 'ipasshuser' not in obj_classes:
                obj_classes.append('ipasshuser')

            if 'ipauserauthtype' in entry_attrs and 'ipauserauthtypeclass' not in obj_classes:
                obj_classes.append('ipauserauthtypeclass')

            if 'userclass' in entry_attrs and 'ipauser' not in obj_classes:
                obj_classes.append('ipauser')

            if 'ipatokenradiusconfiglink' in entry_attrs:
                cl = entry_attrs['ipatokenradiusconfiglink']
                if cl:
                    if 'ipatokenradiusproxyuser' not in obj_classes:
                        obj_classes.append('ipatokenradiusproxyuser')

                    answer = self.api.Object['radiusproxy'].get_dn_if_exists(cl)
                    entry_attrs['ipatokenradiusconfiglink'] = answer

        return dn
Beispiel #27
0
def create_ipa_nssdb():
    db = NSSDatabase(paths.IPA_NSSDB_DIR)
    pwdfile = os.path.join(db.secdir, 'pwdfile.txt')

    ipautil.backup_file(pwdfile)
    ipautil.backup_file(os.path.join(db.secdir, 'cert8.db'))
    ipautil.backup_file(os.path.join(db.secdir, 'key3.db'))
    ipautil.backup_file(os.path.join(db.secdir, 'secmod.db'))

    with open(pwdfile, 'w') as f:
        f.write(ipautil.ipa_generate_password(pwd_len=40))
    os.chmod(pwdfile, 0o600)

    db.create_db(pwdfile)
    os.chmod(os.path.join(db.secdir, 'cert8.db'), 0o644)
    os.chmod(os.path.join(db.secdir, 'key3.db'), 0o644)
    os.chmod(os.path.join(db.secdir, 'secmod.db'), 0o644)
Beispiel #28
0
def create_ipa_nssdb():
    db = NSSDatabase(paths.IPA_NSSDB_DIR)
    pwdfile = os.path.join(db.secdir, 'pwdfile.txt')

    ipautil.backup_file(pwdfile)
    ipautil.backup_file(os.path.join(db.secdir, 'cert8.db'))
    ipautil.backup_file(os.path.join(db.secdir, 'key3.db'))
    ipautil.backup_file(os.path.join(db.secdir, 'secmod.db'))

    with open(pwdfile, 'w') as f:
        f.write(ipautil.ipa_generate_password(pwd_len=40))
    os.chmod(pwdfile, 0o600)

    db.create_db(pwdfile)
    os.chmod(os.path.join(db.secdir, 'cert8.db'), 0o644)
    os.chmod(os.path.join(db.secdir, 'key3.db'), 0o644)
    os.chmod(os.path.join(db.secdir, 'secmod.db'), 0o644)
Beispiel #29
0
    def secure_ajp_connector(self):
        """ Update AJP connector to use a password protection  """

        server_xml = lxml.etree.parse(paths.PKI_TOMCAT_SERVER_XML)
        doc = server_xml.getroot()

        # no AJP connector means no need to update anything
        connectors = doc.xpath('//Connector[@port="8009"]')
        if len(connectors) == 0:
            return

        # AJP connector is set on port 8009. Use non-greedy search to find it
        connector = connectors[0]

        # Detect tomcat version and choose the right option name
        # pre-9.0.31.0 uses 'requiredSecret'
        # 9.0.31.0 or later uses 'secret'
        secretattr = 'requiredSecret'
        oldattr = 'requiredSecret'
        if self.__is_newer_tomcat_version('9.0.31.0'):
            secretattr = 'secret'

        rewrite = True
        if secretattr in connector.attrib:
            # secret is already in place
            # Perhaps, we need to synchronize it with Apache configuration
            self.ajp_secret = connector.attrib[secretattr]
            rewrite = False
        else:
            if oldattr in connector.attrib:
                self.ajp_secret = connector.attrib[oldattr]
                connector.attrib[secretattr] = self.ajp_secret
                del connector.attrib[oldattr]
            else:
                # Generate password, don't use special chars to not break XML
                self.ajp_secret = ipautil.ipa_generate_password(special=None)
                connector.attrib[secretattr] = self.ajp_secret

        if rewrite:
            pent = pwd.getpwnam(constants.PKI_USER)
            with open(paths.PKI_TOMCAT_SERVER_XML, "wb") as fd:
                server_xml.write(fd, pretty_print=True, encoding="utf-8")
                os.fchmod(fd.fileno(), 0o660)
                os.fchown(fd.fileno(), pent.pw_uid, pent.pw_gid)
Beispiel #30
0
    def __common_setup(self, realm_name, host_name, domain_name, admin_password):
        self.fqdn = host_name
        self.realm = realm_name.upper()
        self.host = host_name.split(".")[0]
        self.ip = socket.getaddrinfo(host_name, None, socket.AF_UNSPEC, socket.SOCK_STREAM)[0][4][0]
        self.domain = domain_name
        self.suffix = ipautil.realm_to_suffix(self.realm)
        self.kdc_password = ipautil.ipa_generate_password()
        self.admin_password = admin_password
        self.dm_password = admin_password

        self.__setup_sub_dict()

        self.backup_state("running", self.is_running())
        try:
            self.stop()
        except Exception:
            # It could have been not running
            pass
Beispiel #31
0
def install_check(api, replica_config, options):
    if replica_config is not None and not replica_config.setup_kra:
        return

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

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

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

        if options.promote:
            return

        with certdb.NSSDatabase() as tmpdb:
            pw = ipautil.write_tmp_file(ipautil.ipa_generate_password())
            tmpdb.create_db(pw.name)
            tmpdb.import_pkcs12(replica_config.dir + "/cacert.p12", pw.name,
                                replica_config.dirman_password)
            kra_cert_nicknames = [
                "storageCert cert-pki-kra", "transportCert cert-pki-kra",
                "auditSigningCert cert-pki-kra"
            ]
            if not all(
                    tmpdb.has_nickname(nickname)
                    for nickname in kra_cert_nicknames):
                raise RuntimeError("Missing KRA certificates, please create a "
                                   "new replica file.")
Beispiel #32
0
    def __common_setup(self, realm_name, host_name, domain_name, admin_password):
        self.fqdn = host_name
        self.realm = realm_name.upper()
        self.host = host_name.split(".")[0]
        self.ip = socket.getaddrinfo(host_name, None, socket.AF_UNSPEC, socket.SOCK_STREAM)[0][4][0]
        self.domain = domain_name
        self.suffix = ipautil.realm_to_suffix(self.realm)
        self.kdc_password = ipautil.ipa_generate_password()
        self.admin_password = admin_password
        self.dm_password = admin_password

        self.__setup_sub_dict()

        self.backup_state("running", self.is_running())
        try:
            self.stop()
        except Exception:
            # It could have been not running
            pass
Beispiel #33
0
def install_check(api, replica_config, options):
    if replica_config is not None and not replica_config.setup_kra:
        return

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

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

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

        if options.promote:
            return

        with certdb.NSSDatabase() as tmpdb:
            pw = ipautil.write_tmp_file(ipautil.ipa_generate_password())
            tmpdb.create_db(pw.name)
            tmpdb.import_pkcs12(replica_config.dir + "/cacert.p12", pw.name,
                                replica_config.dirman_password)
            kra_cert_nicknames = [
                "storageCert cert-pki-kra", "transportCert cert-pki-kra",
                "auditSigningCert cert-pki-kra"
            ]
            if not all(tmpdb.has_nickname(nickname)
                       for nickname in kra_cert_nicknames):
                raise RuntimeError("Missing KRA certificates, please create a "
                                   "new replica file.")
Beispiel #34
0
    def export_key(self):
        _fd, tmpfile = tempfile.mkstemp(dir=paths.TMP)
        password = ipautil.ipa_generate_password()
        args = [
            paths.OPENSSL, "pkcs12", "-export", "-in", self.certfile, "-out",
            tmpfile, "-password", "pass:{pwd}".format(pwd=password)
        ]
        if self.keyfile is not None:
            args.extend(["-inkey", self.keyfile])

        try:
            ipautil.run(args, nolog=(password, ))
            with open(tmpfile, 'rb') as f:
                data = f.read()
        finally:
            os.remove(tmpfile)
        return json_encode({
            'export password': password,
            'pkcs12 data': b64encode(data).decode('ascii')
        })
Beispiel #35
0
 def export_key(self):
     tdir = tempfile.mkdtemp(dir=paths.TMP)
     try:
         pk12pwfile = os.path.join(tdir, 'pk12pwfile')
         password = ipautil.ipa_generate_password()
         with open(pk12pwfile, 'w') as f:
             f.write(password)
         pk12file = os.path.join(tdir, 'pk12file')
         nssdb = NSSDatabase(self.nssdb_path)
         nssdb.run_pk12util([
             "-o", pk12file,
             "-n", self.nickname,
             "-k", self.nssdb_pwdfile,
             "-w", pk12pwfile,
         ])
         with open(pk12file, 'rb') as f:
             data = f.read()
     finally:
         shutil.rmtree(tdir)
     return json_encode({'export password': password,
                         'pkcs12 data': b64encode(data).decode('ascii')})
Beispiel #36
0
    def export_key(self):
        _fd, tmpfile = tempfile.mkstemp(dir=paths.TMP)
        password = ipautil.ipa_generate_password()
        args = [
            paths.OPENSSL,
            "pkcs12", "-export",
            "-in", self.certfile,
            "-out", tmpfile,
            "-password", "pass:{pwd}".format(pwd=password)
        ]
        if self.keyfile is not None:
            args.extend(["-inkey", self.keyfile])

        try:
            ipautil.run(args, nolog=(password, ))
            with open(tmpfile, 'r') as f:
                data = f.read()
        finally:
            os.remove(tmpfile)
        return json_encode({'export password': password,
                            'pkcs12 data': b64encode(data)})
Beispiel #37
0
 def export_key(self):
     tdir = tempfile.mkdtemp(dir=paths.TMP)
     try:
         nsspwfile = os.path.join(tdir, 'nsspwfile')
         with open(nsspwfile, 'w+') as f:
             f.write(self.nssdb_password)
         pk12pwfile = os.path.join(tdir, 'pk12pwfile')
         password = ipautil.ipa_generate_password()
         with open(pk12pwfile, 'w+') as f:
             f.write(password)
         pk12file = os.path.join(tdir, 'pk12file')
         ipautil.run([
             paths.PK12UTIL, "-d", self.nssdb_path, "-o", pk12file, "-n",
             self.nickname, "-k", nsspwfile, "-w", pk12pwfile
         ])
         with open(pk12file, 'r') as f:
             data = f.read()
     finally:
         shutil.rmtree(tdir)
     return json_encode({
         'export password': password,
         'pkcs12 data': b64encode(data)
     })
Beispiel #38
0
 def export_key(self):
     tdir = tempfile.mkdtemp(dir=paths.TMP)
     try:
         nsspwfile = os.path.join(tdir, 'nsspwfile')
         with open(nsspwfile, 'w+') as f:
             f.write(self.nssdb_password)
         pk12pwfile = os.path.join(tdir, 'pk12pwfile')
         password = ipautil.ipa_generate_password()
         with open(pk12pwfile, 'w+') as f:
             f.write(password)
         pk12file = os.path.join(tdir, 'pk12file')
         ipautil.run([paths.PK12UTIL,
                      "-d", self.nssdb_path,
                      "-o", pk12file,
                      "-n", self.nickname,
                      "-k", nsspwfile,
                      "-w", pk12pwfile])
         with open(pk12file, 'r') as f:
             data = f.read()
     finally:
         shutil.rmtree(tdir)
     return json_encode({'export password': password,
                         'pkcs12 data': b64encode(data)})
Beispiel #39
0
    def setup_admin(self):
        self.admin_user = "******" % self.fqdn
        self.admin_password = ipautil.ipa_generate_password()
        self.admin_dn = DN(('uid', self.admin_user), ('ou', 'people'),
                           ('o', 'ipaca'))

        # remove user if left-over exists
        try:
            entry = api.Backend.ldap2.delete_entry(self.admin_dn)
        except errors.NotFound:
            pass

        # add user
        entry = api.Backend.ldap2.make_entry(
            self.admin_dn,
            objectclass=[
                "top", "person", "organizationalPerson", "inetOrgPerson",
                "cmsuser"
            ],
            uid=[self.admin_user],
            cn=[self.admin_user],
            sn=[self.admin_user],
            usertype=['adminType'],
            mail=['root@localhost'],
            userPassword=[self.admin_password],
            userstate=['1'])
        api.Backend.ldap2.add_entry(entry)

        for group in self.admin_groups:
            self.__add_admin_to_group(group)

        # Now wait until the other server gets replicated this data
        ldap_uri = ipaldap.get_ldap_uri(self.master_host)
        master_conn = ipaldap.LDAPClient(ldap_uri)
        master_conn.gssapi_bind()
        replication.wait_for_entry(master_conn, entry.dn)
        del master_conn
Beispiel #40
0
    def setup_admin(self):
        self.admin_user = "******" % self.fqdn
        self.admin_password = ipautil.ipa_generate_password()
        self.admin_dn = DN(('uid', self.admin_user),
                           ('ou', 'people'), ('o', 'ipaca'))

        # remove user if left-over exists
        try:
            entry = api.Backend.ldap2.delete_entry(self.admin_dn)
        except errors.NotFound:
            pass

        # add user
        entry = api.Backend.ldap2.make_entry(
            self.admin_dn,
            objectclass=["top", "person", "organizationalPerson",
                         "inetOrgPerson", "cmsuser"],
            uid=[self.admin_user],
            cn=[self.admin_user],
            sn=[self.admin_user],
            usertype=['adminType'],
            mail=['root@localhost'],
            userPassword=[self.admin_password],
            userstate=['1']
        )
        api.Backend.ldap2.add_entry(entry)

        for group in self.admin_groups:
            self.__add_admin_to_group(group)

        # Now wait until the other server gets replicated this data
        ldap_uri = ipaldap.get_ldap_uri(self.master_host)
        master_conn = ipaldap.LDAPClient(ldap_uri)
        master_conn.gssapi_bind()
        replication.wait_for_entry(master_conn, entry.dn)
        del master_conn
Beispiel #41
0
def install_check(installer):
    options = installer
    dirsrv_pkcs12_file = installer._dirsrv_pkcs12_file
    http_pkcs12_file = installer._http_pkcs12_file
    pkinit_pkcs12_file = installer._pkinit_pkcs12_file
    dirsrv_pkcs12_info = installer._dirsrv_pkcs12_info
    http_pkcs12_info = installer._http_pkcs12_info
    pkinit_pkcs12_info = installer._pkinit_pkcs12_info
    external_cert_file = installer._external_cert_file
    external_ca_file = installer._external_ca_file
    http_ca_cert = installer._ca_cert

    tasks.check_ipv6_stack_enabled()
    tasks.check_selinux_status()

    if options.master_password:
        msg = ("WARNING:\noption '-P/--master-password' is deprecated. "
               "KDC master password of sufficient strength is autogenerated "
               "during IPA server installation and should not be set "
               "manually.")
        print(textwrap.fill(msg, width=79, replace_whitespace=False))

    installer._installation_cleanup = True

    print("\nThe log file for this installation can be found in "
          "/var/log/ipaserver-install.log")
    if (not options.external_ca and not options.external_cert_files
            and is_ipa_configured()):
        installer._installation_cleanup = False
        raise ScriptError(
            "IPA server is already configured on this system.\n"
            "If you want to reinstall the IPA server, please uninstall "
            "it first using 'ipa-server-install --uninstall'.")

    client_fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE)
    if client_fstore.has_files():
        installer._installation_cleanup = False
        raise ScriptError(
            "IPA client is already configured on this system.\n"
            "Please uninstall it before configuring the IPA server, "
            "using 'ipa-client-install --uninstall'")

    fstore = sysrestore.FileStore(SYSRESTORE_DIR_PATH)
    sstore = sysrestore.StateFile(SYSRESTORE_DIR_PATH)

    # This will override any settings passed in on the cmdline
    if ipautil.file_exists(paths.ROOT_IPA_CACHE):
        if options.dm_password is not None:
            dm_password = options.dm_password
        else:
            dm_password = read_password("Directory Manager", confirm=False)
        if dm_password is None:
            raise ScriptError("Directory Manager password required")
        try:
            cache_vars = read_cache(dm_password)
            options.__dict__.update(cache_vars)
            if cache_vars.get('external_ca', False):
                options.external_ca = False
                options.interactive = False
        except Exception as e:
            raise ScriptError("Cannot process the cache file: %s" % str(e))

    # We only set up the CA if the PKCS#12 options are not given.
    if options.dirsrv_cert_files:
        setup_ca = False
    else:
        setup_ca = True
    options.setup_ca = setup_ca

    if not setup_ca and options.ca_subject:
        raise ScriptError(
            "--ca-subject cannot be used with CA-less installation")
    if not setup_ca and options.subject_base:
        raise ScriptError(
            "--subject-base cannot be used with CA-less installation")
    if not setup_ca and options.setup_kra:
        raise ScriptError(
            "--setup-kra cannot be used with CA-less installation")

    print("======================================="
          "=======================================")
    print("This program will set up the FreeIPA Server.")
    print("")
    print("This includes:")
    if setup_ca:
        print("  * Configure a stand-alone CA (dogtag) for certificate "
              "management")
    if not options.no_ntp:
        print("  * Configure the Network Time Daemon (ntpd)")
    print("  * Create and configure an instance of Directory Server")
    print("  * Create and configure a Kerberos Key Distribution Center (KDC)")
    print("  * Configure Apache (httpd)")
    if options.setup_kra:
        print("  * Configure KRA (dogtag) for secret management")
    if options.setup_dns:
        print("  * Configure DNS (bind)")
    if options.setup_adtrust:
        print("  * Configure Samba (smb) and winbind for managing AD trusts")
    if not options.no_pkinit:
        print("  * Configure the KDC to enable PKINIT")
    if options.no_ntp:
        print("")
        print("Excluded by options:")
        print("  * Configure the Network Time Daemon (ntpd)")
    if installer.interactive:
        print("")
        print("To accept the default shown in brackets, press the Enter key.")
    print("")

    if not options.external_cert_files:
        # Make sure the 389-ds ports are available
        check_dirsrv(not installer.interactive)

    if not options.no_ntp:
        try:
            ipaclient.install.ntpconf.check_timedate_services()
        except ipaclient.install.ntpconf.NTPConflictingService as e:
            print(
                ("WARNING: conflicting time&date synchronization service '%s'"
                 " will be disabled" % e.conflicting_service))
            print("in favor of ntpd")
            print("")
        except ipaclient.install.ntpconf.NTPConfigurationError:
            pass

    # Check to see if httpd is already configured to listen on 443
    if httpinstance.httpd_443_configured():
        raise ScriptError("Aborting installation")

    if not options.setup_dns and installer.interactive:
        if ipautil.user_input(
                "Do you want to configure integrated DNS "
                "(BIND)?", False):
            options.setup_dns = True
        print("")

    # check bind packages are installed
    if options.setup_dns:
        # Don't require an external DNS to say who we are if we are
        # setting up a local DNS server.
        options.no_host_dns = True

    # check the hostname is correctly configured, it must be as the kldap
    # utilities just use the hostname as returned by getaddrinfo to set
    # up some of the standard entries

    if options.host_name:
        host_default = options.host_name
    else:
        host_default = get_fqdn()

    try:
        if not installer.interactive or options.host_name:
            verify_fqdn(host_default, options.no_host_dns)
            host_name = host_default
        else:
            host_name = read_host_name(host_default, options.no_host_dns)
    except BadHostError as e:
        raise ScriptError(e)

    host_name = host_name.lower()
    root_logger.debug("will use host_name: %s\n" % host_name)

    if not options.domain_name:
        domain_name = read_domain_name(host_name[host_name.find(".") + 1:],
                                       not installer.interactive)
        root_logger.debug("read domain_name: %s\n" % domain_name)
        try:
            validate_domain_name(domain_name)
        except ValueError as e:
            raise ScriptError("Invalid domain name: %s" % unicode(e))
    else:
        domain_name = options.domain_name

    domain_name = domain_name.lower()

    if not options.realm_name:
        realm_name = read_realm_name(domain_name, not installer.interactive)
        root_logger.debug("read realm_name: %s\n" % realm_name)
    else:
        realm_name = options.realm_name.upper()

    if not options.subject_base:
        options.subject_base = installutils.default_subject_base(realm_name)

    if not options.ca_subject:
        options.ca_subject = \
            installutils.default_ca_subject_dn(options.subject_base)

    if options.http_cert_files:
        if options.http_pin is None:
            options.http_pin = installutils.read_password(
                "Enter Apache Server private key unlock",
                confirm=False,
                validate=False,
                retry=False)
            if options.http_pin is None:
                raise ScriptError(
                    "Apache Server private key unlock password required")
        http_pkcs12_file, http_pin, http_ca_cert = load_pkcs12(
            cert_files=options.http_cert_files,
            key_password=options.http_pin,
            key_nickname=options.http_cert_name,
            ca_cert_files=options.ca_cert_files,
            host_name=host_name)
        http_pkcs12_info = (http_pkcs12_file.name, http_pin)

    if options.dirsrv_cert_files:
        if options.dirsrv_pin is None:
            options.dirsrv_pin = read_password(
                "Enter Directory Server private key unlock",
                confirm=False,
                validate=False,
                retry=False)
            if options.dirsrv_pin is None:
                raise ScriptError(
                    "Directory Server private key unlock password required")
        dirsrv_pkcs12_file, dirsrv_pin, dirsrv_ca_cert = load_pkcs12(
            cert_files=options.dirsrv_cert_files,
            key_password=options.dirsrv_pin,
            key_nickname=options.dirsrv_cert_name,
            ca_cert_files=options.ca_cert_files,
            host_name=host_name)
        dirsrv_pkcs12_info = (dirsrv_pkcs12_file.name, dirsrv_pin)

    if options.pkinit_cert_files:
        if options.pkinit_pin is None:
            options.pkinit_pin = read_password(
                "Enter Kerberos KDC private key unlock",
                confirm=False,
                validate=False,
                retry=False)
            if options.pkinit_pin is None:
                raise ScriptError(
                    "Kerberos KDC private key unlock password required")
        pkinit_pkcs12_file, pkinit_pin, _pkinit_ca_cert = load_pkcs12(
            cert_files=options.pkinit_cert_files,
            key_password=options.pkinit_pin,
            key_nickname=options.pkinit_cert_name,
            ca_cert_files=options.ca_cert_files,
            host_name=host_name)
        pkinit_pkcs12_info = (pkinit_pkcs12_file.name, pkinit_pin)

    if (options.http_cert_files and options.dirsrv_cert_files
            and http_ca_cert != dirsrv_ca_cert):
        raise ScriptError(
            "Apache Server SSL certificate and Directory Server SSL "
            "certificate are not signed by the same CA certificate")

    if not options.dm_password:
        dm_password = read_dm_password()

        if dm_password is None:
            raise ScriptError("Directory Manager password required")
    else:
        dm_password = options.dm_password

    if not options.master_password:
        master_password = ipa_generate_password()
    else:
        master_password = options.master_password

    if not options.admin_password:
        admin_password = read_admin_password()
        if admin_password is None:
            raise ScriptError("IPA admin password required")
    else:
        admin_password = options.admin_password

    # Configuration for ipalib, we will bootstrap and finalize later, after
    # we are sure we have the configuration file ready.
    cfg = dict(
        context='installer',
        confdir=paths.ETC_IPA,
        in_server=True,
        # make sure host name specified by user is used instead of default
        host=host_name,
    )
    if setup_ca:
        # we have an IPA-integrated CA
        cfg['ca_host'] = host_name

    # Create the management framework config file and finalize api
    target_fname = paths.IPA_DEFAULT_CONF
    fd = open(target_fname, "w")
    fd.write("[global]\n")
    fd.write("host=%s\n" % host_name)
    fd.write("basedn=%s\n" % ipautil.realm_to_suffix(realm_name))
    fd.write("realm=%s\n" % realm_name)
    fd.write("domain=%s\n" % domain_name)
    fd.write("xmlrpc_uri=https://%s/ipa/xml\n" % format_netloc(host_name))
    fd.write("ldap_uri=ldapi://%%2fvar%%2frun%%2fslapd-%s.socket\n" %
             installutils.realm_to_serverid(realm_name))
    if setup_ca:
        fd.write("enable_ra=True\n")
        fd.write("ra_plugin=dogtag\n")
        fd.write("dogtag_version=10\n")
    else:
        fd.write("enable_ra=False\n")
        fd.write("ra_plugin=none\n")
    fd.write("mode=production\n")
    fd.close()

    # Must be readable for everyone
    os.chmod(target_fname, 0o644)

    api.bootstrap(**cfg)
    api.finalize()

    if setup_ca:
        ca.install_check(False, None, options)
    if options.setup_kra:
        kra.install_check(api, None, options)

    if options.setup_dns:
        dns.install_check(False, api, False, options, host_name)
        ip_addresses = dns.ip_addresses
    else:
        ip_addresses = get_server_ip_address(host_name,
                                             not installer.interactive, False,
                                             options.ip_addresses)

        # check addresses here, dns module is doing own check
        network_ip_address_warning(ip_addresses)
        broadcast_ip_address_warning(ip_addresses)

    if options.setup_adtrust:
        adtrust.install_check(False, options, api)

    # installer needs to update hosts file when DNS subsystem will be
    # installed or custom addresses are used
    if options.ip_addresses or options.setup_dns:
        installer._update_hosts_file = True

    print()
    print("The IPA Master Server will be configured with:")
    print("Hostname:       %s" % host_name)
    print("IP address(es): %s" % ", ".join(str(ip) for ip in ip_addresses))
    print("Domain name:    %s" % domain_name)
    print("Realm name:     %s" % realm_name)
    print()

    if options.setup_dns:
        print("BIND DNS server will be configured to serve IPA domain with:")
        print("Forwarders:       %s" %
              ("No forwarders" if not options.forwarders else ", ".join(
                  [str(ip) for ip in options.forwarders])))
        print('Forward policy:   %s' % options.forward_policy)
        print("Reverse zone(s):  %s" %
              ("No reverse zone" if options.no_reverse or not dns.reverse_zones
               else ", ".join(str(rz) for rz in dns.reverse_zones)))
        print()

    if not options.setup_adtrust:
        # If domain name and realm does not match, IPA server will not be able
        # to estabilish trust with Active Directory. Print big fat warning.

        realm_not_matching_domain = (domain_name.upper() != realm_name)

        if realm_not_matching_domain:
            print("WARNING: Realm name does not match the domain name.\n"
                  "You will not be able to estabilish trusts with Active "
                  "Directory unless\nthe realm name of the IPA server matches "
                  "its domain name.\n\n")

    if installer.interactive and not user_input(
            "Continue to configure the system with these values?", False):
        raise ScriptError("Installation aborted")

    options.realm_name = realm_name
    options.domain_name = domain_name
    options.dm_password = dm_password
    options.master_password = master_password
    options.admin_password = admin_password
    options._host_name_overridden = bool(options.host_name)
    options.host_name = host_name
    options.ip_addresses = ip_addresses

    installer._fstore = fstore
    installer._sstore = sstore
    installer._dirsrv_pkcs12_file = dirsrv_pkcs12_file
    installer._http_pkcs12_file = http_pkcs12_file
    installer._pkinit_pkcs12_file = pkinit_pkcs12_file
    installer._dirsrv_pkcs12_info = dirsrv_pkcs12_info
    installer._http_pkcs12_info = http_pkcs12_info
    installer._pkinit_pkcs12_info = pkinit_pkcs12_info
    installer._external_cert_file = external_cert_file
    installer._external_ca_file = external_ca_file
    installer._ca_cert = http_ca_cert
Beispiel #42
0
def install_check(installer):
    options = installer
    dirsrv_pkcs12_file = installer._dirsrv_pkcs12_file
    http_pkcs12_file = installer._http_pkcs12_file
    pkinit_pkcs12_file = installer._pkinit_pkcs12_file
    dirsrv_pkcs12_info = installer._dirsrv_pkcs12_info
    http_pkcs12_info = installer._http_pkcs12_info
    pkinit_pkcs12_info = installer._pkinit_pkcs12_info
    external_cert_file = installer._external_cert_file
    external_ca_file = installer._external_ca_file
    http_ca_cert = installer._ca_cert
    dirsrv_ca_cert = None
    pkinit_ca_cert = None

    tasks.check_ipv6_stack_enabled()
    tasks.check_selinux_status()
    check_ldap_conf()

    mask_str = validate_mask()
    if mask_str:
        print("Unexpected system mask: %s, expected 0022" % mask_str)
        if installer.interactive:
            if not user_input("Do you want to continue anyway?", True):
                raise ScriptError(
                    "Unexpected system mask: %s" % mask_str)
        else:
            raise ScriptError("Unexpected system mask: %s" % mask_str)

    if options.master_password:
        msg = ("WARNING:\noption '-P/--master-password' is deprecated. "
               "KDC master password of sufficient strength is autogenerated "
               "during IPA server installation and should not be set "
               "manually.")
        print(textwrap.fill(msg, width=79, replace_whitespace=False))

    installer._installation_cleanup = True

    print("\nThe log file for this installation can be found in "
          "/var/log/ipaserver-install.log")
    if (not options.external_ca and not options.external_cert_files and
            is_ipa_configured()):
        installer._installation_cleanup = False
        raise ScriptError(
            "IPA server is already configured on this system.\n"
            "If you want to reinstall the IPA server, please uninstall "
            "it first using 'ipa-server-install --uninstall'.")

    client_fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE)
    if client_fstore.has_files():
        installer._installation_cleanup = False
        raise ScriptError(
            "IPA client is already configured on this system.\n"
            "Please uninstall it before configuring the IPA server, "
            "using 'ipa-client-install --uninstall'")

    fstore = sysrestore.FileStore(SYSRESTORE_DIR_PATH)
    sstore = sysrestore.StateFile(SYSRESTORE_DIR_PATH)

    # This will override any settings passed in on the cmdline
    if os.path.isfile(paths.ROOT_IPA_CACHE):
        if options.dm_password is not None:
            dm_password = options.dm_password
        else:
            dm_password = read_password("Directory Manager", confirm=False)
        if dm_password is None:
            raise ScriptError("Directory Manager password required")
        try:
            cache_vars = read_cache(dm_password)
            options.__dict__.update(cache_vars)
            if cache_vars.get('external_ca', False):
                options.external_ca = False
                options.interactive = False
        except Exception as e:
            raise ScriptError("Cannot process the cache file: %s" % str(e))

    # We only set up the CA if the PKCS#12 options are not given.
    if options.dirsrv_cert_files:
        setup_ca = False
    else:
        setup_ca = True
    options.setup_ca = setup_ca

    if not setup_ca and options.ca_subject:
        raise ScriptError(
            "--ca-subject cannot be used with CA-less installation")
    if not setup_ca and options.subject_base:
        raise ScriptError(
            "--subject-base cannot be used with CA-less installation")
    if not setup_ca and options.setup_kra:
        raise ScriptError(
            "--setup-kra cannot be used with CA-less installation")

    print("======================================="
          "=======================================")
    print("This program will set up the FreeIPA Server.")
    print("Version {}".format(version.VERSION))
    print("")
    print("This includes:")
    if setup_ca:
        print("  * Configure a stand-alone CA (dogtag) for certificate "
              "management")
    if not options.no_ntp:
        print("  * Configure the NTP client (chronyd)")
    print("  * Create and configure an instance of Directory Server")
    print("  * Create and configure a Kerberos Key Distribution Center (KDC)")
    print("  * Configure Apache (httpd)")
    if options.setup_kra:
        print("  * Configure KRA (dogtag) for secret management")
    if options.setup_dns:
        print("  * Configure DNS (bind)")
    if options.setup_adtrust:
        print("  * Configure Samba (smb) and winbind for managing AD trusts")
    if not options.no_pkinit:
        print("  * Configure the KDC to enable PKINIT")
    if options.no_ntp:
        print("")
        print("Excluded by options:")
        print("  * Configure the NTP client (chronyd)")
    if installer.interactive:
        print("")
        print("To accept the default shown in brackets, press the Enter key.")
    print("")

    if not options.external_cert_files:
        # Make sure the 389-ds ports are available
        check_dirsrv(not installer.interactive)

    if not options.no_ntp:
        try:
            ipaclient.install.timeconf.check_timedate_services()
        except ipaclient.install.timeconf.NTPConflictingService as e:
            print("WARNING: conflicting time&date synchronization service '{}'"
                  " will be disabled".format(e.conflicting_service))
            print("in favor of chronyd")
            print("")
        except ipaclient.install.timeconf.NTPConfigurationError:
            pass

    if not options.setup_dns and installer.interactive:
        if ipautil.user_input("Do you want to configure integrated DNS "
                              "(BIND)?", False):
            options.setup_dns = True
        print("")

    # check bind packages are installed
    if options.setup_dns:
        # Don't require an external DNS to say who we are if we are
        # setting up a local DNS server.
        options.no_host_dns = True

    # check the hostname is correctly configured, it must be as the kldap
    # utilities just use the hostname as returned by getaddrinfo to set
    # up some of the standard entries

    if options.host_name:
        host_default = options.host_name
    else:
        host_default = get_fqdn()

    try:
        if not installer.interactive or options.host_name:
            verify_fqdn(host_default, options.no_host_dns)
            host_name = host_default
        else:
            host_name = read_host_name(host_default, options.no_host_dns)
    except BadHostError as e:
        raise ScriptError(e)

    host_name = host_name.lower()
    logger.debug("will use host_name: %s\n", host_name)

    if not options.domain_name:
        domain_name = read_domain_name(host_name[host_name.find(".")+1:],
                                       not installer.interactive)
        logger.debug("read domain_name: %s\n", domain_name)
        try:
            validate_domain_name(domain_name)
        except ValueError as e:
            raise ScriptError("Invalid domain name: %s" % unicode(e))
    else:
        domain_name = options.domain_name

    domain_name = domain_name.lower()

    if not options.realm_name:
        realm_name = read_realm_name(domain_name, not installer.interactive)
        logger.debug("read realm_name: %s\n", realm_name)

        try:
            validate_domain_name(realm_name, entity="realm")
        except ValueError as e:
            raise ScriptError("Invalid realm name: {}".format(unicode(e)))
    else:
        realm_name = options.realm_name.upper()

    if not options.subject_base:
        options.subject_base = installutils.default_subject_base(realm_name)

    if not options.ca_subject:
        options.ca_subject = \
            installutils.default_ca_subject_dn(options.subject_base)

    if options.http_cert_files:
        if options.http_pin is None:
            options.http_pin = installutils.read_password(
                "Enter Apache Server private key unlock",
                confirm=False, validate=False, retry=False)
            if options.http_pin is None:
                raise ScriptError(
                    "Apache Server private key unlock password required")
        http_pkcs12_file, http_pin, http_ca_cert = load_pkcs12(
            cert_files=options.http_cert_files,
            key_password=options.http_pin,
            key_nickname=options.http_cert_name,
            ca_cert_files=options.ca_cert_files,
            host_name=host_name)
        http_pkcs12_info = (http_pkcs12_file.name, http_pin)

    if options.dirsrv_cert_files:
        if options.dirsrv_pin is None:
            options.dirsrv_pin = read_password(
                "Enter Directory Server private key unlock",
                confirm=False, validate=False, retry=False)
            if options.dirsrv_pin is None:
                raise ScriptError(
                    "Directory Server private key unlock password required")
        dirsrv_pkcs12_file, dirsrv_pin, dirsrv_ca_cert = load_pkcs12(
            cert_files=options.dirsrv_cert_files,
            key_password=options.dirsrv_pin,
            key_nickname=options.dirsrv_cert_name,
            ca_cert_files=options.ca_cert_files,
            host_name=host_name)
        dirsrv_pkcs12_info = (dirsrv_pkcs12_file.name, dirsrv_pin)

    if options.pkinit_cert_files:
        if options.pkinit_pin is None:
            options.pkinit_pin = read_password(
                "Enter Kerberos KDC private key unlock",
                confirm=False, validate=False, retry=False)
            if options.pkinit_pin is None:
                raise ScriptError(
                    "Kerberos KDC private key unlock password required")
        pkinit_pkcs12_file, pkinit_pin, pkinit_ca_cert = load_pkcs12(
            cert_files=options.pkinit_cert_files,
            key_password=options.pkinit_pin,
            key_nickname=options.pkinit_cert_name,
            ca_cert_files=options.ca_cert_files,
            realm_name=realm_name)
        pkinit_pkcs12_info = (pkinit_pkcs12_file.name, pkinit_pin)

    if (options.http_cert_files and options.dirsrv_cert_files and
            http_ca_cert != dirsrv_ca_cert):
        raise ScriptError(
            "Apache Server SSL certificate and Directory Server SSL "
            "certificate are not signed by the same CA certificate")

    if (options.http_cert_files and
            options.pkinit_cert_files and
            http_ca_cert != pkinit_ca_cert):
        raise ScriptError(
            "Apache Server SSL certificate and PKINIT KDC "
            "certificate are not signed by the same CA certificate")

    if not options.dm_password:
        dm_password = read_dm_password()

        if dm_password is None:
            raise ScriptError("Directory Manager password required")
    else:
        dm_password = options.dm_password

    if not options.master_password:
        master_password = ipa_generate_password()
    else:
        master_password = options.master_password

    if not options.admin_password:
        admin_password = read_admin_password()
        if admin_password is None:
            raise ScriptError("IPA admin password required")
    else:
        admin_password = options.admin_password

    # Configuration for ipalib, we will bootstrap and finalize later, after
    # we are sure we have the configuration file ready.
    cfg = dict(
        context='installer',
        confdir=paths.ETC_IPA,
        in_server=True,
        # make sure host name specified by user is used instead of default
        host=host_name,
    )
    if setup_ca:
        # we have an IPA-integrated CA
        cfg['ca_host'] = host_name

    # Create the management framework config file and finalize api
    target_fname = paths.IPA_DEFAULT_CONF
    ipaconf = IPAChangeConf("IPA Server Install")
    ipaconf.setOptionAssignment(" = ")
    ipaconf.setSectionNameDelimiters(("[", "]"))

    xmlrpc_uri = 'https://{0}/ipa/xml'.format(
                    ipautil.format_netloc(host_name))
    ldapi_uri = ipaldap.realm_to_ldapi_uri(realm_name)

    # [global] section
    gopts = [
        ipaconf.setOption('host', host_name),
        ipaconf.setOption('basedn', ipautil.realm_to_suffix(realm_name)),
        ipaconf.setOption('realm', realm_name),
        ipaconf.setOption('domain', domain_name),
        ipaconf.setOption('xmlrpc_uri', xmlrpc_uri),
        ipaconf.setOption('ldap_uri', ldapi_uri),
        ipaconf.setOption('mode', 'production')
    ]

    if setup_ca:
        gopts.extend([
            ipaconf.setOption('enable_ra', 'True'),
            ipaconf.setOption('ra_plugin', 'dogtag'),
            ipaconf.setOption('dogtag_version', '10')
        ])
    else:
        gopts.extend([
            ipaconf.setOption('enable_ra', 'False'),
            ipaconf.setOption('ra_plugin', 'None')
        ])

    opts = [
        ipaconf.setSection('global', gopts),
        {'name': 'empty', 'type': 'empty'}
    ]

    ipaconf.newConf(target_fname, opts)

    # Must be readable for everyone
    os.chmod(target_fname, 0o644)

    api.bootstrap(**cfg)
    api.finalize()

    if setup_ca:
        ca.install_check(False, None, options)
    if options.setup_kra:
        kra.install_check(api, None, options)

    if options.setup_dns:
        dns.install_check(False, api, False, options, host_name)
        ip_addresses = dns.ip_addresses
    else:
        ip_addresses = get_server_ip_address(host_name,
                                             not installer.interactive, False,
                                             options.ip_addresses)

        # check addresses here, dns module is doing own check
        no_matching_interface_for_ip_address_warning(ip_addresses)

    instance_name = "-".join(realm_name.split("."))
    dirsrv = services.knownservices.dirsrv
    if (options.external_cert_files
           and dirsrv.is_installed(instance_name)
           and not dirsrv.is_running(instance_name)):
        logger.debug('Starting Directory Server')
        services.knownservices.dirsrv.start(instance_name)

    if options.setup_adtrust:
        adtrust.install_check(False, options, api)

    # installer needs to update hosts file when DNS subsystem will be
    # installed or custom addresses are used
    if options.ip_addresses or options.setup_dns:
        installer._update_hosts_file = True

    print()
    print("The IPA Master Server will be configured with:")
    print("Hostname:       %s" % host_name)
    print("IP address(es): %s" % ", ".join(str(ip) for ip in ip_addresses))
    print("Domain name:    %s" % domain_name)
    print("Realm name:     %s" % realm_name)
    print()

    if setup_ca:
        ca.print_ca_configuration(options)
        print()

    if options.setup_dns:
        print("BIND DNS server will be configured to serve IPA domain with:")
        print("Forwarders:       %s" % (
            "No forwarders" if not options.forwarders
            else ", ".join([str(ip) for ip in options.forwarders])
        ))
        print('Forward policy:   %s' % options.forward_policy)
        print("Reverse zone(s):  %s" % (
            "No reverse zone" if options.no_reverse or not dns.reverse_zones
            else ", ".join(str(rz) for rz in dns.reverse_zones)
        ))
        print()

    if not options.setup_adtrust:
        # If domain name and realm does not match, IPA server will not be able
        # to establish trust with Active Directory. Print big fat warning.

        realm_not_matching_domain = (domain_name.upper() != realm_name)

        if realm_not_matching_domain:
            print("WARNING: Realm name does not match the domain name.\n"
                  "You will not be able to establish trusts with Active "
                  "Directory unless\nthe realm name of the IPA server matches "
                  "its domain name.\n\n")

    if installer.interactive and not user_input(
            "Continue to configure the system with these values?", False):
        raise ScriptError("Installation aborted")

    options.realm_name = realm_name
    options.domain_name = domain_name
    options.dm_password = dm_password
    options.master_password = master_password
    options.admin_password = admin_password
    options._host_name_overridden = bool(options.host_name)
    options.host_name = host_name
    options.ip_addresses = ip_addresses

    installer._fstore = fstore
    installer._sstore = sstore
    installer._dirsrv_pkcs12_file = dirsrv_pkcs12_file
    installer._http_pkcs12_file = http_pkcs12_file
    installer._pkinit_pkcs12_file = pkinit_pkcs12_file
    installer._dirsrv_pkcs12_info = dirsrv_pkcs12_info
    installer._http_pkcs12_info = http_pkcs12_info
    installer._pkinit_pkcs12_info = pkinit_pkcs12_info
    installer._external_cert_file = external_cert_file
    installer._external_ca_file = external_ca_file
    installer._ca_cert = http_ca_cert
Beispiel #43
0
 def create_noise_file(self):
     if ipautil.file_exists(self.noise_fname):
         os.remove(self.noise_fname)
     with open(self.noise_fname, "w") as f:
         self.set_perms(f)
         f.write(ipautil.ipa_generate_password())
Beispiel #44
0
    def __setup_softhsm(self):
        assert self.ods_uid is not None
        assert self.named_gid is not None

        token_dir_exists = os.path.exists(paths.DNSSEC_TOKENS_DIR)

        # create dnssec directory
        if not os.path.exists(paths.IPA_DNSSEC_DIR):
            self.logger.debug("Creating %s directory", paths.IPA_DNSSEC_DIR)
            os.mkdir(paths.IPA_DNSSEC_DIR)
            os.chmod(paths.IPA_DNSSEC_DIR, 0o770)
            # chown ods:named
            os.chown(paths.IPA_DNSSEC_DIR, self.ods_uid, self.named_gid)

        # setup softhsm2 config file
        softhsm_conf_txt = ("# SoftHSM v2 configuration file \n"
                            "# File generated by IPA instalation\n"
                            "directories.tokendir = %(tokens_dir)s\n"
                            "objectstore.backend = file") % {
                               'tokens_dir': paths.DNSSEC_TOKENS_DIR
                            }
        self.logger.debug("Creating new softhsm config file")
        named_fd = open(paths.DNSSEC_SOFTHSM2_CONF, 'w')
        named_fd.seek(0)
        named_fd.truncate(0)
        named_fd.write(softhsm_conf_txt)
        named_fd.close()
        os.chmod(paths.DNSSEC_SOFTHSM2_CONF, 0o644)

        # setting up named to use softhsm2
        if not self.fstore.has_file(paths.SYSCONFIG_NAMED):
            self.fstore.backup_file(paths.SYSCONFIG_NAMED)

        # setting up named and ipa-dnskeysyncd to use our softhsm2 config
        for sysconfig in [paths.SYSCONFIG_NAMED,
                          paths.SYSCONFIG_IPA_DNSKEYSYNCD]:
            installutils.set_directive(sysconfig, 'SOFTHSM2_CONF',
                                       paths.DNSSEC_SOFTHSM2_CONF,
                                       quotes=False, separator='=')

        if (token_dir_exists and os.path.exists(paths.DNSSEC_SOFTHSM_PIN) and
                os.path.exists(paths.DNSSEC_SOFTHSM_PIN_SO)):
            # there is initialized softhsm
            return

        # remove old tokens
        if token_dir_exists:
            self.logger.debug('Removing old tokens directory %s',
                              paths.DNSSEC_TOKENS_DIR)
            shutil.rmtree(paths.DNSSEC_TOKENS_DIR)

        # create tokens subdirectory
        self.logger.debug('Creating tokens %s directory',
                          paths.DNSSEC_TOKENS_DIR)
        # sticky bit is required by daemon
        os.mkdir(paths.DNSSEC_TOKENS_DIR)
        os.chmod(paths.DNSSEC_TOKENS_DIR, 0o770 | stat.S_ISGID)
        # chown to ods:named
        os.chown(paths.DNSSEC_TOKENS_DIR, self.ods_uid, self.named_gid)

        # generate PINs for softhsm
        allowed_chars = u'123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
        pin_length = 30  # Bind allows max 32 bytes including ending '\0'
        pin = ipautil.ipa_generate_password(allowed_chars, pin_length)
        pin_so = ipautil.ipa_generate_password(allowed_chars, pin_length)

        self.logger.debug("Saving user PIN to %s", paths.DNSSEC_SOFTHSM_PIN)
        named_fd = open(paths.DNSSEC_SOFTHSM_PIN, 'w')
        named_fd.seek(0)
        named_fd.truncate(0)
        named_fd.write(pin)
        named_fd.close()
        os.chmod(paths.DNSSEC_SOFTHSM_PIN, 0o770)
        # chown to ods:named
        os.chown(paths.DNSSEC_SOFTHSM_PIN, self.ods_uid, self.named_gid)

        self.logger.debug("Saving SO PIN to %s", paths.DNSSEC_SOFTHSM_PIN_SO)
        named_fd = open(paths.DNSSEC_SOFTHSM_PIN_SO, 'w')
        named_fd.seek(0)
        named_fd.truncate(0)
        named_fd.write(pin_so)
        named_fd.close()
        # owner must be root
        os.chmod(paths.DNSSEC_SOFTHSM_PIN_SO, 0o400)

        # initialize SoftHSM

        command = [
            paths.SOFTHSM2_UTIL,
            '--init-token',
            '--slot', str(softhsm_slot),
            '--label', softhsm_token_label,
            '--pin', pin,
            '--so-pin', pin_so,
        ]
        self.logger.debug("Initializing tokens")
        os.environ["SOFTHSM2_CONF"] = paths.DNSSEC_SOFTHSM2_CONF
        ipautil.run(command, nolog=(pin, pin_so,))
Beispiel #45
0
def install_check(installer):
    options = installer
    dirsrv_pkcs12_file = installer._dirsrv_pkcs12_file
    http_pkcs12_file = installer._http_pkcs12_file
    pkinit_pkcs12_file = installer._pkinit_pkcs12_file
    dirsrv_pkcs12_info = installer._dirsrv_pkcs12_info
    http_pkcs12_info = installer._http_pkcs12_info
    pkinit_pkcs12_info = installer._pkinit_pkcs12_info
    external_cert_file = installer._external_cert_file
    external_ca_file = installer._external_ca_file
    http_ca_cert = installer._ca_cert
    dirsrv_ca_cert = None
    pkinit_ca_cert = None

    tasks.check_ipv6_stack_enabled()
    tasks.check_selinux_status()
    check_ldap_conf()

    mask_str = validate_mask()
    if mask_str:
        print("Unexpected system mask: %s, expected 0022" % mask_str)
        if installer.interactive:
            if not user_input("Do you want to continue anyway?", True):
                raise ScriptError(
                    "Unexpected system mask: %s" % mask_str)
        else:
            raise ScriptError("Unexpected system mask: %s" % mask_str)

    if options.master_password:
        msg = ("WARNING:\noption '-P/--master-password' is deprecated. "
               "KDC master password of sufficient strength is autogenerated "
               "during IPA server installation and should not be set "
               "manually.")
        print(textwrap.fill(msg, width=79, replace_whitespace=False))

    installer._installation_cleanup = True

    print("\nThe log file for this installation can be found in "
          "/var/log/ipaserver-install.log")
    if (not options.external_ca and not options.external_cert_files and
            is_ipa_configured()):
        installer._installation_cleanup = False
        raise ScriptError(
            "IPA server is already configured on this system.\n"
            "If you want to reinstall the IPA server, please uninstall "
            "it first using 'ipa-server-install --uninstall'.")

    client_fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE)
    if client_fstore.has_files():
        installer._installation_cleanup = False
        raise ScriptError(
            "IPA client is already configured on this system.\n"
            "Please uninstall it before configuring the IPA server, "
            "using 'ipa-client-install --uninstall'")

    fstore = sysrestore.FileStore(SYSRESTORE_DIR_PATH)
    sstore = sysrestore.StateFile(SYSRESTORE_DIR_PATH)

    # This will override any settings passed in on the cmdline
    if os.path.isfile(paths.ROOT_IPA_CACHE):
        if options.dm_password is not None:
            dm_password = options.dm_password
        else:
            dm_password = read_password("Directory Manager", confirm=False)
        if dm_password is None:
            raise ScriptError("Directory Manager password required")
        try:
            cache_vars = read_cache(dm_password)
            options.__dict__.update(cache_vars)
            if cache_vars.get('external_ca', False):
                options.external_ca = False
                options.interactive = False
        except Exception as e:
            raise ScriptError("Cannot process the cache file: %s" % str(e))

    # We only set up the CA if the PKCS#12 options are not given.
    if options.dirsrv_cert_files:
        setup_ca = False
    else:
        setup_ca = True
    options.setup_ca = setup_ca

    if not setup_ca and options.ca_subject:
        raise ScriptError(
            "--ca-subject cannot be used with CA-less installation")
    if not setup_ca and options.subject_base:
        raise ScriptError(
            "--subject-base cannot be used with CA-less installation")
    if not setup_ca and options.setup_kra:
        raise ScriptError(
            "--setup-kra cannot be used with CA-less installation")

    print("======================================="
          "=======================================")
    print("This program will set up the FreeIPA Server.")
    print("Version {}".format(version.VERSION))
    print("")
    print("This includes:")
    if setup_ca:
        print("  * Configure a stand-alone CA (dogtag) for certificate "
              "management")
    if not options.no_ntp:
        print("  * Configure the NTP client (chronyd)")
    print("  * Create and configure an instance of Directory Server")
    print("  * Create and configure a Kerberos Key Distribution Center (KDC)")
    print("  * Configure Apache (httpd)")
    if options.setup_kra:
        print("  * Configure KRA (dogtag) for secret management")
    if options.setup_dns:
        print("  * Configure DNS (bind)")
    if options.setup_adtrust:
        print("  * Configure Samba (smb) and winbind for managing AD trusts")
    if not options.no_pkinit:
        print("  * Configure the KDC to enable PKINIT")
    if options.no_ntp:
        print("")
        print("Excluded by options:")
        print("  * Configure the NTP client (chronyd)")
    if installer.interactive:
        print("")
        print("To accept the default shown in brackets, press the Enter key.")
    print("")

    if not options.external_cert_files:
        # Make sure the 389-ds ports are available
        check_dirsrv(not installer.interactive)

    if not options.no_ntp:
        try:
            timeconf.check_timedate_services()
        except timeconf.NTPConflictingService as e:
            print(
                "WARNING: conflicting time&date synchronization service "
                "'{}' will be disabled in favor of chronyd\n".format(
                    e.conflicting_service
                )
            )
        except timeconf.NTPConfigurationError:
            pass

    if not options.setup_dns and installer.interactive:
        if ipautil.user_input("Do you want to configure integrated DNS "
                              "(BIND)?", False):
            options.setup_dns = True
        print("")

    # check bind packages are installed
    if options.setup_dns:
        # Don't require an external DNS to say who we are if we are
        # setting up a local DNS server.
        options.no_host_dns = True

    # check the hostname is correctly configured, it must be as the kldap
    # utilities just use the hostname as returned by getaddrinfo to set
    # up some of the standard entries

    if options.host_name:
        host_default = options.host_name
    else:
        host_default = get_fqdn()

    try:
        if not installer.interactive or options.host_name:
            verify_fqdn(host_default, options.no_host_dns)
            host_name = host_default
        else:
            host_name = read_host_name(host_default, options.no_host_dns)
    except BadHostError as e:
        raise ScriptError(e)

    host_name = host_name.lower()
    logger.debug("will use host_name: %s\n", host_name)

    if not options.domain_name:
        domain_name = read_domain_name(host_name[host_name.find(".")+1:],
                                       not installer.interactive)
        logger.debug("read domain_name: %s\n", domain_name)
        try:
            validate_domain_name(domain_name)
        except ValueError as e:
            raise ScriptError("Invalid domain name: %s" % unicode(e))
    else:
        domain_name = options.domain_name

    domain_name = domain_name.lower()

    if not options.realm_name:
        realm_name = read_realm_name(domain_name, not installer.interactive)
        logger.debug("read realm_name: %s\n", realm_name)

        try:
            validate_domain_name(realm_name, entity="realm")
        except ValueError as e:
            raise ScriptError("Invalid realm name: {}".format(unicode(e)))
    else:
        realm_name = options.realm_name.upper()

    if not options.subject_base:
        options.subject_base = installutils.default_subject_base(realm_name)

    if not options.ca_subject:
        options.ca_subject = \
            installutils.default_ca_subject_dn(options.subject_base)

    if options.http_cert_files:
        if options.http_pin is None:
            options.http_pin = installutils.read_password(
                "Enter Apache Server private key unlock",
                confirm=False, validate=False, retry=False)
            if options.http_pin is None:
                raise ScriptError(
                    "Apache Server private key unlock password required")
        http_pkcs12_file, http_pin, http_ca_cert = load_pkcs12(
            cert_files=options.http_cert_files,
            key_password=options.http_pin,
            key_nickname=options.http_cert_name,
            ca_cert_files=options.ca_cert_files,
            host_name=host_name)
        http_pkcs12_info = (http_pkcs12_file.name, http_pin)

    if options.dirsrv_cert_files:
        if options.dirsrv_pin is None:
            options.dirsrv_pin = read_password(
                "Enter Directory Server private key unlock",
                confirm=False, validate=False, retry=False)
            if options.dirsrv_pin is None:
                raise ScriptError(
                    "Directory Server private key unlock password required")
        dirsrv_pkcs12_file, dirsrv_pin, dirsrv_ca_cert = load_pkcs12(
            cert_files=options.dirsrv_cert_files,
            key_password=options.dirsrv_pin,
            key_nickname=options.dirsrv_cert_name,
            ca_cert_files=options.ca_cert_files,
            host_name=host_name)
        dirsrv_pkcs12_info = (dirsrv_pkcs12_file.name, dirsrv_pin)

    if options.pkinit_cert_files:
        if options.pkinit_pin is None:
            options.pkinit_pin = read_password(
                "Enter Kerberos KDC private key unlock",
                confirm=False, validate=False, retry=False)
            if options.pkinit_pin is None:
                raise ScriptError(
                    "Kerberos KDC private key unlock password required")
        pkinit_pkcs12_file, pkinit_pin, pkinit_ca_cert = load_pkcs12(
            cert_files=options.pkinit_cert_files,
            key_password=options.pkinit_pin,
            key_nickname=options.pkinit_cert_name,
            ca_cert_files=options.ca_cert_files,
            realm_name=realm_name)
        pkinit_pkcs12_info = (pkinit_pkcs12_file.name, pkinit_pin)

    if (options.http_cert_files and options.dirsrv_cert_files and
            http_ca_cert != dirsrv_ca_cert):
        raise ScriptError(
            "Apache Server SSL certificate and Directory Server SSL "
            "certificate are not signed by the same CA certificate")

    if (options.http_cert_files and
            options.pkinit_cert_files and
            http_ca_cert != pkinit_ca_cert):
        raise ScriptError(
            "Apache Server SSL certificate and PKINIT KDC "
            "certificate are not signed by the same CA certificate")

    if not options.dm_password:
        dm_password = read_dm_password()

        if dm_password is None:
            raise ScriptError("Directory Manager password required")
    else:
        dm_password = options.dm_password

    if not options.master_password:
        master_password = ipa_generate_password()
    else:
        master_password = options.master_password

    if not options.admin_password:
        admin_password = read_admin_password()
        if admin_password is None:
            raise ScriptError("IPA admin password required")
    else:
        admin_password = options.admin_password

    # Configuration for ipalib, we will bootstrap and finalize later, after
    # we are sure we have the configuration file ready.
    cfg = dict(
        context='installer',
        confdir=paths.ETC_IPA,
        in_server=True,
        # make sure host name specified by user is used instead of default
        host=host_name,
    )
    if setup_ca:
        # we have an IPA-integrated CA
        cfg['ca_host'] = host_name

    # Create the management framework config file and finalize api
    target_fname = paths.IPA_DEFAULT_CONF
    ipaconf = IPAChangeConf("IPA Server Install")
    ipaconf.setOptionAssignment(" = ")
    ipaconf.setSectionNameDelimiters(("[", "]"))

    xmlrpc_uri = 'https://{0}/ipa/xml'.format(
                    ipautil.format_netloc(host_name))
    ldapi_uri = ipaldap.realm_to_ldapi_uri(realm_name)

    # [global] section
    gopts = [
        ipaconf.setOption('host', host_name),
        ipaconf.setOption('basedn', ipautil.realm_to_suffix(realm_name)),
        ipaconf.setOption('realm', realm_name),
        ipaconf.setOption('domain', domain_name),
        ipaconf.setOption('xmlrpc_uri', xmlrpc_uri),
        ipaconf.setOption('ldap_uri', ldapi_uri),
        ipaconf.setOption('mode', 'production')
    ]

    if setup_ca:
        gopts.extend([
            ipaconf.setOption('enable_ra', 'True'),
            ipaconf.setOption('ra_plugin', 'dogtag'),
            ipaconf.setOption('dogtag_version', '10')
        ])
    else:
        gopts.extend([
            ipaconf.setOption('enable_ra', 'False'),
            ipaconf.setOption('ra_plugin', 'None')
        ])

    opts = [
        ipaconf.setSection('global', gopts),
        {'name': 'empty', 'type': 'empty'}
    ]

    ipaconf.newConf(target_fname, opts)

    # Must be readable for everyone
    os.chmod(target_fname, 0o644)

    api.bootstrap(**cfg)
    api.finalize()

    if setup_ca:
        ca.install_check(False, None, options)
    if options.setup_kra:
        kra.install_check(api, None, options)

    if options.setup_dns:
        dns.install_check(False, api, False, options, host_name)
        ip_addresses = dns.ip_addresses
    else:
        ip_addresses = get_server_ip_address(host_name,
                                             not installer.interactive, False,
                                             options.ip_addresses)

        # check addresses here, dns module is doing own check
        no_matching_interface_for_ip_address_warning(ip_addresses)

    instance_name = "-".join(realm_name.split("."))
    dirsrv = services.knownservices.dirsrv
    if (options.external_cert_files
           and dirsrv.is_installed(instance_name)
           and not dirsrv.is_running(instance_name)):
        logger.debug('Starting Directory Server')
        services.knownservices.dirsrv.start(instance_name)

    if options.setup_adtrust:
        adtrust.install_check(False, options, api)

    # installer needs to update hosts file when DNS subsystem will be
    # installed or custom addresses are used
    if options.ip_addresses or options.setup_dns:
        installer._update_hosts_file = True

    if not options.no_ntp and not options.unattended and not (
            options.ntp_servers or options.ntp_pool):
        options.ntp_servers, options.ntp_pool = timeconf.get_time_source()

    print()
    print("The IPA Master Server will be configured with:")
    print("Hostname:       %s" % host_name)
    print("IP address(es): %s" % ", ".join(str(ip) for ip in ip_addresses))
    print("Domain name:    %s" % domain_name)
    print("Realm name:     %s" % realm_name)
    print()

    if setup_ca:
        ca.print_ca_configuration(options)
        print()

    if options.setup_dns:
        print("BIND DNS server will be configured to serve IPA domain with:")
        print("Forwarders:       %s" % (
            "No forwarders" if not options.forwarders
            else ", ".join([str(ip) for ip in options.forwarders])
        ))
        print('Forward policy:   %s' % options.forward_policy)
        print("Reverse zone(s):  %s" % (
            "No reverse zone" if options.no_reverse or not dns.reverse_zones
            else ", ".join(str(rz) for rz in dns.reverse_zones)
        ))
        print()

    if not options.setup_adtrust:
        # If domain name and realm does not match, IPA server will not be able
        # to establish trust with Active Directory. Print big fat warning.

        realm_not_matching_domain = (domain_name.upper() != realm_name)

        if realm_not_matching_domain:
            print("WARNING: Realm name does not match the domain name.\n"
                  "You will not be able to establish trusts with Active "
                  "Directory unless\nthe realm name of the IPA server matches "
                  "its domain name.\n\n")

    if options.ntp_servers or options.ntp_pool:
        if options.ntp_servers:
            for server in options.ntp_servers:
                print("NTP server:\t{}".format(server))

        if options.ntp_pool:
            print("NTP pool:\t{}".format(options.ntp_pool))

    if installer.interactive and not user_input(
            "Continue to configure the system with these values?", False):
        raise ScriptError("Installation aborted")

    options.realm_name = realm_name
    options.domain_name = domain_name
    options.dm_password = dm_password
    options.master_password = master_password
    options.admin_password = admin_password
    options._host_name_overridden = bool(options.host_name)
    options.host_name = host_name
    options.ip_addresses = ip_addresses

    installer._fstore = fstore
    installer._sstore = sstore
    installer._dirsrv_pkcs12_file = dirsrv_pkcs12_file
    installer._http_pkcs12_file = http_pkcs12_file
    installer._pkinit_pkcs12_file = pkinit_pkcs12_file
    installer._dirsrv_pkcs12_info = dirsrv_pkcs12_info
    installer._http_pkcs12_info = http_pkcs12_info
    installer._pkinit_pkcs12_info = pkinit_pkcs12_info
    installer._external_cert_file = external_cert_file
    installer._external_ca_file = external_ca_file
    installer._ca_cert = http_ca_cert
Beispiel #46
0
 def check_userpassword(self, entry_attrs, **options):
     if 'userpassword' not in entry_attrs and options.get('random'):
         entry_attrs['userpassword'] = ipa_generate_password(
             entropy_bits=TMP_PWD_ENTROPY_BITS)
         # save the password so it can be displayed in post_callback
         setattr(context, 'randompassword', entry_attrs['userpassword'])
Beispiel #47
0
    def create_db(self, user=None, group=None, mode=None, backup=False):
        """Create cert DB

        :param user: User owner the secdir
        :param group: Group owner of the secdir
        :param mode: Mode of the secdir
        :param backup: Backup the sedir files
        """
        if mode is not None:
            dirmode = mode
            filemode = mode & 0o666
            pwdfilemode = mode & 0o660
        else:
            dirmode = 0o750
            filemode = 0o640
            pwdfilemode = 0o640

        uid = -1
        gid = -1
        if user is not None:
            uid = pwd.getpwnam(user).pw_uid
        if group is not None:
            gid = grp.getgrnam(group).gr_gid

        if backup:
            for filename in self.backup_filenames:
                ipautil.backup_file(filename)

        if not os.path.exists(self.secdir):
            os.makedirs(self.secdir, dirmode)

        if not os.path.exists(self.pwd_file):
            # Create the password file for this db
            with io.open(os.open(self.pwd_file,
                                 os.O_CREAT | os.O_WRONLY,
                                 pwdfilemode), 'w', closefd=True) as f:
                f.write(ipautil.ipa_generate_password())
                # flush and sync tempfile inode
                f.flush()
                os.fsync(f.fileno())

        # In case dbtype is auto, let certutil decide which type of DB
        # to create.
        if self.dbtype == 'auto':
            dbdir = self.secdir
        else:
            dbdir = '{}:{}'.format(self.dbtype, self.secdir)
        args = [
            paths.CERTUTIL,
            '-d', dbdir,
            '-N',
            '-f', self.pwd_file,
            # -@ in case it's an old db and it must be migrated
            '-@', self.pwd_file,
        ]
        ipautil.run(args, stdin=None, cwd=self.secdir)
        self._set_filenames(self._detect_dbtype())
        if self.filenames is None:
            # something went wrong...
            raise ValueError(
                "Failed to create NSSDB at '{}'".format(self.secdir)
            )

        # Finally fix up perms
        os.chown(self.secdir, uid, gid)
        os.chmod(self.secdir, dirmode)
        tasks.restore_context(self.secdir, force=True)
        for filename in self.filenames:
            if os.path.exists(filename):
                os.chown(filename, uid, gid)
                if filename == self.pwd_file:
                    new_mode = pwdfilemode
                else:
                    new_mode = filemode
                os.chmod(filename, new_mode)
                tasks.restore_context(filename, force=True)
Beispiel #48
0
    def import_files(self, files, import_keys=False, key_password=None,
                     key_nickname=None):
        """
        Import certificates and a single private key from multiple files

        The files may be in PEM and DER certificate, PKCS#7 certificate chain,
        PKCS#8 and raw private key and PKCS#12 formats.

        :param files: Names of files to import
        :param import_keys: Whether to import private keys
        :param key_password: Password to decrypt private keys
        :param key_nickname: Nickname of the private key to import from PKCS#12
            files
        """
        key_file = None
        extracted_key = None
        extracted_certs = []

        for filename in files:
            try:
                with open(filename, 'rb') as f:
                    data = f.read()
            except IOError as e:
                raise RuntimeError(
                    "Failed to open %s: %s" % (filename, e.strerror))

            # Try to parse the file as PEM file
            matches = list(
                re.finditer(
                    br'-----BEGIN (.+?)-----(.*?)-----END \1-----',
                    data, re.DOTALL
                )
            )
            if matches:
                loaded = False
                for match in matches:
                    body = match.group()
                    label = match.group(1)
                    line = len(data[:match.start() + 1].splitlines())

                    if label in (b'CERTIFICATE', b'X509 CERTIFICATE',
                                 b'X.509 CERTIFICATE'):
                        try:
                            cert = x509.load_pem_x509_certificate(body)
                        except ValueError as e:
                            if label != b'CERTIFICATE':
                                logger.warning(
                                    "Skipping certificate in %s at line %s: "
                                    "%s",
                                    filename, line, e)
                                continue
                        else:
                            extracted_certs.append(cert)
                            loaded = True
                            continue

                    if label in (b'PKCS7', b'PKCS #7 SIGNED DATA',
                                 b'CERTIFICATE'):
                        try:
                            certs = x509.pkcs7_to_certs(body)
                        except ipautil.CalledProcessError as e:
                            if label == b'CERTIFICATE':
                                logger.warning(
                                    "Skipping certificate in %s at line %s: "
                                    "%s",
                                    filename, line, e)
                            else:
                                logger.warning(
                                    "Skipping PKCS#7 in %s at line %s: %s",
                                    filename, line, e)
                            continue
                        else:
                            extracted_certs.extend(certs)
                            loaded = True
                            continue

                    if label in (b'PRIVATE KEY', b'ENCRYPTED PRIVATE KEY',
                                 b'RSA PRIVATE KEY', b'DSA PRIVATE KEY',
                                 b'EC PRIVATE KEY'):
                        if not import_keys:
                            continue

                        if key_file:
                            raise RuntimeError(
                                "Can't load private key from both %s and %s" %
                                (key_file, filename))

                        # the args -v2 aes256 -v2prf hmacWithSHA256 are needed
                        # on OpenSSL 1.0.2 (fips mode). As soon as FreeIPA
                        # requires OpenSSL 1.1.0 we'll be able to drop them
                        args = [
                            paths.OPENSSL, 'pkcs8',
                            '-topk8',
                            '-v2', 'aes256', '-v2prf', 'hmacWithSHA256',
                            '-passout', 'file:' + self.pwd_file,
                        ]
                        if ((label != b'PRIVATE KEY' and key_password) or
                                label == b'ENCRYPTED PRIVATE KEY'):
                            key_pwdfile = ipautil.write_tmp_file(key_password)
                            args += [
                                '-passin', 'file:' + key_pwdfile.name,
                            ]
                        try:
                            result = ipautil.run(
                                args, stdin=body, capture_output=True)
                        except ipautil.CalledProcessError as e:
                            logger.warning(
                                "Skipping private key in %s at line %s: %s",
                                filename, line, e)
                            continue
                        else:
                            extracted_key = result.raw_output
                            key_file = filename
                            loaded = True
                            continue
                if loaded:
                    continue
                raise RuntimeError("Failed to load %s" % filename)

            # Try to load the file as DER certificate
            try:
                cert = x509.load_der_x509_certificate(data)
            except ValueError:
                pass
            else:
                extracted_certs.append(cert)
                continue

            # Try to import the file as PKCS#12 file
            if import_keys:
                try:
                    self.import_pkcs12(filename, key_password)
                except Pkcs12ImportUnknownError:
                    # the file may not be a PKCS#12 file,
                    # go to the generic error about unrecognized format
                    pass
                except RuntimeError as e:
                    raise RuntimeError("Failed to load %s: %s" %
                                       (filename, str(e)))
                else:
                    if key_file:
                        raise RuntimeError(
                            "Can't load private key from both %s and %s" %
                            (key_file, filename))
                    key_file = filename

                    server_certs = self.find_server_certs()
                    if key_nickname:
                        for nickname, _trust_flags in server_certs:
                            if nickname == key_nickname:
                                break
                        else:
                            raise RuntimeError(
                                "Server certificate \"%s\" not found in %s" %
                                (key_nickname, filename))
                    else:
                        if len(server_certs) > 1:
                            raise RuntimeError(
                                "%s server certificates found in %s, "
                                "expecting only one" %
                                (len(server_certs), filename))

                    continue

            # Supported formats were tried but none succeeded
            raise RuntimeError("Failed to load %s: unrecognized format" %
                               filename)

        if import_keys and not key_file:
            raise RuntimeError(
                "No server certificates found in %s" % (', '.join(files)))

        for cert in extracted_certs:
            nickname = str(DN(cert.subject))
            self.add_cert(cert, nickname, EMPTY_TRUST_FLAGS)

        if extracted_key:
            with tempfile.NamedTemporaryFile() as in_file, \
                    tempfile.NamedTemporaryFile() as out_file:
                for cert in extracted_certs:
                    in_file.write(cert.public_bytes(x509.Encoding.PEM))
                in_file.write(extracted_key)
                in_file.flush()
                out_password = ipautil.ipa_generate_password()
                out_pwdfile = ipautil.write_tmp_file(out_password)
                args = [
                    paths.OPENSSL, 'pkcs12',
                    '-export',
                    '-in', in_file.name,
                    '-out', out_file.name,
                    '-passin', 'file:' + self.pwd_file,
                    '-passout', 'file:' + out_pwdfile.name,
                    '-certpbe', 'aes-128-cbc',
                    '-keypbe', 'aes-128-cbc',
                ]
                try:
                    ipautil.run(args)
                except ipautil.CalledProcessError as e:
                    raise RuntimeError(
                        "No matching certificate found for private key from "
                        "%s" % key_file)

                self.import_pkcs12(out_file.name, out_password)
Beispiel #49
0
    def __spawn_instance(self):
        """
        Create and configure a new KRA instance using pkispawn.
        Creates a configuration file with IPA-specific
        parameters and passes it to the base class to call pkispawn
        """

        # Create an empty and secured file
        (cfg_fd, cfg_file) = tempfile.mkstemp()
        os.close(cfg_fd)
        pent = pwd.getpwnam(self.service_user)
        os.chown(cfg_file, pent.pw_uid, pent.pw_gid)
        self.tmp_agent_db = tempfile.mkdtemp(prefix="tmp-",
                                             dir=paths.VAR_LIB_IPA)
        tmp_agent_pwd = ipautil.ipa_generate_password()

        # Create a temporary file for the admin PKCS #12 file
        (admin_p12_fd, admin_p12_file) = tempfile.mkstemp()
        os.close(admin_p12_fd)

        # Create KRA configuration
        config = RawConfigParser()
        config.optionxform = str
        config.add_section("KRA")

        # Security Domain Authentication
        config.set("KRA", "pki_security_domain_https_port", "443")
        config.set("KRA", "pki_security_domain_password", self.admin_password)
        config.set("KRA", "pki_security_domain_user", self.admin_user)

        # issuing ca
        config.set("KRA", "pki_issuing_ca_uri",
                   "https://%s" % ipautil.format_netloc(self.fqdn, 443))

        # Server
        config.set("KRA", "pki_enable_proxy", "True")
        config.set("KRA", "pki_restart_configured_instance", "False")
        config.set("KRA", "pki_backup_keys", "True")
        config.set("KRA", "pki_backup_password", self.admin_password)

        # Client security database
        config.set("KRA", "pki_client_database_dir", self.tmp_agent_db)
        config.set("KRA", "pki_client_database_password", tmp_agent_pwd)
        config.set("KRA", "pki_client_database_purge", "True")
        config.set("KRA", "pki_client_pkcs12_password", self.admin_password)

        # Administrator
        config.set("KRA", "pki_admin_name", self.admin_user)
        config.set("KRA", "pki_admin_uid", self.admin_user)
        config.set("KRA", "pki_admin_email", "root@localhost")
        config.set("KRA", "pki_admin_password", self.admin_password)
        config.set("KRA", "pki_admin_nickname", "ipa-ca-agent")
        config.set("KRA", "pki_admin_subject_dn",
                   str(DN(('cn', 'ipa-ca-agent'), self.subject_base)))
        config.set("KRA", "pki_import_admin_cert", "False")
        config.set("KRA", "pki_client_admin_cert_p12", admin_p12_file)

        # Directory server
        config.set("KRA", "pki_ds_ldap_port", "389")
        config.set("KRA", "pki_ds_password", self.dm_password)
        config.set("KRA", "pki_ds_base_dn", str(self.basedn))
        config.set("KRA", "pki_ds_database", "ipaca")
        config.set("KRA", "pki_ds_create_new_db", "False")

        self._use_ldaps_during_spawn(config)

        # Certificate subject DNs
        config.set("KRA", "pki_subsystem_subject_dn",
                   str(DN(('cn', 'CA Subsystem'), self.subject_base)))
        config.set("KRA", "pki_sslserver_subject_dn",
                   str(DN(('cn', self.fqdn), self.subject_base)))
        config.set("KRA", "pki_audit_signing_subject_dn",
                   str(DN(('cn', 'KRA Audit'), self.subject_base)))
        config.set(
            "KRA", "pki_transport_subject_dn",
            str(DN(('cn', 'KRA Transport Certificate'), self.subject_base)))
        config.set(
            "KRA", "pki_storage_subject_dn",
            str(DN(('cn', 'KRA Storage Certificate'), self.subject_base)))

        # Certificate nicknames
        # Note that both the server certs and subsystem certs reuse
        # the ca certs.
        config.set("KRA", "pki_subsystem_nickname",
                   "subsystemCert cert-pki-ca")
        config.set("KRA", "pki_sslserver_nickname", "Server-Cert cert-pki-ca")
        config.set("KRA", "pki_audit_signing_nickname",
                   "auditSigningCert cert-pki-kra")
        config.set("KRA", "pki_transport_nickname",
                   "transportCert cert-pki-kra")
        config.set("KRA", "pki_storage_nickname", "storageCert cert-pki-kra")

        # Shared db settings
        # Needed because CA and KRA share the same database
        # We will use the dbuser created for the CA
        config.set("KRA", "pki_share_db", "True")
        config.set(
            "KRA", "pki_share_dbuser_dn",
            str(DN(('uid', 'pkidbuser'), ('ou', 'people'), ('o', 'ipaca'))))

        if not (os.path.isdir(paths.PKI_TOMCAT_ALIAS_DIR)
                and os.path.isfile(paths.PKI_TOMCAT_PASSWORD_CONF)):
            # generate pin which we know can be used for FIPS NSS database
            pki_pin = ipautil.ipa_generate_password()
            config.set("KRA", "pki_pin", pki_pin)
        else:
            pki_pin = None

        _p12_tmpfile_handle, p12_tmpfile_name = tempfile.mkstemp(dir=paths.TMP)

        if self.clone:
            krafile = self.pkcs12_info[0]
            shutil.copy(krafile, p12_tmpfile_name)
            pent = pwd.getpwnam(self.service_user)
            os.chown(p12_tmpfile_name, pent.pw_uid, pent.pw_gid)

            # Security domain registration
            config.set("KRA", "pki_security_domain_hostname", self.fqdn)
            config.set("KRA", "pki_security_domain_https_port", "443")
            config.set("KRA", "pki_security_domain_user", self.admin_user)
            config.set("KRA", "pki_security_domain_password",
                       self.admin_password)

            # Clone
            config.set("KRA", "pki_clone", "True")
            config.set("KRA", "pki_clone_pkcs12_path", p12_tmpfile_name)
            config.set("KRA", "pki_clone_pkcs12_password", self.dm_password)
            config.set("KRA", "pki_clone_setup_replication", "False")
            config.set(
                "KRA", "pki_clone_uri",
                "https://%s" % ipautil.format_netloc(self.master_host, 443))
        else:
            # the admin cert file is needed for the first instance of KRA
            cert = self.get_admin_cert()
            # First make sure that the directory exists
            parentdir = os.path.dirname(paths.ADMIN_CERT_PATH)
            if not os.path.exists(parentdir):
                os.makedirs(parentdir)
            with open(paths.ADMIN_CERT_PATH, "wb") as admin_path:
                admin_path.write(
                    base64.b64encode(cert.public_bytes(x509.Encoding.DER)))

        # Generate configuration file
        with open(cfg_file, "w") as f:
            config.write(f)

        try:
            DogtagInstance.spawn_instance(self,
                                          cfg_file,
                                          nolog_list=(self.dm_password,
                                                      self.admin_password,
                                                      pki_pin, tmp_agent_pwd))
        finally:
            os.remove(p12_tmpfile_name)
            os.remove(cfg_file)
            os.remove(admin_p12_file)

        shutil.move(paths.KRA_BACKUP_KEYS_P12, paths.KRACERT_P12)
        logger.debug("completed creating KRA instance")
Beispiel #50
0
    if (options.http_cert_files and options.dirsrv_cert_files and
            http_ca_cert != dirsrv_ca_cert):
        sys.exit("Apache Server SSL certificate and Directory Server SSL "
                 "certificate are not signed by the same CA certificate")

    if not options.dm_password:
        dm_password = read_dm_password()

        if dm_password is None:
            sys.exit("Directory Manager password required")
    else:
        dm_password = options.dm_password

    if not options.master_password:
        master_password = ipa_generate_password()
    else:
        master_password = options.master_password

    if not options.admin_password:
        admin_password = read_admin_password()
        if admin_password is None:
            sys.exit("IPA admin password required")
    else:
        admin_password = options.admin_password

    if setup_kra:
        try:
            kra.install_check(None, options, False,
                              dogtag.install_constants.DOGTAG_VERSION)
        except RuntimeError as e:
Beispiel #51
0
 def generate_random(self):
     return ipautil.ipa_generate_password()
Beispiel #52
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")
Beispiel #53
0
    def create_db(self, user=None, group=None, mode=None, backup=False):
        """Create cert DB

        :param user: User owner the secdir
        :param group: Group owner of the secdir
        :param mode: Mode of the secdir
        :param backup: Backup the sedir files
        """
        if mode is not None:
            dirmode = mode
            filemode = mode & 0o666
            pwdfilemode = mode & 0o660
        else:
            dirmode = 0o750
            filemode = 0o640
            pwdfilemode = 0o640

        uid = -1
        gid = -1
        if user is not None:
            uid = pwd.getpwnam(user).pw_uid
        if group is not None:
            gid = grp.getgrnam(group).gr_gid

        if backup:
            for filename in self.backup_filenames:
                ipautil.backup_file(filename)

        if not os.path.exists(self.secdir):
            os.makedirs(self.secdir, dirmode)

        if not os.path.exists(self.pwd_file):
            # Create the password file for this db
            with io.open(os.open(self.pwd_file,
                                 os.O_CREAT | os.O_WRONLY,
                                 pwdfilemode), 'w', closefd=True) as f:
                f.write(ipautil.ipa_generate_password())
                f.flush()

        # In case dbtype is auto, let certutil decide which type of DB
        # to create.
        if self.dbtype == 'auto':
            dbdir = self.secdir
        else:
            dbdir = '{}:{}'.format(self.dbtype, self.secdir)
        args = [
            paths.CERTUTIL,
            '-d', dbdir,
            '-N',
            '-f', self.pwd_file,
            # -@ in case it's an old db and it must be migrated
            '-@', self.pwd_file,
        ]
        ipautil.run(args, stdin=None, cwd=self.secdir)
        self._set_filenames(self._detect_dbtype())
        if self.filenames is None:
            # something went wrong...
            raise ValueError(
                "Failed to create NSSDB at '{}'".format(self.secdir)
            )

        # Finally fix up perms
        os.chown(self.secdir, uid, gid)
        os.chmod(self.secdir, dirmode)
        tasks.restore_context(self.secdir, force=True)
        for filename in self.filenames:
            if os.path.exists(filename):
                os.chown(filename, uid, gid)
                if filename == self.pwd_file:
                    new_mode = pwdfilemode
                else:
                    new_mode = filemode
                os.chmod(filename, new_mode)
                tasks.restore_context(filename, force=True)
Beispiel #54
0
    def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
        assert isinstance(dn, DN)

        # then givenname and sn are required attributes
        if 'givenname' not in entry_attrs:
            raise errors.RequirementError(name='givenname', error=_('givenname is required'))

        if 'sn' not in entry_attrs:
            raise errors.RequirementError(name='sn', error=_('sn is required'))

        # we don't want an user private group to be created for this user
        # add NO_UPG_MAGIC description attribute to let the DS plugin know
        entry_attrs.setdefault('description', [])
        entry_attrs['description'].append(NO_UPG_MAGIC)

        # uidNumber/gidNumber
        entry_attrs.setdefault('uidnumber', baseldap.DNA_MAGIC)
        entry_attrs.setdefault('gidnumber', baseldap.DNA_MAGIC)

        if not client_has_capability(
                options['version'], 'optional_uid_params'):
            # https://fedorahosted.org/freeipa/ticket/2886
            # Old clients say 999 (OLD_DNA_MAGIC) when they really mean
            # "assign a value dynamically".
            OLD_DNA_MAGIC = 999
            if entry_attrs.get('uidnumber') == OLD_DNA_MAGIC:
                entry_attrs['uidnumber'] = baseldap.DNA_MAGIC
            if entry_attrs.get('gidnumber') == OLD_DNA_MAGIC:
                entry_attrs['gidnumber'] = baseldap.DNA_MAGIC


        # Check the lenght of the RDN (uid) value
        config = ldap.get_ipa_config()
        if 'ipamaxusernamelength' in config:
            if len(keys[-1]) > int(config.get('ipamaxusernamelength')[0]):
                raise errors.ValidationError(
                    name=self.obj.primary_key.cli_name,
                    error=_('can be at most %(len)d characters') % dict(
                        len = int(config.get('ipamaxusernamelength')[0])
                    )
                )
        default_shell = config.get('ipadefaultloginshell', [paths.SH])[0]
        entry_attrs.setdefault('loginshell', default_shell)
        # hack so we can request separate first and last name in CLI
        full_name = '%s %s' % (entry_attrs['givenname'], entry_attrs['sn'])
        entry_attrs.setdefault('cn', full_name)

        # Homedirectory
        # (order is : option, placeholder (TBD), CLI default value (here in config))
        if 'homedirectory' not in entry_attrs:
            # get home's root directory from config
            homes_root = config.get('ipahomesrootdir', [paths.HOME_DIR])[0]
            # build user's home directory based on his uid
            entry_attrs['homedirectory'] = posixpath.join(homes_root, keys[-1])

        # Kerberos principal
        entry_attrs.setdefault('krbprincipalname', '%s@%s' % (entry_attrs['uid'], api.env.realm))


        # If requested, generate a userpassword
        if 'userpassword' not in entry_attrs and options.get('random'):
            entry_attrs['userpassword'] = ipa_generate_password(baseuser_pwdchars)
            # save the password so it can be displayed in post_callback
            setattr(context, 'randompassword', entry_attrs['userpassword'])

        # Check the email or create it
        if 'mail' in entry_attrs:
            entry_attrs['mail'] = self.obj.normalize_and_validate_email(entry_attrs['mail'], config)
        else:
            # No e-mail passed in. If we have a default e-mail domain set
            # then we'll add it automatically.
            defaultdomain = config.get('ipadefaultemaildomain', [None])[0]
            if defaultdomain:
                entry_attrs['mail'] = self.obj.normalize_and_validate_email(keys[-1], config)

        # If the manager is defined, check it is a ACTIVE user to validate it
        if 'manager' in entry_attrs:
            entry_attrs['manager'] = self.obj.normalize_manager(entry_attrs['manager'], self.obj.active_container_dn)

        if ('objectclass' in entry_attrs
            and 'userclass' in entry_attrs
            and 'ipauser' not in entry_attrs['objectclass']):
            entry_attrs['objectclass'].append('ipauser')

        if 'ipatokenradiusconfiglink' in entry_attrs:
            cl = entry_attrs['ipatokenradiusconfiglink']
            if cl:
                if 'objectclass' not in entry_attrs:
                    _entry = ldap.get_entry(dn, ['objectclass'])
                    entry_attrs['objectclass'] = _entry['objectclass']

                if 'ipatokenradiusproxyuser' not in entry_attrs['objectclass']:
                    entry_attrs['objectclass'].append('ipatokenradiusproxyuser')

                answer = self.api.Object['radiusproxy'].get_dn_if_exists(cl)
                entry_attrs['ipatokenradiusconfiglink'] = answer

        return dn
Beispiel #55
0
    def import_files(self, files, import_keys=False, key_password=None,
                     key_nickname=None):
        """
        Import certificates and a single private key from multiple files

        The files may be in PEM and DER certificate, PKCS#7 certificate chain,
        PKCS#8 and raw private key and PKCS#12 formats.

        :param files: Names of files to import
        :param import_keys: Whether to import private keys
        :param key_password: Password to decrypt private keys
        :param key_nickname: Nickname of the private key to import from PKCS#12
            files
        """
        key_file = None
        extracted_key = None
        extracted_certs = []

        for filename in files:
            try:
                with open(filename, 'rb') as f:
                    data = f.read()
            except IOError as e:
                raise RuntimeError(
                    "Failed to open %s: %s" % (filename, e.strerror))

            # Try to parse the file as PEM file
            matches = list(
                re.finditer(
                    br'-----BEGIN (.+?)-----(.*?)-----END \1-----',
                    data, re.DOTALL
                )
            )
            if matches:
                loaded = False
                for match in matches:
                    body = match.group()
                    label = match.group(1)
                    line = len(data[:match.start() + 1].splitlines())

                    if label in (b'CERTIFICATE', b'X509 CERTIFICATE',
                                 b'X.509 CERTIFICATE'):
                        try:
                            cert = x509.load_pem_x509_certificate(body)
                        except ValueError as e:
                            if label != b'CERTIFICATE':
                                logger.warning(
                                    "Skipping certificate in %s at line %s: "
                                    "%s",
                                    filename, line, e)
                                continue
                        else:
                            extracted_certs.append(cert)
                            loaded = True
                            continue

                    if label in (b'PKCS7', b'PKCS #7 SIGNED DATA',
                                 b'CERTIFICATE'):
                        try:
                            certs = x509.pkcs7_to_certs(body)
                        except ipautil.CalledProcessError as e:
                            if label == b'CERTIFICATE':
                                logger.warning(
                                    "Skipping certificate in %s at line %s: "
                                    "%s",
                                    filename, line, e)
                            else:
                                logger.warning(
                                    "Skipping PKCS#7 in %s at line %s: %s",
                                    filename, line, e)
                            continue
                        else:
                            extracted_certs.extend(certs)
                            loaded = True
                            continue

                    if label in (b'PRIVATE KEY', b'ENCRYPTED PRIVATE KEY',
                                 b'RSA PRIVATE KEY', b'DSA PRIVATE KEY',
                                 b'EC PRIVATE KEY'):
                        if not import_keys:
                            continue

                        if key_file:
                            raise RuntimeError(
                                "Can't load private key from both %s and %s" %
                                (key_file, filename))

                        # the args -v2 aes256 -v2prf hmacWithSHA256 are needed
                        # on OpenSSL 1.0.2 (fips mode). As soon as FreeIPA
                        # requires OpenSSL 1.1.0 we'll be able to drop them
                        args = [
                            paths.OPENSSL, 'pkcs8',
                            '-topk8',
                            '-v2', 'aes256', '-v2prf', 'hmacWithSHA256',
                            '-passout', 'file:' + self.pwd_file,
                        ]
                        if ((label != b'PRIVATE KEY' and key_password) or
                                label == b'ENCRYPTED PRIVATE KEY'):
                            key_pwdfile = ipautil.write_tmp_file(key_password)
                            args += [
                                '-passin', 'file:' + key_pwdfile.name,
                            ]
                        try:
                            result = ipautil.run(
                                args, stdin=body, capture_output=True)
                        except ipautil.CalledProcessError as e:
                            logger.warning(
                                "Skipping private key in %s at line %s: %s",
                                filename, line, e)
                            continue
                        else:
                            extracted_key = result.raw_output
                            key_file = filename
                            loaded = True
                            continue
                if loaded:
                    continue
                raise RuntimeError("Failed to load %s" % filename)

            # Try to load the file as DER certificate
            try:
                cert = x509.load_der_x509_certificate(data)
            except ValueError:
                pass
            else:
                extracted_certs.append(cert)
                continue

            # Try to import the file as PKCS#12 file
            if import_keys:
                try:
                    self.import_pkcs12(filename, key_password)
                except RuntimeError:
                    pass
                else:
                    if key_file:
                        raise RuntimeError(
                            "Can't load private key from both %s and %s" %
                            (key_file, filename))
                    key_file = filename

                    server_certs = self.find_server_certs()
                    if key_nickname:
                        for nickname, _trust_flags in server_certs:
                            if nickname == key_nickname:
                                break
                        else:
                            raise RuntimeError(
                                "Server certificate \"%s\" not found in %s" %
                                (key_nickname, filename))
                    else:
                        if len(server_certs) > 1:
                            raise RuntimeError(
                                "%s server certificates found in %s, "
                                "expecting only one" %
                                (len(server_certs), filename))

                    continue

            raise RuntimeError("Failed to load %s" % filename)

        if import_keys and not key_file:
            raise RuntimeError(
                "No server certificates found in %s" % (', '.join(files)))

        for cert in extracted_certs:
            nickname = str(DN(cert.subject))
            self.add_cert(cert, nickname, EMPTY_TRUST_FLAGS)

        if extracted_key:
            with tempfile.NamedTemporaryFile() as in_file, \
                    tempfile.NamedTemporaryFile() as out_file:
                for cert in extracted_certs:
                    in_file.write(cert.public_bytes(x509.Encoding.PEM))
                in_file.write(extracted_key)
                in_file.flush()
                out_password = ipautil.ipa_generate_password()
                out_pwdfile = ipautil.write_tmp_file(out_password)
                args = [
                    paths.OPENSSL, 'pkcs12',
                    '-export',
                    '-in', in_file.name,
                    '-out', out_file.name,
                    '-passin', 'file:' + self.pwd_file,
                    '-passout', 'file:' + out_pwdfile.name,
                ]
                try:
                    ipautil.run(args)
                except ipautil.CalledProcessError as e:
                    raise RuntimeError(
                        "No matching certificate found for private key from "
                        "%s" % key_file)

                self.import_pkcs12(out_file.name, out_password)
Beispiel #56
0
 def create_noise_file(self):
     if os.path.isfile(self.noise_fname):
         os.remove(self.noise_fname)
     with open(self.noise_fname, "w") as f:
         self.set_perms(f)
         f.write(ipautil.ipa_generate_password())
Beispiel #57
0
 def check_userpassword(self, entry_attrs, **options):
     if 'userpassword' not in entry_attrs and options.get('random'):
         entry_attrs['userpassword'] = ipa_generate_password(
             baseuser_pwdchars, pwd_len=GEN_TMP_PWD_LEN)
         # save the password so it can be displayed in post_callback
         setattr(context, 'randompassword', entry_attrs['userpassword'])
Beispiel #58
0
    def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
        assert isinstance(dn, DN)
        if not options.get('noprivate', False):
            try:
                # The Managed Entries plugin will allow a user to be created
                # even if a group has a duplicate name. This would leave a user
                # without a private group. Check for both the group and the user.
                self.api.Object['group'].get_dn_if_exists(keys[-1])
                try:
                    self.api.Command['user_show'](keys[-1])
                    self.obj.handle_duplicate_entry(*keys)
                except errors.NotFound:
                    raise errors.ManagedGroupExistsError(group=keys[-1])
            except errors.NotFound:
                pass
        else:
            # we don't want an user private group to be created for this user
            # add NO_UPG_MAGIC description attribute to let the DS plugin know
            entry_attrs.setdefault('description', [])
            entry_attrs['description'].append(NO_UPG_MAGIC)

        entry_attrs.setdefault('uidnumber', baseldap.DNA_MAGIC)

        if not client_has_capability(
                options['version'], 'optional_uid_params'):
            # https://fedorahosted.org/freeipa/ticket/2886
            # Old clients say 999 (OLD_DNA_MAGIC) when they really mean
            # "assign a value dynamically".
            OLD_DNA_MAGIC = 999
            if entry_attrs.get('uidnumber') == OLD_DNA_MAGIC:
                entry_attrs['uidnumber'] = baseldap.DNA_MAGIC
            if entry_attrs.get('gidnumber') == OLD_DNA_MAGIC:
                entry_attrs['gidnumber'] = baseldap.DNA_MAGIC

        validate_nsaccountlock(entry_attrs)
        config = ldap.get_ipa_config()[1]
        if 'ipamaxusernamelength' in config:
            if len(keys[-1]) > int(config.get('ipamaxusernamelength')[0]):
                raise errors.ValidationError(
                    name=self.obj.primary_key.cli_name,
                    error=_('can be at most %(len)d characters') % dict(
                        len = int(config.get('ipamaxusernamelength')[0])
                    )
                )
        default_shell = config.get('ipadefaultloginshell', ['/bin/sh'])[0]
        entry_attrs.setdefault('loginshell', default_shell)
        # hack so we can request separate first and last name in CLI
        full_name = '%s %s' % (entry_attrs['givenname'], entry_attrs['sn'])
        entry_attrs.setdefault('cn', full_name)
        if 'homedirectory' not in entry_attrs:
            # get home's root directory from config
            homes_root = config.get('ipahomesrootdir', ['/home'])[0]
            # build user's home directory based on his uid
            entry_attrs['homedirectory'] = posixpath.join(homes_root, keys[-1])
        entry_attrs.setdefault('krbpwdpolicyreference',
                               DN(('cn', 'global_policy'), ('cn', api.env.realm), ('cn', 'kerberos'),
                                  api.env.basedn))
        entry_attrs.setdefault('krbprincipalname', '%s@%s' % (entry_attrs['uid'], api.env.realm))

        if entry_attrs.get('gidnumber') is None:
            # gidNumber wasn't specified explicity, find out what it should be
            if not options.get('noprivate', False) and ldap.has_upg():
                # User Private Groups - uidNumber == gidNumber
                entry_attrs['gidnumber'] = entry_attrs['uidnumber']
            else:
                # we're adding new users to a default group, get its gidNumber
                # get default group name from config
                def_primary_group = config.get('ipadefaultprimarygroup')
                group_dn = self.api.Object['group'].get_dn(def_primary_group)
                try:
                    (group_dn, group_attrs) = ldap.get_entry(group_dn, ['gidnumber'])
                except errors.NotFound:
                    error_msg = _('Default group for new users not found')
                    raise errors.NotFound(reason=error_msg)
                if 'gidnumber' not in group_attrs:
                    error_msg = _('Default group for new users is not POSIX')
                    raise errors.NotFound(reason=error_msg)
                entry_attrs['gidnumber'] = group_attrs['gidnumber']

        if 'userpassword' not in entry_attrs and options.get('random'):
            entry_attrs['userpassword'] = ipa_generate_password(user_pwdchars)
            # save the password so it can be displayed in post_callback
            setattr(context, 'randompassword', entry_attrs['userpassword'])

        if 'mail' in entry_attrs:
            entry_attrs['mail'] = self.obj._normalize_and_validate_email(entry_attrs['mail'], config)
        else:
            # No e-mail passed in. If we have a default e-mail domain set
            # then we'll add it automatically.
            defaultdomain = config.get('ipadefaultemaildomain', [None])[0]
            if defaultdomain:
                entry_attrs['mail'] = self.obj._normalize_and_validate_email(keys[-1], config)

        if 'manager' in entry_attrs:
            entry_attrs['manager'] = self.obj._normalize_manager(entry_attrs['manager'])

        if ('objectclass' in entry_attrs
            and 'userclass' in entry_attrs
            and 'ipauser' not in entry_attrs['objectclass']):
            entry_attrs['objectclass'].append('ipauser')

        if 'ipatokenradiusconfiglink' in entry_attrs:
            cl = entry_attrs['ipatokenradiusconfiglink']
            if cl:
                if 'objectclass' not in entry_attrs:
                    _entry = ldap.get_entry(dn, ['objectclass'])
                    entry_attrs['objectclass'] = _entry['objectclass']

                if 'ipatokenradiusproxyuser' not in entry_attrs['objectclass']:
                    entry_attrs['objectclass'].append('ipatokenradiusproxyuser')

                answer = self.api.Object['radiusproxy'].get_dn_if_exists(cl)
                entry_attrs['ipatokenradiusconfiglink'] = answer

        return dn
Beispiel #59
0
    def import_files(self, files, db_password_filename, import_keys=False,
                     key_password=None, key_nickname=None):
        """
        Import certificates and a single private key from multiple files

        The files may be in PEM and DER certificate, PKCS#7 certificate chain,
        PKCS#8 and raw private key and PKCS#12 formats.

        :param files: Names of files to import
        :param db_password_filename: Name of file containing the database
            password
        :param import_keys: Whether to import private keys
        :param key_password: Password to decrypt private keys
        :param key_nickname: Nickname of the private key to import from PKCS#12
            files
        """
        key_file = None
        extracted_key = None
        extracted_certs = ''

        for filename in files:
            try:
                with open(filename, 'rb') as f:
                    data = f.read()
            except IOError as e:
                raise RuntimeError(
                    "Failed to open %s: %s" % (filename, e.strerror))

            # Try to parse the file as PEM file
            matches = list(re.finditer(
                r'-----BEGIN (.+?)-----(.*?)-----END \1-----', data, re.DOTALL))
            if matches:
                loaded = False
                for match in matches:
                    body = match.group()
                    label = match.group(1)
                    line = len(data[:match.start() + 1].splitlines())

                    if label in ('CERTIFICATE', 'X509 CERTIFICATE',
                                 'X.509 CERTIFICATE'):
                        try:
                            x509.load_certificate(match.group(2))
                        except NSPRError as e:
                            if label != 'CERTIFICATE':
                                root_logger.warning(
                                    "Skipping certificate in %s at line %s: %s",
                                    filename, line, e)
                                continue
                        else:
                            extracted_certs += body + '\n'
                            loaded = True
                            continue

                    if label in ('PKCS7', 'PKCS #7 SIGNED DATA', 'CERTIFICATE'):
                        args = [
                            paths.OPENSSL, 'pkcs7',
                            '-print_certs',
                        ]
                        try:
                            result = ipautil.run(
                                args, stdin=body, capture_output=True)
                        except ipautil.CalledProcessError as e:
                            if label == 'CERTIFICATE':
                                root_logger.warning(
                                    "Skipping certificate in %s at line %s: %s",
                                    filename, line, e)
                            else:
                                root_logger.warning(
                                    "Skipping PKCS#7 in %s at line %s: %s",
                                    filename, line, e)
                            continue
                        else:
                            extracted_certs += result.output + '\n'
                            loaded = True
                            continue

                    if label in ('PRIVATE KEY', 'ENCRYPTED PRIVATE KEY',
                                 'RSA PRIVATE KEY', 'DSA PRIVATE KEY',
                                 'EC PRIVATE KEY'):
                        if not import_keys:
                            continue

                        if key_file:
                            raise RuntimeError(
                                "Can't load private key from both %s and %s" %
                                (key_file, filename))

                        args = [
                            paths.OPENSSL, 'pkcs8',
                            '-topk8',
                            '-passout', 'file:' + db_password_filename,
                        ]
                        if ((label != 'PRIVATE KEY' and key_password) or
                            label == 'ENCRYPTED PRIVATE KEY'):
                            key_pwdfile = ipautil.write_tmp_file(key_password)
                            args += [
                                '-passin', 'file:' + key_pwdfile.name,
                            ]
                        try:
                            result = ipautil.run(
                                args, stdin=body, capture_output=True)
                        except ipautil.CalledProcessError as e:
                            root_logger.warning(
                                "Skipping private key in %s at line %s: %s",
                                filename, line, e)
                            continue
                        else:
                            extracted_key = result.output
                            key_file = filename
                            loaded = True
                            continue
                if loaded:
                    continue
                raise RuntimeError("Failed to load %s" % filename)

            # Try to load the file as DER certificate
            try:
                x509.load_certificate(data, x509.DER)
            except NSPRError:
                pass
            else:
                data = x509.make_pem(base64.b64encode(data))
                extracted_certs += data + '\n'
                continue

            # Try to import the file as PKCS#12 file
            if import_keys:
                try:
                    self.import_pkcs12(
                        filename, db_password_filename, key_password)
                except RuntimeError:
                    pass
                else:
                    if key_file:
                        raise RuntimeError(
                            "Can't load private key from both %s and %s" %
                            (key_file, filename))
                    key_file = filename

                    server_certs = self.find_server_certs()
                    if key_nickname:
                        for nickname, trust_flags in server_certs:
                            if nickname == key_nickname:
                                break
                        else:
                            raise RuntimeError(
                                "Server certificate \"%s\" not found in %s" %
                                (key_nickname, filename))
                    else:
                        if len(server_certs) > 1:
                            raise RuntimeError(
                                "%s server certificates found in %s, "
                                "expecting only one" %
                                (len(server_certs), filename))

                    continue

            raise RuntimeError("Failed to load %s" % filename)

        if import_keys and not key_file:
            raise RuntimeError(
                "No server certificates found in %s" % (', '.join(files)))

        nss_certs = x509.load_certificate_list(extracted_certs)
        nss_cert = None
        for nss_cert in nss_certs:
            nickname = str(nss_cert.subject)
            self.add_cert(nss_cert.der_data, nickname, ',,')
        del nss_certs, nss_cert

        if extracted_key:
            in_file = ipautil.write_tmp_file(extracted_certs + extracted_key)
            out_file = tempfile.NamedTemporaryFile()
            out_password = ipautil.ipa_generate_password()
            out_pwdfile = ipautil.write_tmp_file(out_password)
            args = [
                paths.OPENSSL, 'pkcs12',
                '-export',
                '-in', in_file.name,
                '-out', out_file.name,
                '-passin', 'file:' + db_password_filename,
                '-passout', 'file:' + out_pwdfile.name,
            ]
            try:
                ipautil.run(args)
            except ipautil.CalledProcessError as e:
                raise RuntimeError(
                    "No matching certificate found for private key from %s" %
                    key_file)

            self.import_pkcs12(out_file.name, db_password_filename,
                               out_password)