From f589cc1e267d6d7b67a6463b4495b7a9c982669f Mon Sep 17 00:00:00 2001 From: Matthew Harmsen Date: Sat, 28 Jul 2012 18:59:30 -0700 Subject: PKI Deployment Scriptlets * TRAC Ticket #263 - Dogtag 10: Fix 'pkidestroy' problem of sporadically "not" removing "/etc/sysconfig/{pki_instance_id}" . . . * TRAC Ticket #264 - Dogtag 10: Enable various other subsystems for configuration . . . * TRAC Ticket #261 - Dogtag 10: Revisit command-line options of 'pkispawn' and 'pkidestroy' . . . * TRAC Ticket #268 - Dogtag 10: Create a parameter for optional restart of configured PKI instance . . . * TRAC Ticket #270 - Dogtag 10: Add missing parameters to 'pkideployment.cfg' . . . * TRAC Ticket #265 - Dogtag 10: Provide configurable options for PKI client information . . . * TRAC Ticket #275 - Dogtag 10: Add debug information (comments) to Tomcat 7 "logging.properties" * TRAC Ticket #276 - Dogtag 10: Relocate all 'pin' data to the 'sensitive' dictionary * TRAC Ticket #277 - Dogtag 10: Create an 'archive' for 'manifest' and 'pkideployment.cfg' files * TRAC Ticket #278 - Dogtag 10: Fix Miscellaneous PKI Deployment Scriptlet Issues . . . --- base/common/shared/conf/logging.properties | 15 + base/deploy/config/pkideployment.cfg | 28 +- base/deploy/src/pkidestroy | 18 - base/deploy/src/pkispawn | 29 - base/deploy/src/scriptlets/configuration.jy | 62 +- base/deploy/src/scriptlets/configuration.py | 38 +- base/deploy/src/scriptlets/finalization.py | 82 ++- .../deploy/src/scriptlets/infrastructure_layout.py | 42 +- base/deploy/src/scriptlets/initialization.py | 18 +- base/deploy/src/scriptlets/instance_layout.py | 9 +- base/deploy/src/scriptlets/pkiconfig.py | 21 +- base/deploy/src/scriptlets/pkihelper.py | 247 +++++++- base/deploy/src/scriptlets/pkijython.py | 33 +- base/deploy/src/scriptlets/pkimanifest.py | 2 - base/deploy/src/scriptlets/pkimessages.py | 59 +- base/deploy/src/scriptlets/pkiparser.py | 654 ++++++++++----------- base/deploy/src/scriptlets/security_databases.py | 9 +- base/deploy/src/scriptlets/subsystem_layout.py | 10 +- 18 files changed, 772 insertions(+), 604 deletions(-) (limited to 'base') diff --git a/base/common/shared/conf/logging.properties b/base/common/shared/conf/logging.properties index f1fb462aa..dfdc0a40f 100644 --- a/base/common/shared/conf/logging.properties +++ b/base/common/shared/conf/logging.properties @@ -28,6 +28,21 @@ handlers = 1catalina.org.apache.juli.FileHandler, 2localhost.org.apache.juli.Fil # Describes specific configuration info for Handlers. ############################################################ +# Change the following settings to allow for more granular debugging: +# +# * 1catalina.org.apache.juli.FileHandler.level = ALL +# * 2localhost.org.apache.juli.FileHandler.level = ALL +# +# and add the following lines to the end of this file: +# +# * org.apache.catalina.loader.level = FINEST +# * org.apache.catalina.loader.WebappClassLoader.level = FINEST +# * org.apache.catalina.loader.StandardClassLoader.level = FINEST +# * com.netscape.cms.servlet.base.level = FINEST +# * com.netscape.cms.servlet.base.CMSStartServlet.level = FINEST +# * java.net.URLClassLoader.level = FINEST +# + 1catalina.org.apache.juli.FileHandler.level = FINE 1catalina.org.apache.juli.FileHandler.directory = ${catalina.base}/logs 1catalina.org.apache.juli.FileHandler.prefix = catalina. diff --git a/base/deploy/config/pkideployment.cfg b/base/deploy/config/pkideployment.cfg index d0acd7f33..ae02bb450 100644 --- a/base/deploy/config/pkideployment.cfg +++ b/base/deploy/config/pkideployment.cfg @@ -10,10 +10,12 @@ [Sensitive] pki_admin_password= pki_backup_password= +pki_client_database_password= pki_client_pkcs12_password= pki_clone_pkcs12_password= pki_ds_password= pki_security_domain_password= +pki_token_password= ############################################################################### ## 'Common' Data: ## ## ## @@ -42,8 +44,10 @@ pki_audit_signing_nickname= pki_audit_signing_signing_algorithm=SHA256withRSA pki_audit_signing_subject_dn= pki_audit_signing_token= -pki_backup_file= pki_backup_keys=False +pki_client_database_dir= +pki_client_database_purge=True +pki_client_dir= pki_ds_base_dn= pki_ds_bind_dn=cn=Directory Manager pki_ds_database= @@ -53,6 +57,7 @@ pki_ds_ldaps_port=636 pki_ds_remove_data=True pki_ds_secure_connection=False pki_group=pkiuser +pki_restart_configured_instance=True pki_security_domain_hostname= pki_security_domain_https_port=8443 pki_security_domain_name= @@ -69,6 +74,7 @@ pki_subsystem_key_type=rsa pki_subsystem_nickname= pki_subsystem_subject_dn= pki_subsystem_token= +pki_token_name=internal pki_user=pkiuser ############################################################################### ## 'Apache' Data: ## @@ -99,12 +105,16 @@ pki_https_port=443 [Tomcat] pki_ajp_port=8009 pki_clone=False +pki_clone_pkcs12_path= +pki_clone_replication_security=None +pki_clone_uri= pki_enable_java_debugger=False +pki_enable_proxy=False pki_http_port=8080 pki_https_port=8443 pki_instance_name=pki-tomcat -pki_proxy_http_port= -pki_proxy_https_port= +pki_proxy_http_port=80 +pki_proxy_https_port=443 pki_security_manager=false pki_tomcat_server_port=8005 ############################################################################### @@ -132,6 +142,10 @@ pki_ca_signing_signing_algorithm=SHA256withRSA pki_ca_signing_subject_dn= pki_ca_signing_token= pki_external=False +pki_external_ca_cert_chain_path= +pki_external_ca_cert_path= +pki_external_csr_path= +pki_external_step_two=False pki_ocsp_signing_key_algorithm=SHA256withRSA pki_ocsp_signing_key_size=2048 pki_ocsp_signing_key_type=rsa @@ -142,7 +156,7 @@ pki_ocsp_signing_token= pki_subordinate=False pki_subsystem=CA pki_subsystem_name= -pki_war_name=ca.war +pki_war_file=ca.war ############################################################################### ## 'KRA' Data: ## ## ## @@ -167,7 +181,7 @@ pki_transport_nickname= pki_transport_signing_algorithm=SHA256withRSA pki_transport_subject_dn= pki_transport_token= -pki_war_name=kra.war +pki_war_file=kra.war ############################################################################### ## 'OCSP' Data: ## ## ## @@ -185,7 +199,7 @@ pki_ocsp_signing_subject_dn= pki_ocsp_signing_token= pki_subsystem=OCSP pki_subsystem_name= -pki_war_name=ocsp.war +pki_war_file=ocsp.war ############################################################################### ## 'RA' Data: ## ## ## @@ -205,7 +219,7 @@ pki_subsystem_name= [TKS] pki_subsystem=TKS pki_subsystem_name= -pki_war_name=tks.war +pki_war_file=tks.war ############################################################################### ## 'TPS' Data: ## ## ## diff --git a/base/deploy/src/pkidestroy b/base/deploy/src/pkidestroy index 1e0f02031..165ccb06c 100755 --- a/base/deploy/src/pkidestroy +++ b/base/deploy/src/pkidestroy @@ -30,9 +30,7 @@ try: import logging import os import pprint - import random import socket - import string import struct import subprocess import time @@ -139,22 +137,6 @@ def main(argv): config.pki_log.debug(pp.pformat(config.pki_subsystem_dict), extra=config.PKI_INDENTATION_LEVEL_0) - # Override PKI configuration file values with 'custom' command-line values. - if not config.custom_pki_admin_domain_name is None: - config.pki_common_dict['pki_admin_domain_name'] =\ - config.custom_pki_admin_domain_name - if not config.custom_pki_instance_name is None: - config.pki_web_server_dict['pki_instance_name'] =\ - config.custom_pki_instance_name - if not config.custom_pki_http_port is None: - config.pki_web_server_dict['pki_http_port'] =\ - config.custom_pki_http_port - if not config.custom_pki_https_port is None: - config.pki_web_server_dict['pki_https_port'] =\ - config.custom_pki_https_port - if not config.custom_pki_ajp_port is None: - config.pki_web_server_dict['pki_ajp_port'] =\ - config.custom_pki_ajp_port # NEVER print out 'sensitive' name/value pairs!!! config.pki_log.debug(log.PKI_DICTIONARY_COMMON, extra=config.PKI_INDENTATION_LEVEL_0) diff --git a/base/deploy/src/pkispawn b/base/deploy/src/pkispawn index 75c196787..795c57917 100755 --- a/base/deploy/src/pkispawn +++ b/base/deploy/src/pkispawn @@ -30,9 +30,7 @@ try: import logging import os import pprint - import random import socket - import string import struct import subprocess import time @@ -90,17 +88,6 @@ def main(argv): print log.PKI_SUBPROCESS_ERROR_1 % exc sys.exit(1) - # Generate random 'pin's for use as security database passwords - pin_low = 100000000000 - pin_high = 999999999999 - config.pki_pin = random.randint(pin_low, pin_high) - config.pki_client_pin = random.randint(pin_low, pin_high) - - # Generate a one-time pin to be used prior to configuration - config.pki_one_time_pin =\ - ''.join(random.choice(string.ascii_letters + string.digits)\ - for x in range(20)) - # Initialize 'pretty print' for objects pp = pprint.PrettyPrinter(indent=4) @@ -168,22 +155,6 @@ def main(argv): config.pki_log.debug(pp.pformat(config.pki_subsystem_dict), extra=config.PKI_INDENTATION_LEVEL_0) - # Override PKI configuration file values with 'custom' command-line values. - if not config.custom_pki_admin_domain_name is None: - config.pki_common_dict['pki_admin_domain_name'] =\ - config.custom_pki_admin_domain_name - if not config.custom_pki_instance_name is None: - config.pki_web_server_dict['pki_instance_name'] =\ - config.custom_pki_instance_name - if not config.custom_pki_http_port is None: - config.pki_web_server_dict['pki_http_port'] =\ - config.custom_pki_http_port - if not config.custom_pki_https_port is None: - config.pki_web_server_dict['pki_https_port'] =\ - config.custom_pki_https_port - if not config.custom_pki_ajp_port is None: - config.pki_web_server_dict['pki_ajp_port'] =\ - config.custom_pki_ajp_port # NEVER print out 'sensitive' name/value pairs!!! config.pki_log.debug(log.PKI_DICTIONARY_COMMON, extra=config.PKI_INDENTATION_LEVEL_0) diff --git a/base/deploy/src/scriptlets/configuration.jy b/base/deploy/src/scriptlets/configuration.jy index 0746d40fc..d06119ada 100644 --- a/base/deploy/src/scriptlets/configuration.jy +++ b/base/deploy/src/scriptlets/configuration.jy @@ -23,12 +23,16 @@ from com.netscape.cms.client.cli import ClientConfig def main(argv): rv = 0 - # Establish 'master' as the PKI jython dictionary + # Establish 'master' and 'sensitive' as two separate PKI jython dictionaries master = dict() + sensitive = dict() # Import the master dictionary from 'pkispawn' master = pickle.loads(argv[1]) + # Import the sensitive data dictionary from 'pkispawn' + sensitive = pickle.loads(argv[2]) + # Optionally enable a java debugger (e. g. - 'eclipse'): if config.str2bool(master['pki_enable_java_debugger']): config.wait_to_attach_an_external_java_debugger() @@ -64,13 +68,13 @@ def main(argv): # Initialize token jyutil.security_databases.initialize_token( - master['pki_client_database_path'], + master['pki_client_database_dir'], master['pki_dry_run_flag'], master['pki_jython_log_level']) # Log into token token = jyutil.security_databases.log_into_token( - master['pki_client_database_path'], + master['pki_client_database_dir'], master['pki_client_password_conf'], master['pki_dry_run_flag'], master['pki_jython_log_level']) @@ -124,54 +128,18 @@ def main(argv): log.PKI_JYTHON_NOT_YET_IMPLEMENTED) return self.rv else: + # CA data = jyutil.rest_client.construct_pki_configuration_data( - master, token) - elif master['pki_subsystem'] == "KRA": - if config.str2bool(master['pki_clone']): - print "%s '%s %s' %s" %\ - (log.PKI_JYTHON_INDENTATION_2, - log.PKI_JYTHON_CLONED_PKI_SUBSYSTEM, - master['pki_subsystem'], - log.PKI_JYTHON_NOT_YET_IMPLEMENTED) - return self.rv - else: - print "%s '%s' %s" %\ - (log.PKI_JYTHON_INDENTATION_2, - master['pki_subsystem'], - log.PKI_JYTHON_NOT_YET_IMPLEMENTED) - return self.rv - elif master['pki_subsystem'] == "OCSP": - if config.str2bool(master['pki_clone']): - print "%s '%s %s' %s" %\ - (log.PKI_JYTHON_INDENTATION_2, - log.PKI_JYTHON_CLONED_PKI_SUBSYSTEM, - master['pki_subsystem'], - log.PKI_JYTHON_NOT_YET_IMPLEMENTED) - return self.rv - else: - print "%s '%s' %s" %\ - (log.PKI_JYTHON_INDENTATION_2, - master['pki_subsystem'], - log.PKI_JYTHON_NOT_YET_IMPLEMENTED) - return self.rv - elif master['pki_subsystem'] == "TKS": - if config.str2bool(master['pki_clone']): - print "%s '%s %s' %s" %\ - (log.PKI_JYTHON_INDENTATION_2, - log.PKI_JYTHON_CLONED_PKI_SUBSYSTEM, - master['pki_subsystem'], - log.PKI_JYTHON_NOT_YET_IMPLEMENTED) - return self.rv - else: - print "%s '%s' %s" %\ - (log.PKI_JYTHON_INDENTATION_2, - master['pki_subsystem'], - log.PKI_JYTHON_NOT_YET_IMPLEMENTED) - return self.rv + master, sensitive, token) + else: + # KRA, OCSP, or TKS + data = jyutil.rest_client.construct_pki_configuration_data( + master, sensitive, token) # Formulate PKI Subsystem Configuration Data Response jyutil.rest_client.configure_pki_data(data, - master) + master, + sensitive) if __name__ == "__main__": diff --git a/base/deploy/src/scriptlets/configuration.py b/base/deploy/src/scriptlets/configuration.py index 742a4ec33..365bc39a5 100644 --- a/base/deploy/src/scriptlets/configuration.py +++ b/base/deploy/src/scriptlets/configuration.py @@ -22,6 +22,7 @@ # PKI Deployment Imports import pkiconfig as config from pkiconfig import pki_master_dict as master +from pkiconfig import pki_sensitive_dict as sensitive import pkihelper as util import pkimessages as log import pkiscriptlet @@ -37,7 +38,7 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): if not config.pki_dry_run_flag: # Place "slightly" less restrictive permissions on # the top-level client directory ONLY - util.directory.create(master['pki_client_path'], + util.directory.create(master['pki_client_dir'], uid=0, gid=0, perms=config.PKI_DEPLOYMENT_DEFAULT_CLIENT_DIR_PERMISSIONS) # Since 'certutil' does NOT strip the 'token=' portion of @@ -46,7 +47,7 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): # allowing 'certutil' to generate the security databases util.password.create_password_conf( master['pki_client_password_conf'], - master['pki_client_pin'], pin_sans_token=True) + sensitive['pki_client_database_password'], pin_sans_token=True) util.file.modify(master['pki_client_password_conf'], uid=0, gid=0) # Similarly, create a simple password file containing the @@ -54,12 +55,11 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): # into a PKCS #12 file util.password.create_client_pkcs12_password_conf( master['pki_client_pkcs12_password_conf']) - util.file.modify(master['pki_client_pkcs12_password_conf'], - uid=0, gid=0) - util.directory.create(master['pki_client_database_path'], + util.file.modify(master['pki_client_pkcs12_password_conf']) + util.directory.create(master['pki_client_database_dir'], uid=0, gid=0) util.certutil.create_security_databases( - master['pki_client_database_path'], + master['pki_client_database_dir'], master['pki_client_cert_database'], master['pki_client_key_database'], master['pki_client_secmod_database'], @@ -73,14 +73,14 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): # allowing 'certutil' to generate the security databases util.password.create_password_conf( master['pki_client_password_conf'], - master['pki_client_pin'], pin_sans_token=True) + sensitive['pki_client_database_password'], pin_sans_token=True) # Similarly, create a simple password file containing the # PKCS #12 password used when exporting the "Admin Certificate" # into a PKCS #12 file util.password.create_client_pkcs12_password_conf( master['pki_client_pkcs12_password_conf']) util.certutil.create_security_databases( - master['pki_client_database_path'], + master['pki_client_database_dir'], master['pki_client_cert_database'], master['pki_client_key_database'], master['pki_client_secmod_database'], @@ -130,10 +130,12 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): def respawn(self): config.pki_log.info(log.CONFIGURATION_RESPAWN_1, __name__, extra=config.PKI_INDENTATION_LEVEL_1) - util.file.modify(master['pki_client_password_conf'], - uid=0, gid=0) - util.file.modify(master['pki_client_pkcs12_password_conf'], - uid=0, gid=0) + if util.file.exists(master['pki_client_password_conf']): + util.file.modify(master['pki_client_password_conf'], + uid=0, gid=0) + if util.file.exists(master['pki_client_pkcs12_password_conf']): + util.file.modify(master['pki_client_pkcs12_password_conf'], + uid=0, gid=0) # ALWAYS Restart this Apache/Tomcat PKI Process util.systemd.restart() return self.rv @@ -144,20 +146,24 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): if not config.pki_dry_run_flag: if master['pki_subsystem'] in config.PKI_APACHE_SUBSYSTEMS and\ util.instance.apache_instances() == 1: - util.directory.delete(master['pki_client_path']) + if util.directory.exists(master['pki_client_dir']): + util.directory.delete(master['pki_client_dir']) util.symlink.delete(master['pki_systemd_service_link']) elif master['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS and\ util.instance.tomcat_instances() == 1: - util.directory.delete(master['pki_client_path']) + if util.directory.exists(master['pki_client_dir']): + util.directory.delete(master['pki_client_dir']) util.symlink.delete(master['pki_systemd_service_link']) else: # ALWAYS display correct information (even during dry_run) if master['pki_subsystem'] in config.PKI_APACHE_SUBSYSTEMS and\ util.instance.apache_instances() == 0: - util.directory.delete(master['pki_client_path']) + if util.directory.exists(master['pki_client_dir']): + util.directory.delete(master['pki_client_dir']) util.symlink.delete(master['pki_systemd_service_link']) elif master['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS and\ util.instance.tomcat_instances() == 0: - util.directory.delete(master['pki_client_path']) + if util.directory.exists(master['pki_client_dir']): + util.directory.delete(master['pki_client_dir']) util.symlink.delete(master['pki_systemd_service_link']) return self.rv diff --git a/base/deploy/src/scriptlets/finalization.py b/base/deploy/src/scriptlets/finalization.py index bceec67e0..ab66cd74a 100644 --- a/base/deploy/src/scriptlets/finalization.py +++ b/base/deploy/src/scriptlets/finalization.py @@ -35,23 +35,36 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): def spawn(self): config.pki_log.info(log.FINALIZATION_SPAWN_1, __name__, extra=config.PKI_INDENTATION_LEVEL_1) - # Save a copy of the configuration file used by this process - # (which may be used later by 'pkidestroy') - util.file.copy(config.pkideployment_cfg, - master['pki_subsystem_registry_path'] +\ - "/" + config.PKI_DEPLOYMENT_DEFAULT_CONFIGURATION_FILE) - # Save a timestamped copy of the installation manifest file - filename = master['pki_subsystem_registry_path'] + "/" +\ - "spawn" + "_" + "manifest" + "." +\ - master['pki_timestamp'] + "." + "csv" - config.pki_log.info(log.PKI_MANIFEST_MESSAGE_1, filename, + # For debugging/auditing purposes, save a timestamped copy of + # this configuration file in the subsystem archive + util.file.copy(master['pki_deployment_cfg_replica'], + master['pki_deployment_cfg_spawn_archive']) + # Save a copy of the installation manifest file + config.pki_log.info(log.PKI_MANIFEST_MESSAGE_1, master['pki_manifest'], extra=config.PKI_INDENTATION_LEVEL_2) # for record in manifest.database: # print tuple(record) if not config.pki_dry_run_flag: - manifest.file.register(filename) + manifest.file.register(master['pki_manifest']) manifest.file.write() - util.file.modify(filename, silent=True) + util.file.modify(master['pki_manifest'], silent=True) + # Also, for debugging/auditing purposes, save a timestamped copy of + # this installation manifest file + util.file.copy(master['pki_manifest'], + master['pki_manifest_spawn_archive']) + # Optionally, programmatically 'restart' the configured PKI instance + if config.str2bool(master['pki_restart_configured_instance']): + util.systemd.restart() + # Optionally, 'purge' the entire temporary client infrastructure + # including the client NSS security databases and password files + # + # WARNING: If the PKCS #12 file containing the Admin Cert was + # placed under this infrastructure, it may accidentally + # be deleted! + # + if config.str2bool(master['pki_client_database_purge']): + if util.directory.exists(master['pki_client_dir']): + util.directory.delete(master['pki_client_dir']) # Log final process messages config.pki_log.info(log.PKISPAWN_END_MESSAGE_2, master['pki_subsystem'], @@ -66,22 +79,39 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): extra=config.PKI_INDENTATION_LEVEL_1) # Save a copy of the configuration file used by this process # (which may be used later by 'pkidestroy') - util.file.copy(config.pkideployment_cfg, - master['pki_subsystem_registry_path'] +\ - "/" + config.PKI_DEPLOYMENT_DEFAULT_CONFIGURATION_FILE, + util.file.copy(master['pki_deployment_cfg'], + master['pki_deployment_cfg_replica'], overwrite_flag=True) - # Save a timestamped copy of the updated manifest file - filename = master['pki_subsystem_registry_path'] + "/" +\ - "respawn" + "_" + "manifest" + "." +\ - master['pki_timestamp'] + "." + "csv" - config.pki_log.info(log.PKI_MANIFEST_MESSAGE_1, filename, + # Also, for debugging/auditing purposes, save a timestamped copy of + # this configuration file in the subsystem archive + util.file.copy(master['pki_deployment_cfg_replica'], + master['pki_deployment_cfg_respawn_archive']) + # Save a copy of the updated manifest file + config.pki_log.info(log.PKI_MANIFEST_MESSAGE_1, master['pki_manifest'], extra=config.PKI_INDENTATION_LEVEL_2) # for record in manifest.database: # print tuple(record) if not config.pki_dry_run_flag: - manifest.file.register(filename) + manifest.file.register(master['pki_manifest']) manifest.file.write() - util.file.modify(filename, silent=True) + util.file.modify(master['pki_manifest'], silent=True) + # Also, for debugging/auditing purposes, save a timestamped copy of + # this installation manifest file + util.file.copy(master['pki_manifest'], + master['pki_manifest_respawn_archive']) + # Optionally, programmatically 'restart' the configured PKI instance + if config.str2bool(master['pki_restart_configured_instance']): + util.systemd.restart() + # Optionally, 'purge' the entire temporary client infrastructure + # including the client NSS security databases and password files + # + # WARNING: If the PKCS #12 file containing the Admin Cert was + # placed under this infrastructure, it may accidentally + # be deleted! + # + if config.str2bool(master['pki_client_database_purge']): + if util.directory.exists(master['pki_client_dir']): + util.directory.delete(master['pki_client_dir']) # Log final process messages config.pki_log.info(log.PKIRESPAWN_END_MESSAGE_2, master['pki_subsystem'], @@ -94,10 +124,6 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): def destroy(self): config.pki_log.info(log.FINALIZATION_DESTROY_1, __name__, extra=config.PKI_INDENTATION_LEVEL_1) - config.pki_log.info(log.PKIDESTROY_END_MESSAGE_2, - master['pki_subsystem'], - master['pki_instance_id'], - extra=config.PKI_INDENTATION_LEVEL_0) if not config.pki_dry_run_flag: util.file.modify(master['pki_destroy_log'], silent=True) # Start this Apache/Tomcat PKI Process @@ -116,4 +142,8 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): elif master['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS and\ util.instance.tomcat_instances() >= 0: util.systemd.start() + config.pki_log.info(log.PKIDESTROY_END_MESSAGE_2, + master['pki_subsystem'], + master['pki_instance_id'], + extra=config.PKI_INDENTATION_LEVEL_0) return self.rv diff --git a/base/deploy/src/scriptlets/infrastructure_layout.py b/base/deploy/src/scriptlets/infrastructure_layout.py index d5ce233c6..4baada902 100644 --- a/base/deploy/src/scriptlets/infrastructure_layout.py +++ b/base/deploy/src/scriptlets/infrastructure_layout.py @@ -34,8 +34,39 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): def spawn(self): config.pki_log.info(log.ADMIN_DOMAIN_SPAWN_1, __name__, extra=config.PKI_INDENTATION_LEVEL_1) - # establish top-level infrastructure base + # NOTE: It was determined that since the "pkidestroy" command + # relies upon a symbolic link to a replica of the original + # "pkideployment.cfg" configuration file used by the + # "pkispawn" command of an instance, it is necessary to + # create any required instance and subsystem directories + # in this top-level "infrastructure_layout" scriptlet + # (rather than the "instance_layout" and "subsystem_layout" + # scriptlets) so that a copy of this configuration file can + # be saved, and the required symbolic link can be created. + # + # establish the top-level infrastructure, instance, and subsystem + # registry directories for storage of a copy of the original + # "pkideployment.cfg" configuration file used to spawn this instance, + # and save a copy of this file + util.directory.create(master['pki_registry_path']) + util.directory.create(master['pki_instance_type_registry_path']) + util.directory.create(master['pki_instance_registry_path']) + util.directory.create(master['pki_subsystem_registry_path']) + util.file.copy(master['pki_deployment_cfg'], + master['pki_deployment_cfg_replica']) + # establish top-level infrastructure, instance, and subsystem + # base directories and create the "registry" symbolic link that + # the "pkidestroy" executable relies upon util.directory.create(master['pki_path']) + util.directory.create(master['pki_instance_path']) + util.directory.create(master['pki_subsystem_path']) + util.symlink.create(master['pki_instance_registry_path'], + master['pki_subsystem_registry_link']) + # + # NOTE: If "infrastructure_layout" scriptlet execution has been + # successfully executed to this point, the "pkidestroy" command + # may always be utilized to remove the entire infrastructure. + # # no need to establish top-level infrastructure logs # since it now stores 'pkispawn'/'pkidestroy' logs # and will already exist @@ -44,8 +75,6 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): if master['pki_configuration_path'] !=\ config.PKI_DEPLOYMENT_CONFIGURATION_ROOT: util.directory.create(master['pki_configuration_path']) - # establish top-level infrastructure registry - util.directory.create(master['pki_registry_path']) return self.rv def respawn(self): @@ -82,10 +111,6 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): util.directory.delete(master['pki_configuration_path']) # remove top-level infrastructure registry util.directory.delete(master['pki_registry_path']) - if master['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS: - util.file.delete( - master['pki_target_tomcat_conf_instance_id']) - else: # ALWAYS display correct information (even during dry_run) if master['pki_subsystem'] in config.PKI_SUBSYSTEMS and\ @@ -102,7 +127,4 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): util.directory.delete(master['pki_configuration_path']) # remove top-level infrastructure registry util.directory.delete(master['pki_registry_path']) - if master['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS: - util.file.delete( - master['pki_target_tomcat_conf_instance_id']) return self.rv diff --git a/base/deploy/src/scriptlets/initialization.py b/base/deploy/src/scriptlets/initialization.py index da1a93465..f158592d3 100644 --- a/base/deploy/src/scriptlets/initialization.py +++ b/base/deploy/src/scriptlets/initialization.py @@ -32,8 +32,6 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): rv = 0 def spawn(self): - # detect and avoid any namespace collisions - util.namespace.collision_detection() # begin official logging config.pki_log.info(log.PKISPAWN_BEGIN_MESSAGE_2, master['pki_subsystem'], @@ -41,6 +39,11 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): extra=config.PKI_INDENTATION_LEVEL_0) config.pki_log.info(log.INITIALIZATION_SPAWN_1, __name__, extra=config.PKI_INDENTATION_LEVEL_1) + # verify that this type of "subsystem" does NOT yet + # exist for this "instance" + util.instance.verify_subsystem_does_not_exist() + # detect and avoid any namespace collisions + util.namespace.collision_detection() # initialize 'uid' and 'gid' util.identity.add_uid_and_gid(master['pki_user'], master['pki_group']) # establish 'uid' and 'gid' @@ -50,6 +53,8 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): util.configuration_file.verify_sensitive_data() # verify existence of MUTUALLY EXCLUSIVE configuration file data util.configuration_file.verify_mutually_exclusive_data() + # verify existence of PREDEFINED configuration file data + util.configuration_file.verify_predefined_configuration_file_data() # verify selinux context of selected ports util.configuration_file.populate_non_default_ports() util.configuration_file.verify_selinux_ports() @@ -63,6 +68,9 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): extra=config.PKI_INDENTATION_LEVEL_0) config.pki_log.info(log.INITIALIZATION_RESPAWN_1, __name__, extra=config.PKI_INDENTATION_LEVEL_1) + # verify that this type of "subsystem" currently EXISTS + # for this "instance" + util.instance.verify_subsystem_exists() # establish 'uid' and 'gid' util.identity.set_uid(master['pki_user']) util.identity.set_gid(master['pki_group']) @@ -76,6 +84,12 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): extra=config.PKI_INDENTATION_LEVEL_0) config.pki_log.info(log.INITIALIZATION_DESTROY_1, __name__, extra=config.PKI_INDENTATION_LEVEL_1) + # verify that this type of "subsystem" currently EXISTS + # for this "instance" + util.instance.verify_subsystem_exists() + # verify that the command-line parameters match the values + # that are present in the corresponding configuration file + util.configuration_file.verify_command_matches_configuration_file() # establish 'uid' and 'gid' util.identity.set_uid(master['pki_user']) util.identity.set_gid(master['pki_group']) diff --git a/base/deploy/src/scriptlets/instance_layout.py b/base/deploy/src/scriptlets/instance_layout.py index 7829e240c..013a960a6 100644 --- a/base/deploy/src/scriptlets/instance_layout.py +++ b/base/deploy/src/scriptlets/instance_layout.py @@ -34,15 +34,10 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): def spawn(self): config.pki_log.info(log.INSTANCE_SPAWN_1, __name__, extra=config.PKI_INDENTATION_LEVEL_1) - # establish instance base - util.directory.create(master['pki_instance_path']) # establish instance logs util.directory.create(master['pki_instance_log_path']) # establish instance configuration util.directory.create(master['pki_instance_configuration_path']) - # establish instance registry - util.directory.create(master['pki_instance_type_registry_path']) - util.directory.create(master['pki_instance_registry_path']) # establish Apache/Tomcat specific instance if master['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS: # establish Tomcat instance base @@ -256,6 +251,8 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): util.directory.delete(master['pki_instance_configuration_path']) # remove Tomcat instance registry util.directory.delete(master['pki_instance_type_registry_path']) + # remove PKI 'tomcat.conf' instance file + util.file.delete(master['pki_target_tomcat_conf_instance_id']) else: # ALWAYS display correct information (even during dry_run) if master['pki_subsystem'] in config.PKI_APACHE_SUBSYSTEMS and\ @@ -283,4 +280,6 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): util.directory.delete(master['pki_instance_configuration_path']) # remove Tomcat instance registry util.directory.delete(master['pki_instance_type_registry_path']) + # remove PKI 'tomcat.conf' instance file + util.file.delete(master['pki_target_tomcat_conf_instance_id']) return self.rv diff --git a/base/deploy/src/scriptlets/pkiconfig.py b/base/deploy/src/scriptlets/pkiconfig.py index 64183224f..47ed16fc6 100644 --- a/base/deploy/src/scriptlets/pkiconfig.py +++ b/base/deploy/src/scriptlets/pkiconfig.py @@ -107,28 +107,25 @@ pki_install_time = None pki_timestamp = None pki_architecture = None pki_hostname = None -pki_pin = None -pki_client_pin = None -pki_one_time_pin = None +# PKI Deployment Command-Line Variables +pki_deployment_executable = None + # PKI Deployment "Mandatory" Command-Line Variables pki_subsystem = None # 'pkispawn' ONLY -pkideployment_cfg = "/usr/share/pki/deployment/config/pkideployment.cfg" +pkideployment_cfg = None +# 'pkidestroy' ONLY +pki_deployed_instance_name = None # PKI Deployment "Optional" Command-Line Variables pki_dry_run_flag = False -pki_root_prefix = None +# 'pkispawn' ONLY pki_update_flag = False -# PKI Deployment "Custom" Command-Line Variables -custom_pki_admin_domain_name = None -custom_pki_instance_name = None -# 'pkispawn' ONLY -custom_pki_http_port = None -custom_pki_https_port = None -custom_pki_ajp_port = None +# PKI Deployment "Test" Command-Line Variables +pki_root_prefix = None # PKI Deployment Helper Functions diff --git a/base/deploy/src/scriptlets/pkihelper.py b/base/deploy/src/scriptlets/pkihelper.py index 31877bf4f..c172301af 100644 --- a/base/deploy/src/scriptlets/pkihelper.py +++ b/base/deploy/src/scriptlets/pkihelper.py @@ -421,8 +421,9 @@ class configuration_file: if not sensitive.has_key('pki_ds_password') or\ not len(sensitive['pki_ds_password']): config.pki_log.error( - log.PKIHELPER_UNDEFINED_DS_PASSWORD_1, - config.pkideployment_cfg, + log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2, + "pki_ds_password", + master['pki_deployment_cfg'], extra=config.PKI_INDENTATION_LEVEL_2) sys.exit(1) # Verify existence of Admin Password (except for Clones) @@ -430,8 +431,9 @@ class configuration_file: if not sensitive.has_key('pki_admin_password') or\ not len(sensitive['pki_admin_password']): config.pki_log.error( - log.PKIHELPER_UNDEFINED_ADMIN_PASSWORD_1, - config.pkideployment_cfg, + log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2, + "pki_admin_password", + master['pki_deployment_cfg'], extra=config.PKI_INDENTATION_LEVEL_2) sys.exit(1) # If required, verify existence of Backup Password @@ -439,16 +441,27 @@ class configuration_file: if not sensitive.has_key('pki_backup_password') or\ not len(sensitive['pki_backup_password']): config.pki_log.error( - log.PKIHELPER_UNDEFINED_BACKUP_PASSWORD_1, - config.pkideployment_cfg, + log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2, + "pki_backup_password", + master['pki_deployment_cfg'], extra=config.PKI_INDENTATION_LEVEL_2) sys.exit(1) + # Verify existence of Client Pin for NSS client security databases + if not sensitive.has_key('pki_client_database_password') or\ + not len(sensitive['pki_client_database_password']): + config.pki_log.error( + log.PKIHELPER_UNDEFINED_CLIENT_DATABASE_PASSWORD_2, + "pki_client_database_password", + master['pki_deployment_cfg'], + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) # Verify existence of Client PKCS #12 Password for Admin Cert if not sensitive.has_key('pki_client_pkcs12_password') or\ not len(sensitive['pki_client_pkcs12_password']): config.pki_log.error( - log.PKIHELPER_UNDEFINED_CLIENT_PKCS12_PASSWORD_1, - config.pkideployment_cfg, + log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2, + "pki_client_pkcs12_password", + master['pki_deployment_cfg'], extra=config.PKI_INDENTATION_LEVEL_2) sys.exit(1) # Verify existence of PKCS #12 Password (ONLY for Clones) @@ -456,8 +469,9 @@ class configuration_file: if not sensitive.has_key('pki_clone_pkcs12_password') or\ not len(sensitive['pki_clone_pkcs12_password']): config.pki_log.error( - log.PKIHELPER_UNDEFINED_CLONE_PKCS12_PASSWORD_1, - config.pkideployment_cfg, + log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2, + "pki_clone_pkcs12_password", + master['pki_deployment_cfg'], extra=config.PKI_INDENTATION_LEVEL_2) sys.exit(1) # Verify existence of Security Domain Password File @@ -468,8 +482,19 @@ class configuration_file: if not sensitive.has_key('pki_security_domain_password') or\ not len(sensitive['pki_security_domain_password']): config.pki_log.error( - log.PKIHELPER_UNDEFINED_SECURITY_DOMAIN_PASSWORD_1, - config.pkideployment_cfg, + log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2, + "pki_security_domain_password", + master['pki_deployment_cfg'], + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + # If required, verify existence of Token Password + if not master['pki_token_name'] == "internal": + if not sensitive.has_key('pki_token_password') or\ + not len(sensitive['pki_token_password']): + config.pki_log.error( + log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2, + "pki_token_password", + master['pki_deployment_cfg'], extra=config.PKI_INDENTATION_LEVEL_2) sys.exit(1) return @@ -483,31 +508,132 @@ class configuration_file: config.str2bool(master['pki_subordinate']): config.pki_log.error( log.PKIHELPER_MUTUALLY_EXCLUSIVE_CLONE_EXTERNAL_SUB_CA, - config.pkideployment_cfg, + master['pki_deployment_cfg'], extra=config.PKI_INDENTATION_LEVEL_2) sys.exit(1) elif config.str2bool(master['pki_clone']) and\ config.str2bool(master['pki_external']): config.pki_log.error( log.PKIHELPER_MUTUALLY_EXCLUSIVE_CLONE_EXTERNAL_CA, - config.pkideployment_cfg, + master['pki_deployment_cfg'], extra=config.PKI_INDENTATION_LEVEL_2) sys.exit(1) elif config.str2bool(master['pki_clone']) and\ config.str2bool(master['pki_subordinate']): config.pki_log.error( log.PKIHELPER_MUTUALLY_EXCLUSIVE_CLONE_SUB_CA, - config.pkideployment_cfg, + master['pki_deployment_cfg'], extra=config.PKI_INDENTATION_LEVEL_2) sys.exit(1) elif config.str2bool(master['pki_external']) and\ config.str2bool(master['pki_subordinate']): config.pki_log.error( log.PKIHELPER_MUTUALLY_EXCLUSIVE_EXTERNAL_SUB_CA, - config.pkideployment_cfg, + master['pki_deployment_cfg'], extra=config.PKI_INDENTATION_LEVEL_2) sys.exit(1) + def verify_predefined_configuration_file_data(self): + # Silently verify the existence of any required 'predefined' data + # + # FUTURE: As much as is possible, alter this routine to verify + # ALL name/value pairs for the requested configuration + # scenario. This should include checking for the + # "existence" of ALL required "name" parameters, as well as + # the "existence", "type", and "correctness" of ALL required + # "value" parameters. + # + if master['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS: + if config.str2bool(config.pki_master_dict['pki_clone']): + # Verify existence of clone parameters + if not master.has_key('pki_clone_pkcs12_path') or\ + not len(master['pki_clone_pkcs12_path']): + config.pki_log.error( + log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2, + "pki_clone_pkcs12_path", + master['pki_deployment_cfg'], + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + elif not os.path.isfile(master['pki_clone_pkcs12_path']): + config.pki_log.error( + log.PKI_FILE_ALREADY_EXISTS_NOT_A_FILE_1, + master['pki_clone_pkcs12_path'], + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + if not master.has_key('pki_clone_replication_security') or\ + not len(master['pki_clone_replication_security']): + config.pki_log.error( + log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2, + "pki_clone_replication_security", + master['pki_deployment_cfg'], + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + if not master.has_key('pki_clone_uri') or\ + not len(master['pki_clone_uri']): + config.pki_log.error( + log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2, + "pki_clone_uri", + master['pki_deployment_cfg'], + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + elif master['pki_subsystem'] == "CA" and\ + config.str2bool(config.pki_master_dict['pki_external']): + if not master.has_key('pki_external_step_two') or\ + not len(master['pki_external_step_two']): + config.pki_log.error( + log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2, + "pki_external_step_two", + master['pki_deployment_cfg'], + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + if not config.str2bool(config.pki_master_dict['pki_step_two']): + if not master.has_key('pki_external_csr_path') or\ + not len(master['pki_external_csr_path']): + config.pki_log.error( + log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2, + "pki_external_csr_path", + master['pki_deployment_cfg'], + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + elif not os.path.isfile(master['pki_external_csr_path']): + config.pki_log.error( + log.PKI_FILE_ALREADY_EXISTS_NOT_A_FILE_1, + master['pki_external_csr_path'], + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + else: + if not master.has_key('pki_external_ca_cert_chain_path') or\ + not len(master['pki_external_ca_cert_chain_path']): + config.pki_log.error( + log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2, + "pki_external_ca_cert_chain_path", + master['pki_deployment_cfg'], + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + elif not os.path.isfile( + master['pki_external_ca_cert_chain_path']): + config.pki_log.error( + log.PKI_FILE_ALREADY_EXISTS_NOT_A_FILE_1, + master['pki_external_ca_cert_chain_path'], + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + if not master.has_key('pki_external_ca_cert_path') or\ + not len(master['pki_external_ca_cert_path']): + config.pki_log.error( + log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2, + "pki_external_ca_cert_path", + master['pki_deployment_cfg'], + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + elif not os.path.isfile( + master['pki_external_ca_cert_path']): + config.pki_log.error( + log.PKI_FILE_ALREADY_EXISTS_NOT_A_FILE_1, + master['pki_external_ca_cert_path'], + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + return + def populate_non_default_ports(self): if master['pki_http_port'] != \ config.PKI_DEPLOYMENT_DEFAULT_TOMCAT_HTTP_PORT: @@ -557,6 +683,20 @@ class configuration_file: sys.exit(1) return + def verify_command_matches_configuration_file(self): + # Silently verify that the command-line parameters match the values + # that are present in the corresponding configuration file + if master['pki_deployment_executable'] == 'pkidestroy': + if master['pki_deployed_instance_name'] !=\ + master['pki_instance_id']: + config.pki_log.error( + log.PKIHELPER_COMMAND_LINE_PARAMETER_MISMATCH_2, + master['pki_deployed_instance_name'], + master['pki_instance_id'], + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + return + # PKI Deployment XML File Class @@ -677,6 +817,32 @@ class instance: sys.exit(1) return rv + def verify_subsystem_exists(self): + try: + if not os.path.exists(master['pki_subsystem_path']): + config.pki_log.error(log.PKI_SUBSYSTEM_DOES_NOT_EXIST_2, + master['pki_subsystem'], + master['pki_instance_id'], + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + except OSError as exc: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + + def verify_subsystem_does_not_exist(self): + try: + if os.path.exists(master['pki_subsystem_path']): + config.pki_log.error(log.PKI_SUBSYSTEM_ALREADY_EXISTS_2, + master['pki_subsystem'], + master['pki_instance_id'], + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + except OSError as exc: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + # PKI Deployment Directory Class class directory: @@ -792,10 +958,10 @@ class directory: def delete(self, name, recursive_flag=True, critical_failure=True): try: if not os.path.exists(name) or not os.path.isdir(name): - config.pki_log.error( + # Simply issue a warning and continue + config.pki_log.warning( log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1, name, extra=config.PKI_INDENTATION_LEVEL_2) - sys.exit(1) else: if recursive_flag == True: # rm -rf @@ -816,6 +982,17 @@ class directory: sys.exit(1) return + def exists(self, name): + try: + if not os.path.exists(name) or not os.path.isdir(name): + return False + else: + return True + except OSError as exc: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + def is_empty(self, name): try: if not os.listdir(name): @@ -1165,10 +1342,10 @@ class file: def delete(self, name, critical_failure=True): try: if not os.path.exists(name) or not os.path.isfile(name): - config.pki_log.error( + # Simply issue a warning and continue + config.pki_log.warning( log.PKI_FILE_MISSING_OR_NOT_A_FILE_1, name, extra=config.PKI_INDENTATION_LEVEL_2) - sys.exit(1) else: # rm -f config.pki_log.info(log.PKIHELPER_RM_F_1, name, @@ -1182,6 +1359,17 @@ class file: sys.exit(1) return + def exists(self, name): + try: + if not os.path.exists(name) or not os.path.isfile(name): + return False + else: + return True + except OSError as exc: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + def copy(self, old_name, new_name, uid=None, gid=None, perms=config.PKI_DEPLOYMENT_DEFAULT_FILE_PERMISSIONS, acls=None, overwrite_flag=False, critical_failure=True): @@ -1601,10 +1789,10 @@ class symlink: def delete(self, link, critical_failure=True): try: if not os.path.exists(link) or not os.path.islink(link): - config.pki_log.error( + # Simply issue a warning and continue + config.pki_log.warning( log.PKI_SYMLINK_MISSING_OR_NOT_A_SYMLINK_1, link, extra=config.PKI_INDENTATION_LEVEL_2) - sys.exit(1) else: # rm -f config.pki_log.info(log.PKIHELPER_RM_F_1, link, @@ -1618,6 +1806,17 @@ class symlink: sys.exit(1) return + def exists(self, name): + try: + if not os.path.exists(name) or not os.path.islink(name): + return False + else: + return True + except OSError as exc: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + # PKI Deployment War File Class class war: @@ -2149,6 +2348,7 @@ class jython: property = "" # Compose this "jython" command data = pickle.dumps(master) + sensitive_data = pickle.dumps(sensitive) ld_library_path = "LD_LIBRARY_PATH" if master['pki_architecture'] == 64: ld_library_path = ld_library_path + "=" +\ @@ -2158,7 +2358,8 @@ class jython: ld_library_path = ld_library_path + "=" +\ "/usr/lib/jss:/usr/lib:/lib" command = "export" + " " + ld_library_path + ";" + "jython" + " " +\ - property + " " + scriptlet + " " + "\"" + data + "\"" + property + " " + scriptlet + " " + "\"" + data + "\"" +\ + " " + "\"" + sensitive_data + "\"" # Display this "jython" command config.pki_log.info( log.PKIHELPER_INVOKE_JYTHON_3, diff --git a/base/deploy/src/scriptlets/pkijython.py b/base/deploy/src/scriptlets/pkijython.py index ffd8884cd..0c482bbdf 100644 --- a/base/deploy/src/scriptlets/pkijython.py +++ b/base/deploy/src/scriptlets/pkijython.py @@ -154,23 +154,6 @@ import pkimessages as log # PKI Deployment Jython Helper Functions -def extract_sensitive_data(configuration_file): - "Read 'sensitive' configuration file section into a dictionary" - try: - parser = ConfigParser.ConfigParser() - # Make keys case-sensitive! - parser.optionxform = str - parser.read(configuration_file) - # return dict(parser._sections['Sensitive']) - dictionary = {} - for option in parser.options('Sensitive'): - dictionary[option] = parser.get('Sensitive', option) - return dictionary - except ConfigParser.ParsingError, err: - javasystem.out.println(log.PKI_JYTHON_EXCEPTION_PARSER + " '" +\ - configuration_file + "': " + str(err)) - javasystem.exit(1) - def generateCRMFRequest(token, keysize, subjectdn, dualkey): kg = token.getKeyPairGenerator(KeyPairAlgorithm.RSA) x = Integer(keysize) @@ -285,7 +268,7 @@ class rest_client: e.printStackTrace() javasystem.exit(1) - def construct_pki_configuration_data(self, master, token): + def construct_pki_configuration_data(self, master, sensitive, token): data = None if master['pki_jython_log_level'] >= config.PKI_JYTHON_INFO_LOG_LEVEL: print "%s %s '%s'" %\ @@ -293,10 +276,9 @@ class rest_client: log.PKI_JYTHON_CONSTRUCTING_PKI_DATA, master['pki_subsystem']) if not master['pki_dry_run_flag']: - sensitive = extract_sensitive_data(master['pki_deployment_cfg']) data = ConfigurationData() # Miscellaneous Configuration Information - data.setPin(master['pki_one_time_pin']) + data.setPin(sensitive['pki_one_time_pin']) data.setToken(ConfigurationData.TOKEN_DEFAULT) if master['pki_instance_type'] == "Tomcat": data.setSubsystemName(master['pki_subsystem_name']) @@ -390,7 +372,7 @@ class rest_client: if master['pki_instance_type'] == "Tomcat": if config.str2bool(master['pki_backup_keys']): data.setBackupKeys("true") - data.setBackupFile(master['pki_backup_file']) + data.setBackupFile(master['pki_backup_keys_p12']) data.setBackupPassword( sensitive['pki_backup_password']) else: @@ -569,7 +551,7 @@ class rest_client: data.setSystemCerts(systemCerts) return data - def configure_pki_data(self, data, master): + def configure_pki_data(self, data, master, sensitive): if master['pki_jython_log_level'] >= config.PKI_JYTHON_INFO_LOG_LEVEL: print "%s %s '%s'" %\ (log.PKI_JYTHON_INDENTATION_2, @@ -577,7 +559,6 @@ class rest_client: master['pki_subsystem']) if not master['pki_dry_run_flag']: try: - sensitive = extract_sensitive_data(master['pki_deployment_cfg']) response = self.client.configure(data) javasystem.out.println(log.PKI_JYTHON_RESPONSE_STATUS +\ " " + response.getStatus()) @@ -595,7 +576,7 @@ class rest_client: javasystem.out.println(log.PKI_JYTHON_CDATA_REQUEST + " " +\ cdata.getRequest()) # Store the Administration Certificate in a file - admin_cert_file = os.path.join(master['pki_client_path'], + admin_cert_file = os.path.join(master['pki_client_dir'], master['pki_client_admin_cert']) javasystem.out.println(log.PKI_JYTHON_ADMIN_CERT_SAVE +\ " " + "'" + admin_cert_file + "'") @@ -626,7 +607,7 @@ class rest_client: "-f" + " " +\ master['pki_client_password_conf'] + " " +\ "-d" + " " +\ - master['pki_client_database_path'] + " " +\ + master['pki_client_database_dir'] + " " +\ "-a" + " " +\ "-i" + " " +\ admin_cert_file @@ -643,7 +624,7 @@ class rest_client: re.sub("'", "'", master['pki_admin_nickname']) +\ "\"" + " " +\ "-d" + " " +\ - master['pki_client_database_path'] + " " +\ + master['pki_client_database_dir'] + " " +\ "-k" + " " +\ master['pki_client_password_conf'] + " " +\ "-w" + " " +\ diff --git a/base/deploy/src/scriptlets/pkimanifest.py b/base/deploy/src/scriptlets/pkimanifest.py index 4f45e4b61..04a638f06 100644 --- a/base/deploy/src/scriptlets/pkimanifest.py +++ b/base/deploy/src/scriptlets/pkimanifest.py @@ -65,8 +65,6 @@ class record(object): # PKI Deployment Manifest File Class class file: - """FUTURE: Consider creating a single manifest file - that is always overwritten.""" global database filename = None diff --git a/base/deploy/src/scriptlets/pkimessages.py b/base/deploy/src/scriptlets/pkimessages.py index 9dfd454a1..ccd7570d1 100644 --- a/base/deploy/src/scriptlets/pkimessages.py +++ b/base/deploy/src/scriptlets/pkimessages.py @@ -55,17 +55,6 @@ PKI_VERBOSITY=\ # PKI Deployment Error Messages PKI_BADZIPFILE_ERROR_1 = "zipfile.BadZipFile: %s!" -PKI_CUSTOM_APACHE_INSTANCE_1 = "When a custom '%s' subsystem is being "\ - "deployed, the 'instance', 'http_port', and "\ - "'https_port' must ALL be specified!" -PKI_CUSTOM_TOMCAT_INSTANCE_1 = "When a custom '%s' subsystem is being "\ - "deployed, the 'instance', 'http_port', "\ - "'https_port', and 'ajp_port' must ALL be "\ - "specified!" -PKI_CUSTOM_TOMCAT_AJP_PORT_1 = "When a custom '%s' subsystem is being "\ - "deployed, ONLY the 'instance', "\ - "'http_port', and 'https_port' MUST be "\ - "specified; NO 'ajp_port' should be requested!" PKI_DIRECTORY_ALREADY_EXISTS_1 = "Directory '%s' already exists!" PKI_DIRECTORY_ALREADY_EXISTS_NOT_A_DIRECTORY_1 = "Directory '%s' already "\ "exists BUT it is NOT a "\ @@ -81,6 +70,7 @@ PKI_FILE_ALREADY_EXISTS_NOT_A_FILE_1 = "File '%s' already "\ PKI_FILE_MISSING_OR_NOT_A_FILE_1 = "File '%s' is either missing "\ "or is NOT a regular file!" PKI_FILE_NOT_A_WAR_FILE_1 = "File '%s' is NOT a war file!" +PKI_INSTANCE_DOES_NOT_EXIST_1 = "PKI instance '%s' does NOT exist!" PKI_SECURITY_DATABASES_ALREADY_EXIST_3 = "Security databases '%s', '%s', "\ "and/or '%s' already exist!" PKI_SECURITY_DATABASES_DO_NOT_EXIST_3 = "Security databases '%s', '%s', "\ @@ -113,6 +103,17 @@ PKIDESTROY_BEGIN_MESSAGE_2 = "BEGIN destroying subsystem '%s' of "\ "instance '%s' . . ." PKIDESTROY_END_MESSAGE_2 = "END destroying subsystem '%s' of "\ "instance '%s'" +PKIDESTROY_EPILOG =\ +"REMINDER:\n\n"\ +" The default PKI instance path will be calculated and placed in front\n"\ +" of the mandatory '-i ' parameter, and the values that reside\n"\ +" in a copy of the 'pkideployment.cfg' file that was most recently used\n"\ +" by this instance's 'pkispawn' (or 'pkispawn -u') command will be\n"\ +" utilized by 'pkidestroy' to remove this instance.\n\n"\ +" Finally, if an optional '-p ' is defined, this value WILL be\n"\ +" prepended to the default PKI instance path which is placed in front\n"\ +" of the specified '-i ' parameter.\n\n" +\ +PKI_VERBOSITY PKIRESPAWN_BEGIN_MESSAGE_2 = "BEGIN respawning subsystem '%s' of "\ "instance '%s' . . ." PKIRESPAWN_END_MESSAGE_2 = "END respawning subsystem '%s' of "\ @@ -121,6 +122,20 @@ PKISPAWN_BEGIN_MESSAGE_2 = "BEGIN spawning subsystem '%s' of "\ "instance '%s' . . ." PKISPAWN_END_MESSAGE_2 = "END spawning subsystem '%s' of "\ "instance '%s'" +PKISPAWN_EPILOG =\ +"REMINDER:\n\n"\ +" If two or more Apache or Tomcat PKI 'instances' are specified via\n"\ +" separate configuration files, remember that the following parameters\n"\ +" MUST differ between PKI 'instances':\n\n"\ +" Apache: 'pki_instance_name', 'pki_http_port', and 'pki_https_port'\n"\ +" Tomcat: 'pki_instance_name', 'pki_http_port', 'pki_https_port',\n"\ +" 'pki_ajp_port', and 'pki_tomcat_server_port'\n\n"\ +" Optionally, the 'pki_admin_domain_name' may be changed instead of, or\n"\ +" in addition to, the 'pki_instance_name' since a PKI instance is\n"\ +" defined as '${pki_instance_name}[.${pki_admin_domain_name}]'.\n\n"\ +" Finally, if an optional '-p ' is defined, this value WILL NOT\n"\ +" be prepended in front of the mandatory '-f '.\n\n" +\ +PKI_VERBOSITY # PKI Deployment "Helper" Messages @@ -147,6 +162,9 @@ PKIHELPER_CERTUTIL_SELF_SIGNED_CERTIFICATE_1 = "executing '%s'" PKIHELPER_CHMOD_2 = "chmod %o %s" PKIHELPER_CHOWN_3 = "chown %s:%s %s" PKIHELPER_CHOWN_H_3 = "chown -h %s:%s %s" +PKIHELPER_COMMAND_LINE_PARAMETER_MISMATCH_2 = "the command-line parameter "\ + "'%s' DOES NOT match the "\ + "configuration file value '%s'!" PKIHELPER_COPY_WITH_SLOT_SUBSTITUTION_2 = "copying '%s' --> '%s' "\ "with slot substitution" PKIHELPER_CP_P_2 = "cp -p %s %s" @@ -166,7 +184,7 @@ PKIHELPER_GROUP_ADD_KEYERROR_1 = "KeyError: pki_group %s" PKIHELPER_INVALID_SELINUX_CONTEXT_FOR_PORT = "port %s has invalid selinux "\ "context %s" PKIHELPER_INVOKE_JYTHON_3 = "executing 'export %s;"\ - "jython %s %s '" + "jython %s %s '" PKIHELPER_IS_A_DIRECTORY_1 = "'%s' is a directory" PKIHELPER_IS_A_FILE_1 = "'%s' is a file" PKIHELPER_IS_A_SYMLINK_1 = "'%s' is a symlink" @@ -209,18 +227,11 @@ PKIHELPER_TOMCAT_INSTANCES_2 = "instance '%s' contains '%d' "\ "Tomcat PKI subsystems" PKIHELPER_TOUCH_1 = "touch %s" PKIHELPER_UID_2 = "UID of '%s' is %s" -PKIHELPER_UNDEFINED_ADMIN_PASSWORD_1 =\ - "A value for 'pki_admin_password' MUST be defined in '%s'" -PKIHELPER_UNDEFINED_BACKUP_PASSWORD_1 =\ - "A value for 'pki_backup_password' MUST be defined in '%s'" -PKIHELPER_UNDEFINED_CLIENT_PKCS12_PASSWORD_1 =\ - "A value for 'pki_client_pkcs12_password' MUST be defined in '%s'" -PKIHELPER_UNDEFINED_CLONE_PKCS12_PASSWORD_1 =\ - "A value for 'pki_clone_pkcs12_password' MUST be defined in '%s'" -PKIHELPER_UNDEFINED_DS_PASSWORD_1 =\ - "A value for 'pki_ds_password' MUST be defined in '%s'" -PKIHELPER_UNDEFINED_SECURITY_DOMAIN_PASSWORD_1 =\ - "A value for 'pki_security_domain_password' MUST be defined in '%s'" +PKIHELPER_UNDEFINED_CLIENT_DATABASE_PASSWORD_2 =\ + "Either a value for '%s' MUST be defined in '%s', or "\ + "the randomly generated client pin MUST be used" +PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2 =\ + "A value for '%s' MUST be defined in '%s'" PKIHELPER_USER_1 = "retrieving UID for '%s' . . ." PKIHELPER_USER_ADD_2 = "adding UID '%s' for user '%s' . . ." PKIHELPER_USER_ADD_DEFAULT_2 = "adding default UID '%s' for user '%s' . . ." diff --git a/base/deploy/src/scriptlets/pkiparser.py b/base/deploy/src/scriptlets/pkiparser.py index 6e1404180..e39b19700 100644 --- a/base/deploy/src/scriptlets/pkiparser.py +++ b/base/deploy/src/scriptlets/pkiparser.py @@ -24,6 +24,8 @@ import ConfigParser import argparse import logging import os +import random +import string import sys import time @@ -36,16 +38,20 @@ import pkimessages as log # PKI Deployment Helper Functions def process_command_line_arguments(argv): "Read and process command-line options" + config.pki_deployment_executable = os.path.basename(argv[0]) description = None - if os.path.basename(argv[0]) == 'pkispawn': + if config.pki_deployment_executable == 'pkispawn': description = 'PKI Instance Installation and Configuration' - elif os.path.basename(argv[0]) == 'pkidestroy': + epilog = log.PKISPAWN_EPILOG + elif config.pki_deployment_executable == 'pkidestroy': description = 'PKI Instance Removal' + epilog = log.PKIDESTROY_EPILOG parser = argparse.ArgumentParser( description=description, add_help=False, formatter_class=argparse.RawDescriptionHelpFormatter, - epilog=log.PKI_VERBOSITY) + epilog=epilog) + # Establish 'Mandatory' command-line options mandatory = parser.add_argument_group('mandatory arguments') mandatory.add_argument('-s', dest='pki_subsystem', action='store', @@ -53,12 +59,20 @@ def process_command_line_arguments(argv): required=True, metavar='', help='where is ' 'CA, KRA, OCSP, RA, TKS, or TPS') - if os.path.basename(argv[0]) == 'pkispawn': + if config.pki_deployment_executable == 'pkispawn': mandatory.add_argument('-f', dest='pkideployment_cfg', action='store', nargs=1, required=True, metavar='', - help='specifies configuration filename') - + help='configuration filename ' + '(MUST specify complete path)') + elif config.pki_deployment_executable == 'pkidestroy': + mandatory.add_argument('-i', + dest='pki_deployed_instance_name', + action='store', + nargs=1, metavar='', + help='FORMAT: ${pki_instance_name}' + '[.${pki_admin_domain_name}]') + # Establish 'Optional' command-line options optional = parser.add_argument_group('optional arguments') optional.add_argument('--dry_run', dest='pki_dry_run_flag', action='store_true', @@ -66,73 +80,40 @@ def process_command_line_arguments(argv): optional.add_argument('-h', '--help', dest='help', action='help', help='show this help message and exit') - if os.path.basename(argv[0]) == 'pkispawn': + if config.pki_deployment_executable == 'pkispawn': optional.add_argument('-u', dest='pki_update_flag', action='store_true', help='update instance of specified subsystem') optional.add_argument('-v', dest='pki_verbosity', action='count', help='display verbose information (details below)') - custom = parser.add_argument_group('custom arguments ' - '(OVERRIDES configuration file values)') - if os.path.basename(argv[0]) == 'pkispawn': - custom.add_argument('-i', - dest='custom_pki_instance_name', action='store', - nargs=1, metavar='', - help='PKI instance name ' - '(MUST specify REQUIRED ports)') - custom.add_argument('-d', - dest='custom_pki_admin_domain_name', action='store', - nargs=1, metavar='', - help='PKI admin domain name (instance name suffix)') - custom.add_argument('--http_port', - dest='custom_pki_http_port', action='store', - nargs=1, metavar='', - help='HTTP port (CA, KRA, OCSP, RA, TKS, TPS)') - custom.add_argument('--https_port', - dest='custom_pki_https_port', action='store', - nargs=1, metavar='', - help='HTTPS port (CA, KRA, OCSP, RA, TKS, TPS)') - custom.add_argument('--ajp_port', - dest='custom_pki_ajp_port', action='store', - nargs=1, metavar='', - help='AJP port (CA, KRA, OCSP, TKS)') - elif os.path.basename(argv[0]) == 'pkidestroy': - custom.add_argument('-i', - dest='custom_pki_instance_name', action='store', - nargs=1, metavar='', - help='PKI instance name') - custom.add_argument('-d', - dest='custom_pki_admin_domain_name', action='store', - nargs=1, metavar='', - help='PKI admin domain name (instance name suffix)') - + # Establish 'Test' command-line options test = parser.add_argument_group('test arguments') test.add_argument('-p', dest='pki_root_prefix', action='store', nargs=1, metavar='', help='directory prefix to specify local directory ' '[TEST ONLY]') + # Parse command-line options args = parser.parse_args() - + # Process 'Mandatory' command-line options + # '-s' config.pki_subsystem = str(args.pki_subsystem).strip('[\']') + if config.pki_deployment_executable == 'pkispawn': + # '-f' + config.pkideployment_cfg = str(args.pkideployment_cfg).strip('[\']') + elif config.pki_deployment_executable == 'pkidestroy': + # '-i' + config.pki_deployed_instance_name =\ + str(args.pki_deployed_instance_name).strip('[\']') + # Process 'Optional' command-line options + # '--dry_run' if args.pki_dry_run_flag: config.pki_dry_run_flag = args.pki_dry_run_flag - if not args.pki_root_prefix is None: - config.pki_root_prefix = str(args.pki_root_prefix).strip('[\']') - if config.pki_root_prefix is None or\ - len(config.pki_root_prefix) == 0: - config.pki_root_prefix = "" - elif not os.path.exists(config.pki_root_prefix) or\ - not os.path.isdir(config.pki_root_prefix): - print "ERROR: " +\ - log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1 %\ - config.pki_root_prefix - print - parser.print_help() - parser.exit(-1); - if os.path.basename(argv[0]) == 'pkispawn': + if config.pki_deployment_executable == 'pkispawn': + # '-u' config.pki_update_flag = args.pki_update_flag + # '-v' if args.pki_verbosity == 1: config.pki_jython_log_level = config.PKI_JYTHON_INFO_LOG_LEVEL config.pki_console_log_level = logging.INFO @@ -155,151 +136,47 @@ def process_command_line_arguments(argv): config.pki_jython_log_level = config.PKI_JYTHON_WARNING_LOG_LEVEL config.pki_console_log_level = logging.WARNING config.pki_log_level = logging.INFO - if not args.custom_pki_instance_name is None: - config.custom_pki_instance_name =\ - str(args.custom_pki_instance_name).strip('[\']') - if not args.custom_pki_admin_domain_name is None: - config.custom_pki_admin_domain_name =\ - str(args.custom_pki_admin_domain_name).strip('[\']') - if config.pki_subsystem in config.PKI_APACHE_SUBSYSTEMS: - if not config.custom_pki_instance_name is None: - default_pki_instance_name = config.custom_pki_instance_name - else: - default_pki_instance_name =\ - config.PKI_DEPLOYMENT_DEFAULT_APACHE_INSTANCE_NAME - if not config.custom_pki_admin_domain_name is None: - default_pki_instance_path =\ - config.pki_root_prefix +\ - config.PKI_DEPLOYMENT_BASE_ROOT + "/" +\ - default_pki_instance_name + "." +\ - config.custom_pki_admin_domain_name + "/" +\ - config.pki_subsystem.lower() - else: - default_pki_instance_path =\ - config.pki_root_prefix +\ - config.PKI_DEPLOYMENT_BASE_ROOT + "/" +\ - default_pki_instance_name + "/" +\ - config.pki_subsystem.lower() - elif config.pki_subsystem in config.PKI_TOMCAT_SUBSYSTEMS: - if not config.custom_pki_instance_name is None: - default_pki_instance_name = config.custom_pki_instance_name - else: - default_pki_instance_name =\ - config.PKI_DEPLOYMENT_DEFAULT_TOMCAT_INSTANCE_NAME - if not config.custom_pki_admin_domain_name is None: - default_pki_instance_path =\ - config.pki_root_prefix +\ - config.PKI_DEPLOYMENT_BASE_ROOT + "/" +\ - default_pki_instance_name + "." +\ - config.custom_pki_admin_domain_name + "/" +\ - config.pki_subsystem.lower() - else: - default_pki_instance_path =\ - config.pki_root_prefix +\ - config.PKI_DEPLOYMENT_BASE_ROOT + "/" +\ - default_pki_instance_name + "/" +\ - config.pki_subsystem.lower() - if os.path.basename(argv[0]) == 'pkispawn': - if args.pki_update_flag: - # "respawn" - if not os.path.exists(default_pki_instance_path): - print "ERROR: " + log.PKI_SUBSYSTEM_DOES_NOT_EXIST_2 %\ - (config.pki_subsystem, default_pki_instance_name) - print - parser.exit(-1); - else: - # "spawn" - if os.path.exists(default_pki_instance_path): - print "ERROR: " + log.PKI_SUBSYSTEM_ALREADY_EXISTS_2 %\ - (config.pki_subsystem, default_pki_instance_name) - print - parser.exit(-1); - config.pkideployment_cfg = str(args.pkideployment_cfg).strip('[\']') - if not args.custom_pki_http_port is None: - config.custom_pki_http_port =\ - str(args.custom_pki_http_port).strip('[\']') - if not args.custom_pki_https_port is None: - config.custom_pki_https_port =\ - str(args.custom_pki_https_port).strip('[\']') - if not args.custom_pki_ajp_port is None: - if config.pki_subsystem in config.PKI_TOMCAT_SUBSYSTEMS: - config.custom_pki_ajp_port =\ - str(args.custom_pki_ajp_port).strip('[\']') - else: - print "ERROR: " +\ - log.PKI_CUSTOM_TOMCAT_AJP_PORT_1 %\ - config.pki_subsystem - print - parser.print_help() - parser.exit(-1); - if not args.custom_pki_instance_name is None or\ - not args.custom_pki_http_port is None or\ - not args.custom_pki_https_port is None or\ - not args.custom_pki_ajp_port is None: - if config.pki_subsystem in config.PKI_APACHE_SUBSYSTEMS: - if args.custom_pki_instance_name is None or\ - args.custom_pki_http_port is None or\ - args.custom_pki_https_port is None: - print "ERROR: " + log.PKI_CUSTOM_APACHE_INSTANCE_1 %\ - config.pki_subsystem - print - parser.print_help() - parser.exit(-1); - elif config.pki_subsystem in config.PKI_TOMCAT_SUBSYSTEMS: - if args.custom_pki_instance_name is None or\ - args.custom_pki_http_port is None or\ - args.custom_pki_https_port is None or\ - args.custom_pki_ajp_port is None: - print "ERROR: " + log.PKI_CUSTOM_TOMCAT_INSTANCE_1 %\ - config.pki_subsystem - print - parser.print_help() - parser.exit(-1); - elif os.path.basename(argv[0]) == 'pkidestroy': - # NOTE: When performing 'pkidestroy', a 'pki_instance_name' and/or - # a 'pki_admin_domain_name' MUST be explicitly specified if - # a PKI instance has NOT been installed in the default location - # using the default PKI instance name! - if not os.path.exists(default_pki_instance_path): + # Process 'Test' command-line options + # '-p' + if not args.pki_root_prefix is None: + config.pki_root_prefix = str(args.pki_root_prefix).strip('[\']') + # Validate command-line options + if config.pki_root_prefix is None or\ + len(config.pki_root_prefix) == 0: + config.pki_root_prefix = "" + elif not os.path.exists(config.pki_root_prefix) or\ + not os.path.isdir(config.pki_root_prefix): + print "ERROR: " +\ + log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1 %\ + config.pki_root_prefix + print + parser.print_help() + parser.exit(-1); + if config.pki_deployment_executable == 'pkidestroy': + # verify that previously deployed instance exists + deployed_pki_instance_path = config.pki_root_prefix +\ + config.PKI_DEPLOYMENT_BASE_ROOT + "/" +\ + config.pki_deployed_instance_name + if not os.path.exists(deployed_pki_instance_path): + print "ERROR: " + log.PKI_INSTANCE_DOES_NOT_EXIST_1 %\ + deployed_pki_instance_path + print + parser.exit(-1); + # verify that previously deployed subsystem for this instance exists + deployed_pki_subsystem_path = deployed_pki_instance_path + "/" +\ + config.pki_subsystem.lower() + if not os.path.exists(deployed_pki_subsystem_path): print "ERROR: " + log.PKI_SUBSYSTEM_DOES_NOT_EXIST_2 %\ - (config.pki_subsystem, default_pki_instance_name) + (config.pki_subsystem, deployed_pki_instance_path) print parser.exit(-1); - if config.pki_subsystem in config.PKI_APACHE_SUBSYSTEMS: - if not config.custom_pki_admin_domain_name is None: - default_pki_instance_registry_path =\ - config.pki_root_prefix +\ - config.PKI_DEPLOYMENT_REGISTRY_ROOT + "/" +\ - config.PKI_DEPLOYMENT_DEFAULT_APACHE_SERVICE_NAME + "/" +\ - default_pki_instance_name + "." +\ - config.custom_pki_admin_domain_name + "/" +\ - config.pki_subsystem.lower() - else: - default_pki_instance_registry_path =\ - config.pki_root_prefix +\ - config.PKI_DEPLOYMENT_REGISTRY_ROOT + "/" +\ - config.PKI_DEPLOYMENT_DEFAULT_APACHE_SERVICE_NAME + "/" +\ - default_pki_instance_name + "/" +\ - config.pki_subsystem.lower() - elif config.pki_subsystem in config.PKI_TOMCAT_SUBSYSTEMS: - if not config.custom_pki_admin_domain_name is None: - default_pki_instance_registry_path =\ - config.pki_root_prefix +\ - config.PKI_DEPLOYMENT_REGISTRY_ROOT + "/" +\ - config.PKI_DEPLOYMENT_DEFAULT_TOMCAT_SERVICE_NAME + "/" +\ - default_pki_instance_name + "." +\ - config.custom_pki_admin_domain_name + "/" +\ - config.pki_subsystem.lower() - else: - default_pki_instance_registry_path =\ - config.pki_root_prefix +\ - config.PKI_DEPLOYMENT_REGISTRY_ROOT + "/" +\ - config.PKI_DEPLOYMENT_DEFAULT_TOMCAT_SERVICE_NAME + "/" +\ - default_pki_instance_name + "/" +\ - config.pki_subsystem.lower() + # establish complete path to previously deployed configuration file config.pkideployment_cfg =\ - default_pki_instance_registry_path + "/" +\ + deployed_pki_subsystem_path + "/" +\ + "registry" + "/" +\ + config.pki_subsystem.lower() + "/" +\ config.PKI_DEPLOYMENT_DEFAULT_CONFIGURATION_FILE + # always verify that configuration file exists if not os.path.exists(config.pkideployment_cfg) or\ not os.path.isfile(config.pkideployment_cfg): print "ERROR: " +\ @@ -354,6 +231,8 @@ def compose_pki_master_dictionary(): try: config.pki_master_dict = dict() # 'pkispawn'/'pkirespawn'/'pkidestroy' name/value pairs + config.pki_master_dict['pki_deployment_executable'] =\ + config.pki_deployment_executable config.pki_master_dict['pki_install_time'] = config.pki_install_time config.pki_master_dict['pki_timestamp'] = config.pki_timestamp config.pki_master_dict['pki_certificate_timestamp'] =\ @@ -362,13 +241,27 @@ def compose_pki_master_dictionary(): config.pki_master_dict['pki_hostname'] = config.pki_hostname config.pki_master_dict['pki_dns_domainname'] =\ config.pki_dns_domainname - config.pki_master_dict['pki_pin'] = config.pki_pin - config.pki_master_dict['pki_client_pin'] = config.pki_client_pin - config.pki_master_dict['pki_one_time_pin'] = config.pki_one_time_pin config.pki_master_dict['pki_dry_run_flag'] = config.pki_dry_run_flag config.pki_master_dict['pki_jython_log_level'] =\ config.pki_jython_log_level config.pki_master_dict['pki_deployment_cfg'] = config.pkideployment_cfg + config.pki_master_dict['pki_deployed_instance_name'] =\ + config.pki_deployed_instance_name + # Generate random 'pin's for use as security database passwords + # and add these to the "sensitive" key value pairs read in from + # the configuration file + pin_low = 100000000000 + pin_high = 999999999999 + config.pki_sensitive_dict['pki_pin'] =\ + random.randint(pin_low, pin_high) + config.pki_sensitive_dict['pki_client_pin'] =\ + random.randint(pin_low, pin_high) + # Generate a one-time pin to be used prior to configuration + # and add this to the "sensitive" key value pairs read in from + # the configuration file + config.pki_sensitive_dict['pki_one_time_pin'] =\ + ''.join(random.choice(string.ascii_letters + string.digits)\ + for x in range(20)) # Configuration file name/value pairs # NEVER add "sensitive" key value pairs to the master dictionary!!! config.pki_master_dict.update(config.pki_common_dict) @@ -420,7 +313,7 @@ def compose_pki_master_dictionary(): # OLD: "pki-${pki_subsystem}" # (e. g. Tomcat: "pki-ca", "pki-kra", "pki-ocsp", "pki-tks") # (e. g. Apache: "pki-ra", "pki-tps") - # NEW: "[${pki_admin_domain_name}-]${pki_instance_name}" + # NEW: "${pki_instance_name}[.${pki_admin_domain_name}]" # (e. g. Tomcat: "pki-tomcat", "pki-tomcat.example.com") # (e. g. Apache: "pki-apache", "pki-apache.example.com") # @@ -487,7 +380,7 @@ def compose_pki_master_dictionary(): "lib") config.pki_master_dict['pki_tomcat_systemd'] =\ config.PKI_DEPLOYMENT_TOMCAT_SYSTEMD - config.pki_master_dict['pki_war_path'] =\ + config.pki_master_dict['pki_war_source_dir'] =\ os.path.join(config.PKI_DEPLOYMENT_SOURCE_ROOT, config.pki_master_dict['pki_subsystem'].lower(), "war") @@ -496,8 +389,8 @@ def compose_pki_master_dictionary(): config.pki_master_dict['pki_subsystem'].lower(), "webapps") config.pki_master_dict['pki_war'] =\ - os.path.join(config.pki_master_dict['pki_war_path'], - config.pki_master_dict['pki_war_name']) + os.path.join(config.pki_master_dict['pki_war_source_dir'], + config.pki_master_dict['pki_war_file']) config.pki_master_dict['pki_source_catalina_properties'] =\ os.path.join(config.pki_master_dict['pki_source_shared_path'], "catalina.properties") @@ -932,6 +825,9 @@ def compose_pki_master_dictionary(): config.pki_master_dict['pki_subsystem_log_path'] =\ os.path.join(config.pki_master_dict['pki_instance_log_path'], config.pki_master_dict['pki_subsystem'].lower()) + config.pki_master_dict['pki_subsystem_archive_log_path'] =\ + os.path.join(config.pki_master_dict['pki_subsystem_log_path'], + "archive") # Instance-based PKI subsystem configuration name/value pairs config.pki_master_dict['pki_subsystem_configuration_path'] =\ os.path.join( @@ -983,6 +879,9 @@ def compose_pki_master_dictionary(): config.pki_master_dict['pki_subsystem_logs_link'] =\ os.path.join(config.pki_master_dict['pki_subsystem_path'], "logs") + config.pki_master_dict['pki_subsystem_registry_link'] =\ + os.path.join(config.pki_master_dict['pki_subsystem_path'], + "registry") # PKI Target (war file) name/value pairs if config.pki_master_dict['pki_subsystem'] in\ config.PKI_TOMCAT_SUBSYSTEMS: @@ -1232,13 +1131,9 @@ def compose_pki_master_dictionary(): config.pki_master_dict['PKI_AJP_REDIRECT_PORT_SLOT'] =\ config.pki_master_dict['pki_https_port'] config.pki_master_dict['PKI_CERT_DB_PASSWORD_SLOT'] =\ - config.pki_master_dict['pki_pin'] + config.pki_sensitive_dict['pki_pin'] config.pki_master_dict['PKI_CFG_PATH_NAME_SLOT'] =\ config.pki_master_dict['pki_target_cs_cfg'] - config.pki_master_dict['PKI_CLOSE_AJP_PORT_COMMENT_SLOT'] =\ - "-->" - config.pki_master_dict['PKI_CLOSE_ENABLE_PROXY_COMMENT_SLOT'] =\ - "-->" config.pki_master_dict\ ['PKI_CLOSE_SEPARATE_PORTS_SERVER_COMMENT_SLOT'] =\ "-->" @@ -1272,10 +1167,6 @@ def compose_pki_master_dictionary(): "tomcat") config.pki_master_dict['PKI_MACHINE_NAME_SLOT'] =\ config.pki_master_dict['pki_hostname'] - config.pki_master_dict['PKI_OPEN_AJP_PORT_COMMENT_SLOT'] =\ - "" + config.pki_master_dict['PKI_CLOSE_ENABLE_PROXY_COMMENT_SLOT'] =\ + "-->" + config.pki_master_dict['PKI_PROXY_SECURE_PORT_SLOT'] = "" + config.pki_master_dict['PKI_PROXY_UNSECURE_PORT_SLOT'] = "" + config.pki_master_dict['PKI_OPEN_AJP_PORT_COMMENT_SLOT'] =\ + "