示例#1
0
文件: cert.py 项目: tiran/pki
def start_stop(instance):
    """Start the server, run the block, and guarantee stop afterwards."""
    logger.info('Starting the instance')
    instance.start()
    logger.info('Sleeping for 10 seconds to allow server time to start...')
    time.sleep(10)
    try:
        yield
    finally:
        logger.info('Stopping the instance')
        instance.stop()
示例#2
0
    def destroy(self, deployer):

        logger.info(log.PKIDESTROY_BEGIN_MESSAGE_2,
                    deployer.mdict['pki_subsystem'],
                    deployer.mdict['pki_instance_name'])

        logger.info('Initialization')

        instance = pki.server.instance.PKIInstance(deployer.mdict['pki_instance_name'])
        instance.load()

        try:
            # verify that this type of "subsystem" currently EXISTS
            # for this "instance"
            deployer.instance.verify_subsystem_exists()
            # verify that the command-line parameters match the values
            # that are present in the corresponding configuration file
            deployer.configuration_file.verify_command_matches_configuration_file()
            # establish 'uid' and 'gid'
            deployer.identity.set_uid(deployer.mdict['pki_user'])
            deployer.identity.set_gid(deployer.mdict['pki_group'])
            # get ports to remove selinux context
            deployer.configuration_file.populate_non_default_ports()

            # remove kra connector from CA if this is a KRA
            deployer.kra_connector.deregister()

            # remove tps connector from TKS if this is a TPS
            deployer.tps_connector.deregister()

            # de-register instance from its Security Domain
            #
            #     NOTE:  Since the security domain of an instance must be up
            #            and running in order to be de-registered, this step
            #            must be done PRIOR to instance shutdown because this
            #            instance's security domain may be a part of a
            #            tightly-coupled shared instance.
            #

            # Previously we obtained the token through a command line interface
            # no longer supported. Thus we assume no token and the deregister op will
            # take place without the token using an alternate method.

            deployer.security_domain.deregister(None)

        except Exception as e:  # pylint: disable=broad-except
            logger.error(str(e))
            # If it is a normal destroy, pass any exception
            if not deployer.mdict['pki_force_destroy']:
                raise

        finally:
            # ALWAYS Stop this Tomcat PKI Process
            instance.stop()
示例#3
0
    def destroy(self, deployer):

        logger.info(log.PKIDESTROY_BEGIN_MESSAGE_2,
                    deployer.mdict['pki_subsystem'],
                    deployer.mdict['pki_instance_name'])

        logger.info('Initialization')

        instance = self.instance
        instance.load()

        try:
            # verify that this type of "subsystem" currently EXISTS
            # for this "instance"
            deployer.instance.verify_subsystem_exists()
            # verify that the command-line parameters match the values
            # that are present in the corresponding configuration file
            deployer.configuration_file.verify_command_matches_configuration_file(
            )
            # establish 'uid' and 'gid'
            deployer.identity.set_uid(deployer.mdict['pki_user'])
            deployer.identity.set_gid(deployer.mdict['pki_group'])
            # get ports to remove selinux context
            deployer.configuration_file.populate_non_default_ports()

            # remove kra connector from CA if this is a KRA
            deployer.kra_connector.deregister()

            # remove tps connector from TKS if this is a TPS
            deployer.tps_connector.deregister()

            # de-register instance from its Security Domain
            #
            #     NOTE:  Since the security domain of an instance must be up
            #            and running in order to be de-registered, this step
            #            must be done PRIOR to instance shutdown because this
            #            instance's security domain may be a part of a
            #            tightly-coupled shared instance.
            #

            deployer.security_domain.deregister()

        except Exception as e:  # pylint: disable=broad-except
            logger.error(str(e))
            # If it is a normal destroy, pass any exception
            if not deployer.force:
                raise

        finally:
            # ALWAYS Stop this Tomcat PKI Process
            logger.info('Stopping PKI server')
            instance.stop(wait=True,
                          max_wait=deployer.startup_timeout,
                          timeout=deployer.request_timeout)
示例#4
0
    def execute(self, argv):

        try:
            opts, args = getopt.gnu_getopt(argv, 'i:v', [
                'verbose', 'debug', 'help'])

        except getopt.GetoptError as e:
            logger.error(e)
            self.print_help()
            sys.exit(1)

        for o, _ in opts:
            if o == '--debug':
                logging.getLogger().setLevel(logging.DEBUG)

            elif o in ('-v', '--verbose'):
                logging.getLogger().setLevel(logging.INFO)

            elif o == '--help':
                self.print_help()
                sys.exit()

            else:
                logger.error('Unknown option: %s', o)
                self.print_help()
                sys.exit(1)

        if len(args) != 1:
            logger.error('Missing instance ID')
            self.print_help()
            sys.exit(1)

        instance_name = args[0]

        instance = pki.server.instance.PKIInstance(instance_name)

        if not instance.is_valid():
            logger.error('Invalid instance %s.', instance_name)
            sys.exit(1)

        if not instance.is_active():
            self.print_message('%s instance already stopped' % instance_name)
            return

        instance.load()
        instance.stop()

        self.print_message('%s instance stopped' % instance_name)
