diff options
author | Matthew Harmsen <mharmsen@redhat.com> | 2012-05-04 20:29:35 -0700 |
---|---|---|
committer | Matthew Harmsen <mharmsen@redhat.com> | 2012-05-07 11:28:10 -0700 |
commit | 391d345b5a6a1a905e3db4105a65dd4fdd0d19a9 (patch) | |
tree | cf73a152055f6bbc217c42bf8a8f0396ab3fd3dd /base/deploy/src/scriptlets/pkihelper.py | |
parent | 9ad4d60592fdc37ae89672c29859b8463e183718 (diff) | |
download | pki-391d345b5a6a1a905e3db4105a65dd4fdd0d19a9.tar.gz pki-391d345b5a6a1a905e3db4105a65dd4fdd0d19a9.tar.xz pki-391d345b5a6a1a905e3db4105a65dd4fdd0d19a9.zip |
PKI Deployment Scriptlets
* Re-aligned code to account for revised layout documented at
http://pki.fedoraproject.org/wiki/PKI_Instance_Deployment
* Massaged logic to comply with PKI subsystem running within
a shared instance
* Developed code to take advantage of a single shared NSS security
database model
* Completed the following two 'scriptlets':
* Dogtag 10: Python 'slot_assignment.py' Installation Scriptlet
(https://fedorahosted.org/pki/ticket/146)
* Dogtag 10: Python 'security_databases.py' Installation Scriptlet
(https://fedorahosted.org/pki/ticket/136)
* Created several additional PKI deployment helper utilities.
Diffstat (limited to 'base/deploy/src/scriptlets/pkihelper.py')
-rw-r--r-- | base/deploy/src/scriptlets/pkihelper.py | 711 |
1 files changed, 659 insertions, 52 deletions
diff --git a/base/deploy/src/scriptlets/pkihelper.py b/base/deploy/src/scriptlets/pkihelper.py index 95b5bf0a7..b04af2db0 100644 --- a/base/deploy/src/scriptlets/pkihelper.py +++ b/base/deploy/src/scriptlets/pkihelper.py @@ -1,4 +1,5 @@ #!/usr/bin/python -t + # Authors: # Matthew Harmsen <mharmsen@redhat.com> # @@ -23,7 +24,11 @@ import errno import sys import os +import fileinput +import random import shutil +import string +import subprocess from grp import getgrnam from pwd import getpwnam import zipfile @@ -32,11 +37,12 @@ import zipfile # PKI Deployment Imports import pkiconfig as config from pkiconfig import pki_master_dict as master +from pkiconfig import pki_slots_dict as slots import pkimanifest as manifest import pkimessages as log -# PKI Deployment Functions +# PKI Deployment Helper Functions def pki_copytree(src, dst, symlinks=False, ignore=None): """Recursively copy a directory tree using copy2(). @@ -165,27 +171,30 @@ class identity: # PKI Deployment Instance Class class instance: - def apache_instances(self, name): + def apache_instances(self): rv = 0 try: - if not os.path.exists(name) or not os.path.isdir(name): + if not os.path.exists(master['pki_webserver_path']) or\ + not os.path.isdir(master['pki_webserver_path']): config.pki_log.error( - log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1, name, + log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1, + master['pki_webserver_path'], extra=config.PKI_INDENTATION_LEVEL_2) sys.exit(1) # count number of PKI subsystems present # within the specfied Apache instance for subsystem in config.PKI_APACHE_SUBSYSTEMS: - path = name + "/" + subsystem.lower() + path = master['pki_webserver_path'] + "/" + subsystem.lower() if os.path.exists(path) and os.path.isdir(path): rv = rv + 1 # always display correct information (even during dry_run) if config.pki_dry_run_flag and rv > 0: config.pki_log.debug(log.PKIHELPER_APACHE_INSTANCES_2, - name, rv - 1, + master['pki_webserver_path'], rv - 1, extra=config.PKI_INDENTATION_LEVEL_2) else: - config.pki_log.debug(log.PKIHELPER_APACHE_INSTANCES_2, name, + config.pki_log.debug(log.PKIHELPER_APACHE_INSTANCES_2, + master['pki_webserver_path'], rv, extra=config.PKI_INDENTATION_LEVEL_2) except OSError as exc: config.pki_log.error(log.PKI_OSERROR_1, exc, @@ -193,28 +202,38 @@ class instance: sys.exit(1) return rv - def pki_subsystem_instances(self, name): + def pki_subsystem_instances(self): rv = 0 try: - if not os.path.exists(name) or not os.path.isdir(name): + if not os.path.exists(master['pki_instance_path']) or\ + not os.path.isdir(master['pki_instance_path']): config.pki_log.error( - log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1, name, + log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1, + master['pki_instance_path'], extra=config.PKI_INDENTATION_LEVEL_2) sys.exit(1) - # count total number of PKI subsystems present + # count total number of Apache PKI subsystems present # within the specfied PKI instance - for subsystem in config.PKI_SUBSYSTEMS: - path = name + "/" + subsystem.lower() - if os.path.exists(path) and os.path.isdir(path): + for apache_subsystem in config.PKI_APACHE_SUBSYSTEMS: + apache_path = master['pki_instance_path'] + "/" + "apache" +\ + "/" + apache_subsystem.lower() + if os.path.exists(apache_path) and os.path.isdir(apache_path): + rv = rv + 1 + # count total number of Tomcat PKI subsystems present + # within the specfied PKI instance + for tomcat_subsystem in config.PKI_TOMCAT_SUBSYSTEMS: + tomcat_path = master['pki_instance_path'] + "/" + "tomcat" +\ + "/" + tomcat_subsystem.lower() + if os.path.exists(tomcat_path) and os.path.isdir(tomcat_path): rv = rv + 1 # always display correct information (even during dry_run) if config.pki_dry_run_flag and rv > 0: config.pki_log.debug(log.PKIHELPER_PKI_SUBSYSTEM_INSTANCES_2, - name, rv - 1, + master['pki_instance_path'], rv - 1, extra=config.PKI_INDENTATION_LEVEL_2) else: config.pki_log.debug(log.PKIHELPER_PKI_SUBSYSTEM_INSTANCES_2, - name, rv, + master['pki_instance_path'], rv, extra=config.PKI_INDENTATION_LEVEL_2) except OSError as exc: config.pki_log.error(log.PKI_OSERROR_1, exc, @@ -222,27 +241,30 @@ class instance: sys.exit(1) return rv - def tomcat_instances(self, name): + def tomcat_instances(self): rv = 0 try: - if not os.path.exists(name) or not os.path.isdir(name): + if not os.path.exists(master['pki_webserver_path']) or\ + not os.path.isdir(master['pki_webserver_path']): config.pki_log.error( - log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1, name, + log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1, + master['pki_webserver_path'], extra=config.PKI_INDENTATION_LEVEL_2) sys.exit(1) # count number of PKI subsystems present # within the specfied Tomcat instance for subsystem in config.PKI_TOMCAT_SUBSYSTEMS: - path = name + "/" + subsystem.lower() + path = master['pki_webserver_path'] + "/" + subsystem.lower() if os.path.exists(path) and os.path.isdir(path): rv = rv + 1 # always display correct information (even during dry_run) if config.pki_dry_run_flag and rv > 0: config.pki_log.debug(log.PKIHELPER_TOMCAT_INSTANCES_2, - name, rv - 1, + master['pki_webserver_path'], rv - 1, extra=config.PKI_INDENTATION_LEVEL_2) else: - config.pki_log.debug(log.PKIHELPER_TOMCAT_INSTANCES_2, name, + config.pki_log.debug(log.PKIHELPER_TOMCAT_INSTANCES_2, + master['pki_webserver_path'], rv, extra=config.PKI_INDENTATION_LEVEL_2) except OSError as exc: config.pki_log.error(log.PKI_OSERROR_1, exc, @@ -250,6 +272,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_name'], + extra=config.PKI_INDENTATION_LEVEL_1) + 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_name'], + extra=config.PKI_INDENTATION_LEVEL_1) + 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: @@ -295,11 +343,6 @@ class directory: extra=config.PKI_INDENTATION_LEVEL_2) if critical_failure == True: sys.exit(1) - else: - config.pki_log.error(log.PKI_DIRECTORY_ALREADY_EXISTS_1, name, - extra=config.PKI_INDENTATION_LEVEL_2) - if critical_failure == True: - sys.exit(1) except OSError as exc: if exc.errno == errno.EEXIST: pass @@ -397,13 +440,13 @@ class directory: def is_empty(self, name): try: if not os.listdir(name): - config.pki_log.debug(log.PKIHELPER_DIRECTORY_IS_NOT_EMPTY_1, - name, extra=config.PKI_INDENTATION_LEVEL_2) - return False - else: config.pki_log.debug(log.PKIHELPER_DIRECTORY_IS_EMPTY_1, name, extra=config.PKI_INDENTATION_LEVEL_2) return True + else: + config.pki_log.debug(log.PKIHELPER_DIRECTORY_IS_NOT_EMPTY_1, + name, extra=config.PKI_INDENTATION_LEVEL_2) + return False except OSError as exc: config.pki_log.error(log.PKI_OSERROR_1, exc, extra=config.PKI_INDENTATION_LEVEL_2) @@ -561,12 +604,7 @@ class directory: dir_acls=None, file_acls=None, symlink_acls=None, recursive_flag=True, overwrite_flag=False, critical_failure=True): try: - if not os.path.exists(old_name) or not os.path.isdir(old_name): - config.pki_log.error( - log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1, old_name, - extra=config.PKI_INDENTATION_LEVEL_2) - sys.exit(1) - elif config.pki_dry_run_flag: + if config.pki_dry_run_flag: if recursive_flag == True: # cp -rp <old_name> <new_name> config.pki_log.info(log.PKIHELPER_CP_RP_2, @@ -580,6 +618,11 @@ class directory: config.pki_log.info( log.PKIHELPER_SET_MODE_1, new_name, extra=config.PKI_INDENTATION_LEVEL_2) + elif not os.path.exists(old_name) or not os.path.isdir(old_name): + config.pki_log.error( + log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1, old_name, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) else: if os.path.exists(new_name): if not overwrite_flag: @@ -673,11 +716,6 @@ class file: extra=config.PKI_INDENTATION_LEVEL_2) if critical_failure == True: sys.exit(1) - else: - config.pki_log.error(log.PKI_FILE_ALREADY_EXISTS_1, name, - extra=config.PKI_INDENTATION_LEVEL_2) - if critical_failure == True: - sys.exit(1) except OSError as exc: if exc.errno == errno.EEXIST: pass @@ -769,16 +807,174 @@ class file: perms=config.PKI_DEPLOYMENT_DEFAULT_FILE_PERMISSIONS, acls=None, overwrite_flag=False, critical_failure=True): try: - if not os.path.exists(old_name) or not os.path.isfile(old_name): + if config.pki_dry_run_flag: + # cp -p <old_name> <new_name> + config.pki_log.info(log.PKIHELPER_CP_P_2, + old_name, new_name, + extra=config.PKI_INDENTATION_LEVEL_2) + # chmod <perms> <new_name> + config.pki_log.debug(log.PKIHELPER_CHMOD_2, + perms, new_name, + extra=config.PKI_INDENTATION_LEVEL_3) + # chown <uid>:<gid> <new_name> + config.pki_log.debug(log.PKIHELPER_CHOWN_3, + uid, gid, new_name, + extra=config.PKI_INDENTATION_LEVEL_3) + elif not os.path.exists(old_name) or not os.path.isfile(old_name): config.pki_log.error( log.PKI_FILE_MISSING_OR_NOT_A_FILE_1, old_name, extra=config.PKI_INDENTATION_LEVEL_2) sys.exit(1) - elif config.pki_dry_run_flag: + else: + if os.path.exists(new_name): + if not overwrite_flag: + config.pki_log.error( + log.PKI_FILE_ALREADY_EXISTS_1, new_name, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) # cp -p <old_name> <new_name> config.pki_log.info(log.PKIHELPER_CP_P_2, old_name, new_name, extra=config.PKI_INDENTATION_LEVEL_2) + shutil.copy2(old_name, new_name) + if uid == None: + uid = identity.get_uid() + if gid == None: + gid = identity.get_gid() + # chmod <perms> <new_name> + config.pki_log.debug(log.PKIHELPER_CHMOD_2, + perms, new_name, + extra=config.PKI_INDENTATION_LEVEL_3) + os.chmod(new_name, perms) + # chown <uid>:<gid> <new_name> + config.pki_log.debug(log.PKIHELPER_CHOWN_3, + uid, gid, new_name, + extra=config.PKI_INDENTATION_LEVEL_3) + os.chown(new_name, uid, gid) + # Store record in installation manifest + record = manifest.record() + record.name = new_name + record.type = manifest.RECORD_TYPE_FILE + record.user = master['pki_user'] + record.group = master['pki_group'] + record.uid = uid + record.gid = gid + record.permissions = perms + record.acls = acls + manifest.database.append(record) + except OSError as exc: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + except shutil.Error as exc: + config.pki_log.error(log.PKI_SHUTIL_ERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + return + + def apply_slot_substitution( + self, name, uid=None, gid=None, + perms=config.PKI_DEPLOYMENT_DEFAULT_FILE_PERMISSIONS, + acls=None, critical_failure=True): + try: + if config.pki_dry_run_flag: + # applying in-place slot substitutions on <name> + config.pki_log.info(log.PKIHELPER_APPLY_SLOT_SUBSTITUTION_1, + name, + extra=config.PKI_INDENTATION_LEVEL_2) + # NOTE: During dry_run, this file may not exist! + if os.path.exists(name) and os.path.isfile(name): + for line in fileinput.FileInput(name, inplace=1): + for slot in slots: + if slot != '__name__' and slots[slot] in line: + config.pki_log.debug( + log.PKIHELPER_SLOT_SUBSTITUTION_2, + slots[slot], master[slot], + extra=config.PKI_INDENTATION_LEVEL_3) + # chmod <perms> <name> + config.pki_log.debug(log.PKIHELPER_CHMOD_2, + perms, name, + extra=config.PKI_INDENTATION_LEVEL_3) + # chown <uid>:<gid> <name> + config.pki_log.debug(log.PKIHELPER_CHOWN_3, + uid, gid, name, + extra=config.PKI_INDENTATION_LEVEL_3) + else: + if not os.path.exists(name) or not os.path.isfile(name): + config.pki_log.error( + log.PKI_FILE_MISSING_OR_NOT_A_FILE_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + # applying in-place slot substitutions on <name> + config.pki_log.info(log.PKIHELPER_APPLY_SLOT_SUBSTITUTION_1, + name, + extra=config.PKI_INDENTATION_LEVEL_2) + for line in fileinput.FileInput(name, inplace=1): + for slot in slots: + if slot != '__name__' and slots[slot] in line: + config.pki_log.debug( + log.PKIHELPER_SLOT_SUBSTITUTION_2, + slots[slot], master[slot], + extra=config.PKI_INDENTATION_LEVEL_3) + line=line.replace(slots[slot],master[slot]) + sys.stdout.write(line) + if uid == None: + uid = identity.get_uid() + if gid == None: + gid = identity.get_gid() + # chmod <perms> <name> + config.pki_log.debug(log.PKIHELPER_CHMOD_2, + perms, name, + extra=config.PKI_INDENTATION_LEVEL_3) + os.chmod(name, perms) + # chown <uid>:<gid> <name> + config.pki_log.debug(log.PKIHELPER_CHOWN_3, + uid, gid, name, + extra=config.PKI_INDENTATION_LEVEL_3) + os.chown(name, uid, gid) + # Store record in installation manifest + record = manifest.record() + record.name = name + record.type = manifest.RECORD_TYPE_FILE + record.user = master['pki_user'] + record.group = master['pki_group'] + record.uid = uid + record.gid = gid + record.permissions = perms + record.acls = acls + manifest.database.append(record) + except OSError as exc: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + except shutil.Error as exc: + config.pki_log.error(log.PKI_SHUTIL_ERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + return + + def copy_with_slot_substitution( + self, old_name, new_name, uid=None, gid=None, + perms=config.PKI_DEPLOYMENT_DEFAULT_FILE_PERMISSIONS, + acls=None, overwrite_flag=False, + critical_failure=True): + try: + if config.pki_dry_run_flag: + # copy <old_name> to <new_name> with slot substitutions + config.pki_log.info(log.PKIHELPER_COPY_WITH_SLOT_SUBSTITUTION_2, + old_name, new_name, + extra=config.PKI_INDENTATION_LEVEL_2) + for line in fileinput.FileInput(old_name): + for slot in slots: + if slot != '__name__' and slots[slot] in line: + config.pki_log.debug( + log.PKIHELPER_SLOT_SUBSTITUTION_2, + slots[slot], master[slot], + extra=config.PKI_INDENTATION_LEVEL_3) # chmod <perms> <new_name> config.pki_log.debug(log.PKIHELPER_CHMOD_2, perms, new_name, @@ -787,6 +983,11 @@ class file: config.pki_log.debug(log.PKIHELPER_CHOWN_3, uid, gid, new_name, extra=config.PKI_INDENTATION_LEVEL_3) + elif not os.path.exists(old_name) or not os.path.isfile(old_name): + config.pki_log.error( + log.PKI_FILE_MISSING_OR_NOT_A_FILE_1, old_name, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) else: if os.path.exists(new_name): if not overwrite_flag: @@ -794,11 +995,21 @@ class file: log.PKI_FILE_ALREADY_EXISTS_1, new_name, extra=config.PKI_INDENTATION_LEVEL_2) sys.exit(1) - # cp -p <old_name> <new_name> - config.pki_log.info(log.PKIHELPER_CP_P_2, + # copy <old_name> to <new_name> with slot substitutions + config.pki_log.info(log.PKIHELPER_COPY_WITH_SLOT_SUBSTITUTION_2, old_name, new_name, extra=config.PKI_INDENTATION_LEVEL_2) - shutil.copy2(old_name, new_name) + FILE = open(new_name, "w") + for line in fileinput.FileInput(old_name): + for slot in slots: + if slot != '__name__' and slots[slot] in line: + config.pki_log.debug( + log.PKIHELPER_SLOT_SUBSTITUTION_2, + slots[slot], master[slot], + extra=config.PKI_INDENTATION_LEVEL_3) + line=line.replace(slots[slot],master[slot]) + FILE.write(line) + FILE.close() if uid == None: uid = identity.get_uid() if gid == None: @@ -836,6 +1047,64 @@ class file: sys.exit(1) return + def generate_noise_file(self, name, bytes, uid=None, gid=None, + perms=config.PKI_DEPLOYMENT_DEFAULT_FILE_PERMISSIONS, + acls=None, critical_failure=True): + try: + if not os.path.exists(name): + # generating noise file called <name> and + # filling it with <bytes> random bytes + config.pki_log.info(log.PKIHELPER_NOISE_FILE_2, name, bytes, + extra=config.PKI_INDENTATION_LEVEL_2) + if not config.pki_dry_run_flag: + open(name, "w").close() + FILE = open(name, "w") + noise = ''.join(random.choice(string.ascii_letters +\ + string.digits) for x in range(bytes)) + FILE.write(noise) + FILE.close() + # chmod <perms> <name> + config.pki_log.debug(log.PKIHELPER_CHMOD_2, perms, name, + extra=config.PKI_INDENTATION_LEVEL_3) + if not config.pki_dry_run_flag: + os.chmod(name, perms) + # chown <uid>:<gid> <name> + if uid == None: + uid = identity.get_uid() + if gid == None: + gid = identity.get_gid() + config.pki_log.debug(log.PKIHELPER_CHOWN_3, + uid, gid, name, + extra=config.PKI_INDENTATION_LEVEL_3) + if not config.pki_dry_run_flag: + os.chown(name, uid, gid) + # Store record in installation manifest + record = manifest.record() + record.name = name + record.type = manifest.RECORD_TYPE_FILE + record.user = master['pki_user'] + record.group = master['pki_group'] + record.uid = uid + record.gid = gid + record.permissions = perms + record.acls = acls + manifest.database.append(record) + elif not os.path.isfile(name): + config.pki_log.error( + log.PKI_FILE_ALREADY_EXISTS_NOT_A_FILE_1, name, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + except OSError as exc: + if exc.errno == errno.EEXIST: + pass + else: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + return + # PKI Deployment Symbolic Link Class class symlink: @@ -886,11 +1155,6 @@ class symlink: extra=config.PKI_INDENTATION_LEVEL_2) if critical_failure == True: sys.exit(1) - else: - config.pki_log.error(log.PKI_SYMLINK_ALREADY_EXISTS_1, link, - extra=config.PKI_INDENTATION_LEVEL_2) - if critical_failure == True: - sys.exit(1) except OSError as exc: if exc.errno == errno.EEXIST: pass @@ -1026,6 +1290,347 @@ class war: return +# PKI Deployment Password Class +class password: + def create_password_conf(self, path, overwrite_flag=False): + try: + if not config.pki_dry_run_flag: + if os.path.exists(path): + if overwrite_flag: + config.pki_log.info( + log.PKIHELPER_PASSWORD_CONF_1, path, + extra=config.PKI_INDENTATION_LEVEL_2) + # overwrite the existing 'password.conf' file + with open(path, "wt") as fd: + if master['pki_subsystem'] in\ + config.PKI_APACHE_SUBSYSTEMS: + fd.write("internal" + ":" +\ + str(master['pki_pin'])) + else: + fd.write("internal" + "=" +\ + str(master['pki_pin'])) + fd.closed + else: + config.pki_log.info(log.PKIHELPER_PASSWORD_CONF_1, path, + extra=config.PKI_INDENTATION_LEVEL_2) + # create a new 'password.conf' file + with open(path, "wt") as fd: + if master['pki_subsystem'] in\ + config.PKI_APACHE_SUBSYSTEMS: + fd.write("internal" + ":" +\ + str(master['pki_pin'])) + else: + fd.write("internal" + "=" +\ + str(master['pki_pin'])) + fd.closed + else: + if not os.path.exists(path) or overwrite_flag: + config.pki_log.info(log.PKIHELPER_PASSWORD_CONF_1, path, + extra=config.PKI_INDENTATION_LEVEL_2) + except OSError as exc: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + return + + +# PKI Deployment NSS 'certutil' Class +class certutil: + def create_security_databases(self, path, password_file=None, prefix=None, + critical_failure=True): + try: + # Compose this "certutil" command + command = "certutil" + " " + "-N" + # Provide a path to the NSS security databases + if path: + command = command + " " + "-d" + " " + path + else: + config.pki_log.error( + log.PKIHELPER_CERTUTIL_MISSING_PATH, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + if password_file != None: + command = command + " " + "-f" + " " + password_file + if prefix != None: + command = command + " " + "-P" + " " + prefix + if not config.pki_dry_run_flag: + if not os.path.exists(path): + config.pki_log.error( + log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1, path, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + if os.path.exists(master['pki_cert_database']) or\ + os.path.exists(master['pki_key_database']) or\ + os.path.exists(master['pki_secmod_database']): + # Simply notify user that the security databases exist + config.pki_log.info( + log.PKI_SECURITY_DATABASES_ALREADY_EXIST_3, + master['pki_cert_database'], + master['pki_key_database'], + master['pki_secmod_database'], + extra=config.PKI_INDENTATION_LEVEL_2) + else: + if password_file != None: + if not os.path.exists(password_file) or\ + not os.path.isfile(password_file): + config.pki_log.error( + log.PKI_FILE_MISSING_OR_NOT_A_FILE_1, + password_file, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + # Display this "certutil" command + config.pki_log.info( + log.PKIHELPER_CREATE_SECURITY_DATABASES_1, + command, + extra=config.PKI_INDENTATION_LEVEL_2) + # Execute this "certutil" command + subprocess.call(command, shell=True) + else: + if os.path.exists(master['pki_cert_database']) or\ + os.path.exists(master['pki_key_database']) or\ + os.path.exists(master['pki_secmod_database']): + # Simply notify user that the security databases exist + config.pki_log.info( + log.PKI_SECURITY_DATABASES_ALREADY_EXIST_3, + master['pki_cert_database'], + master['pki_key_database'], + master['pki_secmod_database'], + extra=config.PKI_INDENTATION_LEVEL_2) + else: + # Display this "certutil" command + config.pki_log.info( + log.PKIHELPER_CREATE_SECURITY_DATABASES_1, + command, + extra=config.PKI_INDENTATION_LEVEL_2) + except subprocess.CalledProcessError as exc: + config.pki_log.error(log.PKI_SUBPROCESS_ERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + except OSError as exc: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + return + + def verify_certificate_exists(self, path, token, nickname, + password_file=None): + rv = 0 + try: + # Compose this "certutil" command + command = "certutil" + " " + "-L" + # Provide a path to the NSS security databases + if path: + command = command + " " + "-d" + " " + path + else: + config.pki_log.error( + log.PKIHELPER_CERTUTIL_MISSING_PATH, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + # Specify the 'token' + if token: + command = command + " " + "-h" + " " + "'" + token + "'" + else: + config.pki_log.error( + log.PKIHELPER_CERTUTIL_MISSING_TOKEN, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + # Specify the nickname of this self-signed certificate + if nickname: + command = command + " " + "-n" + " " + "'" + nickname + "'" + else: + config.pki_log.error( + log.PKIHELPER_CERTUTIL_MISSING_NICKNAME, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + # OPTIONALLY specify a password file + if password_file != None: + command = command + " " + "-f" + " " + password_file + # Always execute this command silently + command = command + " > /dev/null 2>&1" + if not config.pki_dry_run_flag: + if not os.path.exists(path): + config.pki_log.error( + log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1, path, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + if not os.path.exists(master['pki_cert_database']) or\ + not os.path.exists(master['pki_key_database']) or\ + not os.path.exists(master['pki_secmod_database']): + # NSS security databases MUST exist! + config.pki_log.error( + log.PKI_SECURITY_DATABASES_DO_NOT_EXIST_3, + master['pki_cert_database'], + master['pki_key_database'], + master['pki_secmod_database'], + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + if password_file != None: + if not os.path.exists(password_file) or\ + not os.path.isfile(password_file): + config.pki_log.error( + log.PKI_FILE_MISSING_OR_NOT_A_FILE_1, + password_file, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + else: + # Check for first time through as dry_run + if not os.path.exists(master['pki_cert_database']) or\ + not os.path.exists(master['pki_key_database']) or\ + not os.path.exists(master['pki_secmod_database']): + return False + # Execute this "certutil" command + subprocess.check_call(command, shell=True) + except subprocess.CalledProcessError as exc: + return False + except OSError as exc: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + return True + + def generate_self_signed_certificate(self, path, token, nickname, + subject, serial_number, + validity_period, issuer_name, + trustargs, noise_file, + password_file=None, + critical_failure=True): + try: + # Compose this "certutil" command + command = "certutil" + " " + "-S" + # Provide a path to the NSS security databases + if path: + command = command + " " + "-d" + " " + path + else: + config.pki_log.error( + log.PKIHELPER_CERTUTIL_MISSING_PATH, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + # Specify the 'token' + if token: + command = command + " " + "-h" + " " + "'" + token + "'" + else: + config.pki_log.error( + log.PKIHELPER_CERTUTIL_MISSING_TOKEN, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + # Specify the nickname of this self-signed certificate + if nickname: + command = command + " " + "-n" + " " + "'" + nickname + "'" + else: + config.pki_log.error( + log.PKIHELPER_CERTUTIL_MISSING_NICKNAME, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + # Specify the subject name (RFC1485) + if subject: + command = command + " " + "-s" + " " + "'" + subject + "'" + else: + config.pki_log.error( + log.PKIHELPER_CERTUTIL_MISSING_SUBJECT, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + # Specify the serial number + if serial_number != None: + command = command + " " + "-m" + " " + str(serial_number) + else: + config.pki_log.error( + log.PKIHELPER_CERTUTIL_MISSING_SERIAL_NUMBER, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + # Specify the months valid + if validity_period != None: + command = command + " " + "-v" + " " + str(validity_period) + else: + config.pki_log.error( + log.PKIHELPER_CERTUTIL_MISSING_VALIDITY_PERIOD, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + # Specify the nickname of the issuer certificate + if issuer_name: + command = command + " " + "-c" + " " +\ + "'" + issuer_name + "'" + else: + config.pki_log.error( + log.PKIHELPER_CERTUTIL_MISSING_ISSUER_NAME, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + # Specify the certificate trust attributes + if trustargs: + command = command + " " + "-t" + " " + "'" + trustargs + "'" + else: + config.pki_log.error( + log.PKIHELPER_CERTUTIL_MISSING_TRUSTARGS, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + # Specify a noise file to be used for key generation + if noise_file: + command = command + " " + "-z" + " " + noise_file + else: + config.pki_log.error( + log.PKIHELPER_CERTUTIL_MISSING_NOISE_FILE, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + # OPTIONALLY specify a password file + if password_file != None: + command = command + " " + "-f" + " " + password_file + # ALWAYS self-sign this certificate + command = command + " " + "-x" + # ALWAYS mask the command-line output of this command + command = command + " " + "> /dev/null 2>&1" + # Display this "certutil" command + config.pki_log.info( + log.PKIHELPER_CERTUTIL_SELF_SIGNED_CERTIFICATE_1, command, + extra=config.PKI_INDENTATION_LEVEL_2) + if not config.pki_dry_run_flag: + if not os.path.exists(path): + config.pki_log.error( + log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1, path, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + if not os.path.exists(master['pki_cert_database']) or\ + not os.path.exists(master['pki_key_database']) or\ + not os.path.exists(master['pki_secmod_database']): + # NSS security databases MUST exist! + config.pki_log.error( + log.PKI_SECURITY_DATABASES_DO_NOT_EXIST_3, + master['pki_cert_database'], + master['pki_key_database'], + master['pki_secmod_database'], + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + if not os.path.exists(noise_file): + config.pki_log.error( + log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1, + noise_file, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + if password_file != None: + if not os.path.exists(password_file) or\ + not os.path.isfile(password_file): + config.pki_log.error( + log.PKI_FILE_MISSING_OR_NOT_A_FILE_1, + password_file, + extra=config.PKI_INDENTATION_LEVEL_2) + sys.exit(1) + # Execute this "certutil" command + subprocess.call(command, shell=True) + except subprocess.CalledProcessError as exc: + config.pki_log.error(log.PKI_SUBPROCESS_ERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + except OSError as exc: + config.pki_log.error(log.PKI_OSERROR_1, exc, + extra=config.PKI_INDENTATION_LEVEL_2) + if critical_failure == True: + sys.exit(1) + return + + # PKI Deployment Helper Class Instances identity = identity() instance = instance() @@ -1033,3 +1638,5 @@ directory = directory() file = file() symlink = symlink() war = war() +password = password() +certutil = certutil() |