示例#5
0
    def spawn(self, deployer):

        external = deployer.configuration_file.external
        standalone = deployer.configuration_file.standalone
        step_one = deployer.configuration_file.external_step_one
        skip_configuration = deployer.configuration_file.skip_configuration

        if (external or standalone) and step_one or skip_configuration:
            logger.info('Skipping configuration')
            return

        logger.info('Configuring subsystem')

        try:
            PKISPAWN_STARTUP_TIMEOUT_SECONDS = \
                int(os.environ['PKISPAWN_STARTUP_TIMEOUT_SECONDS'])
        except (KeyError, ValueError):
            PKISPAWN_STARTUP_TIMEOUT_SECONDS = 60
        if PKISPAWN_STARTUP_TIMEOUT_SECONDS <= 0:
            PKISPAWN_STARTUP_TIMEOUT_SECONDS = 60

        instance = self.instance
        instance.load()

        subsystem = instance.get_subsystem(deployer.mdict['pki_subsystem'].lower())

        # configure internal database
        subsystem.config['internaldb.ldapconn.host'] = deployer.mdict['pki_ds_hostname']

        if config.str2bool(deployer.mdict['pki_ds_secure_connection']):
            subsystem.config['internaldb.ldapconn.secureConn'] = 'true'
            subsystem.config['internaldb.ldapconn.port'] = deployer.mdict['pki_ds_ldaps_port']
        else:
            subsystem.config['internaldb.ldapconn.secureConn'] = 'false'
            subsystem.config['internaldb.ldapconn.port'] = deployer.mdict['pki_ds_ldap_port']

        subsystem.config['internaldb.ldapauth.bindDN'] = deployer.mdict['pki_ds_bind_dn']
        subsystem.config['internaldb.basedn'] = deployer.mdict['pki_ds_base_dn']
        subsystem.config['internaldb.database'] = deployer.mdict['pki_ds_database']

        if config.str2bool(deployer.mdict['pki_share_db']):
            subsystem.config['preop.internaldb.dbuser'] = deployer.mdict['pki_share_dbuser_dn']

        ocsp_uri = deployer.mdict.get('pki_default_ocsp_uri')
        if ocsp_uri:
            subsystem.config['ca.defaultOcspUri'] = ocsp_uri

        if subsystem.name == 'ca':
            serial_number_range_start = deployer.mdict.get('pki_serial_number_range_start')
            if serial_number_range_start:
                subsystem.config['dbs.beginSerialNumber'] = serial_number_range_start

            serial_number_range_end = deployer.mdict.get('pki_serial_number_range_end')
            if serial_number_range_end:
                subsystem.config['dbs.endSerialNumber'] = serial_number_range_end

            request_number_range_start = deployer.mdict.get('pki_request_number_range_start')
            if request_number_range_start:
                subsystem.config['dbs.beginRequestNumber'] = request_number_range_start

            request_number_range_end = deployer.mdict.get('pki_request_number_range_end')
            if request_number_range_end:
                subsystem.config['dbs.endRequestNumber'] = request_number_range_end

            replica_number_range_start = deployer.mdict.get('pki_replica_number_range_start')
            if replica_number_range_start:
                subsystem.config['dbs.beginReplicaNumber'] = replica_number_range_start

            replica_number_range_end = deployer.mdict.get('pki_replica_number_range_end')
            if replica_number_range_end:
                subsystem.config['dbs.endReplicaNumber'] = replica_number_range_end

        if subsystem.name == 'kra':
            if config.str2bool(deployer.mdict['pki_kra_ephemeral_requests']):
                logger.debug('Setting ephemeral requests to true')
                subsystem.config['kra.ephemeralRequests'] = 'true'

        if subsystem.name == 'tps':
            baseDN = subsystem.config['internaldb.basedn']
            dsHost = subsystem.config['internaldb.ldapconn.host']
            dsPort = subsystem.config['internaldb.ldapconn.port']

            subsystem.config['tokendb.activityBaseDN'] = 'ou=Activities,' + baseDN
            subsystem.config['tokendb.baseDN'] = 'ou=Tokens,' + baseDN
            subsystem.config['tokendb.certBaseDN'] = 'ou=Certificates,' + baseDN
            subsystem.config['tokendb.userBaseDN'] = baseDN
            subsystem.config['tokendb.hostport'] = dsHost + ':' + dsPort

        subsystem.save()

        token = pki.nssdb.normalize_token(deployer.mdict['pki_token_name'])
        nssdb = instance.open_nssdb()

        existing = deployer.configuration_file.existing
        step_two = deployer.configuration_file.external_step_two
        clone = deployer.configuration_file.clone

        try:
            if existing or (external or standalone) and step_two:

                self.import_system_cert_requests(deployer, subsystem)
                self.import_system_certs(deployer, nssdb, subsystem)

                self.configure_system_certs(deployer, subsystem)
                self.update_system_certs(deployer, nssdb, subsystem)
                subsystem.save()

                self.validate_system_certs(deployer, nssdb, subsystem)

            else:  # self-signed CA

                # To be implemented in ticket #1692.

                # Generate CA cert request.
                # Self sign CA cert.
                # Import self-signed CA cert into NSS database.

                pass

        finally:
            nssdb.close()

        create_temp_sslserver_cert = self.create_temp_sslserver_cert(deployer, instance)

        server_config = instance.get_server_config()
        unsecurePort = server_config.get_unsecure_port()
        securePort = server_config.get_secure_port()

        if deployer.mdict['pki_security_domain_type'] == 'existing':

            logger.info('Joining existing domain')

            deployer.join_domain()

            subsystem.config['securitydomain.name'] = deployer.domain_info.id
            subsystem.config['securitydomain.select'] = 'existing'

            # hostname and ports point to security domain
            subsystem.config['securitydomain.host'] = deployer.sd_host.Hostname
            subsystem.config['securitydomain.httpport'] = deployer.sd_host.Port
            subsystem.config['securitydomain.httpseeport'] = deployer.sd_host.SecurePort
            subsystem.config['securitydomain.httpsadminport'] = deployer.sd_host.SecureAdminPort
            subsystem.config['securitydomain.httpsagentport'] = deployer.sd_host.SecureAgentPort

        elif config.str2bool(deployer.mdict['pki_subordinate']) and \
                config.str2bool(deployer.mdict['pki_subordinate_create_new_security_domain']):

            logger.info('Creating new security subdomain')

            deployer.join_domain()

            sd_name = deployer.mdict['pki_subordinate_security_domain_name']
            subsystem.config['securitydomain.name'] = sd_name
            subsystem.config['securitydomain.select'] = 'new'

            # hostname and ports point to current host
            subsystem.config['securitydomain.host'] = deployer.mdict['pki_hostname']
            subsystem.config['securitydomain.httpport'] = unsecurePort
            subsystem.config['securitydomain.httpsagentport'] = securePort
            subsystem.config['securitydomain.httpseeport'] = securePort
            subsystem.config['securitydomain.httpsadminport'] = securePort

        else:

            logger.info('Creating new security domain')

            sd_name = deployer.mdict['pki_security_domain_name']
            subsystem.config['securitydomain.name'] = sd_name
            subsystem.config['securitydomain.select'] = 'new'

            # hostname and ports point to current host
            subsystem.config['securitydomain.host'] = deployer.mdict['pki_hostname']
            subsystem.config['securitydomain.httpport'] = unsecurePort
            subsystem.config['securitydomain.httpsagentport'] = securePort
            subsystem.config['securitydomain.httpseeport'] = securePort
            subsystem.config['securitydomain.httpsadminport'] = securePort

        subsystem.config['service.securityDomainPort'] = securePort

        hierarchy = subsystem.config.get('hierarchy.select')
        issuing_ca = deployer.mdict['pki_issuing_ca']

        if not (subsystem.type == 'CA' and hierarchy == 'Root'):

            if not external and not standalone:

                logger.info('Using CA at %s', issuing_ca)

                url = urllib.parse.urlparse(issuing_ca)

                subsystem.config['preop.ca.url'] = issuing_ca
                subsystem.config['preop.ca.hostname'] = url.hostname
                subsystem.config['preop.ca.httpsport'] = str(url.port)
                subsystem.config['preop.ca.httpsadminport'] = str(url.port)

        system_certs_imported = \
            deployer.mdict['pki_server_pkcs12_path'] != '' or \
            deployer.mdict['pki_clone_pkcs12_path'] != ''

        if not (subsystem.type == 'CA' and hierarchy == 'Root'):

            if external or standalone:
                subsystem.config['preop.ca.pkcs7'] = ''

            elif not clone and not system_certs_imported:

                logger.info('Retrieving CA certificate chain from %s', issuing_ca)

                pem_chain = self.get_cert_chain(instance, issuing_ca)
                base64_chain = pki.nssdb.convert_pkcs7(pem_chain, 'pem', 'base64')
                subsystem.config['preop.ca.pkcs7'] = base64_chain

                logger.info('Importing CA certificate chain')

                nssdb = instance.open_nssdb()
                try:
                    nssdb.import_pkcs7(pkcs7_data=pem_chain, trust_attributes='CT,C,C')
                finally:
                    nssdb.close()

        if subsystem.type == 'CA' and clone and not system_certs_imported:

            clone_uri = deployer.mdict['pki_clone_uri']

            logger.info('Retrieving CA certificate chain from %s', clone_uri)

            pem_chain = self.get_cert_chain(instance, clone_uri)
            base64_chain = pki.nssdb.convert_pkcs7(pem_chain, 'pem', 'base64')
            subsystem.config['preop.clone.pkcs7'] = base64_chain

            logger.info('Importing CA certificate chain')

            nssdb = instance.open_nssdb()
            try:
                nssdb.import_pkcs7(pkcs7_data=pem_chain, trust_attributes='CT,C,C')
            finally:
                nssdb.close()

        subsystem.save()

        if config.str2bool(deployer.mdict['pki_ds_remove_data']):

            if config.str2bool(deployer.mdict['pki_ds_create_new_db']):
                logger.info('Removing existing database')
                subsystem.remove_database(force=True)

            elif not config.str2bool(deployer.mdict['pki_clone']) or \
                    config.str2bool(deployer.mdict['pki_clone_setup_replication']):
                logger.info('Emptying existing database')
                subsystem.empty_database(force=True)

            else:
                logger.info('Reusing replicated database')

        logger.info('Initializing database')

        # In most cases, we want to replicate the schema and therefore not add it here.
        # We provide this option though in case the clone already has schema
        # and we want to replicate back to the master.

        # On the other hand, if we are not setting up replication,
        # then we are assuming that replication is already taken care of,
        # and schema has already been replicated.

        setup_schema = not config.str2bool(deployer.mdict['pki_clone']) or \
            not config.str2bool(deployer.mdict['pki_clone_setup_replication']) or \
            not config.str2bool(deployer.mdict['pki_clone_replicate_schema'])

        create_database = config.str2bool(deployer.mdict['pki_ds_create_new_db'])

        # When cloning a subsystem without setting up the replication agreements,
        # the database is a subtree of an existing tree and is already replicated,
        # so there is no need to set up the base entry.

        create_base = config.str2bool(deployer.mdict['pki_ds_create_new_db']) or \
            not config.str2bool(deployer.mdict['pki_clone']) or \
            config.str2bool(deployer.mdict['pki_clone_setup_replication'])

        create_containers = not config.str2bool(deployer.mdict['pki_clone'])

        # If the database is already replicated but not yet indexed, rebuild the indexes.

        rebuild_indexes = config.str2bool(deployer.mdict['pki_clone']) and \
            not config.str2bool(deployer.mdict['pki_clone_setup_replication']) and \
            config.str2bool(deployer.mdict['pki_clone_reindex_data'])

        setup_db_manager = not config.str2bool(deployer.mdict['pki_clone']) or \
            not config.str2bool(deployer.mdict['pki_clone_setup_replication'])

        # If setting up replication, set up VLV indexes after replication.

        setup_vlv_indexes = not config.str2bool(deployer.mdict['pki_clone']) or \
            not config.str2bool(deployer.mdict['pki_clone_setup_replication'])

        subsystem.init_database(
            setup_schema=setup_schema,
            create_database=create_database,
            create_base=create_base,
            create_containers=create_containers,
            rebuild_indexes=rebuild_indexes,
            setup_db_manager=setup_db_manager,
            setup_vlv_indexes=setup_vlv_indexes)

        # Start/Restart this Tomcat PKI Process
        # Optionally prepare to enable a java debugger
        # (e. g. - 'eclipse'):
        if config.str2bool(deployer.mdict['pki_enable_java_debugger']):
            config.prepare_for_an_external_java_debugger(
                deployer.mdict['pki_target_tomcat_conf_instance_id'])
        tomcat_instance_subsystems = \
            len(deployer.instance.tomcat_instance_subsystems())

        if tomcat_instance_subsystems == 1:
            logger.info('Starting server')
            instance.start()

        elif tomcat_instance_subsystems > 1:
            logger.info('Restarting server')
            instance.restart()

        # Configure status request timeout.  This is used for each
        # status request in wait_for_startup
        value = deployer.mdict['pki_status_request_timeout']
        if len(value) == 0:
            status_request_timeout = None
        else:
            status_request_timeout = int(value)
            if status_request_timeout <= 0:
                raise ValueError("timeout must be greater than zero")

        deployer.instance.wait_for_startup(
            subsystem,
            PKISPAWN_STARTUP_TIMEOUT_SECONDS,
            request_timeout=status_request_timeout,
        )

        # Optionally wait for debugger to attach (e. g. - 'eclipse'):
        if config.str2bool(deployer.mdict['pki_enable_java_debugger']):
            config.wait_to_attach_an_external_java_debugger()

        connection = pki.client.PKIConnection(
            protocol='https',
            hostname=deployer.mdict['pki_hostname'],
            port=deployer.mdict['pki_https_port'],
            trust_env=False)

        client = pki.system.SystemConfigClient(
            connection,
            subsystem=deployer.mdict['pki_subsystem_type'])

        # If pki_one_time_pin is not already defined, load from CS.cfg
        if 'pki_one_time_pin' not in deployer.mdict:
            deployer.mdict['pki_one_time_pin'] = subsystem.config['preop.pin']

        logger.info('Configuring %s subsystem', subsystem.type)

        request = deployer.config_client.create_config_request()
        client.configure(request)

        if clone:

            logger.info('Setting up clone')

            clone_setup_request = deployer.config_client.create_clone_setup_request(subsystem)
            clone_setup_request.domainInfo = deployer.domain_info
            clone_setup_request.installToken = deployer.install_token
            client.setupClone(clone_setup_request)

        logger.info('Setting up database')

        database_setup_request = deployer.config_client.create_database_setup_request()
        client.setupDatabase(database_setup_request)

        sslserver = subsystem.get_subsystem_cert('sslserver')

        for tag in subsystem.config['preop.cert.list'].split(','):

            logger.info('Setting up %s certificate', tag)
            cert = deployer.setup_cert(client, tag)

            if not cert:
                continue

            logger.debug('- cert: %s', cert['cert'])
            logger.debug('- request: %s', cert['request'])

            if tag == 'sslserver':
                sslserver['data'] = cert['cert']
                sslserver['request'] = cert['request']
                sslserver['token'] = cert['token']

        if not clone:

            logger.info('Setting up admin user')
            deployer.setup_admin(client)

        if config.str2bool(deployer.mdict['pki_backup_keys']):

            # by default store the backup file in the NSS databases directory
            if not deployer.mdict['pki_backup_file']:
                deployer.mdict['pki_backup_file'] = \
                    deployer.mdict['pki_server_database_path'] + '/' + \
                    deployer.mdict['pki_subsystem'].lower() + '_backup_keys.p12'

            logger.info('Backing up keys into %s', deployer.mdict['pki_backup_file'])
            deployer.backup_keys(instance, subsystem)

        logger.info('Setting up security domain')
        sd_setup_request = deployer.config_client.create_security_domain_setup_request()
        sd_setup_request.domainInfo = deployer.domain_info
        sd_setup_request.installToken = deployer.install_token
        client.setupSecurityDomain(sd_setup_request)

        if not config.str2bool(deployer.mdict['pki_share_db']):
            logger.info('Setting up database user')
            db_user_setup_request = deployer.config_client.create_database_user_setup_request()
            client.setupDatabaseUser(db_user_setup_request)

        logger.info('Finalizing %s configuration', subsystem.type)
        finalize_config_request = deployer.config_client.create_finalize_config_request()
        finalize_config_request.domainInfo = deployer.domain_info
        finalize_config_request.installToken = deployer.install_token
        client.finalizeConfiguration(finalize_config_request)

        if subsystem.type == 'TPS':
            logger.info('Setting up shared secret')
            deployer.setup_shared_secret(instance, subsystem)

        logger.info('%s configuration complete', subsystem.type)

        # Create an empty file that designates the fact that although
        # this server instance has been configured, it has NOT yet
        # been restarted!

        restart_server = os.path.join(instance.conf_dir, 'restart_server_after_configuration')
        logger.debug('Creating %s', restart_server)

        open(restart_server, 'a').close()
        os.chown(restart_server, instance.uid, instance.gid)
        os.chmod(restart_server, 0o660)

        # If temp SSL server cert was created and there's a new perm cert,
        # replace it with the perm cert.
        if create_temp_sslserver_cert and sslserver and sslserver['data']:
            logger.info('Stopping server')
            instance.stop()

            # Remove temp SSL server cert.
            self.remove_temp_sslserver_cert(instance, sslserver)

            # Import perm SSL server cert unless it's already imported
            # earlier in external/standalone installation.

            if not (standalone or external and subsystem.name in ['kra', 'ocsp']):

                nickname = sslserver['nickname']
                token = pki.nssdb.normalize_token(sslserver['token'])

                if not token:
                    token = deployer.mdict['pki_token_name']

                instance.set_sslserver_cert_nickname(nickname, token)

                self.import_perm_sslserver_cert(deployer, instance, sslserver)

            logger.info('Starting server')
            instance.start()

        elif config.str2bool(deployer.mdict['pki_restart_configured_instance']):
            logger.info('Restarting server')
            instance.restart()

        deployer.instance.wait_for_startup(
            subsystem,
            PKISPAWN_STARTUP_TIMEOUT_SECONDS,
            request_timeout=status_request_timeout,
        )
示例#6
0
文件: cert.py 项目: tiran/pki
    def execute(self, argv):
        logging.getLogger().setLevel(logging.INFO)

        try:
            opts, _ = getopt.gnu_getopt(argv, 'i:p:v', [
                'instance=', 'cert=', 'extra-cert=', 'agent-uid=',
                'ldapi-socket=', 'ldap-url=', 'port=', 'verbose', 'debug', 'help',
            ])

        except getopt.GetoptError as e:
            logger.error(e)
            self.print_help()
            sys.exit(1)

        instance_name = 'pki-tomcat'
        all_certs = True
        fix_certs = []
        extra_certs = []
        agent_uid = None
        ldap_url = None
        use_ldapi = False
        port = '8443'

        for o, a in opts:
            if o in ('-i', '--instance'):
                instance_name = a

            elif o == '--cert':
                all_certs = False
                fix_certs.append(a)

            elif o == '--extra-cert':
                try:
                    int(a)
                except ValueError:
                    logger.error('--extra-cert requires serial number as integer')
                    sys.exit(1)
                all_certs = False
                extra_certs.append(a)

            elif o == '--agent-uid':
                agent_uid = a

            elif o == '--ldapi-socket':
                if ldap_url is not None:
                    logger.error('--ldapi-socket cannot be used with --ldap-url')
                    sys.exit(1)
                use_ldapi = True
                ldap_url = 'ldapi://{}'.format(quote(a, safe=''))

            elif o == '--ldap-url':
                if use_ldapi:
                    logger.error('--ldap-url cannot be used with --ldapi-socket')
                    sys.exit(1)
                ldap_url = a

            elif o in ('-p', '--port'):
                port = a
                try:
                    n = int(port)
                    if n < 1 or n > 65535:
                        raise ValueError
                except ValueError:
                    logger.error('-p, --port requires a valid port number as integer')
                    sys.exit(1)

            elif o == '--debug':
                logging.getLogger().setLevel(logging.DEBUG)

            elif o in ('-v', '--verbose'):
                logging.getLogger().setLevel(logging.INFO)

            elif o == '--help':
                self.print_help()
                sys.exit()

            else:
                logger.error('option %s not recognized', o)
                self.print_help()
                sys.exit(1)

        instance = pki.server.instance.PKIInstance(instance_name)

        if not instance.exists():
            logger.error('Invalid instance %s.', instance_name)
            sys.exit(1)

        if not agent_uid:
            logger.error('Must specify --agent-uid')
            sys.exit(1)

        if agent_uid == "pkidbuser":
            logger.error('\'pkidbuser\' cannot be used.')
            sys.exit(1)

        instance.load()

        # 1. Make a list of certs to fix OR use the list provided through CLI options
        if all_certs:
            # TODO: Identify only certs that are EXPIRED or ALMOST EXPIRED
            for subsystem in instance.get_subsystems():
                # Retrieve the subsystem's system certificate
                certs = subsystem.find_system_certs()

                # Iterate on all subsystem's system certificate to prepend
                # subsystem name to the ID
                for cert in certs:
                    if cert['id'] != 'sslserver' and cert['id'] != 'subsystem':
                        cert['id'] = subsystem.name + '_' + cert['id']

                    # Append only unique certificates to other subsystem certificate list
                    # ca_signing isn't supported yet
                    if cert['id'] in fix_certs or cert['id'] == 'ca_signing':
                        continue

                    fix_certs.append(cert['id'])

        logger.info('Fixing the following system certs: %s', fix_certs)
        logger.info('Renewing the following additional certs: %s', extra_certs)

        # Get the CA subsystem and find out Base DN.
        ca_subsystem = instance.get_subsystem('ca')
        basedn = ca_subsystem.get_db_config()['internaldb.basedn']
        dbuser_dn = 'uid=pkidbuser,ou=people,{}'.format(basedn)
        agent_dn = 'uid={},ou=people,{}'.format(agent_uid, basedn)

        dm_pass = ''
        if not use_ldapi:
            # Prompt for DM password
            dm_pass = getpass.getpass(prompt='Enter Directory Manager password: '******'s up
        logger.info('Stopping the instance to proceed with system cert renewal')
        instance.stop()

        # 3. Find the subsystem and disable Self-tests
        try:
            # Placeholder used to hold subsystems whose selftest have been turned off
            # Note: This is initialized as a set to avoid duplicates
            # Example of duplicates:
            # fix_certs = [ca_ocsp_signing, ca_audit_signing] -> will add 'ca' entry twice
            target_subsys = set()

            if 'sslserver' in fix_certs or 'subsystem' in fix_certs:
                # If the cert is either sslserver/subsystem, disable selftest for all
                # subsystems since all subsystems use these 2 certs.
                target_subsys = set(instance.get_subsystems())

            else:
                for cert_id in fix_certs:
                    # Since we already filtered sslserver/subsystem, we can be quite sure
                    # that this split will definitely be of form: <subsys>_<cert_tag>
                    subsystem_name = cert_id.split('_', 1)[0]
                    subsystem = instance.get_subsystem(subsystem_name)

                    # If the subsystem is wrong, stop the process
                    if not subsystem:
                        logger.error('No %s subsystem in instance %s.',
                                     subsystem_name, instance_name)
                        sys.exit(1)

                    target_subsys.add(subsystem)

            if len(extra_certs) > 0:
                target_subsys.add(ca_subsystem)

            # Generate new password for agent account
            agent_pass = gen_random_password()

            with write_temp_file(agent_pass.encode('utf8')) as agent_pass_file, \
                    write_temp_file(dm_pass.encode('utf8')) as dm_pass_file, \
                    ldap_password_authn(
                        instance, target_subsys, dbuser_dn,
                        ldap_url, use_ldapi, dm_pass_file), \
                    suppress_selftest(target_subsys):

                # Verify LDAP connection and DM password
                cmd = ['ldapsearch'] + \
                    ldap_conn_args(ldap_url, use_ldapi, dm_pass_file) + \
                    ['-s', 'base', '-b', basedn, '1.1']
                try:
                    subprocess.check_output(cmd)
                except subprocess.CalledProcessError:
                    logger.error("Failed to connect/authenticate to LDAP at '%s'", ldap_url)
                    sys.exit(1)

                # Reset agent password
                logger.info('Resetting password for %s', agent_dn)
                ldappasswd(ldap_url, use_ldapi, dm_pass_file, agent_dn, agent_pass_file)

                # 4. Bring up the server using a temp SSL cert if the sslcert is expired
                if 'sslserver' in fix_certs:
                    # 4a. Create temp SSL cert
                    logger.info('Creating a temporary sslserver cert')
                    instance.cert_create(cert_id='sslserver', temp_cert=True)

                    # 4b. Delete the existing SSL Cert
                    logger.debug('Removing sslserver cert from instance')
                    instance.cert_del('sslserver')

                    # 4d. Import the temp sslcert into the instance
                    logger.debug('Importing temp sslserver cert')
                    instance.cert_import('sslserver')

                with start_stop(instance):
                    # Place renewal request for all certs in fix_certs
                    for cert_id in fix_certs:
                        logger.info('Requesting new cert for %s', cert_id)
                        instance.cert_create(
                            cert_id=cert_id, renew=True,
                            username=agent_uid, password=agent_pass, secure_port=port)
                    for serial in extra_certs:
                        output = instance.cert_file('{}-renewed'.format(serial))
                        logger.info(
                            'Requesting new cert for %s; writing to %s',
                            serial, output)
                        try:
                            instance.cert_create(
                                serial=serial, renew=True, output=output,
                                username=agent_uid, password=agent_pass, secure_port=port)
                        except pki.PKIException as e:
                            logger.error("Failed to renew certificate %s: %s", serial, e)

                # 8. Delete existing certs and then import the renewed system cert(s)
                for cert_id in fix_certs:
                    # Delete the existing cert from the instance
                    logger.debug('Removing old %s cert from instance %s', cert_id, instance_name)
                    instance.cert_del(cert_id)

                    # Import this new cert into the instance
                    logger.debug('Importing new %s cert into instance %s', cert_id, instance_name)
                    instance.cert_import(cert_id)

                # If subsystem cert was renewed and server was using
                # TLS auth, add the cert to pkidbuser entry
                if dbuser_dn and 'subsystem' in fix_certs:
                    logger.info('Importing new subsystem cert into %s', dbuser_dn)
                    with NamedTemporaryFile(mode='w+b') as der_file:
                        # convert subsystem cert to DER
                        subprocess.check_call([
                            'openssl', 'x509',
                            '-inform', 'PEM', '-outform', 'DER',
                            '-in', instance.cert_file('subsystem'),
                            '-out', der_file.name,
                        ])

                        with write_temp_file(
                            self.PKIDBUSER_LDIF_TEMPLATE
                                .format(dn=dbuser_dn, der_file=der_file.name)
                                .encode('utf-8')
                        ) as ldif_file:
                            # ldapmodify
                            cmd = ['ldapmodify'] + \
                                ldap_conn_args(ldap_url, use_ldapi, dm_pass_file) + \
                                ['-f', ldif_file]
                            subprocess.check_call(cmd)

            # 10. Bring up the server
            logger.info('Starting the instance with renewed certs')
            instance.start()

        except pki.server.PKIServerException as e:
            logger.error(str(e))
            sys.exit(1)
示例#7
0
    def spawn(self, deployer):

        external = deployer.configuration_file.external
        standalone = deployer.configuration_file.standalone
        step_one = deployer.configuration_file.external_step_one
        skip_configuration = deployer.configuration_file.skip_configuration

        if (external or standalone) and step_one or skip_configuration:
            logger.info('Skipping configuration')
            return

        logger.info('Configuring subsystem')

        instance = self.instance
        instance.load()

        subsystems = instance.get_subsystems()
        subsystem = instance.get_subsystem(
            deployer.mdict['pki_subsystem'].lower())

        # configure internal database
        subsystem.config['internaldb.ldapconn.host'] = deployer.mdict[
            'pki_ds_hostname']

        if config.str2bool(deployer.mdict['pki_ds_secure_connection']):
            subsystem.config['internaldb.ldapconn.secureConn'] = 'true'
            subsystem.config['internaldb.ldapconn.port'] = deployer.mdict[
                'pki_ds_ldaps_port']
        else:
            subsystem.config['internaldb.ldapconn.secureConn'] = 'false'
            subsystem.config['internaldb.ldapconn.port'] = deployer.mdict[
                'pki_ds_ldap_port']

        subsystem.config['internaldb.ldapauth.bindDN'] = deployer.mdict[
            'pki_ds_bind_dn']
        subsystem.config['internaldb.basedn'] = deployer.mdict[
            'pki_ds_base_dn']
        subsystem.config['internaldb.database'] = deployer.mdict[
            'pki_ds_database']

        if config.str2bool(deployer.mdict['pki_share_db']):
            subsystem.config['preop.internaldb.dbuser'] = deployer.mdict[
                'pki_share_dbuser_dn']

        ocsp_uri = deployer.mdict.get('pki_default_ocsp_uri')
        if ocsp_uri:
            subsystem.config['ca.defaultOcspUri'] = ocsp_uri

        if subsystem.name == 'ca':
            serial_number_range_start = deployer.mdict.get(
                'pki_serial_number_range_start')
            if serial_number_range_start:
                subsystem.config[
                    'dbs.beginSerialNumber'] = serial_number_range_start

            serial_number_range_end = deployer.mdict.get(
                'pki_serial_number_range_end')
            if serial_number_range_end:
                subsystem.config[
                    'dbs.endSerialNumber'] = serial_number_range_end

            request_number_range_start = deployer.mdict.get(
                'pki_request_number_range_start')
            if request_number_range_start:
                subsystem.config[
                    'dbs.beginRequestNumber'] = request_number_range_start

            request_number_range_end = deployer.mdict.get(
                'pki_request_number_range_end')
            if request_number_range_end:
                subsystem.config[
                    'dbs.endRequestNumber'] = request_number_range_end

            replica_number_range_start = deployer.mdict.get(
                'pki_replica_number_range_start')
            if replica_number_range_start:
                subsystem.config[
                    'dbs.beginReplicaNumber'] = replica_number_range_start

            replica_number_range_end = deployer.mdict.get(
                'pki_replica_number_range_end')
            if replica_number_range_end:
                subsystem.config[
                    'dbs.endReplicaNumber'] = replica_number_range_end

        if subsystem.name == 'kra':
            if config.str2bool(deployer.mdict['pki_kra_ephemeral_requests']):
                logger.debug('Setting ephemeral requests to true')
                subsystem.config['kra.ephemeralRequests'] = 'true'

        if subsystem.name == 'tps':
            baseDN = subsystem.config['internaldb.basedn']
            dsHost = subsystem.config['internaldb.ldapconn.host']
            dsPort = subsystem.config['internaldb.ldapconn.port']

            subsystem.config[
                'tokendb.activityBaseDN'] = 'ou=Activities,' + baseDN
            subsystem.config['tokendb.baseDN'] = 'ou=Tokens,' + baseDN
            subsystem.config[
                'tokendb.certBaseDN'] = 'ou=Certificates,' + baseDN
            subsystem.config['tokendb.userBaseDN'] = baseDN
            subsystem.config['tokendb.hostport'] = dsHost + ':' + dsPort

            nickname = subsystem.config['tps.subsystem.nickname']
            token = subsystem.config['tps.subsystem.tokenname']

            if pki.nssdb.normalize_token(token):
                fullname = token + ':' + nickname
            else:
                fullname = nickname

            timestamp = round(time.time() * 1000 * 1000)

            logger.info('Configuring CA connector')

            ca_url = urllib.parse.urlparse(deployer.mdict['pki_ca_uri'])
            subsystem.config['tps.connector.ca1.enable'] = 'true'
            subsystem.config['tps.connector.ca1.host'] = ca_url.hostname
            subsystem.config['tps.connector.ca1.port'] = str(ca_url.port)
            subsystem.config['tps.connector.ca1.minHttpConns'] = '1'
            subsystem.config['tps.connector.ca1.maxHttpConns'] = '15'
            subsystem.config['tps.connector.ca1.nickName'] = fullname
            subsystem.config['tps.connector.ca1.timeout'] = '30'
            subsystem.config['tps.connector.ca1.uri.enrollment'] = \
                '/ca/ee/ca/profileSubmitSSLClient'
            subsystem.config['tps.connector.ca1.uri.getcert'] = \
                '/ca/ee/ca/displayBySerial'
            subsystem.config['tps.connector.ca1.uri.renewal'] = \
                '/ca/ee/ca/profileSubmitSSLClient'
            subsystem.config['tps.connector.ca1.uri.revoke'] = \
                '/ca/ee/subsystem/ca/doRevoke'
            subsystem.config['tps.connector.ca1.uri.unrevoke'] = \
                '/ca/ee/subsystem/ca/doUnrevoke'

            subsystem.config[
                'config.Subsystem_Connections.ca1.state'] = 'Enabled'
            subsystem.config[
                'config.Subsystem_Connections.ca1.timestamp'] = timestamp

            logger.info('Configuring TKS connector')

            tks_url = urllib.parse.urlparse(deployer.mdict['pki_tks_uri'])
            subsystem.config['tps.connector.tks1.enable'] = 'true'
            subsystem.config['tps.connector.tks1.host'] = tks_url.hostname
            subsystem.config['tps.connector.tks1.port'] = str(tks_url.port)
            subsystem.config['tps.connector.tks1.minHttpConns'] = '1'
            subsystem.config['tps.connector.tks1.maxHttpConns'] = '15'
            subsystem.config['tps.connector.tks1.nickName'] = fullname
            subsystem.config['tps.connector.tks1.timeout'] = '30'
            subsystem.config[
                'tps.connector.tks1.generateHostChallenge'] = 'true'
            subsystem.config['tps.connector.tks1.serverKeygen'] = 'false'
            subsystem.config['tps.connector.tks1.keySet'] = 'defKeySet'
            subsystem.config[
                'tps.connector.tks1.tksSharedSymKeyName'] = 'sharedSecret'
            subsystem.config['tps.connector.tks1.uri.computeRandomData'] = \
                '/tks/agent/tks/computeRandomData'
            subsystem.config['tps.connector.tks1.uri.computeSessionKey'] = \
                '/tks/agent/tks/computeSessionKey'
            subsystem.config['tps.connector.tks1.uri.createKeySetData'] = \
                '/tks/agent/tks/createKeySetData'
            subsystem.config['tps.connector.tks1.uri.encryptData'] = \
                '/tks/agent/tks/encryptData'

            subsystem.config[
                'config.Subsystem_Connections.tks1.state'] = 'Enabled'
            subsystem.config[
                'config.Subsystem_Connections.tks1.timestamp'] = timestamp

            subsystem.config['target.Subsystem_Connections.list'] = 'ca1,tks1'

            keygen = config.str2bool(
                deployer.mdict['pki_enable_server_side_keygen'])

            if keygen:
                logger.info('Configuring KRA connector')

                kra_url = urllib.parse.urlparse(deployer.mdict['pki_kra_uri'])
                subsystem.config['tps.connector.kra1.enable'] = 'true'
                subsystem.config['tps.connector.kra1.host'] = kra_url.hostname
                subsystem.config['tps.connector.kra1.port'] = str(kra_url.port)
                subsystem.config['tps.connector.kra1.minHttpConns'] = '1'
                subsystem.config['tps.connector.kra1.maxHttpConns'] = '15'
                subsystem.config['tps.connector.kra1.nickName'] = fullname
                subsystem.config['tps.connector.kra1.timeout'] = '30'
                subsystem.config['tps.connector.kra1.uri.GenerateKeyPair'] = \
                    '/kra/agent/kra/GenerateKeyPair'
                subsystem.config['tps.connector.kra1.uri.TokenKeyRecovery'] = \
                    '/kra/agent/kra/TokenKeyRecovery'

                subsystem.config[
                    'config.Subsystem_Connections.kra1.state'] = 'Enabled'
                subsystem.config[
                    'config.Subsystem_Connections.kra1.timestamp'] = timestamp

                subsystem.config[
                    'target.Subsystem_Connections.list'] = 'ca1,tks1,kra1'

                subsystem.config['tps.connector.tks1.serverKeygen'] = 'true'

                # TODO: see if there are other profiles need to be configured
                subsystem.config[
                    'op.enroll.userKey.keyGen.encryption.serverKeygen.enable'] = 'true'
                subsystem.config[
                    'op.enroll.userKeyTemporary.keyGen.encryption.serverKeygen.enable'] = 'true'
                subsystem.config[
                    'op.enroll.soKey.keyGen.encryption.serverKeygen.enable'] = 'true'
                subsystem.config[
                    'op.enroll.soKeyTemporary.keyGen.encryption.serverKeygen.enable'] = 'true'

            else:
                # TODO: see if there are other profiles need to be configured
                subsystem.config[
                    'op.enroll.userKey.keyGen.encryption.serverKeygen.enable'] = 'false'
                subsystem.config[
                    'op.enroll.userKeyTemporary.keyGen.encryption.serverKeygen.enable'] = 'false'
                subsystem.config[
                    'op.enroll.userKey.keyGen.encryption.recovery.destroyed.scheme'] = 'GenerateNewKey'
                subsystem.config[
                    'op.enroll.userKeyTemporary.keyGen.encryption.recovery.onHold.scheme'] = 'GenerateNewKey'
                subsystem.config[
                    'op.enroll.soKey.keyGen.encryption.serverKeygen.enable'] = 'false'
                subsystem.config[
                    'op.enroll.soKeyTemporary.keyGen.encryption.serverKeygen.enable'] = 'false'
                subsystem.config[
                    'op.enroll.soKey.keyGen.encryption.recovery.destroyed.scheme'] = 'GenerateNewKey'
                subsystem.config[
                    'op.enroll.soKeyTemporary.keyGen.encryption.recovery.onHold.scheme'] = 'GenerateNewKey'

        subsystem.save()

        token = pki.nssdb.normalize_token(deployer.mdict['pki_token_name'])
        nssdb = instance.open_nssdb()

        existing = deployer.configuration_file.existing
        step_two = deployer.configuration_file.external_step_two
        clone = deployer.configuration_file.clone
        master_url = deployer.mdict['pki_clone_uri']

        try:
            if existing or (external or standalone) and step_two:

                deployer.import_system_cert_requests(subsystem)
                deployer.import_system_certs(nssdb, subsystem)

                deployer.configure_system_certs(subsystem)
                deployer.update_system_certs(nssdb, subsystem)
                subsystem.save()

                deployer.validate_system_certs(nssdb, subsystem)

            elif len(subsystems) > 1:

                for s in subsystems:

                    # find a subsystem that is already installed
                    if s.name == subsystem.name:
                        continue

                    # import cert/request data from the existing subsystem
                    # into the new subsystem being installed

                    logger.info('Importing sslserver cert data from %s',
                                s.type)
                    subsystem.config['%s.sslserver.cert' % subsystem.name] = \
                        s.config['%s.sslserver.cert' % s.name]

                    logger.info('Importing subsystem cert data from %s',
                                s.type)
                    subsystem.config['%s.subsystem.cert' % subsystem.name] = \
                        s.config['%s.subsystem.cert' % s.name]

                    logger.info('Importing sslserver request data from %s',
                                s.type)
                    subsystem.config['%s.sslserver.certreq' % subsystem.name] = \
                        s.config['%s.sslserver.certreq' % s.name]

                    logger.info('Importing subsystem request data from %s',
                                s.type)
                    subsystem.config['%s.subsystem.certreq' % subsystem.name] = \
                        s.config['%s.subsystem.certreq' % s.name]

                    break

            else:  # self-signed CA

                # To be implemented in ticket #1692.

                # Generate CA cert request.
                # Self sign CA cert.
                # Import self-signed CA cert into NSS database.

                pass

        finally:
            nssdb.close()

        create_temp_sslserver_cert = self.create_temp_sslserver_cert(
            deployer, instance)

        server_config = instance.get_server_config()
        unsecurePort = server_config.get_unsecure_port()
        securePort = server_config.get_secure_port()

        proxyUnsecurePort = subsystem.config.get('proxy.unsecurePort')
        if not proxyUnsecurePort:
            proxyUnsecurePort = unsecurePort

        proxySecurePort = subsystem.config.get('proxy.securePort')
        if not proxySecurePort:
            proxySecurePort = securePort

        if deployer.mdict['pki_security_domain_type'] == 'existing':

            logger.info('Joining existing domain')

            deployer.join_security_domain()

            subsystem.configure_security_domain('existing',
                                                deployer.domain_info.id,
                                                deployer.sd_host.Hostname,
                                                deployer.sd_host.Port,
                                                deployer.sd_host.SecurePort)

        elif config.str2bool(deployer.mdict['pki_subordinate']) and \
                config.str2bool(deployer.mdict['pki_subordinate_create_new_security_domain']):

            logger.info('Creating new subordinate security domain')

            deployer.join_security_domain()

            subsystem.configure_security_domain(
                'new', deployer.mdict['pki_subordinate_security_domain_name'],
                deployer.mdict['pki_hostname'], unsecurePort, securePort)

        else:

            logger.info('Creating new security domain')

            subsystem.configure_security_domain(
                'new', deployer.mdict['pki_security_domain_name'],
                deployer.mdict['pki_hostname'], unsecurePort, securePort)

        subsystem.config['service.securityDomainPort'] = securePort

        hierarchy = subsystem.config.get('hierarchy.select')
        issuing_ca = deployer.mdict['pki_issuing_ca']

        if external and subsystem.type == 'CA':
            # No need to use issuing CA during CA installation
            # with external certs since the certs will be provided.
            pass

        elif standalone and subsystem.type in ['KRA', 'OCSP']:
            # No need to use issuing CA during standalone KRA/OCSP
            # installation since the certs will be provided.
            pass

        else:
            # For other cases, use issuing CA to issue certs during installation.
            # KRA will also configure a connector in the issuing CA, and OCSP will
            # configure a publisher in the issuing CA.

            logger.info('Using CA at %s', issuing_ca)
            url = urllib.parse.urlparse(issuing_ca)

            subsystem.config['preop.ca.url'] = issuing_ca
            subsystem.config['preop.ca.hostname'] = url.hostname
            subsystem.config['preop.ca.httpsport'] = str(url.port)
            subsystem.config['preop.ca.httpsadminport'] = str(url.port)

        system_certs_imported = \
            deployer.mdict['pki_server_pkcs12_path'] != '' or \
            deployer.mdict['pki_clone_pkcs12_path'] != ''

        if not (subsystem.type == 'CA' and hierarchy == 'Root'):

            if external and subsystem.type == 'CA' or \
                    standalone and subsystem.type in ['KRA', 'OCSP']:
                subsystem.config['preop.ca.pkcs7'] = ''

            elif not clone and not system_certs_imported:

                logger.info('Retrieving CA certificate chain from %s',
                            issuing_ca)

                pem_chain = deployer.get_ca_signing_cert(instance, issuing_ca)
                base64_chain = pki.nssdb.convert_pkcs7(pem_chain, 'pem',
                                                       'base64')
                subsystem.config['preop.ca.pkcs7'] = base64_chain

                logger.info('Importing CA certificate chain')

                nssdb = instance.open_nssdb()
                try:
                    nssdb.import_pkcs7(pkcs7_data=pem_chain,
                                       trust_attributes='CT,C,C')
                finally:
                    nssdb.close()

        if subsystem.type == 'CA' and clone and not system_certs_imported:

            logger.info('Retrieving CA certificate chain from %s', master_url)

            pem_chain = deployer.get_ca_signing_cert(instance, master_url)
            base64_chain = pki.nssdb.convert_pkcs7(pem_chain, 'pem', 'base64')
            subsystem.config['preop.clone.pkcs7'] = base64_chain

            logger.info('Importing CA certificate chain')

            nssdb = instance.open_nssdb()
            try:
                nssdb.import_pkcs7(pkcs7_data=pem_chain,
                                   trust_attributes='CT,C,C')
            finally:
                nssdb.close()

        subsystem.save()

        if clone:

            if subsystem.type in ['CA', 'KRA']:

                logger.info('Requesting ranges from %s master', subsystem.type)
                subsystem.request_ranges(
                    master_url, session_id=deployer.install_token.token)

            logger.info('Updating configuration for %s clone', subsystem.type)
            subsystem.update_config(master_url,
                                    session_id=deployer.install_token.token)

        if config.str2bool(deployer.mdict['pki_ds_remove_data']):

            if config.str2bool(deployer.mdict['pki_ds_create_new_db']):
                logger.info('Removing existing database')
                subsystem.remove_database(force=True)

            elif not config.str2bool(deployer.mdict['pki_clone']) or \
                    config.str2bool(deployer.mdict['pki_clone_setup_replication']):
                logger.info('Emptying existing database')
                subsystem.empty_database(force=True)

            else:
                logger.info('Reusing replicated database')

        logger.info('Initializing database')

        # In most cases, we want to replicate the schema and therefore not add it here.
        # We provide this option though in case the clone already has schema
        # and we want to replicate back to the master.

        # On the other hand, if we are not setting up replication,
        # then we are assuming that replication is already taken care of,
        # and schema has already been replicated.

        setup_schema = not config.str2bool(deployer.mdict['pki_clone']) or \
            not config.str2bool(deployer.mdict['pki_clone_setup_replication']) or \
            not config.str2bool(deployer.mdict['pki_clone_replicate_schema'])

        create_database = config.str2bool(
            deployer.mdict['pki_ds_create_new_db'])

        # When cloning a subsystem without setting up the replication agreements,
        # the database is a subtree of an existing tree and is already replicated,
        # so there is no need to set up the base entry.

        create_base = config.str2bool(deployer.mdict['pki_ds_create_new_db']) or \
            not config.str2bool(deployer.mdict['pki_clone']) or \
            config.str2bool(deployer.mdict['pki_clone_setup_replication'])

        create_containers = not config.str2bool(deployer.mdict['pki_clone'])

        # Set up replication if required for cloning.

        setup_replication = clone and \
            config.str2bool(deployer.mdict['pki_clone_setup_replication'])

        ds_port = subsystem.config['internaldb.ldapconn.port']
        logger.info('- internaldb.ldapconn.port: %s', ds_port)

        secure_conn = subsystem.config['internaldb.ldapconn.secureConn']
        logger.info('- internaldb.ldapconn.secureConn: %s', secure_conn)

        replication_security = deployer.mdict['pki_clone_replication_security']
        logger.info('- pki_clone_replication_security: %s',
                    replication_security)

        replication_port = deployer.mdict['pki_clone_replication_clone_port']
        logger.info('- pki_clone_replication_clone_port: %s', replication_port)

        master_replication_port = deployer.mdict[
            'pki_clone_replication_master_port']
        logger.info('- pki_clone_replication_master_port: %s',
                    master_replication_port)

        if replication_port == ds_port and secure_conn == 'true':
            replication_security = 'SSL'

        elif not replication_security:
            replication_security = 'None'

        logger.info('- replication_security: %s', replication_security)

        # If the database is already replicated but not yet indexed, rebuild the indexes.

        rebuild_indexes = config.str2bool(deployer.mdict['pki_clone']) and \
            not config.str2bool(deployer.mdict['pki_clone_setup_replication']) and \
            config.str2bool(deployer.mdict['pki_clone_reindex_data'])

        subsystem.init_database(
            setup_schema=setup_schema,
            create_database=create_database,
            create_base=create_base,
            create_containers=create_containers,
            rebuild_indexes=rebuild_indexes,
            setup_replication=setup_replication,
            replication_security=replication_security,
            replication_port=replication_port,
            master_replication_port=master_replication_port)

        subsystem.add_vlv()
        subsystem.reindex_vlv()

        subsystem.load()

        if not clone and subsystem.type == 'CA':
            subsystem.import_profiles(
                input_folder='/usr/share/pki/ca/profiles/ca')

        # Start/Restart this Tomcat PKI Process
        # Optionally prepare to enable a java debugger
        # (e. g. - 'eclipse'):
        if config.str2bool(deployer.mdict['pki_enable_java_debugger']):
            config.prepare_for_an_external_java_debugger(
                deployer.mdict['pki_target_tomcat_conf_instance_id'])
        tomcat_instance_subsystems = \
            len(deployer.instance.tomcat_instance_subsystems())

        if tomcat_instance_subsystems == 1:

            logger.info('Enabling %s subsystem', subsystem.type)
            subsystem.enable()

            logger.info('Starting PKI server')
            instance.start(wait=True,
                           max_wait=deployer.startup_timeout,
                           timeout=deployer.request_timeout)

        elif tomcat_instance_subsystems > 1:

            logger.info('Enabling %s subsystem', subsystem.type)
            subsystem.enable(wait=True,
                             max_wait=deployer.startup_timeout,
                             timeout=deployer.request_timeout)

        logger.info('Waiting for %s subsystem', subsystem.type)
        subsystem.wait_for_startup(deployer.startup_timeout,
                                   deployer.request_timeout)

        # Optionally wait for debugger to attach (e. g. - 'eclipse'):
        if config.str2bool(deployer.mdict['pki_enable_java_debugger']):
            config.wait_to_attach_an_external_java_debugger()

        ca_cert = os.path.join(instance.nssdb_dir, "ca.crt")

        connection = pki.client.PKIConnection(
            protocol='https',
            hostname=deployer.mdict['pki_hostname'],
            port=deployer.mdict['pki_https_port'],
            trust_env=False,
            cert_paths=ca_cert)

        client = pki.system.SystemConfigClient(
            connection, subsystem=deployer.mdict['pki_subsystem_type'])

        # If pki_one_time_pin is not already defined, load from CS.cfg
        if 'pki_one_time_pin' not in deployer.mdict:
            deployer.mdict['pki_one_time_pin'] = subsystem.config['preop.pin']

        system_certs = deployer.setup_system_certs(subsystem, client)

        if subsystem.type == 'CA':
            logger.info('Setting up subsystem user')
            deployer.setup_subsystem_user(instance, subsystem,
                                          system_certs['subsystem'])

        if not clone:
            logger.info('Getting admin certificate')
            admin_cert = deployer.get_admin_cert(subsystem, client)

            logger.info('Setting up admin user')
            deployer.setup_admin_user(subsystem, admin_cert)

        domain_manager = False

        if subsystem.type == 'CA':
            if clone:
                sd_hostname = subsystem.config['securitydomain.host']
                sd_port = subsystem.config['securitydomain.httpsadminport']

                sd_subsystem = deployer.domain_info.subsystems['CA']
                sd_host = sd_subsystem.get_host(sd_hostname, sd_port)

                if sd_host.DomainManager and sd_host.DomainManager.lower(
                ) == 'true':
                    domain_manager = True

        if deployer.mdict['pki_security_domain_type'] == 'existing':

            sd_url = deployer.mdict['pki_security_domain_uri']
            logger.info('Joining security domain at %s', sd_url)
            subsystem.join_security_domain(
                sd_url,
                deployer.mdict['pki_subsystem_name'],
                deployer.mdict['pki_hostname'],
                unsecure_port=proxyUnsecurePort,
                secure_port=proxySecurePort,
                domain_manager=domain_manager,
                clone=clone,
                session_id=deployer.install_token.token)

        else:
            logger.info('Creating security domain')
            subsystem.create_security_domain()

            logger.info('Adding security domain manager')
            subsystem.add_security_domain_host(
                deployer.mdict['pki_subsystem_name'],
                deployer.mdict['pki_hostname'],
                unsecure_port=proxyUnsecurePort,
                secure_port=proxySecurePort,
                domain_manager=True)

        if not config.str2bool(deployer.mdict['pki_share_db']) and not clone:
            logger.info('Setting up database user')
            deployer.setup_database_user(instance, subsystem)

        if subsystem.type == 'CA':

            if clone:
                if sd_host.DomainManager and sd_host.DomainManager.lower(
                ) == 'true':

                    logger.info('Cloning security domain master')

                    subsystem.config['securitydomain.select'] = 'new'
                    subsystem.config['securitydomain.host'] = deployer.mdict[
                        'pki_hostname']
                    subsystem.config['securitydomain.httpport'] = unsecurePort
                    subsystem.config[
                        'securitydomain.httpsadminport'] = securePort
                    subsystem.config[
                        'securitydomain.httpsagentport'] = securePort
                    subsystem.config['securitydomain.httpseeport'] = securePort

        deployer.finalize_subsystem(instance, subsystem)

        logger.info('%s configuration complete', subsystem.type)

        # If temp SSL server cert was created and there's a new perm cert,
        # replace it with the perm cert.
        if create_temp_sslserver_cert and system_certs['sslserver']['data']:

            logger.info('Stopping PKI server')
            instance.stop(wait=True,
                          max_wait=deployer.startup_timeout,
                          timeout=deployer.request_timeout)

            # Remove temp SSL server cert.
            self.remove_temp_sslserver_cert(instance,
                                            system_certs['sslserver'])

            # Import perm SSL server cert unless it's already imported
            # earlier in external/standalone installation.

            if not (standalone
                    or external and subsystem.name in ['kra', 'ocsp']):
                self.import_perm_sslserver_cert(deployer, instance,
                                                system_certs['sslserver'])

            # Store perm SSL server cert nickname and token
            nickname = system_certs['sslserver']['nickname']
            token = pki.nssdb.normalize_token(
                system_certs['sslserver']['token'])

            if not token:
                token = deployer.mdict['pki_token_name']

            instance.set_sslserver_cert_nickname(nickname, token)

            logger.info('Starting PKI server')
            instance.start(wait=True,
                           max_wait=deployer.startup_timeout,
                           timeout=deployer.request_timeout)

        elif config.str2bool(
                deployer.mdict['pki_restart_configured_instance']):

            logger.info('Restarting %s subsystem', subsystem.type)
            subsystem.restart(wait=True,
                              max_wait=deployer.startup_timeout,
                              timeout=deployer.request_timeout)

        logger.info('Waiting for %s subsystem', subsystem.type)
        subsystem.wait_for_startup(deployer.startup_timeout,
                                   deployer.request_timeout)
示例#8
0
    def spawn(self, deployer):

        external = deployer.configuration_file.external
        standalone = deployer.configuration_file.standalone
        step_one = deployer.configuration_file.external_step_one
        skip_configuration = deployer.configuration_file.skip_configuration

        if (external or standalone) and step_one or skip_configuration:
            logger.info('Skipping configuration')
            return

        logger.info('Configuring subsystem')

        try:
            startup_timeout = int(
                os.environ['PKISPAWN_STARTUP_TIMEOUT_SECONDS'])
        except (KeyError, ValueError):
            startup_timeout = 60

        if startup_timeout <= 0:
            startup_timeout = 60

        # Configure status request timeout. This is used for each
        # status request in wait_for_startup().
        value = deployer.mdict['pki_status_request_timeout']
        if len(value) == 0:
            request_timeout = None
        else:
            request_timeout = int(value)
            if request_timeout <= 0:
                raise ValueError("timeout must be greater than zero")

        instance = self.instance
        instance.load()

        subsystems = instance.get_subsystems()
        subsystem = instance.get_subsystem(
            deployer.mdict['pki_subsystem'].lower())

        # configure internal database
        subsystem.config['internaldb.ldapconn.host'] = deployer.mdict[
            'pki_ds_hostname']

        if config.str2bool(deployer.mdict['pki_ds_secure_connection']):
            subsystem.config['internaldb.ldapconn.secureConn'] = 'true'
            subsystem.config['internaldb.ldapconn.port'] = deployer.mdict[
                'pki_ds_ldaps_port']
        else:
            subsystem.config['internaldb.ldapconn.secureConn'] = 'false'
            subsystem.config['internaldb.ldapconn.port'] = deployer.mdict[
                'pki_ds_ldap_port']

        subsystem.config['internaldb.ldapauth.bindDN'] = deployer.mdict[
            'pki_ds_bind_dn']
        subsystem.config['internaldb.basedn'] = deployer.mdict[
            'pki_ds_base_dn']
        subsystem.config['internaldb.database'] = deployer.mdict[
            'pki_ds_database']

        if config.str2bool(deployer.mdict['pki_share_db']):
            subsystem.config['preop.internaldb.dbuser'] = deployer.mdict[
                'pki_share_dbuser_dn']

        ocsp_uri = deployer.mdict.get('pki_default_ocsp_uri')
        if ocsp_uri:
            subsystem.config['ca.defaultOcspUri'] = ocsp_uri

        if subsystem.name == 'ca':
            serial_number_range_start = deployer.mdict.get(
                'pki_serial_number_range_start')
            if serial_number_range_start:
                subsystem.config[
                    'dbs.beginSerialNumber'] = serial_number_range_start

            serial_number_range_end = deployer.mdict.get(
                'pki_serial_number_range_end')
            if serial_number_range_end:
                subsystem.config[
                    'dbs.endSerialNumber'] = serial_number_range_end

            request_number_range_start = deployer.mdict.get(
                'pki_request_number_range_start')
            if request_number_range_start:
                subsystem.config[
                    'dbs.beginRequestNumber'] = request_number_range_start

            request_number_range_end = deployer.mdict.get(
                'pki_request_number_range_end')
            if request_number_range_end:
                subsystem.config[
                    'dbs.endRequestNumber'] = request_number_range_end

            replica_number_range_start = deployer.mdict.get(
                'pki_replica_number_range_start')
            if replica_number_range_start:
                subsystem.config[
                    'dbs.beginReplicaNumber'] = replica_number_range_start

            replica_number_range_end = deployer.mdict.get(
                'pki_replica_number_range_end')
            if replica_number_range_end:
                subsystem.config[
                    'dbs.endReplicaNumber'] = replica_number_range_end

        if subsystem.name == 'kra':
            if config.str2bool(deployer.mdict['pki_kra_ephemeral_requests']):
                logger.debug('Setting ephemeral requests to true')
                subsystem.config['kra.ephemeralRequests'] = 'true'

        if subsystem.name == 'tps':
            baseDN = subsystem.config['internaldb.basedn']
            dsHost = subsystem.config['internaldb.ldapconn.host']
            dsPort = subsystem.config['internaldb.ldapconn.port']

            subsystem.config[
                'tokendb.activityBaseDN'] = 'ou=Activities,' + baseDN
            subsystem.config['tokendb.baseDN'] = 'ou=Tokens,' + baseDN
            subsystem.config[
                'tokendb.certBaseDN'] = 'ou=Certificates,' + baseDN
            subsystem.config['tokendb.userBaseDN'] = baseDN
            subsystem.config['tokendb.hostport'] = dsHost + ':' + dsPort

        subsystem.save()

        token = pki.nssdb.normalize_token(deployer.mdict['pki_token_name'])
        nssdb = instance.open_nssdb()

        existing = deployer.configuration_file.existing
        step_two = deployer.configuration_file.external_step_two
        clone = deployer.configuration_file.clone
        master_url = deployer.mdict['pki_clone_uri']

        try:
            if existing or (external or standalone) and step_two:

                deployer.import_system_cert_requests(subsystem)
                deployer.import_system_certs(nssdb, subsystem)

                deployer.configure_system_certs(subsystem)
                deployer.update_system_certs(nssdb, subsystem)
                subsystem.save()

                deployer.validate_system_certs(nssdb, subsystem)

            elif len(subsystems) > 1:

                for s in subsystems:

                    # find a subsystem that is already installed
                    if s.name == subsystem.name:
                        continue

                    # import cert/request data from the existing subsystem
                    # into the new subsystem being installed

                    logger.info('Importing sslserver cert data from %s',
                                s.type)
                    subsystem.config['%s.sslserver.cert' % subsystem.name] = \
                        s.config['%s.sslserver.cert' % s.name]

                    logger.info('Importing subsystem cert data from %s',
                                s.type)
                    subsystem.config['%s.subsystem.cert' % subsystem.name] = \
                        s.config['%s.subsystem.cert' % s.name]

                    logger.info('Importing sslserver request data from %s',
                                s.type)
                    subsystem.config['%s.sslserver.certreq' % subsystem.name] = \
                        s.config['%s.sslserver.certreq' % s.name]

                    logger.info('Importing subsystem request data from %s',
                                s.type)
                    subsystem.config['%s.subsystem.certreq' % subsystem.name] = \
                        s.config['%s.subsystem.certreq' % s.name]

                    break

            else:  # self-signed CA

                # To be implemented in ticket #1692.

                # Generate CA cert request.
                # Self sign CA cert.
                # Import self-signed CA cert into NSS database.

                pass

        finally:
            nssdb.close()

        create_temp_sslserver_cert = self.create_temp_sslserver_cert(
            deployer, instance)

        server_config = instance.get_server_config()
        unsecurePort = server_config.get_unsecure_port()
        securePort = server_config.get_secure_port()

        proxyUnsecurePort = subsystem.config.get('proxy.unsecurePort')
        if not proxyUnsecurePort:
            proxyUnsecurePort = unsecurePort

        proxySecurePort = subsystem.config.get('proxy.securePort')
        if not proxySecurePort:
            proxySecurePort = securePort

        if deployer.mdict['pki_security_domain_type'] == 'existing':

            logger.info('Joining existing domain')

            deployer.join_security_domain()

            subsystem.configure_security_domain('existing',
                                                deployer.domain_info.id,
                                                deployer.sd_host.Hostname,
                                                deployer.sd_host.Port,
                                                deployer.sd_host.SecurePort)

        elif config.str2bool(deployer.mdict['pki_subordinate']) and \
                config.str2bool(deployer.mdict['pki_subordinate_create_new_security_domain']):

            logger.info('Creating new subordinate security domain')

            deployer.join_security_domain()

            subsystem.configure_security_domain(
                'new', deployer.mdict['pki_subordinate_security_domain_name'],
                deployer.mdict['pki_hostname'], unsecurePort, securePort)

        else:

            logger.info('Creating new security domain')

            subsystem.configure_security_domain(
                'new', deployer.mdict['pki_security_domain_name'],
                deployer.mdict['pki_hostname'], unsecurePort, securePort)

        subsystem.config['service.securityDomainPort'] = securePort

        hierarchy = subsystem.config.get('hierarchy.select')
        issuing_ca = deployer.mdict['pki_issuing_ca']

        if external and subsystem.type == 'CA':
            # No need to use issuing CA during CA installation
            # with external certs since the certs will be provided.
            pass

        elif standalone and subsystem.type in ['KRA', 'OCSP']:
            # No need to use issuing CA during standalone KRA/OCSP
            # installation since the certs will be provided.
            pass

        else:
            # For other cases, use issuing CA to issue certs during installation.
            # KRA will also configure a connector in the issuing CA, and OCSP will
            # configure a publisher in the issuing CA.

            logger.info('Using CA at %s', issuing_ca)
            url = urllib.parse.urlparse(issuing_ca)

            subsystem.config['preop.ca.url'] = issuing_ca
            subsystem.config['preop.ca.hostname'] = url.hostname
            subsystem.config['preop.ca.httpsport'] = str(url.port)
            subsystem.config['preop.ca.httpsadminport'] = str(url.port)

        system_certs_imported = \
            deployer.mdict['pki_server_pkcs12_path'] != '' or \
            deployer.mdict['pki_clone_pkcs12_path'] != ''

        if not (subsystem.type == 'CA' and hierarchy == 'Root'):

            if external and subsystem.type == 'CA' or \
                    standalone and subsystem.type in ['KRA', 'OCSP']:
                subsystem.config['preop.ca.pkcs7'] = ''

            elif not clone and not system_certs_imported:

                logger.info('Retrieving CA certificate chain from %s',
                            issuing_ca)

                pem_chain = deployer.get_ca_signing_cert(instance, issuing_ca)
                base64_chain = pki.nssdb.convert_pkcs7(pem_chain, 'pem',
                                                       'base64')
                subsystem.config['preop.ca.pkcs7'] = base64_chain

                logger.info('Importing CA certificate chain')

                nssdb = instance.open_nssdb()
                try:
                    nssdb.import_pkcs7(pkcs7_data=pem_chain,
                                       trust_attributes='CT,C,C')
                finally:
                    nssdb.close()

        if subsystem.type == 'CA' and clone and not system_certs_imported:

            logger.info('Retrieving CA certificate chain from %s', master_url)

            pem_chain = deployer.get_ca_signing_cert(instance, master_url)
            base64_chain = pki.nssdb.convert_pkcs7(pem_chain, 'pem', 'base64')
            subsystem.config['preop.clone.pkcs7'] = base64_chain

            logger.info('Importing CA certificate chain')

            nssdb = instance.open_nssdb()
            try:
                nssdb.import_pkcs7(pkcs7_data=pem_chain,
                                   trust_attributes='CT,C,C')
            finally:
                nssdb.close()

        subsystem.save()

        if clone:

            if subsystem.type in ['CA', 'KRA']:

                logger.info('Requesting ranges from %s master', subsystem.type)
                subsystem.request_ranges(
                    master_url, session_id=deployer.install_token.token)

            logger.info('Updating configuration for %s clone', subsystem.type)
            subsystem.update_config(master_url,
                                    session_id=deployer.install_token.token)

        if config.str2bool(deployer.mdict['pki_ds_remove_data']):

            if config.str2bool(deployer.mdict['pki_ds_create_new_db']):
                logger.info('Removing existing database')
                subsystem.remove_database(force=True)

            elif not config.str2bool(deployer.mdict['pki_clone']) or \
                    config.str2bool(deployer.mdict['pki_clone_setup_replication']):
                logger.info('Emptying existing database')
                subsystem.empty_database(force=True)

            else:
                logger.info('Reusing replicated database')

        logger.info('Initializing database')

        # In most cases, we want to replicate the schema and therefore not add it here.
        # We provide this option though in case the clone already has schema
        # and we want to replicate back to the master.

        # On the other hand, if we are not setting up replication,
        # then we are assuming that replication is already taken care of,
        # and schema has already been replicated.

        setup_schema = not config.str2bool(deployer.mdict['pki_clone']) or \
            not config.str2bool(deployer.mdict['pki_clone_setup_replication']) or \
            not config.str2bool(deployer.mdict['pki_clone_replicate_schema'])

        create_database = config.str2bool(
            deployer.mdict['pki_ds_create_new_db'])

        # When cloning a subsystem without setting up the replication agreements,
        # the database is a subtree of an existing tree and is already replicated,
        # so there is no need to set up the base entry.

        create_base = config.str2bool(deployer.mdict['pki_ds_create_new_db']) or \
            not config.str2bool(deployer.mdict['pki_clone']) or \
            config.str2bool(deployer.mdict['pki_clone_setup_replication'])

        create_containers = not config.str2bool(deployer.mdict['pki_clone'])

        # Set up replication if required for cloning.

        setup_replication = clone and \
            config.str2bool(deployer.mdict['pki_clone_setup_replication'])

        ds_port = subsystem.config['internaldb.ldapconn.port']
        secure_conn = subsystem.config['internaldb.ldapconn.secureConn']
        replication_security = deployer.mdict['pki_clone_replication_security']
        replication_port = deployer.mdict['pki_clone_replication_clone_port']
        master_replication_port = deployer.mdict[
            'pki_clone_replication_master_port']

        if replication_port == ds_port and secure_conn == 'true':
            replication_security = 'SSL'

        elif not replication_security:
            replication_security = 'None'

        # If the database is already replicated but not yet indexed, rebuild the indexes.

        rebuild_indexes = config.str2bool(deployer.mdict['pki_clone']) and \
            not config.str2bool(deployer.mdict['pki_clone_setup_replication']) and \
            config.str2bool(deployer.mdict['pki_clone_reindex_data'])

        subsystem.init_database(
            setup_schema=setup_schema,
            create_database=create_database,
            create_base=create_base,
            create_containers=create_containers,
            rebuild_indexes=rebuild_indexes,
            setup_replication=setup_replication,
            replication_security=replication_security,
            replication_port=replication_port,
            master_replication_port=master_replication_port)

        subsystem.add_vlv()
        subsystem.reindex_vlv()

        subsystem.load()

        if not clone and subsystem.type == 'CA':
            subsystem.import_profiles(
                input_folder='/usr/share/pki/ca/profiles/ca')

        # Start/Restart this Tomcat PKI Process
        # Optionally prepare to enable a java debugger
        # (e. g. - 'eclipse'):
        if config.str2bool(deployer.mdict['pki_enable_java_debugger']):
            config.prepare_for_an_external_java_debugger(
                deployer.mdict['pki_target_tomcat_conf_instance_id'])
        tomcat_instance_subsystems = \
            len(deployer.instance.tomcat_instance_subsystems())

        if tomcat_instance_subsystems == 1:
            logger.info('Starting server')
            instance.start()

        elif tomcat_instance_subsystems > 1:
            logger.info('Restarting server')
            instance.restart()

        subsystem.wait_for_startup(startup_timeout, request_timeout)

        # Optionally wait for debugger to attach (e. g. - 'eclipse'):
        if config.str2bool(deployer.mdict['pki_enable_java_debugger']):
            config.wait_to_attach_an_external_java_debugger()

        ca_cert = os.path.join(instance.nssdb_dir, "ca.crt")

        connection = pki.client.PKIConnection(
            protocol='https',
            hostname=deployer.mdict['pki_hostname'],
            port=deployer.mdict['pki_https_port'],
            trust_env=False,
            cert_paths=ca_cert)

        client = pki.system.SystemConfigClient(
            connection, subsystem=deployer.mdict['pki_subsystem_type'])

        # If pki_one_time_pin is not already defined, load from CS.cfg
        if 'pki_one_time_pin' not in deployer.mdict:
            deployer.mdict['pki_one_time_pin'] = subsystem.config['preop.pin']

        system_certs = deployer.setup_system_certs(subsystem, client)

        if subsystem.type == 'CA':
            logger.info('Setting up subsystem user')
            deployer.setup_subsystem_user(instance, subsystem,
                                          system_certs['subsystem'])

        if not clone:
            logger.info('Setting up admin user')
            deployer.setup_admin(subsystem, client)

        domain_manager = False

        if subsystem.type == 'CA':
            if clone:
                sd_hostname = subsystem.config['securitydomain.host']
                sd_port = subsystem.config['securitydomain.httpsadminport']

                sd_subsystem = deployer.domain_info.subsystems['CA']
                sd_host = sd_subsystem.get_host(sd_hostname, sd_port)

                if sd_host.DomainManager and sd_host.DomainManager.lower(
                ) == 'true':
                    domain_manager = True

        if deployer.mdict['pki_security_domain_type'] == 'existing':

            sd_url = deployer.mdict['pki_security_domain_uri']
            logger.info('Joining security domain at %s', sd_url)
            subsystem.join_security_domain(
                sd_url,
                deployer.mdict['pki_subsystem_name'],
                deployer.mdict['pki_hostname'],
                unsecure_port=proxyUnsecurePort,
                secure_port=proxySecurePort,
                domain_manager=domain_manager,
                clone=clone,
                session_id=deployer.install_token.token)

        else:
            logger.info('Creating security domain')
            subsystem.create_security_domain()

            logger.info('Adding security domain manager')
            subsystem.add_security_domain_host(
                deployer.mdict['pki_subsystem_name'],
                deployer.mdict['pki_hostname'],
                unsecure_port=proxyUnsecurePort,
                secure_port=proxySecurePort,
                domain_manager=True)

        if not config.str2bool(deployer.mdict['pki_share_db']) and not clone:
            logger.info('Setting up database user')
            deployer.setup_database_user(instance, subsystem)

        logger.info('Finalizing %s configuration', subsystem.type)
        finalize_config_request = deployer.config_client.create_finalize_config_request(
        )
        finalize_config_request.domainInfo = deployer.domain_info
        finalize_config_request.installToken = deployer.install_token
        client.finalizeConfiguration(finalize_config_request)

        subsystem.load()

        if subsystem.type == 'CA':

            if clone:
                if sd_host.DomainManager and sd_host.DomainManager.lower(
                ) == 'true':

                    logger.info('Cloning security domain master')

                    subsystem.config['securitydomain.select'] = 'new'
                    subsystem.config['securitydomain.host'] = deployer.mdict[
                        'pki_hostname']
                    subsystem.config['securitydomain.httpport'] = unsecurePort
                    subsystem.config[
                        'securitydomain.httpsadminport'] = securePort
                    subsystem.config[
                        'securitydomain.httpsagentport'] = securePort
                    subsystem.config['securitydomain.httpseeport'] = securePort

        deployer.finalize_subsystem(instance, subsystem)

        logger.info('%s configuration complete', subsystem.type)

        # Create an empty file that designates the fact that although
        # this server instance has been configured, it has NOT yet
        # been restarted!

        restart_server = os.path.join(instance.conf_dir,
                                      'restart_server_after_configuration')
        logger.debug('Creating %s', restart_server)

        open(restart_server, 'a').close()
        os.chown(restart_server, instance.uid, instance.gid)
        os.chmod(restart_server, 0o660)

        # If temp SSL server cert was created and there's a new perm cert,
        # replace it with the perm cert.
        if create_temp_sslserver_cert and system_certs['sslserver']['data']:
            logger.info('Stopping server')
            instance.stop()

            # Remove temp SSL server cert.
            self.remove_temp_sslserver_cert(instance,
                                            system_certs['sslserver'])

            # Import perm SSL server cert unless it's already imported
            # earlier in external/standalone installation.

            if not (standalone
                    or external and subsystem.name in ['kra', 'ocsp']):
                self.import_perm_sslserver_cert(deployer, instance,
                                                system_certs['sslserver'])

            # Store perm SSL server cert nickname and token
            nickname = system_certs['sslserver']['nickname']
            token = pki.nssdb.normalize_token(
                system_certs['sslserver']['token'])

            if not token:
                token = deployer.mdict['pki_token_name']

            instance.set_sslserver_cert_nickname(nickname, token)

            logger.info('Starting server')
            instance.start()

        elif config.str2bool(
                deployer.mdict['pki_restart_configured_instance']):
            logger.info('Restarting server')
            instance.restart()

        subsystem.wait_for_startup(startup_timeout, request_timeout)