summaryrefslogtreecommitdiffstats
path: root/base/server/python/pki
diff options
context:
space:
mode:
authorEndi S. Dewata <edewata@redhat.com>2013-07-16 17:47:18 -0400
committerEndi S. Dewata <edewata@redhat.com>2013-07-22 09:51:38 -0400
commit6f76531f4a1b81c07f2db5183f5b10c9f4a531c3 (patch)
treee986367bc77f860ff6b0681e43a3871e4965410f /base/server/python/pki
parent4d49d7e1845c372164b7bcc2fe759867cfcab0f2 (diff)
downloadpki-6f76531f4a1b81c07f2db5183f5b10c9f4a531c3.tar.gz
pki-6f76531f4a1b81c07f2db5183f5b10c9f4a531c3.tar.xz
pki-6f76531f4a1b81c07f2db5183f5b10c9f4a531c3.zip
Reorganized deployment tools.
The pkispawn and pkidestroy scripts have been moved into sbin folder. The Python deployment library and the scriptlets were moved into pki.server.deployment and pki.server.deployment.scriptlets packages, respectively.
Diffstat (limited to 'base/server/python/pki')
-rw-r--r--base/server/python/pki/server/deployment/__init__.py0
-rw-r--r--base/server/python/pki/server/deployment/pkiconfig.py177
-rw-r--r--base/server/python/pki/server/deployment/pkihelper.py3516
-rw-r--r--base/server/python/pki/server/deployment/pkilogging.py76
-rw-r--r--base/server/python/pki/server/deployment/pkimanifest.py104
-rw-r--r--base/server/python/pki/server/deployment/pkimessages.py359
-rw-r--r--base/server/python/pki/server/deployment/pkiparser.py1080
-rw-r--r--base/server/python/pki/server/deployment/pkiscriptlet.py41
-rw-r--r--base/server/python/pki/server/deployment/scriptlets/__init__.py0
-rw-r--r--base/server/python/pki/server/deployment/scriptlets/configuration.py140
-rw-r--r--base/server/python/pki/server/deployment/scriptlets/finalization.py106
-rw-r--r--base/server/python/pki/server/deployment/scriptlets/infrastructure_layout.py114
-rw-r--r--base/server/python/pki/server/deployment/scriptlets/initialization.py113
-rw-r--r--base/server/python/pki/server/deployment/scriptlets/instance_layout.py184
-rw-r--r--base/server/python/pki/server/deployment/scriptlets/security_databases.py114
-rw-r--r--base/server/python/pki/server/deployment/scriptlets/selinux_setup.py204
-rw-r--r--base/server/python/pki/server/deployment/scriptlets/slot_substitution.py96
-rw-r--r--base/server/python/pki/server/deployment/scriptlets/subsystem_layout.py121
-rw-r--r--base/server/python/pki/server/deployment/scriptlets/webapp_deployment.py165
19 files changed, 6710 insertions, 0 deletions
diff --git a/base/server/python/pki/server/deployment/__init__.py b/base/server/python/pki/server/deployment/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/base/server/python/pki/server/deployment/__init__.py
diff --git a/base/server/python/pki/server/deployment/pkiconfig.py b/base/server/python/pki/server/deployment/pkiconfig.py
new file mode 100644
index 000000000..2e9463b9d
--- /dev/null
+++ b/base/server/python/pki/server/deployment/pkiconfig.py
@@ -0,0 +1,177 @@
+#!/usr/bin/python -t
+# Authors:
+# Matthew Harmsen <mharmsen@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright (C) 2012 Red Hat, Inc.
+# All rights reserved.
+#
+
+# PKI Deployment Constants
+PKI_DEPLOYMENT_DEFAULT_CLIENT_DIR_PERMISSIONS = 00755
+PKI_DEPLOYMENT_DEFAULT_DIR_PERMISSIONS = 00770
+PKI_DEPLOYMENT_DEFAULT_EXE_PERMISSIONS = 00770
+PKI_DEPLOYMENT_DEFAULT_FILE_PERMISSIONS = 00660
+PKI_DEPLOYMENT_DEFAULT_SECURITY_DATABASE_PERMISSIONS = 00600
+PKI_DEPLOYMENT_DEFAULT_SGID_DIR_PERMISSIONS = 02770
+PKI_DEPLOYMENT_DEFAULT_SYMLINK_PERMISSIONS = 00777
+PKI_DEPLOYMENT_DEFAULT_UMASK = 00002
+
+PKI_DEPLOYMENT_DEFAULT_COMMENT = "'Certificate System'"
+PKI_DEPLOYMENT_DEFAULT_GID = 17
+PKI_DEPLOYMENT_DEFAULT_GROUP = "pkiuser"
+PKI_DEPLOYMENT_DEFAULT_SHELL = "/sbin/nologin"
+PKI_DEPLOYMENT_DEFAULT_UID = 17
+PKI_DEPLOYMENT_DEFAULT_USER = "pkiuser"
+
+PKI_SUBSYSTEMS = ["CA", "KRA", "OCSP", "RA", "TKS", "TPS"]
+PKI_SIGNED_AUDIT_SUBSYSTEMS = ["CA", "KRA", "OCSP", "TKS", "TPS"]
+PKI_APACHE_SUBSYSTEMS = ["RA"]
+PKI_TOMCAT_SUBSYSTEMS = ["CA", "KRA", "OCSP", "TKS", "TPS"]
+PKI_BASE_RESERVED_NAMES = ["alias", "bin", "ca", "common", "conf", "kra",
+ "lib", "logs", "ocsp", "temp", "tks", "tps", "webapps",
+ "work"]
+PKI_CONFIGURATION_RESERVED_NAMES = ["CA", "java", "nssdb", "rpm-gpg",
+ "rsyslog", "tls"]
+PKI_APACHE_REGISTRY_RESERVED_NAMES = ["ra"]
+PKI_TOMCAT_REGISTRY_RESERVED_NAMES = ["ca", "kra", "ocsp", "tks", "tps"]
+
+PKI_INDENTATION_LEVEL_0 = {'indent' : ''}
+PKI_INDENTATION_LEVEL_1 = {'indent' : '... '}
+PKI_INDENTATION_LEVEL_2 = {'indent' : '....... '}
+PKI_INDENTATION_LEVEL_3 = {'indent' : '........... '}
+PKI_INDENTATION_LEVEL_4 = {'indent' : '............... '}
+
+PKI_DEPLOYMENT_INTERRUPT_BANNER = "-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+"\
+ "-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-"
+
+PKI_DEPLOYMENT_SOURCE_ROOT = "/usr/share/pki"
+PKI_DEPLOYMENT_BASE_ROOT = "/var/lib/pki"
+# NOTE: Top-level "/etc/pki" is owned by the "filesystem" package!
+PKI_DEPLOYMENT_CONFIGURATION_ROOT = "/etc/pki"
+PKI_DEPLOYMENT_LOG_ROOT = "/var/log/pki"
+# NOTE: Well-known 'registry root', default 'instance', and default
+# 'configuration file' names MUST be created in order to potentially
+# obtain an instance-specific configuration file
+# (presuming one has not been specified during command-line parsing)
+# because command-line parsing happens prior to reading any
+# configuration files. Although the 'registry root' MUST remain fixed,
+# the default 'instance' name may be overridden by the value specified
+# in the configuration file (the value in the default configuration file
+# should always match the 'default' instance name specified below).
+PKI_DEPLOYMENT_DEFAULT_APACHE_INSTANCE_NAME = "pki-apache"
+PKI_DEPLOYMENT_DEFAULT_TOMCAT_INSTANCE_NAME = "pki-tomcat"
+
+DEFAULT_DEPLOYMENT_CONFIGURATION = "default.cfg"
+USER_DEPLOYMENT_CONFIGURATION = "deployment.cfg"
+
+PKI_DEPLOYMENT_DEFAULT_CONFIGURATION_FILE = \
+ PKI_DEPLOYMENT_CONFIGURATION_ROOT + "/" + DEFAULT_DEPLOYMENT_CONFIGURATION
+PKI_DEPLOYMENT_SLOTS_CONFIGURATION_FILE = \
+ PKI_DEPLOYMENT_SOURCE_ROOT + "/deployment/config/pkislots.cfg"
+
+# subtypes of PKI subsystems
+PKI_DEPLOYMENT_CLONED_PKI_SUBSYSTEM = "Cloned"
+PKI_DEPLOYMENT_EXTERNAL_CA = "External"
+PKI_DEPLOYMENT_SUBORDINATE_CA = "Subordinate"
+
+# default ports (for defined selinux policy)
+PKI_DEPLOYMENT_DEFAULT_TOMCAT_HTTP_PORT = 8080
+PKI_DEPLOYMENT_DEFAULT_TOMCAT_HTTPS_PORT = 8443
+PKI_DEPLOYMENT_DEFAULT_TOMCAT_SERVER_PORT = 8005
+PKI_DEPLOYMENT_DEFAULT_TOMCAT_AJP_PORT = 8009
+
+# PKI Deployment Global Variables
+pki_install_time = None
+pki_timestamp = None
+pki_architecture = None
+pki_hostname = None
+pki_dns_domainname = None
+pki_certificate_timestamp = None
+
+
+# PKI Deployment Command-Line Variables
+pki_deployment_executable = None
+
+# PKI Deployment "Mandatory" Command-Line Variables
+pki_subsystem = None
+# 'pkispawn' ONLY
+default_deployment_cfg = None
+user_deployment_cfg = None
+# 'pkidestroy' ONLY
+pki_deployed_instance_name = None
+pki_secdomain_user = None
+pki_secdomain_pass = None
+
+# PKI Deployment "Test" Command-Line Variables
+pki_root_prefix = None
+
+
+# PKI Deployment Helper Functions
+def str2bool(string):
+ return string.lower() in ("yes", "true", "t", "1")
+
+# NOTE: To utilize the 'preparations_for_an_external_java_debugger(master)'
+# and 'wait_to_attach_an_external_java_debugger(master)' functions,
+# change 'pki_enable_java_debugger=False' to
+# 'pki_enable_java_debugger=True' in the appropriate
+# deployment configuration file.
+def prepare_for_an_external_java_debugger(instance):
+ print
+ print PKI_DEPLOYMENT_INTERRUPT_BANNER
+ print
+ print "The following 'JAVA_OPTS' MUST be enabled (uncommented) in"
+ print "'%s':" % instance
+ print
+ print " JAVA_OPTS=\"-Xdebug -Xrunjdwp:transport=dt_socket,\""
+ print " \"address=8000,server=y,suspend\""
+ print
+ raw_input("Enable external java debugger 'JAVA_OPTS' "\
+ "and press return to continue . . . ")
+ print
+ print PKI_DEPLOYMENT_INTERRUPT_BANNER
+ print
+ return
+
+def wait_to_attach_an_external_java_debugger():
+ print
+ print PKI_DEPLOYMENT_INTERRUPT_BANNER
+ print
+ print "Attach the java debugger to this process on the port specified by"
+ print "the 'address' selected by 'JAVA_OPTS' (e. g. - port 8000) and"
+ print "set any desired breakpoints"
+ print
+ raw_input("Please attach an external java debugger "\
+ "and press return to continue . . . ")
+ print
+ print PKI_DEPLOYMENT_INTERRUPT_BANNER
+ print
+ return
+
+
+# PKI Deployment Logger Variables
+pki_log = None
+pki_log_dir = None
+pki_log_name = None
+pki_log_level = None
+pki_console_log_level = None
+
+# PKI Selinux Constants and parameters
+PKI_INSTANCE_SELINUX_CONTEXT = "pki_tomcat_var_lib_t"
+PKI_LOG_SELINUX_CONTEXT = "pki_tomcat_log_t"
+PKI_CFG_SELINUX_CONTEXT = "pki_tomcat_etc_rw_t"
+PKI_CERTDB_SELINUX_CONTEXT = "pki_tomcat_cert_t"
+PKI_PORT_SELINUX_CONTEXT = "http_port_t"
+pki_selinux_config_ports = []
diff --git a/base/server/python/pki/server/deployment/pkihelper.py b/base/server/python/pki/server/deployment/pkihelper.py
new file mode 100644
index 000000000..6d47a902b
--- /dev/null
+++ b/base/server/python/pki/server/deployment/pkihelper.py
@@ -0,0 +1,3516 @@
+#!/usr/bin/python -t
+
+# Authors:
+# Matthew Harmsen <mharmsen@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright (C) 2012 Red Hat, Inc.
+# All rights reserved.
+#
+
+# System Imports
+import errno
+import sys
+import os
+import fileinput
+import random
+import re
+import requests
+import shutil
+from shutil import Error, WindowsError
+import string
+import subprocess
+import time
+import types
+from datetime import datetime
+from grp import getgrgid
+from grp import getgrnam
+from pwd import getpwnam
+from pwd import getpwuid
+import xml.etree.ElementTree as ET
+import zipfile
+import selinux
+if selinux.is_selinux_enabled():
+ import seobject
+
+
+# PKI Deployment Imports
+from . import pkiconfig as config
+from .pkiconfig import pki_selinux_config_ports as ports
+from . import pkimanifest as manifest
+from . import pkimessages as log
+from .pkiparser import PKIConfigParser
+import pki.account
+import pki.client
+import pki.system
+
+# PKI Deployment Helper Functions
+def pki_copytree(src, dst, symlinks=False, ignore=None):
+ """Recursively copy a directory tree using copy2().
+
+ PATCH: This code was copied from 'shutil.py' and patched to
+ allow 'The destination directory to already exist.'
+
+ If exception(s) occur, an Error is raised with a list of reasons.
+
+ If the optional symlinks flag is true, symbolic links in the
+ source tree result in symbolic links in the destination tree; if
+ it is false, the contents of the files pointed to by symbolic
+ links are copied.
+
+ The optional ignore argument is a callable. If given, it
+ is called with the `src` parameter, which is the directory
+ being visited by pki_copytree(), and `names` which is the list of
+ `src` contents, as returned by os.listdir():
+
+ callable(src, names) -> ignored_names
+
+ Since pki_copytree() is called recursively, the callable will be
+ called once for each directory that is copied. It returns a
+ list of names relative to the `src` directory that should
+ not be copied.
+
+ *** Consider this example code rather than the ultimate tool.
+
+ """
+ names = os.listdir(src)
+ if ignore is not None:
+ ignored_names = ignore(src, names)
+ else:
+ ignored_names = set()
+
+ # PATCH: ONLY execute 'os.makedirs(dst)' if the top-level
+ # destination directory does NOT exist!
+ if not os.path.exists(dst):
+ os.makedirs(dst)
+ errors = []
+ for name in names:
+ if name in ignored_names:
+ continue
+ srcname = os.path.join(src, name)
+ dstname = os.path.join(dst, name)
+ try:
+ if symlinks and os.path.islink(srcname):
+ linkto = os.readlink(srcname)
+ os.symlink(linkto, dstname)
+ elif os.path.isdir(srcname):
+ pki_copytree(srcname, dstname, symlinks, ignore)
+ else:
+ # Will raise a SpecialFileError for unsupported file types
+ shutil.copy2(srcname, dstname)
+ # catch the Error from the recursive pki_copytree so that we can
+ # continue with other files
+ except Error, err:
+ errors.extend(err.args[0])
+ except EnvironmentError, why:
+ errors.append((srcname, dstname, str(why)))
+ try:
+ shutil.copystat(src, dst)
+ except OSError, why:
+ if WindowsError is not None and isinstance(why, WindowsError):
+ # Copying file access times may fail on Windows
+ pass
+ else:
+ errors.extend((src, dst, str(why)))
+ if errors:
+ raise Error, errors
+
+class Identity:
+ """PKI Deployment Identity Class"""
+
+ def __init__(self, deployer):
+ self.master_dict = deployer.master_dict
+
+ def __add_gid(self, pki_group):
+ pki_gid = None
+ try:
+ # Does the specified 'pki_group' exist?
+ pki_gid = getgrnam(pki_group)[2]
+ # Yes, group 'pki_group' exists!
+ config.pki_log.info(log.PKIHELPER_GROUP_ADD_2, pki_group, pki_gid,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ except KeyError as exc:
+ # No, group 'pki_group' does not exist!
+ config.pki_log.debug(log.PKIHELPER_GROUP_ADD_KEYERROR_1, exc,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ try:
+ # Is the default well-known GID already defined?
+ group = getgrgid(config.PKI_DEPLOYMENT_DEFAULT_GID)[0]
+ # Yes, the default well-known GID exists!
+ config.pki_log.info(log.PKIHELPER_GROUP_ADD_DEFAULT_2,
+ group, config.PKI_DEPLOYMENT_DEFAULT_GID,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ # Attempt to create 'pki_group' using a random GID.
+ command = "/usr/sbin/groupadd" + " " + \
+ pki_group + " " + \
+ "> /dev/null 2>&1"
+ except KeyError as exc:
+ # No, the default well-known GID does not exist!
+ config.pki_log.debug(log.PKIHELPER_GROUP_ADD_GID_KEYERROR_1,
+ exc, extra=config.PKI_INDENTATION_LEVEL_2)
+ # Is the specified 'pki_group' the default well-known group?
+ if pki_group == config.PKI_DEPLOYMENT_DEFAULT_GROUP:
+ # Yes, attempt to create the default well-known group
+ # using the default well-known GID.
+ command = "/usr/sbin/groupadd" + " " + \
+ "-g" + " " + \
+ str(config.PKI_DEPLOYMENT_DEFAULT_GID) + " " + \
+ "-r" + " " + \
+ pki_group + " " + \
+ "> /dev/null 2>&1"
+ else:
+ # No, attempt to create 'pki_group' using a random GID.
+ command = "/usr/sbin/groupadd" + " " + \
+ pki_group + " " + \
+ "> /dev/null 2>&1"
+ # Execute this "groupadd" 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)
+ raise
+ return
+
+ def __add_uid(self, pki_user, pki_group):
+ pki_uid = None
+ try:
+ # Does the specified 'pki_user' exist?
+ pki_uid = getpwnam(pki_user)[2]
+ # Yes, user 'pki_user' exists!
+ config.pki_log.info(log.PKIHELPER_USER_ADD_2, pki_user, pki_uid,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ # NOTE: For now, never check validity of specified 'pki_group'!
+ except KeyError as exc:
+ # No, user 'pki_user' does not exist!
+ config.pki_log.debug(log.PKIHELPER_USER_ADD_KEYERROR_1, exc,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ try:
+ # Is the default well-known UID already defined?
+ user = getpwuid(config.PKI_DEPLOYMENT_DEFAULT_UID)[0]
+ # Yes, the default well-known UID exists!
+ config.pki_log.info(log.PKIHELPER_USER_ADD_DEFAULT_2,
+ user, config.PKI_DEPLOYMENT_DEFAULT_UID,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ # Attempt to create 'pki_user' using a random UID.
+ command = "/usr/sbin/useradd" + " " + \
+ "-g" + " " + \
+ pki_group + " " + \
+ "-d" + " " + \
+ config.PKI_DEPLOYMENT_SOURCE_ROOT + " " + \
+ "-s" + " " + \
+ config.PKI_DEPLOYMENT_DEFAULT_SHELL + " " + \
+ "-c" + " " + \
+ config.PKI_DEPLOYMENT_DEFAULT_COMMENT + " " + \
+ pki_user + " " + \
+ "> /dev/null 2>&1"
+ except KeyError as exc:
+ # No, the default well-known UID does not exist!
+ config.pki_log.debug(log.PKIHELPER_USER_ADD_UID_KEYERROR_1,
+ exc, extra=config.PKI_INDENTATION_LEVEL_2)
+ # Is the specified 'pki_user' the default well-known user?
+ if pki_user == config.PKI_DEPLOYMENT_DEFAULT_USER:
+ # Yes, attempt to create the default well-known user
+ # using the default well-known UID.
+ command = "/usr/sbin/useradd" + " " + \
+ "-g" + " " + \
+ pki_group + " " + \
+ "-d" + " " + \
+ config.PKI_DEPLOYMENT_SOURCE_ROOT + " " + \
+ "-s" + " " + \
+ config.PKI_DEPLOYMENT_DEFAULT_SHELL + " " + \
+ "-c" + " " + \
+ config.PKI_DEPLOYMENT_DEFAULT_COMMENT + " " + \
+ "-u" + " " + \
+ str(config.PKI_DEPLOYMENT_DEFAULT_UID) + " " + \
+ "-r" + " " + \
+ pki_user + " " + \
+ "> /dev/null 2>&1"
+ else:
+ # No, attempt to create 'pki_user' using a random UID.
+ command = "/usr/sbin/useradd" + " " + \
+ "-g" + " " + \
+ pki_group + " " + \
+ "-d" + " " + \
+ config.PKI_DEPLOYMENT_SOURCE_ROOT + " " + \
+ "-s" + " " + \
+ config.PKI_DEPLOYMENT_DEFAULT_SHELL + " " + \
+ "-c" + " " + \
+ config.PKI_DEPLOYMENT_DEFAULT_COMMENT + " " + \
+ pki_user + " " + \
+ "> /dev/null 2>&1"
+ # Execute this "useradd" 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)
+ raise
+ return
+
+ def add_uid_and_gid(self, pki_user, pki_group):
+ self.__add_gid(pki_group)
+ self.__add_uid(pki_user, pki_group)
+ return
+
+ def get_uid(self, critical_failure=True):
+ try:
+ pki_uid = self.master_dict['pki_uid']
+ except KeyError as exc:
+ config.pki_log.error(log.PKI_KEYERROR_1, exc,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise
+ return pki_uid
+
+ def get_gid(self, critical_failure=True):
+ try:
+ pki_gid = self.master_dict['pki_gid']
+ except KeyError as exc:
+ config.pki_log.error(log.PKI_KEYERROR_1, exc,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise
+ return pki_gid
+
+ def set_uid(self, name, critical_failure=True):
+ try:
+ config.pki_log.debug(log.PKIHELPER_USER_1, name,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ # id -u <name>
+ pki_uid = getpwnam(name)[2]
+ self.master_dict['pki_uid'] = pki_uid
+ config.pki_log.debug(log.PKIHELPER_UID_2, name, pki_uid,
+ extra=config.PKI_INDENTATION_LEVEL_3)
+ except KeyError as exc:
+ config.pki_log.error(log.PKI_KEYERROR_1, exc,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise
+ return pki_uid
+
+ def set_gid(self, name, critical_failure=True):
+ try:
+ config.pki_log.debug(log.PKIHELPER_GROUP_1, name,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ # id -g <name>
+ pki_gid = getgrnam(name)[2]
+ self.master_dict['pki_gid'] = pki_gid
+ config.pki_log.debug(log.PKIHELPER_GID_2, name, pki_gid,
+ extra=config.PKI_INDENTATION_LEVEL_3)
+ except KeyError as exc:
+ config.pki_log.error(log.PKI_KEYERROR_1, exc,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise
+ return pki_gid
+
+class Namespace:
+ """PKI Deployment Namespace Class"""
+
+ # Silently verify that the selected 'pki_instance_name' will
+ # NOT produce any namespace collisions
+ def __init__(self, deployer):
+ self.master_dict = deployer.master_dict
+
+ def collision_detection(self):
+ # Run simple checks for pre-existing namespace collisions
+ if os.path.exists(self.master_dict['pki_instance_path']):
+ if os.path.exists(self.master_dict['pki_subsystem_path']):
+ # Top-Level PKI base path collision
+ config.pki_log.error(
+ log.PKIHELPER_NAMESPACE_COLLISION_2,
+ self.master_dict['pki_instance_name'],
+ self.master_dict['pki_instance_path'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_NAMESPACE_COLLISION_2 % (self.master_dict['pki_instance_name'],
+ self.master_dict['pki_instance_path']))
+ else:
+ if os.path.exists(self.master_dict['pki_target_tomcat_conf_instance_id']):
+ # Top-Level "/etc/sysconfig" path collision
+ config.pki_log.error(
+ log.PKIHELPER_NAMESPACE_COLLISION_2,
+ self.master_dict['pki_instance_name'],
+ self.master_dict['pki_target_tomcat_conf_instance_id'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_NAMESPACE_COLLISION_2 % (self.master_dict['pki_instance_name'],
+ self.master_dict['pki_target_tomcat_conf_instance_id']))
+ if os.path.exists(self.master_dict['pki_cgroup_systemd_service']):
+ # Systemd cgroup path collision
+ config.pki_log.error(
+ log.PKIHELPER_NAMESPACE_COLLISION_2,
+ self.master_dict['pki_instance_name'],
+ self.master_dict['pki_cgroup_systemd_service_path'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_NAMESPACE_COLLISION_2 % (self.master_dict['pki_instance_name'],
+ self.master_dict['pki_cgroup_systemd_service_path']))
+ if os.path.exists(self.master_dict['pki_cgroup_cpu_systemd_service']):
+ # Systemd cgroup CPU path collision
+ config.pki_log.error(
+ log.PKIHELPER_NAMESPACE_COLLISION_2,
+ self.master_dict['pki_instance_name'],
+ self.master_dict['pki_cgroup_cpu_systemd_service_path'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_NAMESPACE_COLLISION_2 % (self.master_dict['pki_instance_name'],
+ self.master_dict['pki_cgroup_cpu_systemd_service_path']))
+ if os.path.exists(self.master_dict['pki_instance_log_path']) and\
+ os.path.exists(self.master_dict['pki_subsystem_log_path']):
+ # Top-Level PKI log path collision
+ config.pki_log.error(
+ log.PKIHELPER_NAMESPACE_COLLISION_2,
+ self.master_dict['pki_instance_name'],
+ self.master_dict['pki_instance_log_path'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_NAMESPACE_COLLISION_2 % (self.master_dict['pki_instance_name'],
+ self.master_dict['pki_instance_log_path']))
+ if os.path.exists(self.master_dict['pki_instance_configuration_path']) and\
+ os.path.exists(self.master_dict['pki_subsystem_configuration_path']):
+ # Top-Level PKI configuration path collision
+ config.pki_log.error(
+ log.PKIHELPER_NAMESPACE_COLLISION_2,
+ self.master_dict['pki_instance_name'],
+ self.master_dict['pki_instance_configuration_path'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_NAMESPACE_COLLISION_2 % (self.master_dict['pki_instance_name'],
+ self.master_dict['pki_instance_configuration_path']))
+ if os.path.exists(self.master_dict['pki_instance_registry_path']) and\
+ os.path.exists(self.master_dict['pki_subsystem_registry_path']):
+ # Top-Level PKI registry path collision
+ config.pki_log.error(
+ log.PKIHELPER_NAMESPACE_COLLISION_2,
+ self.master_dict['pki_instance_name'],
+ self.master_dict['pki_instance_registry_path'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_NAMESPACE_COLLISION_2 % (self.master_dict['pki_instance_name'],
+ self.master_dict['pki_instance_registry_path']))
+ # Run simple checks for reserved name namespace collisions
+ if self.master_dict['pki_instance_name'] in config.PKI_BASE_RESERVED_NAMES:
+ # Top-Level PKI base path reserved name collision
+ config.pki_log.error(
+ log.PKIHELPER_NAMESPACE_RESERVED_NAME_2,
+ self.master_dict['pki_instance_name'],
+ self.master_dict['pki_instance_path'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_NAMESPACE_RESERVED_NAME_2 % (self.master_dict['pki_instance_name'],
+ self.master_dict['pki_instance_path']))
+ # No need to check for reserved name under Top-Level PKI log path
+ if self.master_dict['pki_instance_name'] in config.PKI_CONFIGURATION_RESERVED_NAMES:
+ # Top-Level PKI configuration path reserved name collision
+ config.pki_log.error(
+ log.PKIHELPER_NAMESPACE_RESERVED_NAME_2,
+ self.master_dict['pki_instance_name'],
+ self.master_dict['pki_instance_configuration_path'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_NAMESPACE_RESERVED_NAME_2 % (self.master_dict['pki_instance_name'],
+ self.master_dict['pki_instance_configuration_path']))
+ if self.master_dict['pki_subsystem'] in config.PKI_APACHE_SUBSYSTEMS:
+ # Top-Level Apache PKI registry path reserved name collision
+ if self.master_dict['pki_instance_name'] in\
+ config.PKI_APACHE_REGISTRY_RESERVED_NAMES:
+ config.pki_log.error(
+ log.PKIHELPER_NAMESPACE_RESERVED_NAME_2,
+ self.master_dict['pki_instance_name'],
+ self.master_dict['pki_instance_registry_path'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_NAMESPACE_RESERVED_NAME_2 % (self.master_dict['pki_instance_name'],
+ self.master_dict['pki_instance_registry_path']))
+ elif self.master_dict['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS:
+ # Top-Level Tomcat PKI registry path reserved name collision
+ if self.master_dict['pki_instance_name'] in\
+ config.PKI_TOMCAT_REGISTRY_RESERVED_NAMES:
+ config.pki_log.error(
+ log.PKIHELPER_NAMESPACE_RESERVED_NAME_2,
+ self.master_dict['pki_instance_name'],
+ self.master_dict['pki_instance_registry_path'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_NAMESPACE_RESERVED_NAME_2 % (self.master_dict['pki_instance_name'],
+ self.master_dict['pki_instance_registry_path']))
+
+
+class ConfigurationFile:
+ """PKI Deployment Configuration File Class"""
+
+ def __init__(self, deployer):
+ self.master_dict = deployer.master_dict
+
+ def log_configuration_url(self):
+ # NOTE: This is the one and only parameter containing a sensitive
+ # parameter that may be stored in a log file.
+ config.pki_log.info(log.PKI_CONFIGURATION_WIZARD_URL_1,
+ self.master_dict['pki_configuration_url'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ config.pki_log.info(log.PKI_CONFIGURATION_WIZARD_RESTART_1,
+ self.master_dict['pki_registry_initscript_command'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+
+ def display_configuration_url(self):
+ # NOTE: This is the one and only parameter containing a sensitive
+ # parameter that may be displayed to the screen.
+ print log.PKI_CONFIGURATION_URL_1 % self.master_dict['pki_configuration_url']
+ print
+ print log.PKI_CONFIGURATION_RESTART_1 % \
+ self.master_dict['pki_registry_initscript_command']
+ print
+
+ def verify_sensitive_data(self):
+ # Silently verify the existence of 'sensitive' data
+ if self.master_dict['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS:
+ # Verify existence of Directory Server Password (ALWAYS)
+ if not self.master_dict.has_key('pki_ds_password') or\
+ not len(self.master_dict['pki_ds_password']):
+ config.pki_log.error(
+ log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2,
+ "pki_ds_password",
+ self.master_dict['pki_user_deployment_cfg'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2 % ("pki_ds_password",
+ self.master_dict['pki_user_deployment_cfg']))
+ # Verify existence of Admin Password (except for Clones)
+ if not config.str2bool(self.master_dict['pki_clone']):
+ if not self.master_dict.has_key('pki_admin_password') or\
+ not len(self.master_dict['pki_admin_password']):
+ config.pki_log.error(
+ log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2,
+ "pki_admin_password",
+ self.master_dict['pki_user_deployment_cfg'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2 % ("pki_admin_password",
+ self.master_dict['pki_user_deployment_cfg']))
+ # If required, verify existence of Backup Password
+ if config.str2bool(self.master_dict['pki_backup_keys']):
+ if not self.master_dict.has_key('pki_backup_password') or\
+ not len(self.master_dict['pki_backup_password']):
+ config.pki_log.error(
+ log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2,
+ "pki_backup_password",
+ self.master_dict['pki_user_deployment_cfg'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2 % ("pki_backup_password",
+ self.master_dict['pki_user_deployment_cfg']))
+ # Verify existence of Client Pin for NSS client security databases
+ if not self.master_dict.has_key('pki_client_database_password') or\
+ not len(self.master_dict['pki_client_database_password']):
+ config.pki_log.error(
+ log.PKIHELPER_UNDEFINED_CLIENT_DATABASE_PASSWORD_2,
+ "pki_client_database_password",
+ self.master_dict['pki_user_deployment_cfg'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_UNDEFINED_CLIENT_DATABASE_PASSWORD_2 % ("pki_client_database_password",
+ self.master_dict['pki_user_deployment_cfg']))
+ # Verify existence of Client PKCS #12 Password for Admin Cert
+ if not self.master_dict.has_key('pki_client_pkcs12_password') or\
+ not len(self.master_dict['pki_client_pkcs12_password']):
+ config.pki_log.error(
+ log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2,
+ "pki_client_pkcs12_password",
+ self.master_dict['pki_user_deployment_cfg'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2 % ("pki_client_pkcs12_password",
+ self.master_dict['pki_user_deployment_cfg']))
+ # Verify existence of PKCS #12 Password (ONLY for Clones)
+ if config.str2bool(self.master_dict['pki_clone']):
+ if not self.master_dict.has_key('pki_clone_pkcs12_password') or\
+ not len(self.master_dict['pki_clone_pkcs12_password']):
+ config.pki_log.error(
+ log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2,
+ "pki_clone_pkcs12_password",
+ self.master_dict['pki_user_deployment_cfg'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2 % ("pki_clone_pkcs12_password",
+ self.master_dict['pki_user_deployment_cfg']))
+ # Verify existence of Security Domain Password File
+ # (ONLY for Clones, KRA, OCSP, TKS, TPS, or Subordinate CA)
+ if config.str2bool(self.master_dict['pki_clone']) or\
+ not self.master_dict['pki_subsystem'] == "CA" or\
+ config.str2bool(self.master_dict['pki_subordinate']):
+ if not self.master_dict.has_key('pki_security_domain_password') or\
+ not len(self.master_dict['pki_security_domain_password']):
+ config.pki_log.error(
+ log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2,
+ "pki_security_domain_password",
+ self.master_dict['pki_user_deployment_cfg'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2 % ("pki_security_domain_password",
+ self.master_dict['pki_user_deployment_cfg']))
+ # If required, verify existence of Token Password
+ if not self.master_dict['pki_token_name'] == "internal":
+ if not self.master_dict.has_key('pki_token_password') or\
+ not len(self.master_dict['pki_token_password']):
+ config.pki_log.error(
+ log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2,
+ "pki_token_password",
+ self.master_dict['pki_user_deployment_cfg'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2 % ("pki_token_password",
+ self.master_dict['pki_user_deployment_cfg']))
+ return
+
+ def verify_mutually_exclusive_data(self):
+ # Silently verify the existence of 'mutually exclusive' data
+ if self.master_dict['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS:
+ if self.master_dict['pki_subsystem'] == "CA":
+ if config.str2bool(self.master_dict['pki_clone']) and\
+ config.str2bool(self.master_dict['pki_external']) and\
+ config.str2bool(self.master_dict['pki_subordinate']):
+ config.pki_log.error(
+ log.PKIHELPER_MUTUALLY_EXCLUSIVE_CLONE_EXTERNAL_SUB_CA,
+ self.master_dict['pki_user_deployment_cfg'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_MUTUALLY_EXCLUSIVE_CLONE_EXTERNAL_SUB_CA % self.master_dict['pki_user_deployment_cfg'])
+ elif config.str2bool(self.master_dict['pki_clone']) and\
+ config.str2bool(self.master_dict['pki_external']):
+ config.pki_log.error(
+ log.PKIHELPER_MUTUALLY_EXCLUSIVE_CLONE_EXTERNAL_CA,
+ self.master_dict['pki_user_deployment_cfg'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_MUTUALLY_EXCLUSIVE_CLONE_EXTERNAL_CA % self.master_dict['pki_user_deployment_cfg'])
+ elif config.str2bool(self.master_dict['pki_clone']) and\
+ config.str2bool(self.master_dict['pki_subordinate']):
+ config.pki_log.error(
+ log.PKIHELPER_MUTUALLY_EXCLUSIVE_CLONE_SUB_CA,
+ self.master_dict['pki_user_deployment_cfg'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_MUTUALLY_EXCLUSIVE_CLONE_SUB_CA % self.master_dict['pki_user_deployment_cfg'])
+ elif config.str2bool(self.master_dict['pki_external']) and\
+ config.str2bool(self.master_dict['pki_subordinate']):
+ config.pki_log.error(
+ log.PKIHELPER_MUTUALLY_EXCLUSIVE_EXTERNAL_SUB_CA,
+ self.master_dict['pki_user_deployment_cfg'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_MUTUALLY_EXCLUSIVE_EXTERNAL_SUB_CA % self.master_dict['pki_user_deployment_cfg'])
+
+ 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" (e. g. - string, boolean, number,
+ # etc.), and "correctness" (e. g. - file, directory, boolean
+ # 'True' or 'False', etc.) of ALL required "value" parameters.
+ #
+ if self.master_dict['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS:
+ if config.str2bool(self.master_dict['pki_clone']):
+ # Verify existence of clone parameters
+ if not self.master_dict.has_key('pki_ds_base_dn') or\
+ not len(self.master_dict['pki_ds_base_dn']):
+ config.pki_log.error(
+ log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2,
+ "pki_ds_base_dn",
+ self.master_dict['pki_user_deployment_cfg'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2 % ("pki_ds_base_dn",
+ self.master_dict['pki_user_deployment_cfg']))
+ if not self.master_dict.has_key('pki_ds_ldap_port') or\
+ not len(self.master_dict['pki_ds_ldap_port']):
+ # FUTURE: Check for unused port value
+ # (e. g. - must be different from master if the
+ # master is located on the same host)
+ config.pki_log.error(
+ log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2,
+ "pki_ds_ldap_port",
+ self.master_dict['pki_user_deployment_cfg'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2 % ("pki_ds_ldap_port",
+ self.master_dict['pki_user_deployment_cfg']))
+ if not self.master_dict.has_key('pki_ds_ldaps_port') or\
+ not len(self.master_dict['pki_ds_ldaps_port']):
+ # FUTURE: Check for unused port value
+ # (e. g. - must be different from master if the
+ # master is located on the same host)
+ config.pki_log.error(
+ log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2,
+ "pki_ds_ldaps_port",
+ self.master_dict['pki_user_deployment_cfg'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2 % ("pki_ds_ldaps_port",
+ self.master_dict['pki_user_deployment_cfg']))
+ # NOTE: Although this will be checked prior to getting to
+ # this method, this clone's 'pki_instance_name' MUST
+ # be different from the master's 'pki_instance_name'
+ # IF AND ONLY IF the master and clone are located on
+ # the same host!
+ if not self.master_dict.has_key('pki_ajp_port') or\
+ not len(self.master_dict['pki_ajp_port']):
+ # FUTURE: Check for unused port value
+ # (e. g. - must be different from master if the
+ # master is located on the same host)
+ config.pki_log.error(
+ log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2,
+ "pki_ajp_port",
+ self.master_dict['pki_user_deployment_cfg'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2 % ("pki_ajp_port",
+ self.master_dict['pki_user_deployment_cfg']))
+ if not self.master_dict.has_key('pki_http_port') or\
+ not len(self.master_dict['pki_http_port']):
+ # FUTURE: Check for unused port value
+ # (e. g. - must be different from master if the
+ # master is located on the same host)
+ config.pki_log.error(
+ log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2,
+ "pki_http_port",
+ self.master_dict['pki_user_deployment_cfg'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2 % ("pki_http_port",
+ self.master_dict['pki_user_deployment_cfg']))
+ if not self.master_dict.has_key('pki_https_port') or\
+ not len(self.master_dict['pki_https_port']):
+ # FUTURE: Check for unused port value
+ # (e. g. - must be different from master if the
+ # master is located on the same host)
+ config.pki_log.error(
+ log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2,
+ "pki_https_port",
+ self.master_dict['pki_user_deployment_cfg'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2 % ("pki_https_port",
+ self.master_dict['pki_user_deployment_cfg']))
+ if not self.master_dict.has_key('pki_tomcat_server_port') or\
+ not len(self.master_dict['pki_tomcat_server_port']):
+ # FUTURE: Check for unused port value
+ # (e. g. - must be different from master if the
+ # master is located on the same host)
+ config.pki_log.error(
+ log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2,
+ "pki_tomcat_server_port",
+ self.master_dict['pki_user_deployment_cfg'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2 % ("pki_tomcat_server_port",
+ self.master_dict['pki_user_deployment_cfg']))
+ if not self.master_dict.has_key('pki_clone_pkcs12_path') or\
+ not len(self.master_dict['pki_clone_pkcs12_path']):
+ config.pki_log.error(
+ log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2,
+ "pki_clone_pkcs12_path",
+ self.master_dict['pki_user_deployment_cfg'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2 % ("pki_clone_pkcs12_path",
+ self.master_dict['pki_user_deployment_cfg']))
+ elif not os.path.isfile(self.master_dict['pki_clone_pkcs12_path']):
+ config.pki_log.error(
+ log.PKI_FILE_ALREADY_EXISTS_NOT_A_FILE_1,
+ self.master_dict['pki_clone_pkcs12_path'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKI_FILE_ALREADY_EXISTS_NOT_A_FILE_1 % "pki_clone_pkcs12_path")
+ if not self.master_dict.has_key('pki_clone_replication_security') or\
+ not len(self.master_dict['pki_clone_replication_security']):
+ config.pki_log.error(
+ log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2,
+ "pki_clone_replication_security",
+ self.master_dict['pki_user_deployment_cfg'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2 % ("pki_clone_replication_security",
+ self.master_dict['pki_user_deployment_cfg']))
+ if not self.master_dict.has_key('pki_clone_uri') or\
+ not len(self.master_dict['pki_clone_uri']):
+ config.pki_log.error(
+ log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2,
+ "pki_clone_uri",
+ self.master_dict['pki_user_deployment_cfg'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2 % ("pki_clone_uri",
+ self.master_dict['pki_user_deployment_cfg']))
+ elif self.master_dict['pki_subsystem'] == "CA" and\
+ config.str2bool(self.master_dict['pki_external']):
+ if not self.master_dict.has_key('pki_external_step_two') or\
+ not len(self.master_dict['pki_external_step_two']):
+ config.pki_log.error(
+ log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2,
+ "pki_external_step_two",
+ self.master_dict['pki_user_deployment_cfg'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2 % ("pki_extrenal_step_two",
+ self.master_dict['pki_user_deployment_cfg']))
+ if not config.str2bool(self.master_dict['pki_external_step_two']):
+ # External CA (Step 1)
+ if not self.master_dict.has_key('pki_external_csr_path') or\
+ not len(self.master_dict['pki_external_csr_path']):
+ config.pki_log.error(
+ log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2,
+ "pki_external_csr_path",
+ self.master_dict['pki_user_deployment_cfg'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2 % ("pki_extrenal_csr_path",
+ self.master_dict['pki_user_deployment_cfg']))
+ elif os.path.exists(self.master_dict['pki_external_csr_path']) and\
+ not os.path.isfile(self.master_dict['pki_external_csr_path']):
+ config.pki_log.error(
+ log.PKI_FILE_ALREADY_EXISTS_NOT_A_FILE_1,
+ self.master_dict['pki_external_csr_path'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2 % "pki_extrenal_csr_path")
+ else:
+ # External CA (Step 2)
+ if not self.master_dict.has_key('pki_external_ca_cert_chain_path') or\
+ not len(self.master_dict['pki_external_ca_cert_chain_path']):
+ config.pki_log.error(
+ log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2,
+ "pki_external_ca_cert_chain_path",
+ self.master_dict['pki_user_deployment_cfg'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2 % ("pki_extrenal_ca_cert_chain_path",
+ self.master_dict['pki_user_deployment_cfg']))
+ elif os.path.exists(
+ self.master_dict['pki_external_ca_cert_chain_path']) and\
+ not os.path.isfile(
+ self.master_dict['pki_external_ca_cert_chain_path']):
+ config.pki_log.error(
+ log.PKI_FILE_ALREADY_EXISTS_NOT_A_FILE_1,
+ self.master_dict['pki_external_ca_cert_chain_path'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2 % "pki_extrenal_ca_cert_chain_path")
+ if not self.master_dict.has_key('pki_external_ca_cert_path') or\
+ not len(self.master_dict['pki_external_ca_cert_path']):
+ config.pki_log.error(
+ log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2,
+ "pki_external_ca_cert_path",
+ self.master_dict['pki_user_deployment_cfg'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2 % ("pki_extrenal_ca_cert_path",
+ self.master_dict['pki_user_deployment_cfg']))
+ elif os.path.exists(self.master_dict['pki_external_ca_cert_path']) and\
+ not os.path.isfile(
+ self.master_dict['pki_external_ca_cert_path']):
+ config.pki_log.error(
+ log.PKI_FILE_ALREADY_EXISTS_NOT_A_FILE_1,
+ self.master_dict['pki_external_ca_cert_path'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2 % "pki_extrenal_ca_cert_path")
+ return
+
+ def populate_non_default_ports(self):
+ if (self.master_dict['pki_http_port'] !=
+ str(config.PKI_DEPLOYMENT_DEFAULT_TOMCAT_HTTP_PORT)):
+ ports.append(self.master_dict['pki_http_port'])
+ if (self.master_dict['pki_https_port'] !=
+ str(config.PKI_DEPLOYMENT_DEFAULT_TOMCAT_HTTPS_PORT)):
+ ports.append(self.master_dict['pki_https_port'])
+ if (self.master_dict['pki_tomcat_server_port'] !=
+ str(config.PKI_DEPLOYMENT_DEFAULT_TOMCAT_SERVER_PORT)):
+ ports.append(self.master_dict['pki_tomcat_server_port'])
+ if (self.master_dict['pki_ajp_port'] !=
+ str(config.PKI_DEPLOYMENT_DEFAULT_TOMCAT_AJP_PORT)):
+ ports.append(self.master_dict['pki_ajp_port'])
+ return
+
+ def verify_selinux_ports(self):
+ # Determine which ports still need to be labelled, and if any are
+ # incorrectly labelled
+ if len(ports) == 0:
+ return
+
+ if not bool(selinux.is_selinux_enabled()):
+ config.pki_log.error(
+ log.PKIHELPER_SELINUX_DISABLED,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ return
+
+ portrecs = seobject.portRecords().get_all()
+ portlist = ports[:]
+ for port in portlist:
+ context = ""
+ for i in portrecs:
+ if (portrecs[i][0] == "unreserved_port_t" or
+ portrecs[i][0] == "reserved_port_t" or
+ i[2] != "tcp"):
+ continue
+ if i[0] <= int(port) and int(port) <= i[1]:
+ context = portrecs[i][0]
+ break
+ if context == "":
+ # port has no current context
+ # leave it in list of ports to set
+ continue
+ elif context == config.PKI_PORT_SELINUX_CONTEXT:
+ # port is already set correctly
+ # remove from list of ports to set
+ ports.remove(port)
+ else:
+ config.pki_log.error(
+ log.PKIHELPER_INVALID_SELINUX_CONTEXT_FOR_PORT,
+ port, context,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_INVALID_SELINUX_CONTEXT_FOR_PORT % (port, context))
+ 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 self.master_dict['pki_deployment_executable'] == 'pkidestroy':
+ if self.master_dict['pki_deployed_instance_name'] != \
+ self.master_dict['pki_instance_name']:
+ config.pki_log.error(
+ log.PKIHELPER_COMMAND_LINE_PARAMETER_MISMATCH_2,
+ self.master_dict['pki_deployed_instance_name'],
+ self.master_dict['pki_instance_name'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2 % (self.master_dict['pki_deployed_instance_name'],
+ self.master_dict['pki_instance_name']))
+ return
+
+# PKI Deployment XML File Class
+# class xml_file:
+# def remove_filter_section_from_web_xml(self,
+# web_xml_source,
+# web_xml_target):
+# config.pki_log.info(log.PKIHELPER_REMOVE_FILTER_SECTION_1,
+# self.master_dict['pki_target_subsystem_web_xml'],
+# extra=config.PKI_INDENTATION_LEVEL_2)
+# begin_filters_section = False
+# begin_servlet_section = False
+# FILE = open(web_xml_target, "w")
+# for line in fileinput.FileInput(web_xml_source):
+# if not begin_filters_section:
+# # Read and write lines until first "<filter>" tag
+# if line.count("<filter>") >= 1:
+# # Mark filters section
+# begin_filters_section = True
+# else:
+# FILE.write(line)
+# elif not begin_servlet_section:
+# # Skip lines until first "<servlet>" tag
+# if line.count("<servlet>") >= 1:
+# # Mark servlets section and write out the opening tag
+# begin_servlet_section = True
+# FILE.write(line)
+# else:
+# continue
+# else:
+# # Read and write lines all lines after "<servlet>" tag
+# FILE.write(line)
+# FILE.close()
+
+class Instance:
+ """PKI Deployment Instance Class"""
+
+ def __init__(self, deployer):
+ self.master_dict = deployer.master_dict
+
+ def apache_instance_subsystems(self):
+ rv = 0
+ try:
+ # count number of PKI subsystems present
+ # within the specified Apache instance
+ for subsystem in config.PKI_APACHE_SUBSYSTEMS:
+ path = self.master_dict['pki_instance_path'] + "/" + subsystem.lower()
+ if os.path.exists(path) and os.path.isdir(path):
+ rv = rv + 1
+ config.pki_log.debug(log.PKIHELPER_APACHE_INSTANCE_SUBSYSTEMS_2,
+ self.master_dict['pki_instance_path'],
+ rv, 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)
+ raise
+ return rv
+
+ def apache_instances(self):
+ rv = 0
+ try:
+ # Since ALL directories under the top-level PKI 'apache' registry
+ # directory SHOULD represent PKI Apache instances, and there
+ # shouldn't be any stray files or symbolic links at this level,
+ # simply count the number of PKI 'apache' instances (directories)
+ # present within the PKI 'apache' registry directory
+ for instance in\
+ os.listdir(self.master_dict['pki_instance_type_registry_path']):
+ if os.path.isdir(
+ os.path.join(self.master_dict['pki_instance_type_registry_path'],
+ instance)) and not\
+ os.path.islink(
+ os.path.join(self.master_dict['pki_instance_type_registry_path'],
+ instance)):
+ rv = rv + 1
+ config.pki_log.debug(log.PKIHELPER_APACHE_INSTANCES_2,
+ self.master_dict['pki_instance_type_registry_path'],
+ rv,
+ 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)
+ raise
+ return rv
+
+ def pki_instance_subsystems(self):
+ rv = 0
+ try:
+ # Since ALL directories within the top-level PKI infrastructure
+ # SHOULD represent PKI instances, look for all possible
+ # PKI instances within the top-level PKI infrastructure
+ for instance in os.listdir(self.master_dict['pki_path']):
+ if os.path.isdir(os.path.join(self.master_dict['pki_path'], instance))\
+ and not\
+ os.path.islink(os.path.join(self.master_dict['pki_path'], instance)):
+ instance_dir = os.path.join(self.master_dict['pki_path'], instance)
+ # Since ANY directory within this PKI instance COULD
+ # be a PKI subsystem, look for all possible
+ # PKI subsystems within this PKI instance
+ for name in os.listdir(instance_dir):
+ if os.path.isdir(os.path.join(instance_dir, name)) and\
+ not os.path.islink(os.path.join(instance_dir, name)):
+ if name.upper() in config.PKI_SUBSYSTEMS:
+ rv = rv + 1
+ config.pki_log.debug(log.PKIHELPER_PKI_INSTANCE_SUBSYSTEMS_2,
+ self.master_dict['pki_instance_path'], rv,
+ 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)
+ raise
+ return rv
+
+ def tomcat_instance_subsystems(self):
+ # Return list of PKI subsystems in the specified tomcat instance
+ rv = []
+ try:
+ for subsystem in config.PKI_TOMCAT_SUBSYSTEMS:
+ path = self.master_dict['pki_instance_path'] + "/" + subsystem.lower()
+ if os.path.exists(path) and os.path.isdir(path):
+ rv.append(subsystem)
+ except OSError as exc:
+ config.pki_log.error(log.PKI_OSERROR_1, exc,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise
+ return rv
+
+ def tomcat_instances(self):
+ rv = 0
+ try:
+ # Since ALL directories under the top-level PKI 'tomcat' registry
+ # directory SHOULD represent PKI Tomcat instances, and there
+ # shouldn't be any stray files or symbolic links at this level,
+ # simply count the number of PKI 'tomcat' instances (directories)
+ # present within the PKI 'tomcat' registry directory
+ for instance in\
+ os.listdir(self.master_dict['pki_instance_type_registry_path']):
+ if os.path.isdir(
+ os.path.join(self.master_dict['pki_instance_type_registry_path'],
+ instance)) and not\
+ os.path.islink(
+ os.path.join(self.master_dict['pki_instance_type_registry_path'],
+ instance)):
+ rv = rv + 1
+ config.pki_log.debug(log.PKIHELPER_TOMCAT_INSTANCES_2,
+ self.master_dict['pki_instance_type_registry_path'],
+ rv,
+ 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)
+ raise
+ return rv
+
+ def verify_subsystem_exists(self):
+ try:
+ if not os.path.exists(self.master_dict['pki_subsystem_path']):
+ config.pki_log.error(log.PKI_SUBSYSTEM_DOES_NOT_EXIST_2,
+ self.master_dict['pki_subsystem'],
+ self.master_dict['pki_instance_name'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKI_SUBSYSTEM_DOES_NOT_EXIST_2 % (self.master_dict['pki_subsystem'],
+ self.master_dict['pki_instance_name']))
+ except OSError as exc:
+ config.pki_log.error(log.PKI_OSERROR_1, exc,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise
+
+ def verify_subsystem_does_not_exist(self):
+ try:
+ if os.path.exists(self.master_dict['pki_subsystem_path']):
+ config.pki_log.error(log.PKI_SUBSYSTEM_ALREADY_EXISTS_2,
+ self.master_dict['pki_subsystem'],
+ self.master_dict['pki_instance_name'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKI_SUBSYSTEM_DOES_NOT_EXIST_2 % (self.master_dict['pki_subsystem'],
+ self.master_dict['pki_instance_name']))
+ except OSError as exc:
+ config.pki_log.error(log.PKI_OSERROR_1, exc,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise
+
+ def get_instance_status(self):
+ connection = pki.client.PKIConnection(
+ protocol='https',
+ hostname=self.master_dict['pki_hostname'],
+ port=self.master_dict['pki_https_port'],
+ subsystem=self.master_dict['pki_subsystem_type'],
+ accept='application/xml')
+
+ try:
+ client = pki.system.SystemStatusClient(connection)
+ response = client.getStatus()
+ config.pki_log.debug(response,
+ extra=config.PKI_INDENTATION_LEVEL_3)
+
+ root = ET.fromstring(response)
+ status = root.findtext("Status")
+ return status
+ except requests.exceptions.ConnectionError:
+ config.pki_log.debug("No connection",
+ extra=config.PKI_INDENTATION_LEVEL_3)
+ return None
+
+ def wait_for_startup(self, timeout):
+ start_time = datetime.today()
+ status = None
+ while status != "running":
+ status = self.get_instance_status()
+ time.sleep(1)
+ stop_time = datetime.today()
+ if (stop_time - start_time).total_seconds() >= timeout:
+ break
+ return status
+
+class Directory:
+ """PKI Deployment Directory Class"""
+
+ def __init__(self, deployer):
+ self.master_dict = deployer.master_dict
+ self.identity = deployer.identity
+ self.manifest_db = deployer.manifest_db
+
+ def create(self, name, uid=None, gid=None,
+ perms=config.PKI_DEPLOYMENT_DEFAULT_DIR_PERMISSIONS,
+ acls=None, critical_failure=True):
+ try:
+ if not os.path.exists(name):
+ # mkdir -p <name>
+ config.pki_log.info(log.PKIHELPER_MKDIR_1, name,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ os.makedirs(name)
+ # 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>
+ if uid == None:
+ uid = self.identity.get_uid()
+ if gid == None:
+ gid = self.identity.get_gid()
+ 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_DIRECTORY
+ record.user = self.master_dict['pki_user']
+ record.group = self.master_dict['pki_group']
+ record.uid = uid
+ record.gid = gid
+ record.permissions = perms
+ record.acls = acls
+ self.manifest_db.append(record)
+ elif not os.path.isdir(name):
+ config.pki_log.error(
+ log.PKI_DIRECTORY_ALREADY_EXISTS_NOT_A_DIRECTORY_1, name,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise Exception(log.PKI_DIRECTORY_ALREADY_EXISTS_NOT_A_DIRECTORY_1 % name)
+ 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:
+ raise
+ return
+
+ def modify(self, name, uid=None, gid=None,
+ perms=config.PKI_DEPLOYMENT_DEFAULT_DIR_PERMISSIONS,
+ acls=None, silent=False, critical_failure=True):
+ try:
+ if os.path.exists(name):
+ if not os.path.isdir(name):
+ config.pki_log.error(
+ log.PKI_DIRECTORY_ALREADY_EXISTS_NOT_A_DIRECTORY_1,
+ name, extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise Exception(log.PKI_DIRECTORY_ALREADY_EXISTS_NOT_A_DIRECTORY_1 % name)
+ # Always re-process each directory whether it needs it or not
+ if not silent:
+ config.pki_log.info(log.PKIHELPER_MODIFY_DIR_1, name,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ # chmod <perms> <name>
+ if not silent:
+ config.pki_log.debug(log.PKIHELPER_CHMOD_2, perms, name,
+ extra=config.PKI_INDENTATION_LEVEL_3)
+ os.chmod(name, perms)
+ # chown <uid>:<gid> <name>
+ if uid == None:
+ uid = self.identity.get_uid()
+ if gid == None:
+ gid = self.identity.get_gid()
+ if not silent:
+ 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
+ if not silent:
+ record = manifest.Record()
+ record.name = name
+ record.type = manifest.RECORD_TYPE_DIRECTORY
+ record.user = self.master_dict['pki_user']
+ record.group = self.master_dict['pki_group']
+ record.uid = uid
+ record.gid = gid
+ record.permissions = perms
+ record.acls = acls
+ self.manifest_db.append(record)
+ else:
+ config.pki_log.error(
+ log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1, name,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise Exception(log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1 % name)
+ except OSError as exc:
+ config.pki_log.error(log.PKI_OSERROR_1, exc,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise
+ return
+
+ def delete(self, name, recursive_flag=True, critical_failure=True):
+ try:
+ if not os.path.exists(name) or not os.path.isdir(name):
+ # 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)
+ else:
+ if recursive_flag == True:
+ # rm -rf <name>
+ config.pki_log.info(log.PKIHELPER_RM_RF_1, name,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ shutil.rmtree(name)
+ else:
+ # rmdir <name>
+ config.pki_log.info(log.PKIHELPER_RMDIR_1, name,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ os.rmdir(name)
+ except OSError as exc:
+ config.pki_log.error(log.PKI_OSERROR_1, exc,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise
+ 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)
+ raise
+
+ def is_empty(self, name):
+ try:
+ if not os.listdir(name):
+ 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)
+ raise
+
+ def set_mode(self, name, uid=None, gid=None,
+ dir_perms=config.PKI_DEPLOYMENT_DEFAULT_DIR_PERMISSIONS,
+ file_perms=config.PKI_DEPLOYMENT_DEFAULT_FILE_PERMISSIONS,
+ symlink_perms=\
+ config.PKI_DEPLOYMENT_DEFAULT_SYMLINK_PERMISSIONS,
+ dir_acls=None, file_acls=None, symlink_acls=None,
+ recursive_flag=True, critical_failure=True):
+ try:
+ if not os.path.exists(name) or not os.path.isdir(name):
+ config.pki_log.error(
+ log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1, name,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1 % name)
+ else:
+ config.pki_log.info(
+ log.PKIHELPER_SET_MODE_1, name,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if uid == None:
+ uid = self.identity.get_uid()
+ if gid == None:
+ gid = self.identity.get_gid()
+ if recursive_flag == True:
+ for root, dirs, files in os.walk(name):
+ for name in files:
+ entity = os.path.join(root, name)
+ if not os.path.islink(entity):
+ temp_file = entity
+ config.pki_log.debug(
+ log.PKIHELPER_IS_A_FILE_1, temp_file,
+ extra=config.PKI_INDENTATION_LEVEL_3)
+ # chmod <file_perms> <name>
+ config.pki_log.debug(log.PKIHELPER_CHMOD_2,
+ file_perms, temp_file,
+ extra=config.PKI_INDENTATION_LEVEL_3)
+ os.chmod(temp_file, file_perms)
+ # chown <uid>:<gid> <name>
+ config.pki_log.debug(log.PKIHELPER_CHOWN_3,
+ uid, gid, temp_file,
+ extra=config.PKI_INDENTATION_LEVEL_3)
+ os.chown(temp_file, uid, gid)
+ # Store record in installation manifest
+ record = manifest.Record()
+ record.name = name
+ record.type = manifest.RECORD_TYPE_FILE
+ record.user = self.master_dict['pki_user']
+ record.group = self.master_dict['pki_group']
+ record.uid = uid
+ record.gid = gid
+ record.permissions = file_perms
+ record.acls = file_acls
+ self.manifest_db.append(record)
+ else:
+ symlink = entity
+ config.pki_log.debug(
+ log.PKIHELPER_IS_A_SYMLINK_1, symlink,
+ extra=config.PKI_INDENTATION_LEVEL_3)
+ # REMINDER: Due to POSIX compliance, 'lchmod'
+ # is NEVER implemented on Linux
+ # systems since 'chmod' CANNOT be
+ # run directly against symbolic
+ # links!
+ # chown -h <uid>:<gid> <symlink>
+ config.pki_log.debug(log.PKIHELPER_CHOWN_H_3,
+ uid, gid, symlink,
+ extra=config.PKI_INDENTATION_LEVEL_3)
+ os.lchown(symlink, uid, gid)
+ # Store record in installation manifest
+ record = manifest.Record()
+ record.name = name
+ record.type = manifest.RECORD_TYPE_SYMLINK
+ record.user = self.master_dict['pki_user']
+ record.group = self.master_dict['pki_group']
+ record.uid = uid
+ record.gid = gid
+ record.permissions = symlink_perms
+ record.acls = symlink_acls
+ self.manifest_db.append(record)
+ for name in dirs:
+ temp_dir = os.path.join(root, name)
+ config.pki_log.debug(
+ log.PKIHELPER_IS_A_DIRECTORY_1, temp_dir,
+ extra=config.PKI_INDENTATION_LEVEL_3)
+ # chmod <dir_perms> <name>
+ config.pki_log.debug(log.PKIHELPER_CHMOD_2,
+ dir_perms, temp_dir,
+ extra=config.PKI_INDENTATION_LEVEL_3)
+ os.chmod(temp_dir, dir_perms)
+ # chown <uid>:<gid> <name>
+ config.pki_log.debug(log.PKIHELPER_CHOWN_3,
+ uid, gid, temp_dir,
+ extra=config.PKI_INDENTATION_LEVEL_3)
+ os.chown(temp_dir, uid, gid)
+ # Store record in installation manifest
+ record = manifest.Record()
+ record.name = name
+ record.type = manifest.RECORD_TYPE_DIRECTORY
+ record.user = self.master_dict['pki_user']
+ record.group = self.master_dict['pki_group']
+ record.uid = uid
+ record.gid = gid
+ record.permissions = dir_perms
+ record.acls = dir_acls
+ self.manifest_db.append(record)
+ else:
+ config.pki_log.debug(
+ log.PKIHELPER_IS_A_DIRECTORY_1, name,
+ extra=config.PKI_INDENTATION_LEVEL_3)
+ name = os.path.join(root, name)
+ # chmod <dir_perms> <name>
+ config.pki_log.debug(log.PKIHELPER_CHMOD_2,
+ dir_perms, name,
+ extra=config.PKI_INDENTATION_LEVEL_3)
+ os.chmod(name, dir_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_DIRECTORY
+ record.user = self.master_dict['pki_user']
+ record.group = self.master_dict['pki_group']
+ record.uid = uid
+ record.gid = gid
+ record.permissions = dir_perms
+ record.acls = dir_acls
+ self.manifest_db.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:
+ raise
+
+ def copy(self, old_name, new_name, uid=None, gid=None,
+ dir_perms=config.PKI_DEPLOYMENT_DEFAULT_DIR_PERMISSIONS,
+ file_perms=config.PKI_DEPLOYMENT_DEFAULT_FILE_PERMISSIONS,
+ symlink_perms=config.PKI_DEPLOYMENT_DEFAULT_SYMLINK_PERMISSIONS,
+ 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)
+ raise Exception(log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1 % old_name)
+ else:
+ if os.path.exists(new_name):
+ if not overwrite_flag:
+ config.pki_log.error(
+ log.PKI_DIRECTORY_ALREADY_EXISTS_1, new_name,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKI_DIRECTORY_ALREADY_EXISTS_1 % new_name)
+ if recursive_flag == True:
+ # cp -rp <old_name> <new_name>
+ config.pki_log.info(log.PKIHELPER_CP_RP_2,
+ old_name, new_name,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ # Due to a limitation in the 'shutil.copytree()'
+ # implementation which requires that
+ # 'The destination directory must not already exist.',
+ # an OSError exception is always thrown due to the
+ # implementation's unchecked call to 'os.makedirs(dst)'.
+ # Consequently, a 'patched' local copy of this routine has
+ # been included in this file with the appropriate fix.
+ pki_copytree(old_name, new_name)
+ else:
+ # 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)
+ # set ownerships, permissions, and acls
+ # of newly created top-level directory
+ self.modify(new_name, uid, gid, dir_perms, dir_acls,
+ True, critical_failure)
+ # set ownerships, permissions, and acls
+ # of contents of newly created top-level directory
+ self.set_mode(new_name, uid, gid,
+ dir_perms, file_perms, symlink_perms,
+ dir_acls, file_acls, symlink_acls,
+ recursive_flag, critical_failure)
+ except OSError as exc:
+ config.pki_log.error(log.PKI_OSERROR_1, exc,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise
+ 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:
+ raise
+ return
+
+class File:
+ """PKI Deployment File Class (also used for executables)"""
+
+ def __init__(self, deployer):
+ self.master_dict = deployer.master_dict
+ self.slots = deployer.slots
+ self.identity = deployer.identity
+ self.manifest_db = deployer.manifest_db
+
+ def create(self, name, uid=None, gid=None,
+ perms=config.PKI_DEPLOYMENT_DEFAULT_FILE_PERMISSIONS,
+ acls=None, critical_failure=True):
+ try:
+ if not os.path.exists(name):
+ # touch <name>
+ config.pki_log.info(log.PKIHELPER_TOUCH_1, name,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ open(name, "w").close()
+ # 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>
+ if uid == None:
+ uid = self.identity.get_uid()
+ if gid == None:
+ gid = self.identity.get_gid()
+ 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 = self.master_dict['pki_user']
+ record.group = self.master_dict['pki_group']
+ record.uid = uid
+ record.gid = gid
+ record.permissions = perms
+ record.acls = acls
+ self.manifest_db.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:
+ raise Exception(log.PKI_FILE_ALREADY_EXISTS_NOT_A_FILE_1 % name)
+ 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:
+ raise
+ return
+
+ def modify(self, name, uid=None, gid=None,
+ perms=config.PKI_DEPLOYMENT_DEFAULT_FILE_PERMISSIONS,
+ acls=None, silent=False, critical_failure=True):
+ try:
+ if os.path.exists(name):
+ if 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:
+ raise Exception(log.PKI_FILE_ALREADY_EXISTS_NOT_A_FILE_1 % name)
+ # Always re-process each file whether it needs it or not
+ if not silent:
+ config.pki_log.info(log.PKIHELPER_MODIFY_FILE_1, name,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ # chmod <perms> <name>
+ if not silent:
+ config.pki_log.debug(log.PKIHELPER_CHMOD_2, perms, name,
+ extra=config.PKI_INDENTATION_LEVEL_3)
+ os.chmod(name, perms)
+ # chown <uid>:<gid> <name>
+ if uid == None:
+ uid = self.identity.get_uid()
+ if gid == None:
+ gid = self.identity.get_gid()
+ if not silent:
+ 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
+ if not silent:
+ record = manifest.Record()
+ record.name = name
+ record.type = manifest.RECORD_TYPE_FILE
+ record.user = self.master_dict['pki_user']
+ record.group = self.master_dict['pki_group']
+ record.uid = uid
+ record.gid = gid
+ record.permissions = perms
+ record.acls = acls
+ self.manifest_db.append(record)
+ else:
+ config.pki_log.error(
+ log.PKI_FILE_MISSING_OR_NOT_A_FILE_1, name,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise Exception(log.PKI_FILE_MISSING_OR_NOT_A_FILE_1 % name)
+ except OSError as exc:
+ config.pki_log.error(log.PKI_OSERROR_1, exc,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise
+ return
+
+ def delete(self, name, critical_failure=True):
+ try:
+ if not os.path.exists(name) or not os.path.isfile(name):
+ # 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)
+ else:
+ # rm -f <name>
+ config.pki_log.info(log.PKIHELPER_RM_F_1, name,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ os.remove(name)
+ except OSError as exc:
+ config.pki_log.error(log.PKI_OSERROR_1, exc,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise
+ 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)
+ raise
+
+ 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):
+ try:
+ if 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)
+ raise Exception(log.PKI_FILE_MISSING_OR_NOT_A_FILE_1 % old_name)
+ 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)
+ raise Exception(log.PKI_FILE_ALREADY_EXISTS_1 % new_name)
+ # 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 = self.identity.get_uid()
+ if gid == None:
+ gid = self.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 = self.master_dict['pki_user']
+ record.group = self.master_dict['pki_group']
+ record.uid = uid
+ record.gid = gid
+ record.permissions = perms
+ record.acls = acls
+ self.manifest_db.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:
+ raise
+ 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:
+ raise
+ 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 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)
+ raise Exception(log.PKI_FILE_MISSING_OR_NOT_A_FILE_1 % name)
+ # 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 self.slots:
+ if slot != '__name__' and self.slots[slot] in line:
+ config.pki_log.debug(
+ log.PKIHELPER_SLOT_SUBSTITUTION_2,
+ self.slots[slot], self.master_dict[slot],
+ extra=config.PKI_INDENTATION_LEVEL_3)
+ line = line.replace(self.slots[slot], self.master_dict[slot])
+ sys.stdout.write(line)
+ if uid == None:
+ uid = self.identity.get_uid()
+ if gid == None:
+ gid = self.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 = self.master_dict['pki_user']
+ record.group = self.master_dict['pki_group']
+ record.uid = uid
+ record.gid = gid
+ record.permissions = perms
+ record.acls = acls
+ self.manifest_db.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:
+ raise
+ 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:
+ raise
+ 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 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)
+ raise Exception(log.PKI_FILE_MISSING_OR_NOT_A_FILE_1 % old_name)
+ 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)
+ raise Exception(log.PKI_FILE_ALREADY_EXISTS_1 % new_name)
+ # 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)
+ with open(new_name, "w") as FILE:
+ for line in fileinput.FileInput(old_name):
+ for slot in self.slots:
+ if slot != '__name__' and self.slots[slot] in line:
+ config.pki_log.debug(
+ log.PKIHELPER_SLOT_SUBSTITUTION_2,
+ self.slots[slot], self.master_dict[slot],
+ extra=config.PKI_INDENTATION_LEVEL_3)
+ line = line.replace(self.slots[slot], self.master_dict[slot])
+ FILE.write(line)
+ if uid == None:
+ uid = self.identity.get_uid()
+ if gid == None:
+ gid = self.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 = self.master_dict['pki_user']
+ record.group = self.master_dict['pki_group']
+ record.uid = uid
+ record.gid = gid
+ record.permissions = perms
+ record.acls = acls
+ self.manifest_db.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:
+ raise
+ 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:
+ raise
+ return
+
+ def generate_noise_file(self, name, random_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 <random_bytes> random bytes
+ config.pki_log.info(log.PKIHELPER_NOISE_FILE_2, name, random_bytes,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ open(name, "w").close()
+ with open(name, "w") as FILE:
+ noise = ''.join(random.choice(string.ascii_letters + \
+ string.digits) for x in range(random_bytes))
+ FILE.write(noise)
+ # 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>
+ if uid == None:
+ uid = self.identity.get_uid()
+ if gid == None:
+ gid = self.identity.get_gid()
+ 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 = self.master_dict['pki_user']
+ record.group = self.master_dict['pki_group']
+ record.uid = uid
+ record.gid = gid
+ record.permissions = perms
+ record.acls = acls
+ self.manifest_db.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:
+ raise Exception(log.PKI_FILE_ALREADY_EXISTS_NOT_A_FILE_1 % name)
+ 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:
+ raise
+ return
+
+class Symlink:
+ """PKI Deployment Symbolic Link Class"""
+
+ def __init__(self, deployer):
+ self.master_dict = deployer.master_dict
+ self.identity = deployer.identity
+ self.manifest_db = deployer.manifest_db
+
+ def create(self, name, link, uid=None, gid=None,
+ acls=None, allow_dangling_symlink=False, critical_failure=True):
+ try:
+ if not os.path.exists(link):
+ if not os.path.exists(name):
+ config.pki_log.warning(
+ log.PKIHELPER_DANGLING_SYMLINK_2, link, name,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if not allow_dangling_symlink:
+ raise Exception("Dangling symlink " + link + " not allowed")
+ # ln -s <name> <link>
+ config.pki_log.info(log.PKIHELPER_LINK_S_2, name, link,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ os.symlink(name, link)
+ # REMINDER: Due to POSIX compliance, 'lchmod' is NEVER
+ # implemented on Linux systems since 'chmod'
+ # CANNOT be run directly against symbolic links!
+ # chown -h <uid>:<gid> <link>
+ if uid == None:
+ uid = self.identity.get_uid()
+ if gid == None:
+ gid = self.identity.get_gid()
+ config.pki_log.debug(log.PKIHELPER_CHOWN_H_3,
+ uid, gid, link,
+ extra=config.PKI_INDENTATION_LEVEL_3)
+ os.lchown(link, uid, gid)
+ # Store record in installation manifest
+ record = manifest.Record()
+ record.name = link
+ record.type = manifest.RECORD_TYPE_SYMLINK
+ record.user = self.master_dict['pki_user']
+ record.group = self.master_dict['pki_group']
+ record.uid = uid
+ record.gid = gid
+ record.permissions = \
+ config.PKI_DEPLOYMENT_DEFAULT_SYMLINK_PERMISSIONS
+ record.acls = acls
+ self.manifest_db.append(record)
+ elif not os.path.islink(link):
+ config.pki_log.error(
+ log.PKI_SYMLINK_ALREADY_EXISTS_NOT_A_SYMLINK_1, link,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise Exception(log.PKI_SYMLINK_ALREADY_EXISTS_NOT_A_SYMLINK_1 % link)
+ 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:
+ raise
+ return
+
+ def modify(self, link, uid=None, gid=None,
+ acls=None, silent=False, critical_failure=True):
+ try:
+ if os.path.exists(link):
+ if not os.path.islink(link):
+ config.pki_log.error(
+ log.PKI_SYMLINK_ALREADY_EXISTS_NOT_A_SYMLINK_1,
+ link, extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise Exception(log.PKI_SYMLINK_ALREADY_EXISTS_NOT_A_SYMLINK_1 % link)
+ # Always re-process each link whether it needs it or not
+ if not silent:
+ config.pki_log.info(log.PKIHELPER_MODIFY_SYMLINK_1, link,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ # REMINDER: Due to POSIX compliance, 'lchmod' is NEVER
+ # implemented on Linux systems since 'chmod'
+ # CANNOT be run directly against symbolic links!
+ # chown -h <uid>:<gid> <link>
+ if uid == None:
+ uid = self.identity.get_uid()
+ if gid == None:
+ gid = self.identity.get_gid()
+ if not silent:
+ config.pki_log.debug(log.PKIHELPER_CHOWN_H_3,
+ uid, gid, link,
+ extra=config.PKI_INDENTATION_LEVEL_3)
+ os.lchown(link, uid, gid)
+ # Store record in installation manifest
+ if not silent:
+ record = manifest.Record()
+ record.name = link
+ record.type = manifest.RECORD_TYPE_SYMLINK
+ record.user = self.master_dict['pki_user']
+ record.group = self.master_dict['pki_group']
+ record.uid = uid
+ record.gid = gid
+ record.permissions = \
+ config.PKI_DEPLOYMENT_DEFAULT_SYMLINK_PERMISSIONS
+ record.acls = acls
+ self.manifest_db.append(record)
+ else:
+ config.pki_log.error(
+ log.PKI_SYMLINK_MISSING_OR_NOT_A_SYMLINK_1, link,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise Exception(log.PKI_SYMLINK_MISSING_OR_NOT_A_SYMLINK_1 % link)
+ except OSError as exc:
+ config.pki_log.error(log.PKI_OSERROR_1, exc,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise
+ return
+
+ def delete(self, link, critical_failure=True):
+ try:
+ if not os.path.exists(link) or not os.path.islink(link):
+ # 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)
+ else:
+ # rm -f <link>
+ config.pki_log.info(log.PKIHELPER_RM_F_1, link,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ os.remove(link)
+ except OSError as exc:
+ config.pki_log.error(log.PKI_OSERROR_1, exc,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise
+ 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)
+ raise
+
+class War:
+ """PKI Deployment War File Class"""
+
+ def __init__(self, deployer):
+ self.master_dict = deployer.master_dict
+
+ def explode(self, name, path, critical_failure=True):
+ try:
+ if os.path.exists(name) and os.path.isfile(name):
+ if not zipfile.is_zipfile(name):
+ config.pki_log.error(
+ log.PKI_FILE_NOT_A_WAR_FILE_1,
+ name, extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise Exception(log.PKI_FILE_NOT_A_WAR_FILE_1 % name)
+ if not os.path.exists(path) or not os.path.isdir(path):
+ config.pki_log.error(
+ log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1,
+ path, extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise Exception(log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1, path)
+ # jar -xf <name> -C <path>
+ config.pki_log.info(log.PKIHELPER_JAR_XF_C_2, name, path,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ # Open war file
+ war = zipfile.ZipFile(name, 'r')
+ # Extract contents of war file to path
+ war.extractall(path)
+ else:
+ config.pki_log.error(
+ log.PKI_FILE_MISSING_OR_NOT_A_FILE_1, name,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise Exception(log.PKI_FILE_MISSING_OR_NOT_A_FILE_1, name)
+ except OSError as exc:
+ config.pki_log.error(log.PKI_OSERROR_1, exc,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise
+ except zipfile.BadZipfile as exc:
+ config.pki_log.error(log.PKI_BADZIPFILE_ERROR_1, exc,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise
+ except zipfile.LargeZipFile as exc:
+ config.pki_log.error(log.PKI_LARGEZIPFILE_ERROR_1, exc,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise
+ return
+
+class Password:
+ """PKI Deployment Password Class"""
+
+ def __init__(self, deployer):
+ self.master_dict = deployer.master_dict
+
+ def create_password_conf(self, path, pin, pin_sans_token=False,
+ overwrite_flag=False, critical_failure=True):
+ try:
+ 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 pin_sans_token == True:
+ fd.write(str(pin))
+ elif self.master_dict['pki_subsystem'] in\
+ config.PKI_APACHE_SUBSYSTEMS:
+ fd.write(self.master_dict['pki_self_signed_token'] + \
+ ":" + str(pin))
+ else:
+ fd.write(self.master_dict['pki_self_signed_token'] + \
+ "=" + str(pin))
+ 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 pin_sans_token == True:
+ fd.write(str(pin))
+ elif self.master_dict['pki_subsystem'] in\
+ config.PKI_APACHE_SUBSYSTEMS:
+ fd.write(self.master_dict['pki_self_signed_token'] + \
+ ":" + str(pin))
+ else:
+ fd.write(self.master_dict['pki_self_signed_token'] + \
+ "=" + str(pin))
+ except OSError as exc:
+ config.pki_log.error(log.PKI_OSERROR_1, exc,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise
+ return
+
+ def create_client_pkcs12_password_conf(self, path, overwrite_flag=False,
+ critical_failure=True):
+ try:
+ 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 'pkcs12_password.conf' file
+ with open(path, "wt") as fd:
+ fd.write(self.master_dict['pki_client_pkcs12_password'])
+ else:
+ config.pki_log.info(log.PKIHELPER_PASSWORD_CONF_1, path,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ # create a new 'pkcs12_password.conf' file
+ with open(path, "wt") as fd:
+ fd.write(self.master_dict['pki_client_pkcs12_password'])
+ except OSError as exc:
+ config.pki_log.error(log.PKI_OSERROR_1, exc,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise
+ return
+
+ def get_password(self, path, token_name, critical_failure=True):
+ if os.path.exists(path) and os.path.isfile(path) and\
+ os.access(path, os.R_OK):
+ tokens = PKIConfigParser.read_simple_configuration_file(path)
+ hardware_token = "hardware-" + token_name
+ if tokens.has_key(hardware_token):
+ token_name = hardware_token
+ token_pwd = tokens[hardware_token]
+ elif tokens.has_key(token_name):
+ token_pwd = tokens[token_name]
+
+ if token_pwd is None or token_pwd == '':
+ # TODO prompt for this password
+ config.pki_log.error(log.PKIHELPER_PASSWORD_NOT_FOUND_1,
+ token_name,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise Exception(log.PKIHELPER_PASSWORD_NOT_FOUND_1 % token_name)
+ else:
+ return
+ return token_pwd
+
+class Certutil:
+ """PKI Deployment NSS 'certutil' Class"""
+
+ def __init__(self, deployer):
+ self.master_dict = deployer.master_dict
+
+ def create_security_databases(self, path, pki_cert_database,
+ pki_key_database, pki_secmod_database,
+ 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)
+ raise Exception(log.PKIHELPER_CERTUTIL_MISSING_PATH)
+ if password_file != None:
+ command = command + " " + "-f" + " " + password_file
+ if prefix != None:
+ command = command + " " + "-P" + " " + prefix
+ 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)
+ raise Exception(log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1 % path)
+ if os.path.exists(pki_cert_database) or\
+ os.path.exists(pki_key_database) or\
+ os.path.exists(pki_secmod_database):
+ # Simply notify user that the security databases exist
+ config.pki_log.info(
+ log.PKI_SECURITY_DATABASES_ALREADY_EXIST_3,
+ pki_cert_database,
+ pki_key_database,
+ 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)
+ raise Exception(log.PKI_FILE_MISSING_OR_NOT_A_FILE_1 % password_file)
+ # 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)
+ 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:
+ raise
+ except OSError as exc:
+ config.pki_log.error(log.PKI_OSERROR_1, exc,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise
+ return
+
+ def verify_certificate_exists(self, path, pki_cert_database,
+ pki_key_database, pki_secmod_database,
+ token, nickname, password_file=None,
+ silent=True, critical_failure=True):
+ 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)
+ raise Exception(log.PKIHELPER_CERTUTIL_MISSING_PATH)
+ # 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)
+ raise Exception(log.PKIHELPER_CERTUTIL_MISSING_TOKEN)
+ # 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)
+ raise Exception(log.PKIHELPER_CERTUTIL_MISSING_NICKNAME)
+ # OPTIONALLY specify a password file
+ if password_file != None:
+ command = command + " " + "-f" + " " + password_file
+ # By default, execute this command silently
+ if silent != False:
+ command = command + " > /dev/null 2>&1"
+ 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)
+ raise Exception(log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1 % path)
+ if not os.path.exists(pki_cert_database) or\
+ not os.path.exists(pki_key_database) or\
+ not os.path.exists(pki_secmod_database):
+ # NSS security databases MUST exist!
+ config.pki_log.error(
+ log.PKI_SECURITY_DATABASES_DO_NOT_EXIST_3,
+ pki_cert_database,
+ pki_key_database,
+ pki_secmod_database,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKI_SECURITY_DATABASES_DO_NOT_EXIST_3 % (pki_cert_database,
+ pki_key_database, pki_secmod_database))
+ 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)
+ raise Exception(log.PKI_FILE_MISSING_OR_NOT_A_FILE_1 % password_file)
+ # 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:
+ raise
+ return True
+
+ def generate_self_signed_certificate(self, path, pki_cert_database,
+ pki_key_database, pki_secmod_database,
+ 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)
+ raise Exception(log.PKIHELPER_CERTUTIL_MISSING_PATH)
+ # 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)
+ raise Exception(log.PKIHELPER_CERTUTIL_MISSING_TOKEN)
+ # 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)
+ raise Exception(log.PKIHELPER_CERTUTIL_MISSING_NICKNAME)
+ # 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)
+ raise Exception(log.PKIHELPER_CERTUTIL_MISSING_SUBJECT)
+ # 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)
+ raise Exception(log.PKIHELPER_CERTUTIL_MISSING_SERIAL_NUMBER)
+ # 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)
+ raise Exception(log.PKIHELPER_CERTUTIL_MISSING_VALIDITY_PERIOD)
+ # 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)
+ raise Exception(log.PKIHELPER_CERTUTIL_MISSING_ISSUER_NAME)
+ # 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)
+ raise Exception(log.PKIHELPER_CERTUTIL_MISSING_TRUSTARGS)
+ # 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)
+ raise Exception(log.PKIHELPER_CERTUTIL_MISSING_NOISE_FILE)
+ # 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 os.path.exists(path):
+ config.pki_log.error(
+ log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1, path,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1 % path)
+ if not os.path.exists(pki_cert_database) or\
+ not os.path.exists(pki_key_database) or\
+ not os.path.exists(pki_secmod_database):
+ # NSS security databases MUST exist!
+ config.pki_log.error(
+ log.PKI_SECURITY_DATABASES_DO_NOT_EXIST_3,
+ pki_cert_database,
+ pki_key_database,
+ pki_secmod_database,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKI_SECURITY_DATABASES_DO_NOT_EXIST_3 % (pki_cert_database,
+ pki_key_database, pki_secmod_database))
+ 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)
+ raise Exception(log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1 % noise_file)
+ 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)
+ raise Exception(log.PKI_FILE_MISSING_OR_NOT_A_FILE_1 % password_file)
+ # 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:
+ raise
+ except OSError as exc:
+ config.pki_log.error(log.PKI_OSERROR_1, exc,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise
+ return
+
+ def import_cert(self, nickname, trust, input_file, password_file,
+ path=None, token=None, critical_failure=True):
+ try:
+ command = ["certutil", "-A"]
+ if path:
+ command.extend(["-d", path])
+
+ if token:
+ command.extend(["-h", token])
+
+ if nickname:
+ command.extend(["-n", nickname ])
+ else:
+ config.pki_log.error(
+ log.PKIHELPER_CERTUTIL_MISSING_NICKNAME,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_CERTUTIL_MISSING_NICKNAME)
+
+ if trust:
+ command.extend(["-t", trust])
+ else:
+ config.pki_log.error(
+ log.PKIHELPER_CERTUTIL_MISSING_TRUSTARGS,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_CERTUTIL_MISSING_TRUSTARGS)
+
+ if input_file:
+ command.extend(["-i", input_file])
+ else:
+ config.pki_log.error(
+ log.PKIHELPER_CERTUTIL_MISSING_INPUT_FILE,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_CERTUTIL_MISSING_INPUT_FILE)
+
+ if password_file:
+ command.extend(["-f", password_file])
+ else:
+ config.pki_log.error(
+ log.PKIHELPER_CERTUTIL_MISSING_PASSWORD_FILE,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_CERTUTIL_MISSING_PASSWORD_FILE)
+
+ config.pki_log.info(command,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ subprocess.call(command)
+ 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:
+ raise
+ except OSError as exc:
+ config.pki_log.error(log.PKI_OSERROR_1, exc,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise
+ return
+
+ def generate_certificate_request(self, subject, key_size,
+ password_file, noise_file,
+ output_file=None, path=None,
+ ascii_format=None, token=None,
+ critical_failure=True):
+ try:
+ command = ["certutil", "-R"]
+ if path:
+ command.extend(["-d", path])
+ else:
+ command.extend(["-d", "."])
+
+ if token:
+ command.extend(["-h", token])
+
+ if subject:
+ command.extend(["-s", subject])
+ else:
+ config.pki_log.error(
+ log.PKIHELPER_CERTUTIL_MISSING_SUBJECT,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_CERTUTIL_MISSING_SUBJECT)
+
+ if key_size:
+ command.extend(["-g", str(key_size)])
+
+ if noise_file:
+ command.extend(["-z", noise_file])
+ else:
+ config.pki_log.error(
+ log.PKIHELPER_CERTUTIL_MISSING_NOISE_FILE,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_CERTUTIL_MISSING_NOISE_FILE)
+
+ if password_file:
+ command.extend(["-f", password_file])
+ else:
+ config.pki_log.error(
+ log.PKIHELPER_CERTUTIL_MISSING_PASSWORD_FILE,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_CERTUTIL_MISSING_PASSWORD_FILE)
+
+ if output_file:
+ command.extend(["-o", output_file])
+
+ # set acsii output
+ if ascii_format:
+ command.append("-a")
+
+ # Display this "certutil" command
+ config.pki_log.info(
+ log.PKIHELPER_CERTUTIL_GENERATE_CSR_1, command,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ 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)
+ raise Exception(log.PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1 % noise_file)
+ 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)
+ raise Exception(log.PKI_FILE_MISSING_OR_NOT_A_FILE_1 % password_file)
+ # Execute this "certutil" command
+ with open(os.devnull, "w") as fnull:
+ subprocess.call(command, stdout=fnull, stderr=fnull)
+ 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:
+ raise
+ except OSError as exc:
+ config.pki_log.error(log.PKI_OSERROR_1, exc,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise
+ return
+
+class PK12util:
+ """PKI Deployment pk12util class"""
+
+ def __init__(self, deployer):
+ self.master_dict = deployer.master_dict
+
+ def create_file(self, out_file, nickname, out_pwfile,
+ db_pwfile, path=None, critical_failure=True):
+ try:
+ command = ["pk12util"]
+ if path:
+ command.extend(["-d", path])
+ if out_file:
+ command.extend(["-o", out_file])
+ else:
+ config.pki_log.error(
+ log.PKIHELPER_PK12UTIL_MISSING_OUTFILE,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_PK12UTIL_MISSING_OUTFILE)
+ if nickname:
+ command.extend(["-n", nickname])
+ else:
+ config.pki_log.error(
+ log.PKIHELPER_PK12UTIL_MISSING_NICKNAME,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_PK12UTIL_MISSING_NICKNAME)
+ if out_pwfile:
+ command.extend(["-w", out_pwfile])
+ else:
+ config.pki_log.error(
+ log.PKIHELPER_PK12UTIL_MISSING_PWFILE,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_PK12UTIL_MISSING_PWFILE)
+ if db_pwfile:
+ command.extend(["-k", db_pwfile])
+ else:
+ config.pki_log.error(
+ log.PKIHELPER_PK12UTIL_MISSING_DBPWFILE,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKIHELPER_PK12UTIL_MISSING_DBPWFILE)
+
+ config.pki_log.info(command,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ with open(os.devnull, "w") as fnull:
+ subprocess.call(command, stdout=fnull, stderr=fnull)
+ 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:
+ raise
+ except OSError as exc:
+ config.pki_log.error(log.PKI_OSERROR_1, exc,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise
+ return
+
+class KRAConnector:
+ """PKI Deployment KRA Connector Class"""
+
+ def __init__(self, deployer):
+ self.master_dict = deployer.master_dict
+ self.password = deployer.password
+
+ def deregister(self, critical_failure=False):
+ try:
+ # this is applicable to KRAs only
+ if self.master_dict['pki_subsystem_type'] != "kra":
+ return
+
+ config.pki_log.info(
+ log.PKIHELPER_KRACONNECTOR_UPDATE_CONTACT,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+
+ cs_cfg = PKIConfigParser.read_simple_configuration_file(
+ self.master_dict['pki_target_cs_cfg'])
+ krahost = cs_cfg.get('service.machineName')
+ kraport = cs_cfg.get('pkicreate.secure_port')
+ cahost = cs_cfg.get('cloning.ca.hostname')
+ caport = cs_cfg.get('cloning.ca.httpsport')
+ if cahost is None or\
+ caport is None:
+ config.pki_log.warning(
+ log.PKIHELPER_KRACONNECTOR_UPDATE_FAILURE,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ config.pki_log.error(
+ log.PKIHELPER_UNDEFINED_CA_HOST_PORT,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise Exception(log.PKIHELPER_UNDEFINED_CA_HOST_PORT)
+ else:
+ return
+
+ # retrieve subsystem nickname
+ subsystemnick = cs_cfg.get('kra.cert.subsystem.nickname')
+ if subsystemnick is None:
+ config.pki_log.warning(
+ log.PKIHELPER_KRACONNECTOR_UPDATE_FAILURE,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ config.pki_log.error(
+ log.PKIHELPER_UNDEFINED_SUBSYSTEM_NICKNAME,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise Exception(log.PKIHELPER_UNDEFINED_SUBSYSTEM_NICKNAME)
+ else:
+ return
+
+ # retrieve name of token based upon type (hardware/software)
+ if ':' in subsystemnick:
+ token_name = subsystemnick.split(':')[0]
+ else:
+ token_name = "internal"
+
+ token_pwd = self.password.get_password(
+ self.master_dict['pki_shared_password_conf'],
+ token_name,
+ critical_failure)
+
+ if token_pwd is None or token_pwd == '':
+ config.pki_log.warning(
+ log.PKIHELPER_KRACONNECTOR_UPDATE_FAILURE,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ config.pki_log.error(
+ log.PKIHELPER_UNDEFINED_TOKEN_PASSWD_1,
+ token_name,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise Exception(log.PKIHELPER_UNDEFINED_TOKEN_PASSWD_1 % token_name)
+ else:
+ return
+
+ self.execute_using_sslget(caport, cahost, subsystemnick,
+ token_pwd, krahost, kraport)
+
+ except subprocess.CalledProcessError as exc:
+ config.pki_log.warning(
+ log.PKIHELPER_KRACONNECTOR_UPDATE_FAILURE_2,
+ str(krahost),
+ str(kraport),
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ config.pki_log.error(log.PKI_SUBPROCESS_ERROR_1, exc,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise
+ return
+
+ def execute_using_pki(self, caport, cahost, subsystemnick,
+ token_pwd, krahost, kraport, critical_failure=False):
+ command = "/bin/pki -p '{}' -h '{}' -n '{}' -P https -d '{}' -c '{}' "\
+ "kraconnector-del {} {}".format(
+ caport, cahost, subsystemnick,
+ self.master_dict['pki_database_path'],
+ token_pwd, krahost, kraport)
+
+ output = subprocess.check_output(command,
+ stderr=subprocess.STDOUT,
+ shell=True)
+
+ error = re.findall("ClientResponseFailure:(.*?)", output)
+ if error:
+ config.pki_log.warning(
+ log.PKIHELPER_KRACONNECTOR_UPDATE_FAILURE_2,
+ str(krahost),
+ str(kraport),
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ config.pki_log.error(log.PKI_SUBPROCESS_ERROR_1, output,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise Exception(log.PKI_SUBPROCESS_ERROR_1 % output)
+
+ def execute_using_sslget(self, caport, cahost, subsystemnick,
+ token_pwd, krahost, kraport):
+ updateURL = "/ca/rest/admin/kraconnector/remove"
+
+ params = "host=" + str(krahost) + \
+ "&port=" + str(kraport)
+
+ command = "/usr/bin/sslget -n '{}' -p '{}' -d '{}' -e '{}' "\
+ "-v -r '{}' {}:{} 2>&1".format(
+ subsystemnick, token_pwd,
+ self.master_dict['pki_database_path'],
+ params, updateURL,
+ cahost, caport)
+
+ # update KRA connector
+ # Execute this "sslget" command
+ # Note that sslget will return non-zero value for HTTP code != 200
+ # and this will raise an exception
+ subprocess.check_output(command,stderr=subprocess.STDOUT,
+ shell=True)
+
+class SecurityDomain:
+ """PKI Deployment Security Domain Class"""
+
+ def __init__(self, deployer):
+ self.master_dict = deployer.master_dict
+ self.password = deployer.password
+
+ def deregister(self, install_token, critical_failure=False):
+ # process this PKI subsystem instance's 'CS.cfg'
+ cs_cfg = PKIConfigParser.read_simple_configuration_file(
+ self.master_dict['pki_target_cs_cfg'])
+
+ # assign key name/value pairs
+ machinename = cs_cfg.get('service.machineName')
+ sport = cs_cfg.get('service.securityDomainPort')
+ ncsport = cs_cfg.get('service.non_clientauth_securePort', '')
+ sechost = cs_cfg.get('securitydomain.host')
+ seceeport = cs_cfg.get('securitydomain.httpseeport')
+ secagentport = cs_cfg.get('securitydomain.httpsagentport')
+ secadminport = cs_cfg.get('securitydomain.httpsadminport')
+ secname = cs_cfg.get('securitydomain.name', 'unknown')
+ adminsport = cs_cfg.get('pkicreate.admin_secure_port', '')
+ typeval = cs_cfg.get('cs.type', '')
+ agentsport = cs_cfg.get('pkicreate.agent_secure_port', '')
+
+ # NOTE: Don't check for the existence of 'httpport', as this will
+ # be undefined for a Security Domain that has been migrated!
+ if sechost is None or\
+ seceeport is None or\
+ secagentport is None or\
+ secadminport is None:
+ config.pki_log.warning(
+ log.PKIHELPER_SECURITY_DOMAIN_UPDATE_FAILURE_2,
+ typeval,
+ secname,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ config.pki_log.error(
+ log.PKIHELPER_SECURITY_DOMAIN_UNDEFINED,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise Exception(log.PKIHELPER_SECURITY_DOMAIN_UNDEFINED)
+ else:
+ return
+
+ config.pki_log.info(log.PKIHELPER_SECURITY_DOMAIN_CONTACT_1,
+ secname,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ listval = typeval.lower() + "List"
+ updateURL = "/ca/agent/ca/updateDomainXML"
+
+ params = "name=" + "\"" + self.master_dict['pki_instance_path'] + "\"" + \
+ "&type=" + str(typeval) + \
+ "&list=" + str(listval) + \
+ "&host=" + str(machinename) + \
+ "&sport=" + str(sport) + \
+ "&ncsport=" + str(ncsport) + \
+ "&adminsport=" + str(adminsport) + \
+ "&agentsport=" + str(agentsport) + \
+ "&operation=remove"
+
+ if install_token:
+ try:
+ # first try install token-based servlet
+ params += "&sessionID=" + str(install_token)
+ adminUpdateURL = "/ca/admin/ca/updateDomainXML"
+ command = "/usr/bin/sslget -p 123456 -d '{}' -e '{}' "\
+ "-v -r '{}' {}:{} 2>&1".format(
+ self.master_dict['pki_database_path'],
+ params, adminUpdateURL,
+ sechost, secadminport)
+ output = subprocess.check_output(command,
+ stderr=subprocess.STDOUT,
+ shell=True)
+ except subprocess.CalledProcessError:
+ config.pki_log.warning(
+ log.PKIHELPER_SECURITY_DOMAIN_UNREACHABLE_1,
+ secname,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ output = self.update_domain_using_agent_port(typeval,
+ secname, params, updateURL, sechost, secagentport,
+ critical_failure)
+ else:
+ output = self.update_domain_using_agent_port(typeval,
+ secname, params, updateURL, sechost, secagentport,
+ critical_failure)
+
+ if not output:
+ if critical_failure == True:
+ raise Exception("Cannot update domain using agent port")
+ else:
+ return
+
+ config.pki_log.debug(log.PKIHELPER_SSLGET_OUTPUT_1,
+ output,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ # Search the output for Status
+ status = re.findall('<Status>(.*?)</Status>', output)
+ if not status:
+ config.pki_log.warning(
+ log.PKIHELPER_SECURITY_DOMAIN_UNREACHABLE_1,
+ secname,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise Exception(log.PKIHELPER_SECURITY_DOMAIN_UNREACHABLE_1 % secname)
+ elif status[0] != "0":
+ error = re.findall('<Error>(.*?)</Error>', output)
+ if not error:
+ error = ""
+ config.pki_log.warning(
+ log.PKIHELPER_SECURITY_DOMAIN_UNREGISTERED_2,
+ typeval,
+ secname,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ config.pki_log.error(
+ log.PKIHELPER_SECURITY_DOMAIN_UPDATE_FAILURE_3,
+ typeval,
+ secname,
+ error,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise Exception(log.PKIHELPER_SECURITY_DOMAIN_UPDATE_FAILURE_3
+ %
+ (typeval, secname, error))
+ else:
+ config.pki_log.info(
+ log.PKIHELPER_SECURITY_DOMAIN_UPDATE_SUCCESS_2,
+ typeval,
+ secname,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+
+ def update_domain_using_agent_port(self, typeval, secname, params,
+ updateURL, sechost, secagentport, critical_failure=False):
+ token_pwd = None
+ cs_cfg = PKIConfigParser.read_simple_configuration_file(
+ self.master_dict['pki_target_cs_cfg'])
+ # retrieve subsystem nickname
+ subsystemnick_param = typeval.lower() + ".cert.subsystem.nickname"
+ subsystemnick = cs_cfg.get(subsystemnick_param)
+ if subsystemnick is None:
+ config.pki_log.warning(
+ log.PKIHELPER_SECURITY_DOMAIN_UPDATE_FAILURE_2,
+ typeval,
+ secname,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ config.pki_log.error(
+ log.PKIHELPER_UNDEFINED_SUBSYSTEM_NICKNAME,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise Exception(log.PKIHELPER_UNDEFINED_SUBSYSTEM_NICKNAME)
+ else:
+ return
+
+ # retrieve name of token based upon type (hardware/software)
+ if ':' in subsystemnick:
+ token_name = subsystemnick.split(':')[0]
+ else:
+ token_name = "internal"
+
+ token_pwd = self.password.get_password(
+ self.master_dict['pki_shared_password_conf'],
+ token_name,
+ critical_failure)
+
+ if token_pwd is None or token_pwd == '':
+ config.pki_log.warning(
+ log.PKIHELPER_SECURITY_DOMAIN_UPDATE_FAILURE_2,
+ typeval,
+ secname,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise Exception(log.PKIHELPER_SECURITY_DOMAIN_UPDATE_FAILURE_2
+ %
+ (typeval, secname))
+ else:
+ return
+
+ command = "/usr/bin/sslget -n '{}' -p '{}' -d '{}' -e '{}' "\
+ "-v -r '{}' {}:{} 2>&1".format(
+ subsystemnick, token_pwd,
+ self.master_dict['pki_database_path'],
+ params, updateURL,
+ sechost, secagentport)
+ try:
+ output = subprocess.check_output(command,
+ stderr=subprocess.STDOUT,
+ shell=True)
+ return output
+ except subprocess.CalledProcessError as exc:
+ config.pki_log.warning(
+ log.PKIHELPER_SECURITY_DOMAIN_UPDATE_FAILURE_2,
+ typeval,
+ secname,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ config.pki_log.warning(
+ log.PKIHELPER_SECURITY_DOMAIN_UNREACHABLE_1,
+ secname,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ config.pki_log.error(log.PKI_SUBPROCESS_ERROR_1, exc,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise
+
+ return None
+
+
+ def get_installation_token(self, secuser, secpass, critical_failure=True):
+ token = None
+
+ if not secuser or not secpass:
+ return None
+
+ # process this PKI subsystem instance's 'CS.cfg'
+ cs_cfg = PKIConfigParser.read_simple_configuration_file(
+ self.master_dict['pki_target_cs_cfg'])
+
+ # assign key name/value pairs
+ machinename = cs_cfg.get('service.machineName')
+ cstype = cs_cfg.get('cs.type', '')
+ sechost = cs_cfg.get('securitydomain.host')
+ secadminport = cs_cfg.get('securitydomain.httpsadminport')
+ #secselect = cs_cfg.get('securitydomain.select') - Selected security domain
+
+ command = "/bin/pki -p '{}' -h '{}' -P https -u '{}' -w '{}' -d '{}' "\
+ "securitydomain-get-install-token --hostname {} "\
+ "--subsystem {}".format(
+ secadminport, sechost, secuser, secpass,
+ self.master_dict['pki_database_path'],
+ machinename, cstype)
+ try:
+ output = subprocess.check_output(command,
+ stderr=subprocess.STDOUT,
+ shell=True)
+
+ token_list = re.findall("Install token: \"(.*)\"", output)
+ if not token_list:
+ config.pki_log.error(
+ log.PKIHELPER_SECURITY_DOMAIN_GET_TOKEN_FAILURE_2,
+ str(sechost),
+ str(secadminport),
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ config.pki_log.error(log.PKI_SUBPROCESS_ERROR_1, output,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise Exception(log.PKIHELPER_SECURITY_DOMAIN_GET_TOKEN_FAILURE_2
+ %
+ (str(sechost), str(secadminport)))
+ else:
+ token = token_list[0]
+ return token
+ except subprocess.CalledProcessError as exc:
+ config.pki_log.error(
+ log.PKIHELPER_SECURITY_DOMAIN_GET_TOKEN_FAILURE_2,
+ str(sechost),
+ str(secadminport),
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ config.pki_log.error(log.PKI_SUBPROCESS_ERROR_1, exc,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ if critical_failure == True:
+ raise
+ return None
+
+class Systemd:
+ """PKI Deployment 'systemd' Execution Management Class"""
+
+ def __init__(self, deployer):
+ self.master_dict = deployer.master_dict
+
+ def start(self, critical_failure=True):
+ try:
+ # Compose this "systemd" execution management command
+ if self.master_dict['pki_subsystem'] in config.PKI_APACHE_SUBSYSTEMS:
+ command = "systemctl" + " " + \
+ "start" + " " + \
+ "pki-apached" + "@" + \
+ self.master_dict['pki_instance_name'] + "." + "service"
+ elif self.master_dict['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS:
+ command = "systemctl" + " " + \
+ "start" + " " + \
+ "pki-tomcatd" + "@" + \
+ self.master_dict['pki_instance_name'] + "." + "service"
+ # Display this "systemd" execution managment command
+ config.pki_log.info(
+ log.PKIHELPER_SYSTEMD_COMMAND_1, command,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ # Execute this "systemd" execution management 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:
+ raise
+ return
+
+ def stop(self, critical_failure=True):
+ try:
+ # Compose this "systemd" execution management command
+ if self.master_dict['pki_subsystem'] in config.PKI_APACHE_SUBSYSTEMS:
+ command = "systemctl" + " " + \
+ "stop" + " " + \
+ "pki-apached" + "@" + \
+ self.master_dict['pki_instance_name'] + "." + "service"
+ elif self.master_dict['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS:
+ command = "systemctl" + " " + \
+ "stop" + " " + \
+ "pki-tomcatd" + "@" + \
+ self.master_dict['pki_instance_name'] + "." + "service"
+ # Display this "systemd" execution managment command
+ config.pki_log.info(
+ log.PKIHELPER_SYSTEMD_COMMAND_1, command,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ # Execute this "systemd" execution management 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:
+ raise
+ return
+
+ def restart(self, critical_failure=True):
+ try:
+ # Compose this "systemd" execution management command
+ if self.master_dict['pki_subsystem'] in config.PKI_APACHE_SUBSYSTEMS:
+ command = "systemctl" + " " + \
+ "restart" + " " + \
+ "pki-apached" + "@" + \
+ self.master_dict['pki_instance_name'] + "." + "service"
+ elif self.master_dict['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS:
+ command = "systemctl" + " " + \
+ "restart" + " " + \
+ "pki-tomcatd" + "@" + \
+ self.master_dict['pki_instance_name'] + "." + "service"
+ # Display this "systemd" execution managment command
+ config.pki_log.info(
+ log.PKIHELPER_SYSTEMD_COMMAND_1, command,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ # Execute this "systemd" execution management 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:
+ raise
+ return
+
+
+class ConfigClient:
+ """PKI Deployment Configuration Client"""
+
+ def __init__(self, deployer):
+ self.deployer = deployer
+ self.master_dict = deployer.master_dict
+
+ def configure_pki_data(self, data):
+ config.pki_log.info(log.PKI_CONFIG_CONFIGURING_PKI_DATA,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+
+ connection = pki.client.PKIConnection(
+ protocol='https',
+ hostname=self.master_dict['pki_hostname'],
+ port=self.master_dict['pki_https_port'],
+ subsystem=self.master_dict['pki_subsystem_type'])
+
+ try:
+ client = pki.system.SystemConfigClient(connection)
+ response = client.configure(data)
+
+ config.pki_log.debug(log.PKI_CONFIG_RESPONSE_STATUS + \
+ " " + str(response['status']),
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ try:
+ certs = response['systemCerts']
+ except KeyError:
+ # no system certs created
+ config.pki_log.debug("No new system certificates generated.",
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ certs = []
+
+ if not isinstance(certs, types.ListType):
+ certs = [certs]
+ for cdata in certs:
+ if self.master_dict['pki_subsystem'] == "CA" and\
+ config.str2bool(self.master_dict['pki_external']) and\
+ not config.str2bool(self.master_dict['pki_external_step_two']):
+ # External CA Step 1
+ if cdata['tag'].lower() == "signing":
+ config.pki_log.info(log.PKI_CONFIG_CDATA_REQUEST + \
+ " " + cdata['request'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+
+ # Save 'External CA Signing Certificate' CSR (Step 1)
+ config.pki_log.info(log.PKI_CONFIG_EXTERNAL_CSR_SAVE + \
+ " '" + self.master_dict['pki_external_csr_path'] + "'",
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ self.deployer.directory.create(
+ os.path.dirname(self.master_dict['pki_external_csr_path']))
+ with open(self.master_dict['pki_external_csr_path'], "w") as f:
+ f.write(cdata['request'])
+ return
+ else:
+ config.pki_log.debug(log.PKI_CONFIG_CDATA_TAG + \
+ " " + cdata['tag'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ config.pki_log.debug(log.PKI_CONFIG_CDATA_CERT + \
+ " " + cdata['cert'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ config.pki_log.debug(log.PKI_CONFIG_CDATA_REQUEST + \
+ " " + cdata['request'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+
+ # Cloned PKI subsystems do not return an Admin Certificate
+ if not config.str2bool(self.master_dict['pki_clone']) and \
+ not config.str2bool(self.master_dict['pki_import_admin_cert']):
+ admin_cert = response['adminCert']['cert']
+ self.process_admin_cert(admin_cert)
+
+ except Exception, e:
+ if hasattr(e, 'response'):
+ root = ET.fromstring(e.response.text)
+ if root.tag == 'PKIException':
+ message = root.findall('.//Message')[0].text
+ if message is not None:
+ config.pki_log.error(log.PKI_CONFIG_JAVA_CONFIGURATION_EXCEPTION + " " + message,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise
+ config.pki_log.error(
+ log.PKI_CONFIG_JAVA_CONFIGURATION_EXCEPTION + " " + str(e),
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise
+ return
+
+ def process_admin_cert(self, admin_cert):
+ config.pki_log.debug(log.PKI_CONFIG_RESPONSE_ADMIN_CERT + \
+ " " + admin_cert,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+
+ # Store the Administration Certificate in a file
+ admin_cert_file = self.master_dict['pki_client_admin_cert']
+ admin_cert_bin_file = admin_cert_file + ".der"
+ config.pki_log.debug(log.PKI_CONFIG_ADMIN_CERT_SAVE + \
+ " '" + admin_cert_file + "'",
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ with open(admin_cert_file, "w") as f:
+ f.write(admin_cert)
+
+ # convert the cert file to binary
+ command = ["AtoB", admin_cert_file, admin_cert_bin_file]
+ config.pki_log.info(command,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ subprocess.call(command)
+
+ os.chmod(admin_cert_file,
+ config.PKI_DEPLOYMENT_DEFAULT_FILE_PERMISSIONS)
+
+ os.chmod(admin_cert_bin_file,
+ config.PKI_DEPLOYMENT_DEFAULT_FILE_PERMISSIONS)
+
+ # Import the Administration Certificate
+ # into the client NSS security database
+ self.deployer.certutil.import_cert(
+ re.sub("&#39;", "'", self.master_dict['pki_admin_nickname']),
+ "u,u,u",
+ admin_cert_bin_file,
+ self.master_dict['pki_client_password_conf'],
+ self.master_dict['pki_client_database_dir'],
+ None,
+ True)
+
+ # create directory for p12 file if it does not exist
+ self.deployer.directory.create(os.path.dirname(
+ self.master_dict['pki_client_admin_cert_p12']))
+
+ # Export the Administration Certificate from the
+ # client NSS security database into a PKCS #12 file
+ self.deployer.pk12util.create_file(
+ self.master_dict['pki_client_admin_cert_p12'],
+ re.sub("&#39;", "'", self.master_dict['pki_admin_nickname']),
+ self.master_dict['pki_client_pkcs12_password_conf'],
+ self.master_dict['pki_client_password_conf'],
+ self.master_dict['pki_client_database_dir'])
+
+ os.chmod(self.master_dict['pki_client_admin_cert_p12'],
+ config.PKI_DEPLOYMENT_DEFAULT_SECURITY_DATABASE_PERMISSIONS)
+
+
+ def construct_pki_configuration_data(self):
+ config.pki_log.info(log.PKI_CONFIG_CONSTRUCTING_PKI_DATA,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+
+ data = pki.system.ConfigurationRequest()
+
+ # Miscellaneous Configuration Information
+ data.pin = self.master_dict['pki_one_time_pin']
+ data.subsystemName = self.master_dict['pki_subsystem_name']
+
+ # Cloning parameters
+ if self.master_dict['pki_instance_type'] == "Tomcat":
+ if config.str2bool(self.master_dict['pki_clone']):
+ self.set_cloning_parameters(data)
+ else:
+ data.isClone = "false"
+
+ # Hierarchy
+ self.set_hierarchy_parameters(data)
+
+ # Security Domain
+ if self.master_dict['pki_subsystem'] != "CA" or\
+ config.str2bool(self.master_dict['pki_clone']) or\
+ config.str2bool(self.master_dict['pki_subordinate']):
+ # PKI KRA, PKI OCSP, PKI RA, PKI TKS, PKI TPS,
+ # CA Clone, KRA Clone, OCSP Clone, TKS Clone, TPS Clone, or
+ # Subordinate CA
+ self.set_existing_security_domain(data)
+ else:
+ # PKI CA or External CA
+ self.set_new_security_domain(data)
+
+ # database
+ if self.master_dict['pki_subsystem'] != "RA":
+ self.set_database_parameters(data)
+
+ # backup
+ if self.master_dict['pki_instance_type'] == "Tomcat":
+ self.set_backup_parameters(data)
+
+ # admin user
+ if not config.str2bool(self.master_dict['pki_clone']):
+ self.set_admin_parameters(data)
+
+ # Issuing CA Information
+ self.set_issuing_ca_parameters(data)
+
+ # Create system certs
+ self.set_system_certs(data)
+
+ return data
+
+ def set_system_certs(self, data):
+ systemCerts = []
+
+ # Create 'CA Signing Certificate'
+ if self.master_dict['pki_subsystem'] == "CA":
+ if not config.str2bool(self.master_dict['pki_clone']):
+ cert1 = self.create_system_cert("ca_signing")
+ cert1.signingAlgorithm = \
+ self.master_dict['pki_ca_signing_signing_algorithm']
+ if config.str2bool(self.master_dict['pki_external_step_two']):
+ # Load the 'External CA Signing Certificate' (Step 2)
+ print(
+ log.PKI_CONFIG_EXTERNAL_CA_LOAD + " " + \
+ "'" + self.master_dict['pki_external_ca_cert_path'] + "'")
+ with open(self.master_dict['pki_external_ca_cert_path']) as f:
+ external_cert = f.read()
+ cert1.cert = external_cert
+
+ # Load the 'External CA Signing Certificate Chain' (Step 2)
+ print(
+ log.PKI_CONFIG_EXTERNAL_CA_CHAIN_LOAD + " " + \
+ "'" + self.master_dict['pki_external_ca_cert_chain_path'] + \
+ "'")
+ with open(self.master_dict['pki_external_ca_cert_chain_path']) as f:
+ external_cert_chain = f.read()
+
+ cert1.certChain = external_cert_chain
+ systemCerts.append(cert1)
+
+ # Create 'OCSP Signing Certificate'
+ if not config.str2bool(self.master_dict['pki_clone']):
+ if self.master_dict['pki_subsystem'] == "CA" or\
+ self.master_dict['pki_subsystem'] == "OCSP":
+ # External CA, Subordinate CA, PKI CA, or PKI OCSP
+ cert2 = self.create_system_cert("ocsp_signing")
+ cert2.signingAlgorithm = \
+ self.master_dict['pki_ocsp_signing_signing_algorithm']
+ systemCerts.append(cert2)
+
+ # Create 'SSL Server Certificate'
+ # all subsystems
+
+ # create new sslserver cert only if this is a new instance
+ cert3 = None
+ system_list = self.deployer.instance.tomcat_instance_subsystems()
+ if len(system_list) >= 2:
+ data.generateServerCert = "false"
+ for subsystem in system_list:
+ dst = self.master_dict['pki_instance_path'] + '/conf/' + \
+ subsystem.lower() + '/CS.cfg'
+ if subsystem != self.master_dict['pki_subsystem'] and \
+ os.path.exists(dst):
+ cert3 = self.retrieve_existing_server_cert(dst)
+ break
+ else:
+ cert3 = self.create_system_cert("ssl_server")
+ systemCerts.append(cert3)
+
+ # Create 'Subsystem Certificate'
+ if not config.str2bool(self.master_dict['pki_clone']):
+ cert4 = self.create_system_cert("subsystem")
+ systemCerts.append(cert4)
+
+ # Create 'Audit Signing Certificate'
+ if not config.str2bool(self.master_dict['pki_clone']):
+ if self.master_dict['pki_subsystem'] != "RA":
+ cert5 = self.create_system_cert("audit_signing")
+ cert5.signingAlgorithm = \
+ self.master_dict['pki_audit_signing_signing_algorithm']
+ systemCerts.append(cert5)
+
+ # Create DRM Transport and storage Certificates
+ if not config.str2bool(self.master_dict['pki_clone']):
+ if self.master_dict['pki_subsystem'] == "KRA":
+ cert6 = self.create_system_cert("transport")
+ systemCerts.append(cert6)
+
+ cert7 = self.create_system_cert("storage")
+ systemCerts.append(cert7)
+
+ data.systemCerts = systemCerts
+
+ def set_cloning_parameters(self, data):
+ data.isClone = "true"
+ data.cloneUri = self.master_dict['pki_clone_uri']
+ data.p12File = self.master_dict['pki_clone_pkcs12_path']
+ data.p12Password = self.master_dict['pki_clone_pkcs12_password']
+ data.replicateSchema = self.master_dict['pki_clone_replicate_schema']
+ data.replicationSecurity = \
+ self.master_dict['pki_clone_replication_security']
+ if self.master_dict['pki_clone_replication_master_port']:
+ data.masterReplicationPort = \
+ self.master_dict['pki_clone_replication_master_port']
+ if self.master_dict['pki_clone_replication_clone_port']:
+ data.cloneReplicationPort = \
+ self.master_dict['pki_clone_replication_clone_port']
+
+ def set_hierarchy_parameters(self, data):
+ if self.master_dict['pki_subsystem'] == "CA":
+ if config.str2bool(self.master_dict['pki_clone']):
+ # Cloned CA
+ data.hierarchy = "root"
+ elif config.str2bool(self.master_dict['pki_external']):
+ # External CA
+ data.hierarchy = "join"
+ elif config.str2bool(self.master_dict['pki_subordinate']):
+ # Subordinate CA
+ data.hierarchy = "join"
+ else:
+ # PKI CA
+ data.hierarchy = "root"
+
+ def set_existing_security_domain(self, data):
+ data.securityDomainType = "existingdomain"
+ data.securityDomainUri = self.master_dict['pki_security_domain_uri']
+ data.securityDomainUser = self.master_dict['pki_security_domain_user']
+ data.securityDomainPassword = self.master_dict['pki_security_domain_password']
+
+ def set_new_security_domain(self, data):
+ data.securityDomainType = "newdomain"
+ data.securityDomainName = self.master_dict['pki_security_domain_name']
+
+ def set_database_parameters(self, data):
+ data.dsHost = self.master_dict['pki_ds_hostname']
+ data.dsPort = self.master_dict['pki_ds_ldap_port']
+ data.baseDN = self.master_dict['pki_ds_base_dn']
+ data.bindDN = self.master_dict['pki_ds_bind_dn']
+ data.database = self.master_dict['pki_ds_database']
+ data.bindpwd = self.master_dict['pki_ds_password']
+ if config.str2bool(self.master_dict['pki_ds_remove_data']):
+ data.removeData = "true"
+ else:
+ data.removeData = "false"
+ if config.str2bool(self.master_dict['pki_ds_secure_connection']):
+ data.secureConn = "true"
+ else:
+ data.secureConn = "false"
+
+ def set_backup_parameters(self, data):
+ if config.str2bool(self.master_dict['pki_backup_keys']):
+ data.backupKeys = "true"
+ data.backupFile = self.master_dict['pki_backup_keys_p12']
+ data.backupPassword = self.master_dict['pki_backup_password']
+ else:
+ data.backupKeys = "false"
+
+ def set_admin_parameters(self, data):
+ data.adminEmail = self.master_dict['pki_admin_email']
+ data.adminName = self.master_dict['pki_admin_name']
+ data.adminPassword = self.master_dict['pki_admin_password']
+ data.adminProfileID = self.master_dict['pki_admin_profile_id']
+ data.adminUID = self.master_dict['pki_admin_uid']
+ data.adminSubjectDN = self.master_dict['pki_admin_subject_dn']
+ if config.str2bool(self.master_dict['pki_import_admin_cert']):
+ data.importAdminCert = "true"
+ # read config from file
+ with open(self.master_dict['pki_admin_cert_file']) as f:
+ b64 = f.read().replace('\n', '')
+ data.adminCert = b64
+ else:
+ data.importAdminCert = "false"
+ data.adminSubjectDN = self.master_dict['pki_admin_subject_dn']
+ if self.master_dict['pki_admin_cert_request_type'] == "pkcs10":
+ data.adminCertRequestType = "pkcs10"
+
+ noise_file = os.path.join(
+ self.master_dict['pki_client_database_dir'], "noise")
+
+ output_file = os.path.join(
+ self.master_dict['pki_client_database_dir'], "admin_pkcs10.bin")
+
+ self.deployer.file.generate_noise_file(
+ noise_file, int(self.master_dict['pki_admin_keysize']))
+
+ self.deployer.certutil.generate_certificate_request(
+ self.master_dict['pki_admin_subject_dn'],
+ self.master_dict['pki_admin_keysize'],
+ self.master_dict['pki_client_password_conf'],
+ noise_file,
+ output_file,
+ self.master_dict['pki_client_database_dir'],
+ None, None, True)
+
+ # convert output to ascii
+ command = ["BtoA", output_file, output_file + ".asc"]
+ config.pki_log.info(command,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ subprocess.call(command)
+
+ with open(output_file + ".asc") as f:
+ b64 = f.read().replace('\n', '')
+
+ data.adminCertRequest = b64
+ else:
+ print "log.PKI_CONFIG_PKCS10_SUPPORT_ONLY"
+ raise Exception(log.PKI_CONFIG_PKCS10_SUPPORT_ONLY)
+
+ def set_issuing_ca_parameters(self, data):
+ if self.master_dict['pki_subsystem'] != "CA" or\
+ config.str2bool(self.master_dict['pki_clone']) or\
+ config.str2bool(self.master_dict['pki_subordinate']) or\
+ config.str2bool(self.master_dict['pki_external']):
+ # PKI KRA, PKI OCSP, PKI RA, PKI TKS, PKI TPS,
+ # CA Clone, KRA Clone, OCSP Clone, TKS Clone, TPS Clone,
+ # Subordinate CA, or External CA
+ data.issuingCA = self.master_dict['pki_issuing_ca']
+ if self.master_dict['pki_subsystem'] == "CA" and\
+ config.str2bool(self.master_dict['pki_external_step_two']):
+ # External CA Step 2
+ data.stepTwo = "true"
+
+ def create_system_cert(self, tag):
+ cert = pki.system.SystemCertData()
+ cert.tag = self.master_dict["pki_%s_tag" % tag]
+ cert.keyAlgorithm = self.master_dict["pki_%s_key_algorithm" % tag]
+ cert.keySize = self.master_dict["pki_%s_key_size" % tag]
+ cert.keyType = self.master_dict["pki_%s_key_type" % tag]
+ cert.nickname = self.master_dict["pki_%s_nickname" % tag]
+ cert.subjectDN = self.master_dict["pki_%s_subject_dn" % tag]
+ cert.token = self.master_dict["pki_%s_token" % tag]
+ return cert
+
+ def retrieve_existing_server_cert(self, cfg_file):
+ cs_cfg = PKIConfigParser.read_simple_configuration_file(cfg_file)
+ cstype = cs_cfg.get('cs.type').lower()
+ cert = pki.system.SystemCertData()
+ cert.tag = self.master_dict["pki_ssl_server_tag"]
+ cert.keyAlgorithm = self.master_dict["pki_ssl_server_key_algorithm"]
+ cert.keySize = self.master_dict["pki_ssl_server_key_size"]
+ cert.keyType = self.master_dict["pki_ssl_server_key_type"]
+ cert.nickname = cs_cfg.get(cstype + ".sslserver.nickname")
+ cert.cert = cs_cfg.get(cstype + ".sslserver.cert")
+ cert.request = cs_cfg.get(cstype + ".sslserver.certreq")
+ cert.subjectDN = self.master_dict["pki_ssl_server_subject_dn"]
+ cert.token = cs_cfg.get(cstype + ".sslserver.tokenname")
+ return cert
+
+class PKIDeployer:
+ """Holds the global dictionaries and the utility objects"""
+
+ def __init__(self, pki_master_dict, pki_slots_dict=None):
+ # Global dictionary variables
+ self.master_dict = pki_master_dict
+ self.slots = pki_slots_dict
+ self.manifest_db = []
+
+ # Utility objects
+ self.identity = Identity(self)
+ self.namespace = Namespace(self)
+ self.configuration_file = ConfigurationFile(self)
+ self.instance = Instance(self)
+ self.directory = Directory(self)
+ self.file = File(self)
+ self.symlink = Symlink(self)
+ self.war = War(self)
+ self.password = Password(self)
+ self.certutil = Certutil(self)
+ self.pk12util = PK12util(self)
+ self.kra_connector = KRAConnector(self)
+ self.security_domain = SecurityDomain(self)
+ self.systemd = Systemd(self)
+ self.config_client = ConfigClient(self)
+
+
diff --git a/base/server/python/pki/server/deployment/pkilogging.py b/base/server/python/pki/server/deployment/pkilogging.py
new file mode 100644
index 000000000..c91a7656f
--- /dev/null
+++ b/base/server/python/pki/server/deployment/pkilogging.py
@@ -0,0 +1,76 @@
+#!/usr/bin/python -t
+# Authors:
+# Matthew Harmsen <mharmsen@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright (C) 2012 Red Hat, Inc.
+# All rights reserved.
+#
+
+# System Imports
+import logging
+import os
+import pprint
+
+sensitive_parameters = []
+
+# Initialize 'pretty print' for objects
+pp = pprint.PrettyPrinter(indent=4)
+
+def log_format(given_dict):
+ new_dict = {}
+
+ # mask sensitive data
+ for key in given_dict:
+ if key in sensitive_parameters:
+ value = 'XXXXXXXX'
+ else:
+ value = given_dict[key]
+ new_dict[key] = value
+
+ return pp.pformat(new_dict)
+
+# PKI Deployment Logging Functions
+def enable_pki_logger(log_dir, log_name, log_level, console_log_level, name):
+ if not os.path.isdir(log_dir):
+ try:
+ os.makedirs(log_dir)
+ except OSError:
+ return OSError
+
+ # Configure logger
+ logger = logging.getLogger(name)
+ logger.setLevel(log_level)
+
+ # Configure console handler
+ console = logging.StreamHandler()
+ console.setLevel(console_log_level)
+ console_format = logging.Formatter('%(name)-12s: ' + \
+ '%(levelname)-8s ' + \
+ '%(indent)s%(message)s')
+ console.setFormatter(console_format)
+ logger.addHandler(console)
+
+ # Configure file handler
+ log_file = logging.FileHandler(log_dir + "/" + log_name, 'w')
+ log_file.setLevel(log_level)
+ file_format = logging.Formatter('%(asctime)s %(name)-12s: ' + \
+ '%(levelname)-8s ' + \
+ '%(indent)s%(message)s',
+ '%Y-%m-%d %H:%M:%S')
+ log_file.setFormatter(file_format)
+ logger.addHandler(log_file)
+
+ return logger
diff --git a/base/server/python/pki/server/deployment/pkimanifest.py b/base/server/python/pki/server/deployment/pkimanifest.py
new file mode 100644
index 000000000..dea2af275
--- /dev/null
+++ b/base/server/python/pki/server/deployment/pkimanifest.py
@@ -0,0 +1,104 @@
+#!/usr/bin/python -t
+# Authors:
+# Matthew Harmsen <mharmsen@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright (C) 2012 Red Hat, Inc.
+# All rights reserved.
+#
+
+# System Imports
+import csv
+
+# PKI Deployment Imports
+from . import pkiconfig as config
+from . import pkimessages as log
+
+
+# PKI Deployment Manifest Constants
+RECORD_TYPE_DIRECTORY = "directory"
+RECORD_TYPE_FILE = "file"
+RECORD_TYPE_SYMLINK = "symlink"
+
+
+# PKI Deployment Manifest Record Class
+class Record(object):
+ __slots__ = "name", \
+ "type", \
+ "user", \
+ "group", \
+ "uid", \
+ "gid", \
+ "permissions", \
+ "acls",
+
+ def __init__(self):
+ self.name = None
+ self.type = None
+ self.user = None
+ self.group = None
+ self.uid = None
+ self.gid = None
+ self.permissions = None
+ self.acls = None
+
+ def items(self):
+ "dict style items"
+ return [
+ (field_name, getattr(self, field_name))
+ for field_name in self.__slots__]
+
+ def __iter__(self):
+ "iterate over fields tuple/list style"
+ for field_name in self.__slots__:
+ yield getattr(self, field_name)
+
+ def __getitem__(self, index):
+ "tuple/list style getitem"
+ return getattr(self, self.__slots__[index])
+
+
+# PKI Deployment Manifest File Class
+class File:
+
+ def __init__(self, database):
+ self.filename = None
+ self.database = database
+
+ def register(self, name):
+ self.filename = name
+
+ def write(self):
+ try:
+ with open(self.filename, "wt") as fd:
+ c = csv.writer(fd)
+ for record in self.database:
+ c.writerow(tuple(record))
+ except IOError as exc:
+ config.pki_log.error(log.PKI_IOERROR_1, exc,
+ extra=config.PKI_INDENTATION_LEVEL_1)
+ raise
+
+ def read(self):
+ try:
+ with open(self.filename, "rt") as fd:
+ cr = csv.reader(fd)
+ for row in cr:
+ print tuple(row)
+ except IOError as exc:
+ config.pki_log.error(log.PKI_IOERROR_1, exc,
+ extra=config.PKI_INDENTATION_LEVEL_1)
+ raise
+
diff --git a/base/server/python/pki/server/deployment/pkimessages.py b/base/server/python/pki/server/deployment/pkimessages.py
new file mode 100644
index 000000000..2e1ecba45
--- /dev/null
+++ b/base/server/python/pki/server/deployment/pkimessages.py
@@ -0,0 +1,359 @@
+#!/usr/bin/python -t
+# Authors:
+# Matthew Harmsen <mharmsen@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright (C) 2012 Red Hat, Inc.
+# All rights reserved.
+#
+
+# PKI Deployment Engine Messages
+PKI_DICTIONARY_DEFAULT = "\n"\
+"=====================================================\n"\
+" DISPLAY CONTENTS OF PKI DEFAULT DICTIONARY\n"\
+"====================================================="
+PKI_DICTIONARY_MASTER = "\n"\
+"=====================================================\n"\
+" DISPLAY CONTENTS OF PKI MASTER DICTIONARY\n"\
+"====================================================="
+PKI_DICTIONARY_SLOTS = "\n"\
+"=====================================================\n"\
+" DISPLAY CONTENTS OF PKI SLOTS DICTIONARY\n"\
+"====================================================="
+PKI_DICTIONARY_SUBSYSTEM = "\n"\
+"=====================================================\n"\
+" DISPLAY CONTENTS OF PKI SUBSYSTEM DICTIONARY\n"\
+"====================================================="
+PKI_DICTIONARY_WEB_SERVER = "\n"\
+"=====================================================\n"\
+" DISPLAY CONTENTS OF PKI WEB SERVER DICTIONARY\n"\
+"====================================================="
+# NEVER print out 'sensitive' data dictionary!!!
+
+
+# PKI Deployment Log Messages
+PKI_VERBOSITY = \
+"VERBOSITY FLAGS CONSOLE MESSAGE LEVEL LOG MESSAGE LEVEL\n"\
+"=======================================================================\n"\
+" NONE error|warning error|warning|info|debug\n"\
+" -v error|warning|info error|warning|info|debug\n"\
+" -vv error|warning|info|debug error|warning|info|debug\n"\
+" "
+
+
+# PKI Deployment Error Messages
+PKI_BADZIPFILE_ERROR_1 = "zipfile.BadZipFile: %s!"
+PKI_CONFIGURATION_RESTART_1 = " After configuration, the server can be "\
+ "operated by the command:\n %s"
+PKI_CONFIGURATION_URL_1 = " Please start the configuration by accessing:\n %s"
+PKI_CONFIGURATION_WIZARD_RESTART_1 = "After configuration, the server can be "\
+ "operated by the command:\n%s"
+PKI_CONFIGURATION_WIZARD_URL_1 = "Configuration Wizard listening on\n%s"
+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 "\
+ "directory!"
+PKI_DIRECTORY_MISSING_OR_NOT_A_DIRECTORY_1 = "Directory '%s' is either "\
+ "missing or is NOT a directory!"
+PKI_DNS_DOMAIN_NOT_SET = "A valid DNS domain name MUST be established "\
+ "to use PKI services!"
+PKI_FILE_ALREADY_EXISTS_1 = "File '%s' already exists!"
+PKI_FILE_ALREADY_EXISTS_NOT_A_FILE_1 = "File '%s' already "\
+ "exists BUT it is NOT a "\
+ "file!"
+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', "\
+ "and/or '%s' do NOT exist!"
+PKI_SUBSYSTEM_NOT_INSTALLED_1 = "Package pki-%s is NOT installed!"
+PKI_SUBSYSTEM_ALREADY_EXISTS_2 = "PKI subsystem '%s' for instance '%s' "\
+ "already exists!"
+PKI_SUBSYSTEM_DOES_NOT_EXIST_2 = "PKI subsystem '%s' for instance '%s' "\
+ "does NOT exist!"
+
+PKI_IOERROR_1 = "IOError: %s!"
+PKI_KEYERROR_1 = "KeyError: %s!"
+PKI_LARGEZIPFILE_ERROR_1 = "zipfile.LargeZipFile: %s!"
+PKI_MANIFEST_MESSAGE_1 = "generating manifest file called '%s'"
+PKI_OSERROR_1 = "OSError: %s!"
+PKI_SHUTIL_ERROR_1 = "shutil.Error: %s!"
+PKI_SUBPROCESS_ERROR_1 = "subprocess.CalledProcessError: %s!"
+PKI_SYMLINK_ALREADY_EXISTS_1 = "Symlink '%s' already exists!"
+PKI_SYMLINK_ALREADY_EXISTS_NOT_A_SYMLINK_1 = "Symlink '%s' already "\
+ "exists BUT it is NOT a "\
+ "symlink!"
+PKI_SYMLINK_MISSING_OR_NOT_A_SYMLINK_1 = "Symlink '%s' is either missing "\
+ "or is NOT a symbolic link!"
+PKI_UNABLE_TO_PARSE_1 = "'Could not parse: '%s'"
+PKI_UNABLE_TO_CREATE_LOG_DIRECTORY_1 = "Could not create log directory '%s'!"
+
+
+# PKI Deployment 'pkispawn' and 'pkidestroy' Messages
+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 <instance>' parameter, and the values that reside\n"\
+" in deployment configuration 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 <prefix>' is defined, this value WILL be\n"\
+" prepended to the default PKI instance path which is placed in front\n"\
+" of the specified '-i <instance>' parameter.\n\n" + \
+PKI_VERBOSITY
+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"\
+" Finally, if an optional '-p <prefix>' is defined, this value WILL NOT\n"\
+" be prepended in front of the mandatory '-f <configuration_file>'.\n\n" + \
+PKI_VERBOSITY
+
+
+# PKI Deployment "Helper" Messages
+PKIHELPER_APACHE_INSTANCE_SUBSYSTEMS_2 = "instance '%s' contains '%d' "\
+ "Apache PKI subsystems"
+PKIHELPER_APACHE_INSTANCES_2 = "PKI Apache registry '%s' contains '%d' "\
+ "Apache PKI instances"
+PKIHELPER_APPLY_SLOT_SUBSTITUTION_1 = "applying in-place "\
+ "slot substitutions on '%s'"
+PKIHELPER_CERTUTIL_GENERATE_CSR_1 = "executing '%s'"
+PKIHELPER_CERTUTIL_MISSING_INPUT_FILE = "certutil: Missing "\
+ "'-i input-file' option!"
+PKIHELPER_CERTUTIL_MISSING_ISSUER_NAME = "certutil: Missing "\
+ "'-c issuer-name' option!"
+PKIHELPER_CERTUTIL_MISSING_NICKNAME = "certutil: Missing "\
+ "'-n nickname' option!"
+PKIHELPER_CERTUTIL_MISSING_NOISE_FILE = "certutil: Missing "\
+ "'-z noise-file' option!"
+PKIHELPER_CERTUTIL_MISSING_PASSWORD_FILE = "certutil: Missing "\
+ "'-f password-file' option!"
+PKIHELPER_CERTUTIL_MISSING_PATH = "certutil: Missing '-d path' option!"
+PKIHELPER_CERTUTIL_MISSING_SERIAL_NUMBER = "certutil: Missing "\
+ "'-m serial-number' option!"
+PKIHELPER_CERTUTIL_MISSING_SUBJECT = "certutil: Missing '-s subject' option!"
+PKIHELPER_CERTUTIL_MISSING_TOKEN = "certutil: Missing '-h token' option!"
+PKIHELPER_CERTUTIL_MISSING_TRUSTARGS = "certutil: Missing "\
+ "'-t trustargs' option!"
+PKIHELPER_CERTUTIL_MISSING_VALIDITY_PERIOD = "certutil: Missing "\
+ "'-v months-valid' option!"
+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"
+PKIHELPER_CP_RP_2 = "cp -rp %s %s"
+PKIHELPER_CREATE_SECURITY_DATABASES_1 = "executing '%s'"
+PKIHELPER_DANGLING_SYMLINK_2 = "Dangling symlink '%s'-->'%s'"
+PKIHELPER_DICTIONARY_MASTER_MISSING_KEY_1 = "KeyError: Master dictionary "\
+ "is missing the key called '%s'!"
+PKIHELPER_DIRECTORY_IS_EMPTY_1 = "directory '%s' is empty"
+PKIHELPER_DIRECTORY_IS_NOT_EMPTY_1 = "directory '%s' is NOT empty"
+PKIHELPER_GID_2 = "GID of '%s' is %s"
+PKIHELPER_GROUP_1 = "retrieving GID for '%s' . . ."
+PKIHELPER_GROUP_ADD_2 = "adding GID '%s' for group '%s' . . ."
+PKIHELPER_GROUP_ADD_DEFAULT_2 = "adding default GID '%s' for group '%s' . . ."
+PKIHELPER_GROUP_ADD_GID_KEYERROR_1 = "KeyError: pki_gid %s"
+PKIHELPER_GROUP_ADD_KEYERROR_1 = "KeyError: pki_group %s"
+PKIHELPER_INVALID_SELINUX_CONTEXT_FOR_PORT = "port %s has invalid selinux "\
+ "context %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"
+PKIHELPER_JAR_XF_C_2 = "jar -xf %s -C %s"
+PKIHELPER_KRACONNECTOR_UPDATE_CONTACT = \
+ "contacting the CA to update the KRA connector"
+PKIHELPER_KRACONNECTOR_UPDATE_FAILURE = "Failed to update KRA connector on CA"
+PKIHELPER_KRACONNECTOR_UPDATE_FAILURE_2 = "Failed to update KRA connector for %s:%s"
+PKIHELPER_LINK_S_2 = "ln -s %s %s"
+PKIHELPER_MKDIR_1 = "mkdir -p %s"
+PKIHELPER_MODIFY_DIR_1 = "modifying '%s'"
+PKIHELPER_MODIFY_FILE_1 = "modifying '%s'"
+PKIHELPER_MODIFY_SYMLINK_1 = "modifying '%s'"
+PKIHELPER_MUTUALLY_EXCLUSIVE_CLONE_EXTERNAL_CA = "cloned CAs and external "\
+ "CAs MUST be MUTUALLY "\
+ "EXCLUSIVE in '%s'"
+PKIHELPER_MUTUALLY_EXCLUSIVE_CLONE_EXTERNAL_SUB_CA = "cloned CAs, external "\
+ "CAs, and subordinate CAs"\
+ "MUST ALL be MUTUALLY "\
+ "EXCLUSIVE in '%s'"
+PKIHELPER_MUTUALLY_EXCLUSIVE_CLONE_SUB_CA = "cloned CAs and subordinate "\
+ "CAs MUST be MUTUALLY "\
+ "EXCLUSIVE in '%s'"
+PKIHELPER_MUTUALLY_EXCLUSIVE_EXTERNAL_SUB_CA = "external CAs and subordinate "\
+ "CAs MUST be MUTUALLY "\
+ "EXCLUSIVE in '%s'"
+PKIHELPER_NAMESPACE_COLLISION_2 = "PKI instance '%s' would produce a "\
+ "namespace collision with '%s'!"
+PKIHELPER_NAMESPACE_RESERVED_NAME_2 = "PKI instance '%s' is already a "\
+ "reserved name under '%s'!"
+PKIHELPER_NOISE_FILE_2 = "generating noise file called '%s' and "\
+ "filling it with '%d' random bytes"
+PKIHELPER_PASSWORD_CONF_1 = "generating '%s'"
+PKIHELPER_PASSWORD_NOT_FOUND_1 = "no password found for '%s'!"
+PKIHELPER_PK12UTIL_MISSING_DBPWFILE = "pk12util missing "\
+ "-k db-password-file option!"
+PKIHELPER_PK12UTIL_MISSING_NICKNAME = "pk12util missing "\
+ "-n nickname option!"
+PKIHELPER_PK12UTIL_MISSING_OUTFILE = "pk12util missing "\
+ "-o output-file option!"
+PKIHELPER_PK12UTIL_MISSING_PWFILE = "pk12util missing "\
+ "-w pw-file option!"
+
+PKIHELPER_PKI_INSTANCE_SUBSYSTEMS_2 = "instance '%s' contains '%d' "\
+ "PKI subsystems"
+PKIHELPER_REMOVE_FILTER_SECTION_1 = "removing filter section from '%s'"
+PKIHELPER_RM_F_1 = "rm -f %s"
+PKIHELPER_RM_RF_1 = "rm -rf %s"
+PKIHELPER_RMDIR_1 = "rmdir %s"
+PKIHELPER_SECURITY_DOMAIN_CONTACT_1 = \
+ "contacting the security domain master to update security domain '%s'"
+PKIHELPER_SECURITY_DOMAIN_GET_TOKEN_FAILURE_2 = \
+ "Failed to get installation token from security domain '%s:%s'"
+PKIHELPER_SECURITY_DOMAIN_UNDEFINED = \
+ "No security domain defined.\n"\
+ "If this is an unconfigured instance, then that is OK.\n"\
+ "Otherwise, manually delete the entry from the security domain master."
+PKIHELPER_SECURITY_DOMAIN_UNREACHABLE_1 = \
+ "security domain '%s' may be offline or unreachable!"
+PKIHELPER_SECURITY_DOMAIN_UNREGISTERED_2 = \
+ "this '%s' entry may not be registered with security domain '%s'!"
+PKIHELPER_SECURITY_DOMAIN_UPDATE_FAILURE_2 = \
+ "this '%s' entry will NOT be deleted from security domain '%s'!"
+PKIHELPER_SECURITY_DOMAIN_UPDATE_FAILURE_3 = \
+ "updateDomainXML FAILED to delete this '%s' entry from "\
+ "security domain '%s': '%s'"
+PKIHELPER_SECURITY_DOMAIN_UPDATE_SUCCESS_2 = \
+ "updateDomainXML SUCCESSFULLY deleted this '%s' entry from "\
+ "security domain '%s'"
+PKIHELPER_SELINUX_DISABLED = "Selinux is disabled. Not checking port contexts"
+PKIHELPER_SET_MODE_1 = "setting ownerships, permissions, and acls on '%s'"
+PKIHELPER_SLOT_SUBSTITUTION_2 = "slot substitution: '%s' ==> '%s'"
+PKIHELPER_SSLGET_OUTPUT_1 = "\n"\
+ "Dump of 'sslget' output:\n"\
+ "=====================================================\n"\
+ "%s\n"\
+ "====================================================="
+PKIHELPER_SYSTEMD_COMMAND_1 = "executing '%s'"
+PKIHELPER_TOMCAT_INSTANCE_SUBSYSTEMS_2 = "instance '%s' contains '%d' "\
+ "Tomcat PKI subsystems"
+PKIHELPER_TOMCAT_INSTANCES_2 = "PKI Tomcat registry '%s' contains '%d' "\
+ "Tomcat PKI instances"
+PKIHELPER_TOUCH_1 = "touch %s"
+PKIHELPER_UID_2 = "UID of '%s' is %s"
+PKIHELPER_UNDEFINED_CA_HOST_PORT = "CA Host or Port is undefined"
+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_UNDEFINED_SUBSYSTEM_NICKNAME = "subsystem nickname not defined"
+PKIHELPER_UNDEFINED_TOKEN_PASSWD_1 = "Password for token '%s' not defined"
+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' . . ."
+PKIHELPER_USER_ADD_KEYERROR_1 = "KeyError: pki_user %s"
+PKIHELPER_USER_ADD_UID_KEYERROR_1 = "KeyError: pki_uid %s"
+
+PKI_CONFIG_ADMIN_CERT_SAVE = "saving Admin Certificate to file:"
+PKI_CONFIG_ADMIN_CERT_ATOB = "converting Admin Certificate to binary:"
+PKI_CONFIG_CDATA_TAG = "tag:"
+PKI_CONFIG_CDATA_CERT = "cert:"
+PKI_CONFIG_CDATA_REQUEST = "request:"
+PKI_CONFIG_CONFIGURING_PKI_DATA = "configuring PKI configuration data."
+PKI_CONFIG_CONSTRUCTING_PKI_DATA = "constructing PKI configuration data."
+PKI_CONFIG_PKCS10_SUPPORT_ONLY = "only the 'pkcs10' certificate request type "\
+ "is currently supported"
+PKI_CONFIG_EXTERNAL_CA_LOAD = "loading external CA signing certificate "\
+ "from file:"
+PKI_CONFIG_EXTERNAL_CA_CHAIN_LOAD = "loading external CA signing certificate "\
+ "chain from file:"
+PKI_CONFIG_EXTERNAL_CSR_SAVE = "saving CA Signing CSR to file:"
+PKI_CONFIG_JAVA_CONFIGURATION_EXCEPTION = \
+ "Exception from Java Configuration Servlet:"
+PKI_CONFIG_RESPONSE_ADMIN_CERT = "adminCert:"
+PKI_CONFIG_RESPONSE_STATUS = "status:"
+PKI_CONFIG_NOT_YET_IMPLEMENTED_1 = " %s NOT YET IMPLEMENTED"
+PKI_CHECK_STATUS_MESSAGE = " To check the status of the subsystem: \n"\
+ " systemctl status pki-tomcatd\@%s.service"
+PKI_ACCESS_URL = " The URL for the subsystem is: \n"\
+ " https://%s:%s/%s"
+PKI_INSTANCE_RESTART_MESSAGE = " To restart the subsystem: \n"\
+ " systemctl restart pki-tomcatd\@%s.service"
+
+
+PKI_SPAWN_INFORMATION_HEADER = "\n ==========================================================================\n"\
+ " INSTALLATION SUMMARY\n"\
+ " ==========================================================================\n"
+
+PKI_SPAWN_INFORMATION_FOOTER = "\n ==========================================================================\n"
+
+
+# PKI Deployment "Scriptlet" Messages
+ADMIN_DOMAIN_DESTROY_1 = "depopulating '%s'"
+ADMIN_DOMAIN_SPAWN_1 = "populating '%s'"
+CONFIGURATION_DESTROY_1 = "unconfiguring '%s'"
+CONFIGURATION_SPAWN_1 = "configuring '%s'"
+FINALIZATION_DESTROY_1 = "finalizing '%s'"
+FINALIZATION_SPAWN_1 = "finalizing '%s'"
+INITIALIZATION_DESTROY_1 = "initializing '%s'"
+INITIALIZATION_SPAWN_1 = "initializing '%s'"
+INSTANCE_DESTROY_1 = "depopulating '%s'"
+INSTANCE_SPAWN_1 = "populating '%s'"
+RESIDUAL_DESTROY_1 = "depopulating '%s'"
+RESIDUAL_SPAWN_1 = "populating '%s'"
+SECURITY_DATABASES_DESTROY_1 = "removing '%s'"
+SECURITY_DATABASES_SPAWN_1 = "generating '%s'"
+SELINUX_DESTROY_1 = "depopulating '%s'"
+SELINUX_SPAWN_1 = "populating '%s'"
+SELINUX_DISABLED_DESTROY_1 = "selinux disabled. skipping unlabelling '%s'"
+SELINUX_DISABLED_SPAWN_1 = "selinux disabled. skipping labelling '%s'"
+SLOT_ASSIGNMENT_DESTROY_1 = "unassigning slots for '%s'"
+SLOT_ASSIGNMENT_SPAWN_1 = "assigning slots for '%s'"
+SUBSYSTEM_DESTROY_1 = "depopulating '%s'"
+SUBSYSTEM_SPAWN_1 = "populating '%s'"
+WEBAPP_DEPLOYMENT_DESTROY_1 = "removing '%s'"
+WEBAPP_DEPLOYMENT_SPAWN_1 = "deploying '%s'"
+SKIP_ADMIN_DOMAIN_SPAWN_1 = "skip populating '%s'"
+SKIP_CONFIGURATION_SPAWN_1 = "skip configuring '%s'"
+SKIP_FINALIZATION_SPAWN_1 = "skip finalizing '%s'"
+SKIP_INITIALIZATION_SPAWN_1 = "skip initializing '%s'"
+SKIP_INSTANCE_SPAWN_1 = "skip populating '%s'"
+SKIP_RESIDUAL_SPAWN_1 = "skip populating '%s'"
+SKIP_SECURITY_DATABASES_SPAWN_1 = "skip generating '%s'"
+SKIP_SELINUX_SPAWN_1 = "skip populating '%s'"
+SKIP_SLOT_ASSIGNMENT_SPAWN_1 = "skip assigning slots for '%s'"
+SKIP_SUBSYSTEM_SPAWN_1 = "skip populating '%s'"
+SKIP_WEBAPP_DEPLOYMENT_SPAWN_1 = "skip deploying '%s'"
diff --git a/base/server/python/pki/server/deployment/pkiparser.py b/base/server/python/pki/server/deployment/pkiparser.py
new file mode 100644
index 000000000..8dbed8deb
--- /dev/null
+++ b/base/server/python/pki/server/deployment/pkiparser.py
@@ -0,0 +1,1080 @@
+#!/usr/bin/python -t
+# Authors:
+# Matthew Harmsen <mharmsen@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright (C) 2012 Red Hat, Inc.
+# All rights reserved.
+#
+
+# System Imports
+import ConfigParser
+import argparse
+import getpass
+import ldap
+import logging
+import os
+import random
+import requests
+import string
+import subprocess
+
+# PKI Imports
+import pki
+import pki.upgrade
+import pki.account
+import pki.client
+import pki.system
+from . import pkiconfig as config
+from . import pkimessages as log
+from . import pkilogging
+
+
+class PKIConfigParser:
+
+ COMMENT_CHAR = '#'
+ OPTION_CHAR = '='
+
+ def __init__(self, description, epilog):
+ self.pki_config = None
+
+ #Read and process command-line options
+ self.arg_parser = argparse.ArgumentParser(
+ description=description,
+ add_help=False,
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ epilog=epilog)
+
+ # Establish 'Mandatory' command-line options
+ self.mandatory = self.arg_parser.add_argument_group('mandatory arguments')
+
+ # Establish 'Optional' command-line options
+ self.optional = self.arg_parser.add_argument_group('optional arguments')
+ self.optional.add_argument('-s',
+ dest='pki_subsystem', action='store',
+ nargs=1, choices=config.PKI_SUBSYSTEMS,
+ metavar='<subsystem>',
+ help='where <subsystem> is '
+ 'CA, KRA, OCSP, RA, TKS, or TPS')
+ self.optional.add_argument('-h', '--help',
+ dest='help', action='help',
+ help='show this help message and exit')
+ self.optional.add_argument('-v',
+ dest='pki_verbosity', action='count',
+ help='display verbose information (details below)')
+
+ # Establish 'Test' command-line options
+ test = self.arg_parser.add_argument_group('test arguments')
+ test.add_argument('-p',
+ dest='pki_root_prefix', action='store',
+ nargs=1, metavar='<prefix>',
+ help='directory prefix to specify local directory '
+ '[TEST ONLY]')
+ self.indent = 0
+ self.ds_connection = None
+ self.sd_connection = None
+
+ # Master and Slot dictionaries
+ self.pki_master_dict = dict()
+ self.pki_slots_dict = dict()
+
+ # PKI Deployment Helper Functions
+ def process_command_line_arguments(self):
+
+ # Parse command-line options
+ args = self.arg_parser.parse_args()
+
+ # Process 'Mandatory' command-line options
+
+ # Process 'Optional' command-line options
+ # '-v'
+ if args.pki_verbosity == 1:
+ config.pki_console_log_level = logging.INFO
+ elif args.pki_verbosity >= 2:
+ config.pki_console_log_level = logging.DEBUG
+ else:
+ # Set default log levels
+ config.pki_console_log_level = logging.WARNING
+
+ # Debug log is always at DEBUG level
+ config.pki_log_level = logging.DEBUG
+
+ # Process 'Test' command-line options
+ # '-p'
+ if args.pki_root_prefix is None:
+ config.pki_root_prefix = ""
+ else:
+ config.pki_root_prefix = str(args.pki_root_prefix).strip('[\']')
+
+ return args
+
+
+ def validate(self):
+
+ # Validate command-line options
+ if len(config.pki_root_prefix) > 0:
+ if 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
+ self.arg_parser.print_help()
+ self.arg_parser.exit(-1)
+
+ # always default that configuration file exists
+ if not os.path.exists(config.default_deployment_cfg) or\
+ not os.path.isfile(config.default_deployment_cfg):
+ print "ERROR: " + \
+ log.PKI_FILE_MISSING_OR_NOT_A_FILE_1 % \
+ config.default_deployment_cfg
+ print
+ self.arg_parser.print_help()
+ self.arg_parser.exit(-1)
+
+ if config.user_deployment_cfg:
+ # verify user configuration file exists
+ if not os.path.exists(config.user_deployment_cfg) or\
+ not os.path.isfile(config.user_deployment_cfg):
+ print "ERROR: " + \
+ log.PKI_FILE_MISSING_OR_NOT_A_FILE_1 % \
+ config.user_deployment_cfg
+ print
+ self.arg_parser.print_help()
+ self.arg_parser.exit(-1)
+
+
+ def init_config(self):
+
+ # RESTEasy
+ resteasy_lib = subprocess.check_output(\
+ 'source /etc/pki/pki.conf && echo $RESTEASY_LIB',
+ shell=True).strip()
+
+ # JNI jar location
+ jni_jar_dir = subprocess.check_output(\
+ 'source /usr/share/pki/etc/pki.conf && echo $JNI_JAR_DIR',
+ shell=True).strip()
+
+ if config.pki_subsystem in config.PKI_TOMCAT_SUBSYSTEMS:
+ default_instance_name = 'pki-tomcat'
+ default_http_port = '8080'
+ default_https_port = '8443'
+ else:
+ default_instance_name = 'pki-apache'
+ default_http_port = '80'
+ default_https_port = '443'
+
+ application_version = str(pki.upgrade.Version(pki.implementation_version()))
+
+ self.pki_config = ConfigParser.SafeConfigParser({
+ 'application_version': application_version,
+ 'pki_instance_name': default_instance_name,
+ 'pki_http_port': default_http_port,
+ 'pki_https_port': default_https_port,
+ 'pki_dns_domainname': config.pki_dns_domainname,
+ 'pki_subsystem': config.pki_subsystem,
+ 'pki_subsystem_type': config.pki_subsystem.lower(),
+ 'pki_root_prefix' : config.pki_root_prefix,
+ 'resteasy_lib': resteasy_lib,
+ 'jni_jar_dir': jni_jar_dir,
+ 'home_dir': os.path.expanduser("~"),
+ 'pki_hostname': config.pki_hostname})
+
+ # Make keys case-sensitive!
+ self.pki_config.optionxform = str
+
+ config.user_config = ConfigParser.SafeConfigParser()
+ config.user_config.optionxform = str
+
+ with open(config.default_deployment_cfg) as f:
+ self.pki_config.readfp(f)
+
+ self.flatten_master_dict()
+
+
+ # The following code is based heavily upon
+ # "http://www.decalage.info/en/python/configparser"
+ @staticmethod
+ def read_simple_configuration_file(filename):
+ values = {}
+ with open(filename) as f:
+ for line in f:
+ # First, remove comments:
+ if PKIConfigParser.COMMENT_CHAR in line:
+ # split on comment char, keep only the part before
+ line, _ = line.split(PKIConfigParser.COMMENT_CHAR, 1)
+ # Second, find lines with an name=value:
+ if PKIConfigParser.OPTION_CHAR in line:
+ # split on name char:
+ name, value = line.split(PKIConfigParser.OPTION_CHAR, 1)
+ # strip spaces:
+ name = name.strip()
+ value = value.strip()
+ # store in dictionary:
+ values[name] = value
+ return values
+
+
+ def set_property(self, section, key, value):
+ if section != "DEFAULT" and not self.pki_config.has_section(section):
+ self.pki_config.add_section(section)
+ self.pki_config.set(section, key, value)
+ self.flatten_master_dict()
+
+ if section != "DEFAULT" and not config.user_config.has_section(section):
+ config.user_config.add_section(section)
+ config.user_config.set(section, key, value)
+
+
+ def print_text(self, message):
+ print ' ' * self.indent + message
+
+ def read_text(self, message,
+ section=None, key=None, default=None,
+ options=None, sign=':', allowEmpty=True, caseSensitive=True):
+
+ if default is None and key is not None:
+ default = self.pki_master_dict[key]
+ if default:
+ message = message + ' [' + default + ']'
+ message = ' ' * self.indent + message + sign + ' '
+
+ done = False
+ while not done:
+ value = raw_input(message)
+ value = value.strip()
+
+ if len(value) == 0: # empty value
+ if allowEmpty:
+ value = default
+ done = True
+ break
+
+ else: # non-empty value
+ if options is not None:
+ for v in options:
+ if caseSensitive:
+ if v == value:
+ done = True
+ break
+ else:
+ if v.lower() == value.lower():
+ done = True
+ break
+ else:
+ done = True
+ break
+
+ value = value.replace("%", "%%")
+ if section:
+ self.set_property(section, key, value)
+
+ return value
+
+
+ def read_password(self, message, section=None, key=None,
+ verifyMessage=None):
+ message = ' ' * self.indent + message + ': '
+ if verifyMessage is not None:
+ verifyMessage = ' ' * self.indent + verifyMessage + ': '
+
+ while True:
+ password = ''
+ while len(password) == 0:
+ password = getpass.getpass(prompt=message)
+
+ if verifyMessage is not None:
+ verification = ''
+ while len(verification) == 0:
+ verification = getpass.getpass(prompt=verifyMessage)
+
+ if password != verification:
+ self.print_text('Passwords do not match.')
+ continue
+
+ break
+
+ password = password.replace("%", "%%")
+ if section:
+ self.set_property(section, key, password)
+
+ return password
+
+ def read_pki_configuration_file(self):
+ "Read configuration file sections into dictionaries"
+ rv = 0
+ try:
+ if config.user_deployment_cfg:
+ print 'Loading deployment configuration from ' + config.user_deployment_cfg + '.'
+ self.pki_config.read([config.user_deployment_cfg])
+ config.user_config.read([config.user_deployment_cfg])
+
+ except ConfigParser.ParsingError, err:
+ print err
+ rv = err
+ return rv
+
+
+ def flatten_master_dict(self):
+ self.pki_master_dict.update(__name__="PKI Master Dictionary")
+
+ default_dict = dict(self.pki_config.items('DEFAULT'))
+ default_dict[0] = None
+ self.pki_master_dict.update(default_dict)
+
+ web_server_dict = None
+ if config.pki_subsystem in config.PKI_TOMCAT_SUBSYSTEMS:
+ if self.pki_config.has_section('Tomcat'):
+ web_server_dict = dict(self.pki_config.items('Tomcat'))
+ else:
+ if self.pki_config.has_section('Apache'):
+ web_server_dict = dict(self.pki_config.items('Apache'))
+
+ if web_server_dict:
+ web_server_dict[0] = None
+ self.pki_master_dict.update(web_server_dict)
+
+ if self.pki_config.has_section(config.pki_subsystem):
+ subsystem_dict = dict(self.pki_config.items(config.pki_subsystem))
+ subsystem_dict[0] = None
+ self.pki_master_dict.update(subsystem_dict)
+
+
+ def ds_connect(self):
+
+ hostname = self.pki_master_dict['pki_ds_hostname']
+
+ if config.str2bool(self.pki_master_dict['pki_ds_secure_connection']):
+ protocol = 'ldaps'
+ port = self.pki_master_dict['pki_ds_ldaps_port']
+ else:
+ protocol = 'ldap'
+ port = self.pki_master_dict['pki_ds_ldap_port']
+
+ self.ds_connection = ldap.initialize(protocol + '://' + hostname + ':' + port)
+ self.ds_connection.search_s('', ldap.SCOPE_BASE)
+
+ def ds_bind(self):
+ self.ds_connection.simple_bind_s(
+ self.pki_master_dict['pki_ds_bind_dn'],
+ self.pki_master_dict['pki_ds_password'])
+
+ def ds_base_dn_exists(self):
+ try:
+ results = self.ds_connection.search_s(
+ self.pki_master_dict['pki_ds_base_dn'],
+ ldap.SCOPE_BASE)
+
+ if results is None or len(results) == 0:
+ return False
+
+ return True
+
+ except ldap.NO_SUCH_OBJECT:
+ return False
+
+ def ds_close(self):
+ self.ds_connection.unbind_s()
+
+ def sd_connect(self):
+ self.sd_connection = pki.client.PKIConnection(
+ protocol='https',
+ hostname=self.pki_master_dict['pki_security_domain_hostname'],
+ port=self.pki_master_dict['pki_security_domain_https_port'],
+ subsystem='ca')
+
+ def sd_get_info(self):
+ sd = pki.system.SecurityDomainClient(self.sd_connection)
+ try:
+ info = sd.getSecurityDomainInfo()
+ except requests.exceptions.HTTPError as e:
+ config.pki_log.info(
+ "unable to access security domain through REST interface. " + \
+ "Trying old interface. " + str(e),
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ info = sd.getOldSecurityDomainInfo()
+ return info
+
+ def sd_authenticate(self):
+ self.sd_connection.authenticate(
+ self.pki_master_dict['pki_security_domain_user'],
+ self.pki_master_dict['pki_security_domain_password'])
+
+ account = pki.account.AccountClient(self.sd_connection)
+ try:
+ account.login()
+ account.logout()
+ except requests.exceptions.HTTPError as e:
+ code = e.response.status_code
+ if code == 404 or code == 501:
+ config.pki_log.warning(
+ "unable to validate security domain user/password " + \
+ "through REST interface. Interface not available",
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ else:
+ raise
+
+ def compose_pki_master_dictionary(self):
+ "Create a single master PKI dictionary from the sectional dictionaries"
+ try:
+ # 'pkispawn'/'pkidestroy' name/value pairs
+ self.pki_master_dict['pki_deployment_executable'] = \
+ config.pki_deployment_executable
+ self.pki_master_dict['pki_install_time'] = config.pki_install_time
+ self.pki_master_dict['pki_timestamp'] = config.pki_timestamp
+ self.pki_master_dict['pki_certificate_timestamp'] = \
+ config.pki_certificate_timestamp
+ self.pki_master_dict['pki_architecture'] = config.pki_architecture
+ self.pki_master_dict['pki_default_deployment_cfg'] = config.default_deployment_cfg
+ self.pki_master_dict['pki_user_deployment_cfg'] = config.user_deployment_cfg
+ self.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
+ self.pki_master_dict['pki_pin'] = \
+ random.randint(pin_low, pin_high)
+ self.pki_master_dict['pki_client_pin'] = \
+ random.randint(pin_low, pin_high)
+
+ self.flatten_master_dict()
+
+ pkilogging.sensitive_parameters = self.pki_master_dict['sensitive_parameters'].split()
+
+ # PKI Target (slot substitution) name/value pairs
+ self.pki_master_dict['pki_target_cs_cfg'] = \
+ os.path.join(
+ self.pki_master_dict['pki_subsystem_configuration_path'],
+ "CS.cfg")
+ self.pki_master_dict['pki_target_registry'] = \
+ os.path.join(self.pki_master_dict['pki_instance_registry_path'],
+ self.pki_master_dict['pki_instance_name'])
+ if self.pki_master_dict['pki_subsystem'] == "CA" and\
+ config.str2bool(self.pki_master_dict['pki_external_step_two']):
+ # Use the 'pki_one_time_pin' established during the setup of
+ # External CA Step 1
+ if os.path.exists(self.pki_master_dict['pki_target_cs_cfg'])\
+ and\
+ os.path.isfile(self.pki_master_dict['pki_target_cs_cfg']):
+ cs_cfg = self.read_simple_configuration_file(
+ self.pki_master_dict['pki_target_cs_cfg'])
+ self.pki_master_dict['pki_one_time_pin'] = \
+ cs_cfg.get('preop.pin')
+ else:
+ config.pki_log.error(log.PKI_FILE_MISSING_OR_NOT_A_FILE_1,
+ self.pki_master_dict['pki_target_cs_cfg'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception(log.PKI_FILE_MISSING_OR_NOT_A_FILE_1)
+ else:
+ # 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
+ self.pki_master_dict['pki_one_time_pin'] = \
+ ''.join(random.choice(string.ascii_letters + string.digits)\
+ for x in range(20))
+ if self.pki_master_dict['pki_subsystem'] in\
+ config.PKI_TOMCAT_SUBSYSTEMS:
+ self.pki_master_dict['pki_target_catalina_properties'] = \
+ os.path.join(
+ self.pki_master_dict['pki_instance_configuration_path'],
+ "catalina.properties")
+ self.pki_master_dict['pki_target_servercertnick_conf'] = \
+ os.path.join(
+ self.pki_master_dict['pki_instance_configuration_path'],
+ "serverCertNick.conf")
+ self.pki_master_dict['pki_target_server_xml'] = \
+ os.path.join(
+ self.pki_master_dict['pki_instance_configuration_path'],
+ "server.xml")
+ self.pki_master_dict['pki_target_context_xml'] = \
+ os.path.join(
+ self.pki_master_dict['pki_instance_configuration_path'],
+ "context.xml")
+ self.pki_master_dict['pki_target_tomcat_conf_instance_id'] = \
+ self.pki_master_dict['pki_root_prefix'] + \
+ "/etc/sysconfig/" + \
+ self.pki_master_dict['pki_instance_name']
+ self.pki_master_dict['pki_target_tomcat_conf'] = \
+ os.path.join(
+ self.pki_master_dict['pki_instance_configuration_path'],
+ "tomcat.conf")
+ # in-place slot substitution name/value pairs
+ self.pki_master_dict['pki_target_velocity_properties'] = \
+ os.path.join(
+ self.pki_master_dict['pki_tomcat_webapps_subsystem_path'],
+ "WEB-INF",
+ "velocity.properties")
+ self.pki_master_dict['pki_target_subsystem_web_xml'] = \
+ os.path.join(
+ self.pki_master_dict['pki_tomcat_webapps_subsystem_path'],
+ "WEB-INF",
+ "web.xml")
+ self.pki_master_dict['pki_target_subsystem_web_xml_orig'] = \
+ os.path.join(
+ self.pki_master_dict['pki_tomcat_webapps_subsystem_path'],
+ "WEB-INF",
+ "web.xml.orig")
+ # subystem-specific slot substitution name/value pairs
+ if self.pki_master_dict['pki_subsystem'] == "CA":
+ self.pki_master_dict['pki_target_flatfile_txt'] = \
+ os.path.join(self.pki_master_dict\
+ ['pki_subsystem_configuration_path'],
+ "flatfile.txt")
+ self.pki_master_dict['pki_target_proxy_conf'] = \
+ os.path.join(self.pki_master_dict\
+ ['pki_subsystem_configuration_path'],
+ "proxy.conf")
+ self.pki_master_dict['pki_target_registry_cfg'] = \
+ os.path.join(self.pki_master_dict\
+ ['pki_subsystem_configuration_path'],
+ "registry.cfg")
+ # '*.profile'
+ self.pki_master_dict['pki_target_admincert_profile'] = \
+ os.path.join(self.pki_master_dict\
+ ['pki_subsystem_configuration_path'],
+ "adminCert.profile")
+ self.pki_master_dict['pki_target_caauditsigningcert_profile']\
+ = os.path.join(self.pki_master_dict\
+ ['pki_subsystem_configuration_path'],
+ "caAuditSigningCert.profile")
+ self.pki_master_dict['pki_target_cacert_profile'] = \
+ os.path.join(self.pki_master_dict\
+ ['pki_subsystem_configuration_path'],
+ "caCert.profile")
+ self.pki_master_dict['pki_target_caocspcert_profile'] = \
+ os.path.join(self.pki_master_dict\
+ ['pki_subsystem_configuration_path'],
+ "caOCSPCert.profile")
+ self.pki_master_dict['pki_target_servercert_profile'] = \
+ os.path.join(self.pki_master_dict\
+ ['pki_subsystem_configuration_path'],
+ "serverCert.profile")
+ self.pki_master_dict['pki_target_subsystemcert_profile'] = \
+ os.path.join(self.pki_master_dict\
+ ['pki_subsystem_configuration_path'],
+ "subsystemCert.profile")
+ # in-place slot substitution name/value pairs
+ self.pki_master_dict['pki_target_profileselect_template'] = \
+ os.path.join(
+ self.pki_master_dict\
+ ['pki_tomcat_webapps_subsystem_path'],
+ "ee",
+ self.pki_master_dict['pki_subsystem'].lower(),
+ "ProfileSelect.template")
+ elif self.pki_master_dict['pki_subsystem'] == "KRA":
+ # '*.profile'
+ self.pki_master_dict['pki_target_servercert_profile'] = \
+ os.path.join(self.pki_master_dict\
+ ['pki_subsystem_configuration_path'],
+ "serverCert.profile")
+ self.pki_master_dict['pki_target_storagecert_profile'] = \
+ os.path.join(self.pki_master_dict\
+ ['pki_subsystem_configuration_path'],
+ "storageCert.profile")
+ self.pki_master_dict['pki_target_subsystemcert_profile'] = \
+ os.path.join(self.pki_master_dict\
+ ['pki_subsystem_configuration_path'],
+ "subsystemCert.profile")
+ self.pki_master_dict['pki_target_transportcert_profile'] = \
+ os.path.join(self.pki_master_dict\
+ ['pki_subsystem_configuration_path'],
+ "transportCert.profile")
+ # Slot assignment name/value pairs
+ # NOTE: Master key == Slots key; Master value ==> Slots value
+ self.pki_master_dict['PKI_INSTANCE_NAME_SLOT'] = \
+ self.pki_master_dict['pki_instance_name']
+ self.pki_master_dict['PKI_INSTANCE_INITSCRIPT_SLOT'] = \
+ os.path.join(self.pki_master_dict['pki_instance_path'],
+ self.pki_master_dict['pki_instance_name'])
+ self.pki_master_dict['PKI_REGISTRY_FILE_SLOT'] = \
+ os.path.join(self.pki_master_dict['pki_subsystem_registry_path'],
+ self.pki_master_dict['pki_instance_name'])
+ if self.pki_master_dict['pki_subsystem'] in\
+ config.PKI_APACHE_SUBSYSTEMS:
+ self.pki_master_dict['FORTITUDE_APACHE_SLOT'] = None
+ self.pki_master_dict['FORTITUDE_AUTH_MODULES_SLOT'] = None
+ self.pki_master_dict['FORTITUDE_DIR_SLOT'] = None
+ self.pki_master_dict['FORTITUDE_LIB_DIR_SLOT'] = None
+ self.pki_master_dict['FORTITUDE_MODULE_SLOT'] = None
+ self.pki_master_dict['FORTITUDE_NSS_MODULES_SLOT'] = None
+ self.pki_master_dict['HTTPD_CONF_SLOT'] = None
+ self.pki_master_dict['LIB_PREFIX_SLOT'] = None
+ self.pki_master_dict['NON_CLIENTAUTH_SECURE_PORT_SLOT'] = None
+ self.pki_master_dict['NSS_CONF_SLOT'] = None
+ self.pki_master_dict['OBJ_EXT_SLOT'] = None
+ self.pki_master_dict['PKI_LOCKDIR_SLOT'] = \
+ os.path.join("/var/lock/pki",
+ "apache")
+ self.pki_master_dict['PKI_PIDDIR_SLOT'] = \
+ os.path.join("/var/run/pki",
+ "apache")
+ self.pki_master_dict['PKI_WEB_SERVER_TYPE_SLOT'] = "apache"
+ self.pki_master_dict['PORT_SLOT'] = None
+ self.pki_master_dict['PROCESS_ID_SLOT'] = None
+ self.pki_master_dict['REQUIRE_CFG_PL_SLOT'] = None
+ self.pki_master_dict['SECURE_PORT_SLOT'] = None
+ self.pki_master_dict['SECURITY_LIBRARIES_SLOT'] = None
+ self.pki_master_dict['PKI_HOSTNAME_SLOT'] = None
+ self.pki_master_dict['SERVER_ROOT_SLOT'] = None
+ self.pki_master_dict['SYSTEM_LIBRARIES_SLOT'] = None
+ self.pki_master_dict['SYSTEM_USER_LIBRARIES_SLOT'] = None
+ self.pki_master_dict['TMP_DIR_SLOT'] = None
+ self.pki_master_dict['TPS_DIR_SLOT'] = None
+ elif self.pki_master_dict['pki_subsystem'] in\
+ config.PKI_TOMCAT_SUBSYSTEMS:
+ self.pki_master_dict['INSTALL_TIME_SLOT'] = \
+ self.pki_master_dict['pki_install_time']
+ self.pki_master_dict['PKI_ADMIN_SECURE_PORT_SLOT'] = \
+ self.pki_master_dict['pki_https_port']
+ self.pki_master_dict\
+ ['PKI_ADMIN_SECURE_PORT_CONNECTOR_NAME_SLOT'] = \
+ "Unused"
+ self.pki_master_dict\
+ ['PKI_ADMIN_SECURE_PORT_SERVER_COMMENT_SLOT'] = \
+ ""
+ self.pki_master_dict['PKI_AGENT_CLIENTAUTH_SLOT'] = \
+ "want"
+ self.pki_master_dict['PKI_AGENT_SECURE_PORT_SLOT'] = \
+ self.pki_master_dict['pki_https_port']
+ self.pki_master_dict['PKI_AJP_PORT_SLOT'] = \
+ self.pki_master_dict['pki_ajp_port']
+ self.pki_master_dict['PKI_AJP_REDIRECT_PORT_SLOT'] = \
+ self.pki_master_dict['pki_https_port']
+ self.pki_master_dict['PKI_CA_HOSTNAME_SLOT'] = \
+ self.pki_master_dict['pki_ca_hostname']
+ self.pki_master_dict['PKI_CA_PORT_SLOT'] = \
+ self.pki_master_dict['pki_ca_port']
+ self.pki_master_dict['PKI_CERT_DB_PASSWORD_SLOT'] = \
+ self.pki_master_dict['pki_pin']
+ self.pki_master_dict['PKI_CFG_PATH_NAME_SLOT'] = \
+ self.pki_master_dict['pki_target_cs_cfg']
+ self.pki_master_dict\
+ ['PKI_CLOSE_SEPARATE_PORTS_SERVER_COMMENT_SLOT'] = \
+ "-->"
+ self.pki_master_dict\
+ ['PKI_CLOSE_SEPARATE_PORTS_WEB_COMMENT_SLOT'] = \
+ "-->"
+ self.pki_master_dict['PKI_EE_SECURE_CLIENT_AUTH_PORT_SLOT'] = \
+ self.pki_master_dict['pki_https_port']
+ self.pki_master_dict\
+ ['PKI_EE_SECURE_CLIENT_AUTH_PORT_CONNECTOR_NAME_SLOT'] = \
+ "Unused"
+ self.pki_master_dict\
+ ['PKI_EE_SECURE_CLIENT_AUTH_PORT_SERVER_COMMENT_SLOT'] = \
+ ""
+ self.pki_master_dict['PKI_EE_SECURE_CLIENT_AUTH_PORT_UI_SLOT'] = \
+ self.pki_master_dict['pki_https_port']
+ self.pki_master_dict['PKI_EE_SECURE_PORT_SLOT'] = \
+ self.pki_master_dict['pki_https_port']
+ self.pki_master_dict['PKI_EE_SECURE_PORT_CONNECTOR_NAME_SLOT'] = \
+ "Unused"
+ self.pki_master_dict['PKI_EE_SECURE_PORT_SERVER_COMMENT_SLOT'] = \
+ ""
+ self.pki_master_dict['PKI_GROUP_SLOT'] = \
+ self.pki_master_dict['pki_group']
+ self.pki_master_dict['PKI_INSTANCE_PATH_SLOT'] = \
+ self.pki_master_dict['pki_instance_path']
+ self.pki_master_dict['PKI_INSTANCE_ROOT_SLOT'] = \
+ self.pki_master_dict['pki_path']
+ self.pki_master_dict['PKI_LOCKDIR_SLOT'] = \
+ os.path.join("/var/lock/pki",
+ "tomcat")
+ self.pki_master_dict['PKI_HOSTNAME_SLOT'] = \
+ self.pki_master_dict['pki_hostname']
+ self.pki_master_dict\
+ ['PKI_OPEN_SEPARATE_PORTS_SERVER_COMMENT_SLOT'] = \
+ "<!--"
+ self.pki_master_dict\
+ ['PKI_OPEN_SEPARATE_PORTS_WEB_COMMENT_SLOT'] = \
+ "<!--"
+ self.pki_master_dict['PKI_PIDDIR_SLOT'] = \
+ os.path.join("/var/run/pki",
+ "tomcat")
+ if config.str2bool(self.pki_master_dict['pki_enable_proxy']):
+ self.pki_master_dict['PKI_CLOSE_AJP_PORT_COMMENT_SLOT'] = \
+ ""
+ self.pki_master_dict['PKI_CLOSE_ENABLE_PROXY_COMMENT_SLOT'] = \
+ ""
+ self.pki_master_dict['PKI_PROXY_SECURE_PORT_SLOT'] = \
+ self.pki_master_dict['pki_proxy_https_port']
+ self.pki_master_dict['PKI_PROXY_UNSECURE_PORT_SLOT'] = \
+ self.pki_master_dict['pki_proxy_http_port']
+ self.pki_master_dict['PKI_OPEN_AJP_PORT_COMMENT_SLOT'] = \
+ ""
+ self.pki_master_dict['PKI_OPEN_ENABLE_PROXY_COMMENT_SLOT'] = \
+ ""
+ else:
+ self.pki_master_dict['PKI_CLOSE_AJP_PORT_COMMENT_SLOT'] = \
+ "-->"
+ self.pki_master_dict['PKI_CLOSE_ENABLE_PROXY_COMMENT_SLOT'] = \
+ "-->"
+ self.pki_master_dict['PKI_PROXY_SECURE_PORT_SLOT'] = ""
+ self.pki_master_dict['PKI_PROXY_UNSECURE_PORT_SLOT'] = ""
+ self.pki_master_dict['PKI_OPEN_AJP_PORT_COMMENT_SLOT'] = \
+ "<!--"
+ self.pki_master_dict['PKI_OPEN_ENABLE_PROXY_COMMENT_SLOT'] = \
+ "<!--"
+ self.pki_master_dict['PKI_TMPDIR_SLOT'] = \
+ self.pki_master_dict['pki_tomcat_tmpdir_path']
+ self.pki_master_dict['PKI_RESTEASY_LIB_SLOT'] = \
+ self.pki_master_dict['resteasy_lib']
+ self.pki_master_dict['PKI_RANDOM_NUMBER_SLOT'] = \
+ self.pki_master_dict['pki_one_time_pin']
+ self.pki_master_dict['PKI_SECURE_PORT_SLOT'] = \
+ self.pki_master_dict['pki_https_port']
+ self.pki_master_dict['PKI_SECURE_PORT_CONNECTOR_NAME_SLOT'] = \
+ "Secure"
+ self.pki_master_dict['PKI_SECURE_PORT_SERVER_COMMENT_SLOT'] = \
+ "<!-- " + \
+ "Shared Ports: Agent, EE, and Admin Secure Port Connector " + \
+ "-->"
+ self.pki_master_dict['PKI_SECURITY_MANAGER_SLOT'] = \
+ self.pki_master_dict['pki_security_manager']
+ self.pki_master_dict['PKI_SERVER_XML_CONF_SLOT'] = \
+ self.pki_master_dict['pki_target_server_xml']
+ self.pki_master_dict['PKI_SSL_SERVER_NICKNAME_SLOT'] = \
+ self.pki_master_dict['pki_ssl_server_nickname']
+ self.pki_master_dict['PKI_SUBSYSTEM_TYPE_SLOT'] = \
+ self.pki_master_dict['pki_subsystem'].lower()
+ self.pki_master_dict['PKI_SYSTEMD_SERVICENAME_SLOT'] = \
+ "pki-tomcatd" + "@" + \
+ self.pki_master_dict['pki_instance_name'] + ".service"
+ self.pki_master_dict['PKI_UNSECURE_PORT_SLOT'] = \
+ self.pki_master_dict['pki_http_port']
+ self.pki_master_dict['PKI_UNSECURE_PORT_CONNECTOR_NAME_SLOT'] = \
+ "Unsecure"
+ self.pki_master_dict['PKI_UNSECURE_PORT_SERVER_COMMENT_SLOT'] = \
+ "<!-- Shared Ports: Unsecure Port Connector -->"
+ self.pki_master_dict['PKI_USER_SLOT'] = \
+ self.pki_master_dict['pki_user']
+ self.pki_master_dict['PKI_WEB_SERVER_TYPE_SLOT'] = \
+ "tomcat"
+ self.pki_master_dict['PKI_WEBAPPS_NAME_SLOT'] = \
+ "webapps"
+ self.pki_master_dict['TOMCAT_CFG_SLOT'] = \
+ self.pki_master_dict['pki_target_tomcat_conf']
+ self.pki_master_dict['TOMCAT_INSTANCE_COMMON_LIB_SLOT'] = \
+ os.path.join(
+ self.pki_master_dict['pki_tomcat_common_lib_path'],
+ "*.jar")
+ self.pki_master_dict['TOMCAT_LOG_DIR_SLOT'] = \
+ self.pki_master_dict['pki_instance_log_path']
+ self.pki_master_dict['TOMCAT_PIDFILE_SLOT'] = \
+ "/var/run/pki/tomcat/" + self.pki_master_dict['pki_instance_name'] + ".pid"
+ self.pki_master_dict['TOMCAT_SERVER_PORT_SLOT'] = \
+ self.pki_master_dict['pki_tomcat_server_port']
+ self.pki_master_dict['TOMCAT_SSL2_CIPHERS_SLOT'] = \
+ "-SSL2_RC4_128_WITH_MD5," + \
+ "-SSL2_RC4_128_EXPORT40_WITH_MD5," + \
+ "-SSL2_RC2_128_CBC_WITH_MD5," + \
+ "-SSL2_RC2_128_CBC_EXPORT40_WITH_MD5," + \
+ "-SSL2_DES_64_CBC_WITH_MD5," + \
+ "-SSL2_DES_192_EDE3_CBC_WITH_MD5"
+ self.pki_master_dict['TOMCAT_SSL3_CIPHERS_SLOT'] = \
+ "-SSL3_FORTEZZA_DMS_WITH_NULL_SHA," + \
+ "-SSL3_FORTEZZA_DMS_WITH_RC4_128_SHA," + \
+ "+SSL3_RSA_WITH_RC4_128_SHA," + \
+ "-SSL3_RSA_EXPORT_WITH_RC4_40_MD5," + \
+ "+SSL3_RSA_WITH_3DES_EDE_CBC_SHA," + \
+ "+SSL3_RSA_WITH_DES_CBC_SHA," + \
+ "-SSL3_RSA_EXPORT_WITH_RC2_CBC_40_MD5," + \
+ "-SSL3_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA," + \
+ "-SSL_RSA_FIPS_WITH_DES_CBC_SHA," + \
+ "+SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA," + \
+ "-SSL3_RSA_WITH_NULL_MD5," + \
+ "-TLS_RSA_EXPORT1024_WITH_RC4_56_SHA," + \
+ "-TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA," + \
+ "+TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"
+ self.pki_master_dict['TOMCAT_SSL_OPTIONS_SLOT'] = \
+ "ssl2=true," + \
+ "ssl3=true," + \
+ "tls=true"
+ self.pki_master_dict['TOMCAT_TLS_CIPHERS_SLOT'] = \
+ "-TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA," + \
+ "-TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA," + \
+ "+TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA," + \
+ "+TLS_ECDH_RSA_WITH_AES_128_CBC_SHA," + \
+ "+TLS_ECDH_RSA_WITH_AES_256_CBC_SHA," + \
+ "-TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA," + \
+ "+TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA," + \
+ "+TLS_RSA_WITH_3DES_EDE_CBC_SHA," + \
+ "+TLS_RSA_WITH_AES_128_CBC_SHA," + \
+ "+TLS_RSA_WITH_AES_256_CBC_SHA," + \
+ "+TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA," + \
+ "+TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA," + \
+ "-TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA," + \
+ "-TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA," + \
+ "-TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA," + \
+ "+TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA," + \
+ "+TLS_DHE_DSS_WITH_AES_128_CBC_SHA," + \
+ "+TLS_DHE_DSS_WITH_AES_256_CBC_SHA," + \
+ "+TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA," + \
+ "+TLS_DHE_RSA_WITH_AES_128_CBC_SHA," + \
+ "+TLS_DHE_RSA_WITH_AES_256_CBC_SHA"
+ if self.pki_master_dict['pki_subsystem'] == "CA":
+ self.pki_master_dict['PKI_ENABLE_RANDOM_SERIAL_NUMBERS'] = \
+ self.pki_master_dict\
+ ['pki_random_serial_numbers_enable'].lower()
+ # Shared Apache/Tomcat NSS security database name/value pairs
+ self.pki_master_dict['pki_shared_pfile'] = \
+ os.path.join(
+ self.pki_master_dict['pki_instance_configuration_path'],
+ "pfile")
+ self.pki_master_dict['pki_shared_password_conf'] = \
+ os.path.join(
+ self.pki_master_dict['pki_instance_configuration_path'],
+ "password.conf")
+ self.pki_master_dict['pki_cert_database'] = \
+ os.path.join(self.pki_master_dict['pki_database_path'],
+ "cert8.db")
+ self.pki_master_dict['pki_key_database'] = \
+ os.path.join(self.pki_master_dict['pki_database_path'],
+ "key3.db")
+ self.pki_master_dict['pki_secmod_database'] = \
+ os.path.join(self.pki_master_dict['pki_database_path'],
+ "secmod.db")
+ self.pki_master_dict['pki_self_signed_token'] = "internal"
+ self.pki_master_dict['pki_self_signed_nickname'] = \
+ self.pki_master_dict['pki_ssl_server_nickname']
+ self.pki_master_dict['pki_self_signed_subject'] = \
+ "cn=" + self.pki_master_dict['pki_hostname'] + "," + \
+ "o=" + self.pki_master_dict['pki_certificate_timestamp']
+ self.pki_master_dict['pki_self_signed_serial_number'] = 0
+ self.pki_master_dict['pki_self_signed_validity_period'] = 12
+ self.pki_master_dict['pki_self_signed_issuer_name'] = \
+ "cn=" + self.pki_master_dict['pki_hostname'] + "," + \
+ "o=" + self.pki_master_dict['pki_certificate_timestamp']
+ self.pki_master_dict['pki_self_signed_trustargs'] = "CTu,CTu,CTu"
+ self.pki_master_dict['pki_self_signed_noise_file'] = \
+ os.path.join(
+ self.pki_master_dict['pki_subsystem_configuration_path'],
+ "noise")
+ self.pki_master_dict['pki_self_signed_noise_bytes'] = 1024
+ # Shared Apache/Tomcat NSS security database convenience symbolic links
+ self.pki_master_dict\
+ ['pki_subsystem_configuration_password_conf_link'] = \
+ os.path.join(
+ self.pki_master_dict['pki_subsystem_configuration_path'],
+ "password.conf")
+
+ if not len(self.pki_master_dict['pki_client_database_password']):
+ # use randomly generated client 'pin'
+ self.pki_master_dict['pki_client_database_password'] = \
+ str(self.pki_master_dict['pki_client_pin'])
+
+ # Configuration scriptlet
+ # 'Security Domain' Configuration name/value pairs
+ # 'Subsystem Name' Configuration name/value pairs
+ # 'Token' Configuration name/value pairs
+ #
+ # Apache - [RA]
+ # Tomcat - [CA], [KRA], [OCSP], [TKS], [TPS]
+ # - [CA Clone], [KRA Clone], [OCSP Clone], [TKS Clone], [TPS Clone]
+ # - [External CA]
+ # - [Subordinate CA]
+ #
+ # The following variables are defined below:
+ #
+ # self.pki_master_dict['pki_security_domain_type']
+ # self.pki_master_dict['pki_security_domain_uri']
+ #
+ # The following variables are established via the specified PKI
+ # deployment configuration file and are NOT redefined below:
+ #
+ # self.pki_master_dict['pki_clone_pkcs12_password']
+ # self.pki_master_dict['pki_security_domain_password']
+ # self.pki_master_dict['pki_token_password']
+ # self.pki_master_dict['pki_clone_pkcs12_path']
+ # self.pki_master_dict['pki_clone_uri']
+ # self.pki_master_dict['pki_security_domain_https_port']
+ # self.pki_master_dict['pki_token_name']
+ #
+ # The following variables are established via the specified PKI
+ # deployment configuration file and potentially overridden below:
+ #
+ # self.pki_master_dict['pki_security_domain_user']
+ # self.pki_master_dict['pki_issuing_ca']
+ #
+
+ # if security domain user is not defined
+ if not len(self.pki_master_dict['pki_security_domain_user']):
+
+ # use the CA admin uid if it's defined
+ if self.pki_config.has_option('CA', 'pki_admin_uid') and\
+ len(self.pki_config.get('CA', 'pki_admin_uid')) > 0:
+ self.pki_master_dict['pki_security_domain_user'] = \
+ self.pki_config.get('CA', 'pki_admin_uid')
+
+ # or use the Default admin uid if it's defined
+ elif self.pki_config.has_option('DEFAULT', 'pki_admin_uid') and\
+ len(self.pki_config.get('DEFAULT', 'pki_admin_uid')) > 0:
+ self.pki_master_dict['pki_security_domain_user'] = \
+ self.pki_config.get('DEFAULT', 'pki_admin_uid')
+
+ # otherwise use the default CA admin uid
+ else:
+ self.pki_master_dict['pki_security_domain_user'] = "caadmin"
+
+ if config.pki_subsystem != "CA" or\
+ config.str2bool(self.pki_master_dict['pki_clone']) or\
+ config.str2bool(self.pki_master_dict['pki_subordinate']):
+ # PKI KRA, PKI OCSP, PKI RA, PKI TKS, PKI TPS,
+ # CA Clone, KRA Clone, OCSP Clone, TKS Clone, TPS Clone, or
+ # Subordinate CA
+ self.pki_master_dict['pki_security_domain_type'] = "existing"
+ self.pki_master_dict['pki_security_domain_uri'] = \
+ "https" + "://" + \
+ self.pki_master_dict['pki_security_domain_hostname'] + ":" + \
+ self.pki_master_dict['pki_security_domain_https_port']
+
+ elif config.str2bool(self.pki_master_dict['pki_external']):
+ # External CA
+ self.pki_master_dict['pki_security_domain_type'] = "new"
+ if not len(self.pki_master_dict['pki_issuing_ca']):
+ self.pki_master_dict['pki_issuing_ca'] = "External CA"
+ else:
+ # PKI CA
+ self.pki_master_dict['pki_security_domain_type'] = "new"
+
+ # 'External CA' Configuration name/value pairs
+ #
+ # Tomcat - [External CA]
+ #
+ # The following variables are established via the specified PKI
+ # deployment configuration file and are NOT redefined below:
+ #
+ # self.pki_master_dict['pki_external_ca_cert_chain_path']
+ # self.pki_master_dict['pki_external_ca_cert_path']
+ # self.pki_master_dict['pki_external_csr_path']
+ # self.pki_master_dict['pki_external_step_two']
+ #
+
+ # 'Backup' Configuration name/value pairs
+ #
+ # Apache - [RA]
+ # Tomcat - [CA], [KRA], [OCSP], [TKS], [TPS]
+ # - [External CA]
+ # - [Subordinate CA]
+ #
+ # The following variables are established via the specified PKI
+ # deployment configuration file and are NOT redefined below:
+ #
+ # self.pki_master_dict['pki_backup_password']
+ # self.pki_master_dict['pki_backup_keys']
+ #
+ if config.str2bool(self.pki_master_dict['pki_backup_keys']):
+ # NOTE: ALWAYS store the PKCS #12 backup keys file
+ # in with the NSS "server" security databases
+ self.pki_master_dict['pki_backup_keys_p12'] = \
+ self.pki_master_dict['pki_database_path'] + "/" + \
+ self.pki_master_dict['pki_subsystem'].lower() + "_" + \
+ "backup" + "_" + "keys" + "." + "p12"
+
+ self.pki_master_dict['pki_admin_profile_id'] = "caAdminCert"
+
+ if not 'pki_import_admin_cert' in self.pki_master_dict:
+ self.pki_master_dict['pki_import_admin_cert'] = 'false'
+
+ self.pki_master_dict['pki_ca_signing_tag'] = "signing"
+ if self.pki_master_dict['pki_subsystem'] == "CA":
+ self.pki_master_dict['pki_ocsp_signing_tag'] = "ocsp_signing"
+ elif self.pki_master_dict['pki_subsystem'] == "OCSP":
+ self.pki_master_dict['pki_ocsp_signing_tag'] = "signing"
+ self.pki_master_dict['pki_ssl_server_tag'] = "sslserver"
+ self.pki_master_dict['pki_subsystem_tag'] = "subsystem"
+ self.pki_master_dict['pki_audit_signing_tag'] = "audit_signing"
+ self.pki_master_dict['pki_transport_tag'] = "transport"
+ self.pki_master_dict['pki_storage_tag'] = "storage"
+
+ # Finalization name/value pairs
+ self.pki_master_dict['pki_default_deployment_cfg_replica'] = \
+ os.path.join(self.pki_master_dict['pki_subsystem_registry_path'],
+ config.DEFAULT_DEPLOYMENT_CONFIGURATION)
+ self.pki_master_dict['pki_user_deployment_cfg_replica'] = \
+ os.path.join(self.pki_master_dict['pki_subsystem_registry_path'],
+ config.USER_DEPLOYMENT_CONFIGURATION)
+ self.pki_master_dict['pki_user_deployment_cfg_spawn_archive'] = \
+ self.pki_master_dict['pki_subsystem_archive_log_path'] + "/" + \
+ "spawn" + "_" + \
+ config.USER_DEPLOYMENT_CONFIGURATION + "." + \
+ self.pki_master_dict['pki_timestamp']
+ self.pki_master_dict['pki_manifest'] = \
+ self.pki_master_dict['pki_subsystem_registry_path'] + "/" + \
+ "manifest"
+ self.pki_master_dict['pki_manifest_spawn_archive'] = \
+ self.pki_master_dict['pki_subsystem_archive_log_path'] + "/" + \
+ "spawn" + "_" + "manifest" + "." + \
+ self.pki_master_dict['pki_timestamp']
+ # Construct the configuration URL containing the one-time pin
+ # and add this to the "sensitive" key value pairs read in from
+ # the configuration file
+ #
+ # NOTE: This is the one and only parameter containing a sensitive
+ # parameter that may be stored in a log file and displayed
+ # to the screen.
+ #
+ self.pki_master_dict['pki_configuration_url'] = \
+ "https://{}:{}/{}/{}?pin={}".format(
+ self.pki_master_dict['pki_hostname'],
+ self.pki_master_dict['pki_https_port'],
+ self.pki_master_dict['pki_subsystem'].lower(),
+ "admin/console/config/login",
+ self.pki_master_dict['pki_one_time_pin'])
+ # Compose this "systemd" execution management command
+ if self.pki_master_dict['pki_subsystem'] in\
+ config.PKI_APACHE_SUBSYSTEMS:
+ self.pki_master_dict['pki_registry_initscript_command'] = \
+ "systemctl" + " " + \
+ "restart" + " " + \
+ "pki-apached" + "@" + \
+ self.pki_master_dict['pki_instance_name'] + "." + "service"
+ elif self.pki_master_dict['pki_subsystem'] in\
+ config.PKI_TOMCAT_SUBSYSTEMS:
+ self.pki_master_dict['pki_registry_initscript_command'] = \
+ "systemctl" + " " + \
+ "restart" + " " + \
+ "pki-tomcatd" + "@" + \
+ self.pki_master_dict['pki_instance_name'] + "." + "service"
+ except OSError as exc:
+ config.pki_log.error(log.PKI_OSERROR_1, exc,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise
+ except KeyError as err:
+ config.pki_log.error(log.PKIHELPER_DICTIONARY_MASTER_MISSING_KEY_1,
+ err, extra=config.PKI_INDENTATION_LEVEL_2)
+ raise
+ return
+
+
+ def compose_pki_slots_dictionary(self):
+ """Read the slots configuration file to create
+ the appropriate PKI slots dictionary"""
+ rv = 0
+ try:
+ parser = ConfigParser.ConfigParser()
+ # Make keys case-sensitive!
+ parser.optionxform = str
+ parser.read(config.PKI_DEPLOYMENT_SLOTS_CONFIGURATION_FILE)
+ # Slots configuration file name/value pairs
+ if config.pki_subsystem in config.PKI_APACHE_SUBSYSTEMS:
+ self.pki_slots_dict = dict(parser.items('Apache'))
+ elif config.pki_subsystem in config.PKI_TOMCAT_SUBSYSTEMS:
+ self.pki_slots_dict = dict(parser.items('Tomcat'))
+ except ConfigParser.ParsingError, err:
+ rv = err
+ return rv
diff --git a/base/server/python/pki/server/deployment/pkiscriptlet.py b/base/server/python/pki/server/deployment/pkiscriptlet.py
new file mode 100644
index 000000000..f37bb1c15
--- /dev/null
+++ b/base/server/python/pki/server/deployment/pkiscriptlet.py
@@ -0,0 +1,41 @@
+#!/usr/bin/python -t
+# Authors:
+# Matthew Harmsen <mharmsen@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright (C) 2012 Red Hat, Inc.
+# All rights reserved.
+#
+
+# System Imports
+import abc
+
+
+# PKI Deployment Abstract Base PKI Scriptlet
+class AbstractBasePkiScriptlet(object):
+ __metaclass__ = abc.ABCMeta
+
+ # pylint: disable-msg=W0613
+ @abc.abstractmethod
+ def spawn(self, deployer):
+ """Retrieve data from the specified PKI dictionary and
+ use it to install a new PKI instance."""
+ return
+ # pylint: disable-msg=W0613
+ @abc.abstractmethod
+ def destroy(self, deployer):
+ """Retrieve data from the specified PKI dictionary and
+ use it to destroy an existing PKI instance."""
+ return
diff --git a/base/server/python/pki/server/deployment/scriptlets/__init__.py b/base/server/python/pki/server/deployment/scriptlets/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/base/server/python/pki/server/deployment/scriptlets/__init__.py
diff --git a/base/server/python/pki/server/deployment/scriptlets/configuration.py b/base/server/python/pki/server/deployment/scriptlets/configuration.py
new file mode 100644
index 000000000..004d8c28d
--- /dev/null
+++ b/base/server/python/pki/server/deployment/scriptlets/configuration.py
@@ -0,0 +1,140 @@
+#!/usr/bin/python -t
+# Authors:
+# Matthew Harmsen <mharmsen@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright (C) 2012 Red Hat, Inc.
+# All rights reserved.
+#
+
+import json
+
+# PKI Deployment Imports
+from .. import pkiconfig as config
+from .. import pkimessages as log
+from .. import pkiscriptlet
+import pki.system
+import pki.encoder
+
+
+# PKI Deployment Configuration Scriptlet
+class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
+ rv = 0
+
+ def spawn(self, deployer):
+
+ if config.str2bool(deployer.master_dict['pki_skip_configuration']):
+ config.pki_log.info(log.SKIP_CONFIGURATION_SPAWN_1, __name__,
+ extra=config.PKI_INDENTATION_LEVEL_1)
+ return self.rv
+ config.pki_log.info(log.CONFIGURATION_SPAWN_1, __name__,
+ extra=config.PKI_INDENTATION_LEVEL_1)
+
+ # Place "slightly" less restrictive permissions on
+ # the top-level client directory ONLY
+ deployer.directory.create(deployer.master_dict['pki_client_subsystem_dir'],
+ uid=0, gid=0,
+ perms=config.PKI_DEPLOYMENT_DEFAULT_CLIENT_DIR_PERMISSIONS)
+ # Since 'certutil' does NOT strip the 'token=' portion of
+ # the 'token=password' entries, create a client password file
+ # which ONLY contains the 'password' for the purposes of
+ # allowing 'certutil' to generate the security databases
+ deployer.password.create_password_conf(
+ deployer.master_dict['pki_client_password_conf'],
+ deployer.master_dict['pki_client_database_password'], pin_sans_token=True)
+ deployer.file.modify(deployer.master_dict['pki_client_password_conf'],
+ uid=0, gid=0)
+ # Similarly, create a simple password file containing the
+ # PKCS #12 password used when exporting the "Admin Certificate"
+ # into a PKCS #12 file
+ deployer.password.create_client_pkcs12_password_conf(
+ deployer.master_dict['pki_client_pkcs12_password_conf'])
+ deployer.file.modify(deployer.master_dict['pki_client_pkcs12_password_conf'])
+ deployer.directory.create(deployer.master_dict['pki_client_database_dir'],
+ uid=0, gid=0)
+ deployer.certutil.create_security_databases(
+ deployer.master_dict['pki_client_database_dir'],
+ deployer.master_dict['pki_client_cert_database'],
+ deployer.master_dict['pki_client_key_database'],
+ deployer.master_dict['pki_client_secmod_database'],
+ password_file=deployer.master_dict['pki_client_password_conf'])
+ deployer.symlink.create(deployer.master_dict['pki_systemd_service'],
+ deployer.master_dict['pki_systemd_service_link'])
+
+ # Start/Restart this Apache/Tomcat PKI Process
+ if deployer.master_dict['pki_subsystem'] in config.PKI_APACHE_SUBSYSTEMS:
+ apache_instance_subsystems = \
+ deployer.instance.apache_instance_subsystems()
+ if apache_instance_subsystems == 1:
+ deployer.systemd.start()
+ elif apache_instance_subsystems > 1:
+ deployer.systemd.restart()
+ elif deployer.master_dict['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS:
+ # Optionally prepare to enable a java debugger
+ # (e. g. - 'eclipse'):
+ if config.str2bool(deployer.master_dict['pki_enable_java_debugger']):
+ config.prepare_for_an_external_java_debugger(
+ deployer.master_dict['pki_target_tomcat_conf_instance_id'])
+ tomcat_instance_subsystems = \
+ len(deployer.instance.tomcat_instance_subsystems())
+ if tomcat_instance_subsystems == 1:
+ deployer.systemd.start()
+ elif tomcat_instance_subsystems > 1:
+ deployer.systemd.restart()
+
+ # wait for startup
+ status = deployer.instance.wait_for_startup(60)
+ if status == None:
+ config.pki_log.error("server failed to restart",
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ raise Exception("server failed to restart")
+
+ # Optionally wait for debugger to attach (e. g. - 'eclipse'):
+ if config.str2bool(deployer.master_dict['pki_enable_java_debugger']):
+ config.wait_to_attach_an_external_java_debugger()
+
+ # Construct PKI Subsystem Configuration Data
+ data = None
+ if deployer.master_dict['pki_instance_type'] == "Apache":
+ if deployer.master_dict['pki_subsystem'] == "RA":
+ config.pki_log.info(log.PKI_CONFIG_NOT_YET_IMPLEMENTED_1,
+ deployer.master_dict['pki_subsystem'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ return self.rv
+ elif deployer.master_dict['pki_instance_type'] == "Tomcat":
+ # CA, KRA, OCSP, TKS, or TPS
+ data = deployer.config_client.construct_pki_configuration_data()
+
+ # Configure the substem
+ deployer.config_client.configure_pki_data(
+ json.dumps(data, cls=pki.encoder.CustomTypeEncoder))
+
+ return self.rv
+
+ def destroy(self, deployer):
+
+ config.pki_log.info(log.CONFIGURATION_DESTROY_1, __name__,
+ extra=config.PKI_INDENTATION_LEVEL_1)
+ if deployer.master_dict['pki_subsystem'] in config.PKI_APACHE_SUBSYSTEMS and\
+ deployer.instance.apache_instance_subsystems() == 1:
+ if deployer.directory.exists(deployer.master_dict['pki_client_dir']):
+ deployer.directory.delete(deployer.master_dict['pki_client_dir'])
+ deployer.symlink.delete(deployer.master_dict['pki_systemd_service_link'])
+ elif deployer.master_dict['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS and\
+ len(deployer.instance.tomcat_instance_subsystems()) == 1:
+ if deployer.directory.exists(deployer.master_dict['pki_client_dir']):
+ deployer.directory.delete(deployer.master_dict['pki_client_dir'])
+ deployer.symlink.delete(deployer.master_dict['pki_systemd_service_link'])
+ return self.rv
diff --git a/base/server/python/pki/server/deployment/scriptlets/finalization.py b/base/server/python/pki/server/deployment/scriptlets/finalization.py
new file mode 100644
index 000000000..0573c24ef
--- /dev/null
+++ b/base/server/python/pki/server/deployment/scriptlets/finalization.py
@@ -0,0 +1,106 @@
+#!/usr/bin/python -t
+# Authors:
+# Matthew Harmsen <mharmsen@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright (C) 2012 Red Hat, Inc.
+# All rights reserved.
+#
+
+# PKI Deployment Imports
+from .. import pkiconfig as config
+from .. import pkimanifest as manifest
+from .. import pkimessages as log
+from .. import pkiscriptlet
+
+
+# PKI Deployment Finalization Scriptlet
+class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
+ rv = 0
+
+ def spawn(self, deployer):
+
+ if deployer.master_dict['pki_subsystem'] == "CA" and\
+ config.str2bool(deployer.master_dict['pki_external_step_two']):
+ # must check for 'External CA Step 2' installation PRIOR to
+ # 'pki_skip_installation' since this value has been set to true
+ # by the initialization scriptlet
+ pass
+ elif config.str2bool(deployer.master_dict['pki_skip_installation']):
+ config.pki_log.info(log.SKIP_FINALIZATION_SPAWN_1, __name__,
+ extra=config.PKI_INDENTATION_LEVEL_1)
+ return self.rv
+ config.pki_log.info(log.FINALIZATION_SPAWN_1, __name__,
+ extra=config.PKI_INDENTATION_LEVEL_1)
+ # For debugging/auditing purposes, save a timestamped copy of
+ # this configuration file in the subsystem archive
+ deployer.file.copy(deployer.master_dict['pki_user_deployment_cfg_replica'],
+ deployer.master_dict['pki_user_deployment_cfg_spawn_archive'])
+ # Save a copy of the installation manifest file
+ config.pki_log.info(log.PKI_MANIFEST_MESSAGE_1, deployer.master_dict['pki_manifest'],
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ # for record in manifest.database:
+ # print tuple(record)
+ manifest_file = manifest.File(deployer.manifest_db)
+ manifest_file.register(deployer.master_dict['pki_manifest'])
+ manifest_file.write()
+ deployer.file.modify(deployer.master_dict['pki_manifest'], silent=True)
+
+ # Also, for debugging/auditing purposes, save a timestamped copy of
+ # this installation manifest file
+ deployer.file.copy(deployer.master_dict['pki_manifest'],
+ deployer.master_dict['pki_manifest_spawn_archive'])
+ # Optionally, programmatically 'restart' the configured PKI instance
+ if config.str2bool(deployer.master_dict['pki_restart_configured_instance']):
+ deployer.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(deployer.master_dict['pki_client_database_purge']):
+ if deployer.directory.exists(deployer.master_dict['pki_client_subsystem_dir']):
+ deployer.directory.delete(deployer.master_dict['pki_client_subsystem_dir'])
+ # If instance has not been configured, print the
+ # configuration URL to the log
+ if config.str2bool(deployer.master_dict['pki_skip_configuration']):
+ deployer.configuration_file.log_configuration_url()
+ # Log final process messages
+ config.pki_log.info(log.PKISPAWN_END_MESSAGE_2,
+ deployer.master_dict['pki_subsystem'],
+ deployer.master_dict['pki_instance_name'],
+ extra=config.PKI_INDENTATION_LEVEL_0)
+ deployer.file.modify(deployer.master_dict['pki_spawn_log'], silent=True)
+ return self.rv
+
+ def destroy(self, deployer):
+
+ config.pki_log.info(log.FINALIZATION_DESTROY_1, __name__,
+ extra=config.PKI_INDENTATION_LEVEL_1)
+ deployer.file.modify(deployer.master_dict['pki_destroy_log'], silent=True)
+ # Start this Apache/Tomcat PKI Process
+ if deployer.master_dict['pki_subsystem'] in config.PKI_APACHE_SUBSYSTEMS and\
+ deployer.instance.apache_instance_subsystems() >= 1:
+ deployer.systemd.start()
+ elif deployer.master_dict['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS and\
+ len(deployer.instance.tomcat_instance_subsystems()) >= 1:
+ deployer.systemd.start()
+ config.pki_log.info(log.PKIDESTROY_END_MESSAGE_2,
+ deployer.master_dict['pki_subsystem'],
+ deployer.master_dict['pki_instance_name'],
+ extra=config.PKI_INDENTATION_LEVEL_0)
+ return self.rv
diff --git a/base/server/python/pki/server/deployment/scriptlets/infrastructure_layout.py b/base/server/python/pki/server/deployment/scriptlets/infrastructure_layout.py
new file mode 100644
index 000000000..5427eebca
--- /dev/null
+++ b/base/server/python/pki/server/deployment/scriptlets/infrastructure_layout.py
@@ -0,0 +1,114 @@
+#!/usr/bin/python -t
+# Authors:
+# Matthew Harmsen <mharmsen@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright (C) 2012 Red Hat, Inc.
+# All rights reserved.
+#
+
+# PKI Deployment Imports
+from .. import pkiconfig as config
+from .. import pkimessages as log
+from .. import pkiscriptlet
+
+
+# PKI Deployment Top-Level Infrastructure Layout Scriptlet
+class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
+ rv = 0
+
+ def spawn(self, deployer):
+
+ if config.str2bool(deployer.master_dict['pki_skip_installation']):
+ config.pki_log.info(log.SKIP_ADMIN_DOMAIN_SPAWN_1, __name__,
+ extra=config.PKI_INDENTATION_LEVEL_1)
+ return self.rv
+ config.pki_log.info(log.ADMIN_DOMAIN_SPAWN_1, __name__,
+ extra=config.PKI_INDENTATION_LEVEL_1)
+ # NOTE: It was determined that since the "pkidestroy" command
+ # relies upon a symbolic link to a replica of the original
+ # deployment 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
+ # deployment configuration file used to spawn this instance,
+ # and save a copy of this file
+ deployer.directory.create(deployer.master_dict['pki_registry_path'])
+ deployer.directory.create(deployer.master_dict['pki_instance_type_registry_path'])
+ deployer.directory.create(deployer.master_dict['pki_instance_registry_path'])
+ deployer.directory.create(deployer.master_dict['pki_subsystem_registry_path'])
+ deployer.file.copy(deployer.master_dict['pki_default_deployment_cfg'],
+ deployer.master_dict['pki_default_deployment_cfg_replica'])
+
+ print "Storing deployment configuration into " + deployer.master_dict['pki_user_deployment_cfg_replica'] + "."
+
+ # Archive the user deployment configuration excluding the sensitive parameters
+ sensitive_parameters = deployer.master_dict['sensitive_parameters'].split()
+ sections = config.user_config.sections()
+ for s in sections:
+ for k in sensitive_parameters:
+ config.user_config.set(s, k, 'XXXXXXXX')
+ with open(deployer.master_dict['pki_user_deployment_cfg_replica'], 'w') as f:
+ config.user_config.write(f)
+
+ # establish top-level infrastructure, instance, and subsystem
+ # base directories and create the "registry" symbolic link that
+ # the "pkidestroy" executable relies upon
+ deployer.directory.create(deployer.master_dict['pki_path'])
+ deployer.directory.create(deployer.master_dict['pki_instance_path'])
+ deployer.directory.create(deployer.master_dict['pki_subsystem_path'])
+ deployer.symlink.create(deployer.master_dict['pki_instance_registry_path'],
+ deployer.master_dict['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
+ # deployer.directory.create(deployer.master_dict['pki_log_path'])
+ # establish top-level infrastructure configuration
+ if deployer.master_dict['pki_configuration_path'] != \
+ config.PKI_DEPLOYMENT_CONFIGURATION_ROOT:
+ deployer.directory.create(deployer.master_dict['pki_configuration_path'])
+ return self.rv
+
+ def destroy(self, deployer):
+
+ config.pki_log.info(log.ADMIN_DOMAIN_DESTROY_1, __name__,
+ extra=config.PKI_INDENTATION_LEVEL_1)
+ # remove top-level infrastructure base
+ if deployer.master_dict['pki_subsystem'] in config.PKI_SUBSYSTEMS and\
+ deployer.instance.pki_instance_subsystems() == 0:
+ # remove top-level infrastructure base
+ deployer.directory.delete(deployer.master_dict['pki_path'])
+ # do NOT remove top-level infrastructure logs
+ # since it now stores 'pkispawn'/'pkidestroy' logs
+ # deployer.directory.delete(deployer.master_dict['pki_log_path'])
+ # remove top-level infrastructure configuration
+ if deployer.directory.is_empty(deployer.master_dict['pki_configuration_path'])\
+ and deployer.master_dict['pki_configuration_path'] != \
+ config.PKI_DEPLOYMENT_CONFIGURATION_ROOT:
+ deployer.directory.delete(deployer.master_dict['pki_configuration_path'])
+ # remove top-level infrastructure registry
+ deployer.directory.delete(deployer.master_dict['pki_registry_path'])
+ return self.rv
diff --git a/base/server/python/pki/server/deployment/scriptlets/initialization.py b/base/server/python/pki/server/deployment/scriptlets/initialization.py
new file mode 100644
index 000000000..54349fc01
--- /dev/null
+++ b/base/server/python/pki/server/deployment/scriptlets/initialization.py
@@ -0,0 +1,113 @@
+#!/usr/bin/python -t
+# Authors:
+# Matthew Harmsen <mharmsen@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright (C) 2012 Red Hat, Inc.
+# All rights reserved.
+#
+
+# PKI Deployment Imports
+from .. import pkiconfig as config
+from .. import pkimessages as log
+from .. import pkiscriptlet
+
+
+# PKI Deployment Initialization Scriptlet
+class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
+ rv = 0
+
+ def spawn(self, deployer):
+
+ # begin official logging
+ config.pki_log.info(log.PKISPAWN_BEGIN_MESSAGE_2,
+ deployer.master_dict['pki_subsystem'],
+ deployer.master_dict['pki_instance_name'],
+ extra=config.PKI_INDENTATION_LEVEL_0)
+ if config.str2bool(deployer.master_dict['pki_skip_installation']):
+ config.pki_log.info(log.SKIP_INITIALIZATION_SPAWN_1, __name__,
+ extra=config.PKI_INDENTATION_LEVEL_1)
+ return self.rv
+ else:
+ config.pki_log.info(log.INITIALIZATION_SPAWN_1, __name__,
+ extra=config.PKI_INDENTATION_LEVEL_1)
+ if deployer.master_dict['pki_subsystem'] == "CA" and\
+ config.str2bool(deployer.master_dict['pki_external_step_two']):
+ # verify that this type of "subsystem" currently EXISTS
+ # for this "instance" (External CA Step 2)
+ deployer.instance.verify_subsystem_exists()
+ deployer.master_dict['pki_skip_installation'] = "True"
+ else:
+ # verify that this type of "subsystem" does NOT yet
+ # exist for this "instance"
+ deployer.instance.verify_subsystem_does_not_exist()
+ # detect and avoid any namespace collisions
+ deployer.namespace.collision_detection()
+ # initialize 'uid' and 'gid'
+ deployer.identity.add_uid_and_gid(deployer.master_dict['pki_user'], deployer.master_dict['pki_group'])
+ # establish 'uid' and 'gid'
+ deployer.identity.set_uid(deployer.master_dict['pki_user'])
+ deployer.identity.set_gid(deployer.master_dict['pki_group'])
+ # verify existence of SENSITIVE configuration file data
+ deployer.configuration_file.verify_sensitive_data()
+ # verify existence of MUTUALLY EXCLUSIVE configuration file data
+ deployer.configuration_file.verify_mutually_exclusive_data()
+ # verify existence of PREDEFINED configuration file data
+ deployer.configuration_file.verify_predefined_configuration_file_data()
+ # verify selinux context of selected ports
+ deployer.configuration_file.populate_non_default_ports()
+ deployer.configuration_file.verify_selinux_ports()
+ return self.rv
+
+ def destroy(self, deployer):
+
+ # begin official logging
+ config.pki_log.info(log.PKIDESTROY_BEGIN_MESSAGE_2,
+ deployer.master_dict['pki_subsystem'],
+ deployer.master_dict['pki_instance_name'],
+ 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"
+ deployer.instance.verify_subsystem_exists()
+ # verify that the command-line parameters match the values
+ # that are present in the corresponding configuration file
+ deployer.configuration_file.verify_command_matches_configuration_file()
+ # establish 'uid' and 'gid'
+ deployer.identity.set_uid(deployer.master_dict['pki_user'])
+ deployer.identity.set_gid(deployer.master_dict['pki_group'])
+ # get ports to remove selinux context
+ deployer.configuration_file.populate_non_default_ports()
+
+ # get deinstallation token
+ token = deployer.security_domain.get_installation_token(
+ config.pki_secdomain_user, config.pki_secdomain_pass)
+
+ # remove kra connector from CA if this is a KRA
+ deployer.kra_connector.deregister()
+
+ # de-register instance from its Security Domain
+ #
+ # NOTE: Since the security domain of an instance must be up
+ # and running in order to be de-registered, this step
+ # must be done PRIOR to instance shutdown because this
+ # instance's security domain may be a part of a
+ # tightly-coupled shared instance.
+ #
+ deployer.security_domain.deregister(token)
+ # ALWAYS Stop this Apache/Tomcat PKI Process
+ deployer.systemd.stop()
+ return self.rv
diff --git a/base/server/python/pki/server/deployment/scriptlets/instance_layout.py b/base/server/python/pki/server/deployment/scriptlets/instance_layout.py
new file mode 100644
index 000000000..081d64029
--- /dev/null
+++ b/base/server/python/pki/server/deployment/scriptlets/instance_layout.py
@@ -0,0 +1,184 @@
+#!/usr/bin/python -t
+# Authors:
+# Matthew Harmsen <mharmsen@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright (C) 2012 Red Hat, Inc.
+# All rights reserved.
+#
+
+# System Imports
+import os
+
+
+# PKI Deployment Imports
+from .. import pkiconfig as config
+from .. import pkimessages as log
+from .. import pkiscriptlet
+
+
+# PKI Deployment Instance Layout Scriptlet
+class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
+ rv = 0
+
+ def spawn(self, deployer):
+
+ if config.str2bool(deployer.master_dict['pki_skip_installation']):
+ config.pki_log.info(log.SKIP_INSTANCE_SPAWN_1, __name__,
+ extra=config.PKI_INDENTATION_LEVEL_1)
+ return self.rv
+ config.pki_log.info(log.INSTANCE_SPAWN_1, __name__,
+ extra=config.PKI_INDENTATION_LEVEL_1)
+ # establish instance logs
+ deployer.directory.create(deployer.master_dict['pki_instance_log_path'])
+ # establish instance configuration
+ deployer.directory.create(deployer.master_dict['pki_instance_configuration_path'])
+ # establish Apache/Tomcat specific instance
+ if deployer.master_dict['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS:
+ # establish Tomcat instance configuration
+ deployer.directory.copy(deployer.master_dict['pki_source_server_path'],
+ deployer.master_dict['pki_instance_configuration_path'],
+ overwrite_flag=True)
+ # establish Tomcat instance base
+ deployer.directory.create(deployer.master_dict['pki_tomcat_common_path'])
+ deployer.directory.create(deployer.master_dict['pki_tomcat_common_lib_path'])
+ # establish Tomcat instance library
+ deployer.directory.create(deployer.master_dict['pki_instance_lib'])
+ for name in os.listdir(deployer.master_dict['pki_tomcat_lib_path']):
+ deployer.symlink.create(
+ os.path.join(
+ deployer.master_dict['pki_tomcat_lib_path'],
+ name),
+ os.path.join(
+ deployer.master_dict['pki_instance_lib'],
+ name))
+ deployer.symlink.create(deployer.master_dict['pki_instance_conf_log4j_properties'],
+ deployer.master_dict['pki_instance_lib_log4j_properties'])
+ deployer.directory.create(deployer.master_dict['pki_tomcat_tmpdir_path'])
+ deployer.directory.create(deployer.master_dict['pki_tomcat_webapps_path'])
+ deployer.directory.create(deployer.master_dict['pki_tomcat_work_path'])
+ deployer.directory.create(deployer.master_dict['pki_tomcat_work_catalina_path'])
+ deployer.directory.create(deployer.master_dict['pki_tomcat_work_catalina_host_path'])
+ deployer.directory.create(
+ deployer.master_dict['pki_tomcat_work_catalina_host_run_path'])
+ deployer.directory.create(
+ deployer.master_dict['pki_tomcat_work_catalina_host_subsystem_path'])
+ # establish Tomcat instance logs
+ # establish Tomcat instance registry
+ # establish Tomcat instance convenience symbolic links
+ deployer.symlink.create(deployer.master_dict['pki_tomcat_bin_path'],
+ deployer.master_dict['pki_tomcat_bin_link'])
+ deployer.symlink.create(deployer.master_dict['pki_tomcat_systemd'],
+ deployer.master_dict['pki_instance_systemd_link'],
+ uid=0, gid=0)
+ # establish Tomcat instance common lib jar symbolic links
+ deployer.symlink.create(deployer.master_dict['pki_apache_commons_collections_jar'],
+ deployer.master_dict['pki_apache_commons_collections_jar_link'])
+ deployer.symlink.create(deployer.master_dict['pki_apache_commons_lang_jar'],
+ deployer.master_dict['pki_apache_commons_lang_jar_link'])
+ deployer.symlink.create(deployer.master_dict['pki_apache_commons_logging_jar'],
+ deployer.master_dict['pki_apache_commons_logging_jar_link'])
+ deployer.symlink.create(deployer.master_dict['pki_commons_codec_jar'],
+ deployer.master_dict['pki_commons_codec_jar_link'])
+ deployer.symlink.create(deployer.master_dict['pki_httpclient_jar'],
+ deployer.master_dict['pki_httpclient_jar_link'])
+ deployer.symlink.create(deployer.master_dict['pki_httpcore_jar'],
+ deployer.master_dict['pki_httpcore_jar_link'])
+ deployer.symlink.create(deployer.master_dict['pki_javassist_jar'],
+ deployer.master_dict['pki_javassist_jar_link'])
+ deployer.symlink.create(deployer.master_dict['pki_resteasy_jaxrs_api_jar'],
+ deployer.master_dict['pki_resteasy_jaxrs_api_jar_link'])
+ deployer.symlink.create(deployer.master_dict['pki_jettison_jar'],
+ deployer.master_dict['pki_jettison_jar_link'])
+ deployer.symlink.create(deployer.master_dict['pki_jss_jar'],
+ deployer.master_dict['pki_jss_jar_link'])
+ deployer.symlink.create(deployer.master_dict['pki_ldapjdk_jar'],
+ deployer.master_dict['pki_ldapjdk_jar_link'])
+ deployer.symlink.create(deployer.master_dict['pki_tomcat_jar'],
+ deployer.master_dict['pki_tomcat_jar_link'])
+ deployer.symlink.create(deployer.master_dict['pki_resteasy_atom_provider_jar'],
+ deployer.master_dict['pki_resteasy_atom_provider_jar_link'])
+ deployer.symlink.create(deployer.master_dict['pki_resteasy_jaxb_provider_jar'],
+ deployer.master_dict['pki_resteasy_jaxb_provider_jar_link'])
+ deployer.symlink.create(deployer.master_dict['pki_resteasy_jaxrs_jar'],
+ deployer.master_dict['pki_resteasy_jaxrs_jar_link'])
+ deployer.symlink.create(deployer.master_dict['pki_resteasy_jettison_provider_jar'],
+ deployer.master_dict['pki_resteasy_jettison_provider_jar_link'])
+ deployer.symlink.create(deployer.master_dict['pki_scannotation_jar'],
+ deployer.master_dict['pki_scannotation_jar_link'])
+ if deployer.master_dict['pki_subsystem'] == 'TKS':
+ deployer.symlink.create(deployer.master_dict['pki_symkey_jar'],
+ deployer.master_dict['pki_symkey_jar_link'])
+ deployer.symlink.create(deployer.master_dict['pki_tomcatjss_jar'],
+ deployer.master_dict['pki_tomcatjss_jar_link'])
+ deployer.symlink.create(deployer.master_dict['pki_velocity_jar'],
+ deployer.master_dict['pki_velocity_jar_link'])
+ deployer.symlink.create(deployer.master_dict['pki_xerces_j2_jar'],
+ deployer.master_dict['pki_xerces_j2_jar_link'])
+ deployer.symlink.create(deployer.master_dict['pki_xml_commons_apis_jar'],
+ deployer.master_dict['pki_xml_commons_apis_jar_link'])
+ deployer.symlink.create(deployer.master_dict['pki_xml_commons_resolver_jar'],
+ deployer.master_dict['pki_xml_commons_resolver_jar_link'])
+ # establish shared NSS security databases for this instance
+ deployer.directory.create(deployer.master_dict['pki_database_path'])
+ # establish instance convenience symbolic links
+ deployer.symlink.create(deployer.master_dict['pki_database_path'],
+ deployer.master_dict['pki_instance_database_link'])
+ deployer.symlink.create(deployer.master_dict['pki_instance_configuration_path'],
+ deployer.master_dict['pki_instance_conf_link'])
+ deployer.symlink.create(deployer.master_dict['pki_instance_log_path'],
+ deployer.master_dict['pki_instance_logs_link'])
+ return self.rv
+
+ def destroy(self, deployer):
+
+ config.pki_log.info(log.INSTANCE_DESTROY_1, __name__,
+ extra=config.PKI_INDENTATION_LEVEL_1)
+ if deployer.master_dict['pki_subsystem'] == 'TKS':
+ deployer.symlink.delete(deployer.master_dict['pki_symkey_jar_link'])
+ if deployer.master_dict['pki_subsystem'] in config.PKI_APACHE_SUBSYSTEMS and\
+ deployer.instance.apache_instance_subsystems() == 0:
+ # remove Apache instance base
+ deployer.directory.delete(deployer.master_dict['pki_instance_path'])
+ # remove Apache instance logs
+ # remove shared NSS security database path for this instance
+ deployer.directory.delete(deployer.master_dict['pki_database_path'])
+ # remove Apache instance configuration
+ deployer.directory.delete(deployer.master_dict['pki_instance_configuration_path'])
+ # remove Apache instance registry
+ deployer.directory.delete(deployer.master_dict['pki_instance_registry_path'])
+ # remove Apache PKI registry (if empty)
+ if deployer.instance.apache_instances() == 0:
+ deployer.directory.delete(
+ deployer.master_dict['pki_instance_type_registry_path'])
+ elif deployer.master_dict['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS and\
+ len(deployer.instance.tomcat_instance_subsystems()) == 0:
+ # remove Tomcat instance base
+ deployer.directory.delete(deployer.master_dict['pki_instance_path'])
+ # remove Tomcat instance logs
+ deployer.directory.delete(deployer.master_dict['pki_instance_log_path'])
+ # remove shared NSS security database path for this instance
+ deployer.directory.delete(deployer.master_dict['pki_database_path'])
+ # remove Tomcat instance configuration
+ deployer.directory.delete(deployer.master_dict['pki_instance_configuration_path'])
+ # remove PKI 'tomcat.conf' instance file
+ deployer.file.delete(deployer.master_dict['pki_target_tomcat_conf_instance_id'])
+ # remove Tomcat instance registry
+ deployer.directory.delete(deployer.master_dict['pki_instance_registry_path'])
+ # remove Tomcat PKI registry (if empty)
+ if deployer.instance.tomcat_instances() == 0:
+ deployer.directory.delete(
+ deployer.master_dict['pki_instance_type_registry_path'])
+ return self.rv
diff --git a/base/server/python/pki/server/deployment/scriptlets/security_databases.py b/base/server/python/pki/server/deployment/scriptlets/security_databases.py
new file mode 100644
index 000000000..3d3193cef
--- /dev/null
+++ b/base/server/python/pki/server/deployment/scriptlets/security_databases.py
@@ -0,0 +1,114 @@
+#!/usr/bin/python -t
+# Authors:
+# Matthew Harmsen <mharmsen@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright (C) 2012 Red Hat, Inc.
+# All rights reserved.
+#
+
+# PKI Deployment Imports
+from .. import pkiconfig as config
+from .. import pkimessages as log
+from .. import pkiscriptlet
+
+
+# PKI Deployment Security Databases Scriptlet
+class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
+ rv = 0
+
+ def spawn(self, deployer):
+
+ if config.str2bool(deployer.master_dict['pki_skip_installation']):
+ config.pki_log.info(log.SKIP_SECURITY_DATABASES_SPAWN_1, __name__,
+ extra=config.PKI_INDENTATION_LEVEL_1)
+ return self.rv
+ config.pki_log.info(log.SECURITY_DATABASES_SPAWN_1, __name__,
+ extra=config.PKI_INDENTATION_LEVEL_1)
+ deployer.password.create_password_conf(
+ deployer.master_dict['pki_shared_password_conf'],
+ deployer.master_dict['pki_pin'])
+ # Since 'certutil' does NOT strip the 'token=' portion of
+ # the 'token=password' entries, create a temporary server 'pfile'
+ # which ONLY contains the 'password' for the purposes of
+ # allowing 'certutil' to generate the security databases
+ deployer.password.create_password_conf(
+ deployer.master_dict['pki_shared_pfile'],
+ deployer.master_dict['pki_pin'], pin_sans_token=True)
+ deployer.file.modify(deployer.master_dict['pki_shared_password_conf'])
+ deployer.certutil.create_security_databases(
+ deployer.master_dict['pki_database_path'],
+ deployer.master_dict['pki_cert_database'],
+ deployer.master_dict['pki_key_database'],
+ deployer.master_dict['pki_secmod_database'],
+ password_file=deployer.master_dict['pki_shared_pfile'])
+ deployer.file.modify(deployer.master_dict['pki_cert_database'], perms=\
+ config.PKI_DEPLOYMENT_DEFAULT_SECURITY_DATABASE_PERMISSIONS)
+ deployer.file.modify(deployer.master_dict['pki_key_database'], perms=\
+ config.PKI_DEPLOYMENT_DEFAULT_SECURITY_DATABASE_PERMISSIONS)
+ deployer.file.modify(deployer.master_dict['pki_secmod_database'], perms=\
+ config.PKI_DEPLOYMENT_DEFAULT_SECURITY_DATABASE_PERMISSIONS)
+
+ if len(deployer.instance.tomcat_instance_subsystems()) < 2:
+ # only create a self signed cert for a new instance
+ rv = deployer.certutil.verify_certificate_exists(
+ deployer.master_dict['pki_database_path'],
+ deployer.master_dict['pki_cert_database'],
+ deployer.master_dict['pki_key_database'],
+ deployer.master_dict['pki_secmod_database'],
+ deployer.master_dict['pki_self_signed_token'],
+ deployer.master_dict['pki_self_signed_nickname'],
+ password_file=deployer.master_dict['pki_shared_pfile'])
+ if not rv:
+ deployer.file.generate_noise_file(
+ deployer.master_dict['pki_self_signed_noise_file'],
+ deployer.master_dict['pki_self_signed_noise_bytes'])
+ deployer.certutil.generate_self_signed_certificate(
+ deployer.master_dict['pki_database_path'],
+ deployer.master_dict['pki_cert_database'],
+ deployer.master_dict['pki_key_database'],
+ deployer.master_dict['pki_secmod_database'],
+ deployer.master_dict['pki_self_signed_token'],
+ deployer.master_dict['pki_self_signed_nickname'],
+ deployer.master_dict['pki_self_signed_subject'],
+ deployer.master_dict['pki_self_signed_serial_number'],
+ deployer.master_dict['pki_self_signed_validity_period'],
+ deployer.master_dict['pki_self_signed_issuer_name'],
+ deployer.master_dict['pki_self_signed_trustargs'],
+ deployer.master_dict['pki_self_signed_noise_file'],
+ password_file=deployer.master_dict['pki_shared_pfile'])
+ # Delete the temporary 'noise' file
+ deployer.file.delete(deployer.master_dict['pki_self_signed_noise_file'])
+ # Delete the temporary 'pfile'
+ deployer.file.delete(deployer.master_dict['pki_shared_pfile'])
+ return self.rv
+
+ def destroy(self, deployer):
+
+ config.pki_log.info(log.SECURITY_DATABASES_DESTROY_1, __name__,
+ extra=config.PKI_INDENTATION_LEVEL_1)
+ if deployer.master_dict['pki_subsystem'] in config.PKI_APACHE_SUBSYSTEMS and\
+ deployer.instance.apache_instance_subsystems() == 0:
+ deployer.file.delete(deployer.master_dict['pki_cert_database'])
+ deployer.file.delete(deployer.master_dict['pki_key_database'])
+ deployer.file.delete(deployer.master_dict['pki_secmod_database'])
+ deployer.file.delete(deployer.master_dict['pki_shared_password_conf'])
+ elif deployer.master_dict['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS and\
+ len(deployer.instance.tomcat_instance_subsystems()) == 0:
+ deployer.file.delete(deployer.master_dict['pki_cert_database'])
+ deployer.file.delete(deployer.master_dict['pki_key_database'])
+ deployer.file.delete(deployer.master_dict['pki_secmod_database'])
+ deployer.file.delete(deployer.master_dict['pki_shared_password_conf'])
+ return self.rv
diff --git a/base/server/python/pki/server/deployment/scriptlets/selinux_setup.py b/base/server/python/pki/server/deployment/scriptlets/selinux_setup.py
new file mode 100644
index 000000000..177233afc
--- /dev/null
+++ b/base/server/python/pki/server/deployment/scriptlets/selinux_setup.py
@@ -0,0 +1,204 @@
+#!/usr/bin/python -t
+# Authors:
+# Ade Lee <alee@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright (C) 2012 Red Hat, Inc.
+# All rights reserved.
+#
+
+import selinux
+import time
+if selinux.is_selinux_enabled():
+ import seobject
+
+# PKI Deployment Imports
+from .. import pkiconfig as config
+from ..pkiconfig import pki_selinux_config_ports as ports
+from .. import pkimessages as log
+from .. import pkiscriptlet
+
+
+# PKI Deployment Selinux Setup Scriptlet
+class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
+ rv = 0
+ suffix = "(/.*)?"
+
+ def restore_context(self, master_dict):
+ selinux.restorecon(master_dict['pki_instance_path'], True)
+ selinux.restorecon(config.PKI_DEPLOYMENT_LOG_ROOT, True)
+ selinux.restorecon(master_dict['pki_instance_log_path'], True)
+ selinux.restorecon(master_dict['pki_instance_configuration_path'], True)
+
+ def spawn(self, deployer):
+
+ if config.str2bool(deployer.master_dict['pki_skip_installation']):
+ config.pki_log.info(log.SKIP_SELINUX_SPAWN_1, __name__,
+ extra=config.PKI_INDENTATION_LEVEL_1)
+ return self.rv
+
+ if not bool(selinux.is_selinux_enabled()):
+ config.pki_log.info(log.SELINUX_DISABLED_SPAWN_1, __name__,
+ extra=config.PKI_INDENTATION_LEVEL_1)
+ return self.rv
+
+ config.pki_log.info(log.SELINUX_SPAWN_1, __name__,
+ extra=config.PKI_INDENTATION_LEVEL_1)
+ # A maximum of 10 tries to create the SELinux contexts
+ counter = 0
+ max_tries = 10
+ while True:
+ try:
+ # check first if any transactions are required
+ if len(ports) == 0 and deployer.master_dict['pki_instance_name'] == \
+ config.PKI_DEPLOYMENT_DEFAULT_TOMCAT_INSTANCE_NAME:
+ self.restore_context(deployer.master_dict)
+ return self.rv
+
+ # add SELinux contexts when adding the first subsystem
+ if deployer.master_dict['pki_subsystem'] in config.PKI_APACHE_SUBSYSTEMS and\
+ deployer.instance.apache_instance_subsystems() == 1 or\
+ deployer.master_dict['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS and\
+ len(deployer.instance.tomcat_instance_subsystems()) == 1:
+
+ trans = seobject.semanageRecords("targeted")
+ trans.start()
+ if deployer.master_dict['pki_instance_name'] != \
+ config.PKI_DEPLOYMENT_DEFAULT_TOMCAT_INSTANCE_NAME:
+
+ fcon = seobject.fcontextRecords()
+
+ config.pki_log.info("adding selinux fcontext \"%s\"",
+ deployer.master_dict['pki_instance_path'] + self.suffix,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ fcon.add(deployer.master_dict['pki_instance_path'] + self.suffix,
+ config.PKI_INSTANCE_SELINUX_CONTEXT, "", "s0", "")
+
+ config.pki_log.info("adding selinux fcontext \"%s\"",
+ deployer.master_dict['pki_instance_log_path'] + self.suffix,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ fcon.add(deployer.master_dict['pki_instance_log_path'] + self.suffix,
+ config.PKI_LOG_SELINUX_CONTEXT, "", "s0", "")
+
+ config.pki_log.info("adding selinux fcontext \"%s\"",
+ deployer.master_dict['pki_instance_configuration_path'] + self.suffix,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ fcon.add(deployer.master_dict['pki_instance_configuration_path'] + self.suffix,
+ config.PKI_CFG_SELINUX_CONTEXT, "", "s0", "")
+
+ config.pki_log.info("adding selinux fcontext \"%s\"",
+ deployer.master_dict['pki_database_path'] + self.suffix,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ fcon.add(deployer.master_dict['pki_database_path'] + self.suffix,
+ config.PKI_CERTDB_SELINUX_CONTEXT, "", "s0", "")
+
+ portRecords = seobject.portRecords()
+ for port in ports:
+ config.pki_log.info("adding selinux port %s", port,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ portRecords.add(port, "tcp", "s0", config.PKI_PORT_SELINUX_CONTEXT)
+
+ trans.finish()
+
+ self.restore_context(deployer.master_dict)
+ break
+ except ValueError as e:
+ error_message = str(e)
+ config.pki_log.debug(error_message)
+ if error_message.strip() == "Could not start semanage transaction":
+ counter = counter + 1
+ if counter >= max_tries:
+ raise
+ time.sleep(5)
+ config.pki_log.debug("Retrying to setup the selinux context ...")
+ else:
+ raise
+
+ return self.rv
+
+ def destroy(self, deployer):
+
+ if not bool(selinux.is_selinux_enabled()):
+ config.pki_log.info(log.SELINUX_DISABLED_DESTROY_1, __name__,
+ extra=config.PKI_INDENTATION_LEVEL_1)
+ return self.rv
+ config.pki_log.info(log.SELINUX_DESTROY_1, __name__,
+ extra=config.PKI_INDENTATION_LEVEL_1)
+
+ # check first if any transactions are required
+ if (len(ports) == 0 and deployer.master_dict['pki_instance_name'] ==
+ config.PKI_DEPLOYMENT_DEFAULT_TOMCAT_INSTANCE_NAME):
+ return self.rv
+ # A maximum of 10 tries to delete the SELinux contexts
+ counter = 1
+ max_tries = 10
+ while True:
+ try:
+ # remove SELinux contexts when removing the last subsystem
+ if (deployer.master_dict['pki_subsystem'] in config.PKI_APACHE_SUBSYSTEMS and
+ deployer.instance.apache_instance_subsystems() == 0 or
+ deployer.master_dict['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS and
+ len(deployer.instance.tomcat_instance_subsystems()) == 0):
+
+ trans = seobject.semanageRecords("targeted")
+ trans.start()
+
+ if deployer.master_dict['pki_instance_name'] != \
+ config.PKI_DEPLOYMENT_DEFAULT_TOMCAT_INSTANCE_NAME:
+
+ fcon = seobject.fcontextRecords()
+
+ config.pki_log.info("deleting selinux fcontext \"%s\"",
+ deployer.master_dict['pki_instance_path'] + self.suffix,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ fcon.delete(deployer.master_dict['pki_instance_path'] + self.suffix , "")
+
+ config.pki_log.info("deleting selinux fcontext \"%s\"",
+ deployer.master_dict['pki_instance_log_path'] + self.suffix,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ fcon.delete(deployer.master_dict['pki_instance_log_path'] + self.suffix, "")
+
+ config.pki_log.info("deleting selinux fcontext \"%s\"",
+ deployer.master_dict['pki_instance_configuration_path'] + self.suffix,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ fcon.delete(deployer.master_dict['pki_instance_configuration_path'] +
+ self.suffix, "")
+
+ config.pki_log.info("deleting selinux fcontext \"%s\"",
+ deployer.master_dict['pki_database_path'] + self.suffix,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ fcon.delete(deployer.master_dict['pki_database_path'] + self.suffix , "")
+
+ portRecords = seobject.portRecords()
+ for port in ports:
+ config.pki_log.info("deleting selinux port %s", port,
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ portRecords.delete(port, "tcp")
+
+ trans.finish()
+ break
+ except ValueError as e:
+ error_message = str(e)
+ config.pki_log.debug(error_message)
+ if error_message.strip() == "Could not start semanage transaction":
+ counter = counter + 1
+ if counter >= max_tries:
+ raise
+ time.sleep(5)
+ config.pki_log.debug("Retrying to remove selinux context ...")
+ else:
+ raise
+
+ return self.rv
diff --git a/base/server/python/pki/server/deployment/scriptlets/slot_substitution.py b/base/server/python/pki/server/deployment/scriptlets/slot_substitution.py
new file mode 100644
index 000000000..726b6dfc0
--- /dev/null
+++ b/base/server/python/pki/server/deployment/scriptlets/slot_substitution.py
@@ -0,0 +1,96 @@
+#!/usr/bin/python -t
+# Authors:
+# Matthew Harmsen <mharmsen@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright (C) 2012 Red Hat, Inc.
+# All rights reserved.
+#
+
+# PKI Deployment Imports
+from .. import pkiconfig as config
+from .. import pkimessages as log
+from .. import pkiscriptlet
+
+
+# PKI Deployment Slot Substitution Scriptlet
+class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
+ rv = 0
+
+ def spawn(self, deployer):
+
+ if config.str2bool(deployer.master_dict['pki_skip_installation']):
+ config.pki_log.info(log.SKIP_SLOT_ASSIGNMENT_SPAWN_1, __name__,
+ extra=config.PKI_INDENTATION_LEVEL_1)
+ return self.rv
+ config.pki_log.info(log.SLOT_ASSIGNMENT_SPAWN_1, __name__,
+ extra=config.PKI_INDENTATION_LEVEL_1)
+ deployer.file.copy_with_slot_substitution(deployer.master_dict['pki_source_cs_cfg'],
+ deployer.master_dict['pki_target_cs_cfg'])
+ deployer.file.copy_with_slot_substitution(deployer.master_dict['pki_source_registry'],
+ deployer.master_dict['pki_target_registry'],
+ uid=0, gid=0, overwrite_flag=True)
+ if deployer.master_dict['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS:
+ deployer.file.copy_with_slot_substitution(
+ deployer.master_dict['pki_source_catalina_properties'],
+ deployer.master_dict['pki_target_catalina_properties'],
+ overwrite_flag=True)
+ deployer.file.copy_with_slot_substitution(
+ deployer.master_dict['pki_source_servercertnick_conf'],
+ deployer.master_dict['pki_target_servercertnick_conf'],
+ overwrite_flag=True)
+ deployer.file.copy_with_slot_substitution(
+ deployer.master_dict['pki_source_server_xml'],
+ deployer.master_dict['pki_target_server_xml'],
+ overwrite_flag=True)
+ deployer.file.copy_with_slot_substitution(
+ deployer.master_dict['pki_source_context_xml'],
+ deployer.master_dict['pki_target_context_xml'],
+ overwrite_flag=True)
+ deployer.file.copy_with_slot_substitution(
+ deployer.master_dict['pki_source_tomcat_conf'],
+ deployer.master_dict['pki_target_tomcat_conf_instance_id'],
+ uid=0, gid=0, overwrite_flag=True)
+ deployer.file.copy_with_slot_substitution(
+ deployer.master_dict['pki_source_tomcat_conf'],
+ deployer.master_dict['pki_target_tomcat_conf'],
+ overwrite_flag=True)
+ deployer.file.apply_slot_substitution(
+ deployer.master_dict['pki_target_velocity_properties'])
+ deployer.file.apply_slot_substitution(
+ deployer.master_dict['pki_target_subsystem_web_xml'])
+ # Strip "<filter>" section from subsystem "web.xml"
+ # This is ONLY necessary because XML comments cannot be "nested"!
+ # deployer.file.copy(deployer.master_dict['pki_target_subsystem_web_xml'],
+ # deployer.master_dict['pki_target_subsystem_web_xml_orig'])
+ # deployer.file.delete(deployer.master_dict['pki_target_subsystem_web_xml'])
+ # util.xml_file.remove_filter_section_from_web_xml(
+ # deployer.master_dict['pki_target_subsystem_web_xml_orig'],
+ # deployer.master_dict['pki_target_subsystem_web_xml'])
+ # deployer.file.delete(deployer.master_dict['pki_target_subsystem_web_xml_orig'])
+ if deployer.master_dict['pki_subsystem'] == "CA":
+ deployer.file.copy_with_slot_substitution(
+ deployer.master_dict['pki_source_proxy_conf'],
+ deployer.master_dict['pki_target_proxy_conf'])
+ deployer.file.apply_slot_substitution(
+ deployer.master_dict['pki_target_profileselect_template'])
+ return self.rv
+
+ def destroy(self, deployer):
+ config.pki_log.info(log.SLOT_ASSIGNMENT_DESTROY_1, __name__,
+ extra=config.PKI_INDENTATION_LEVEL_1)
+ config.pki_log.info("NOTHING NEEDS TO BE IMPLEMENTED",
+ extra=config.PKI_INDENTATION_LEVEL_2)
+ return self.rv
diff --git a/base/server/python/pki/server/deployment/scriptlets/subsystem_layout.py b/base/server/python/pki/server/deployment/scriptlets/subsystem_layout.py
new file mode 100644
index 000000000..8aae3f6c6
--- /dev/null
+++ b/base/server/python/pki/server/deployment/scriptlets/subsystem_layout.py
@@ -0,0 +1,121 @@
+#!/usr/bin/python -t
+# Authors:
+# Matthew Harmsen <mharmsen@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright (C) 2012 Red Hat, Inc.
+# All rights reserved.
+#
+
+# PKI Deployment Imports
+from .. import pkiconfig as config
+from .. import pkimessages as log
+from .. import pkiscriptlet
+
+
+# PKI Deployment Subsystem Layout Scriptlet
+class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
+ rv = 0
+
+ def spawn(self, deployer):
+
+ if config.str2bool(deployer.master_dict['pki_skip_installation']):
+ config.pki_log.info(log.SKIP_SUBSYSTEM_SPAWN_1, __name__,
+ extra=config.PKI_INDENTATION_LEVEL_1)
+ return self.rv
+ config.pki_log.info(log.SUBSYSTEM_SPAWN_1, __name__,
+ extra=config.PKI_INDENTATION_LEVEL_1)
+ # establish instance-based subsystem logs
+ deployer.directory.create(deployer.master_dict['pki_subsystem_log_path'])
+ deployer.directory.create(deployer.master_dict['pki_subsystem_archive_log_path'])
+ if deployer.master_dict['pki_subsystem'] in config.PKI_SIGNED_AUDIT_SUBSYSTEMS:
+ deployer.directory.create(deployer.master_dict['pki_subsystem_signed_audit_log_path'])
+ # establish instance-based subsystem configuration
+ deployer.directory.create(deployer.master_dict['pki_subsystem_configuration_path'])
+ # deployer.directory.copy(deployer.master_dict['pki_source_conf_path'],
+ # deployer.master_dict['pki_subsystem_configuration_path'])
+ # establish instance-based Apache/Tomcat specific subsystems
+ if deployer.master_dict['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS:
+ # establish instance-based Tomcat PKI subsystem base
+ if deployer.master_dict['pki_subsystem'] == "CA":
+ deployer.directory.copy(deployer.master_dict['pki_source_emails'],
+ deployer.master_dict['pki_subsystem_emails_path'])
+ deployer.directory.copy(deployer.master_dict['pki_source_profiles'],
+ deployer.master_dict['pki_subsystem_profiles_path'])
+ # establish instance-based Tomcat PKI subsystem logs
+ # establish instance-based Tomcat PKI subsystem configuration
+ if deployer.master_dict['pki_subsystem'] == "CA":
+ deployer.file.copy(deployer.master_dict['pki_source_flatfile_txt'],
+ deployer.master_dict['pki_target_flatfile_txt'])
+ deployer.file.copy(deployer.master_dict['pki_source_registry_cfg'],
+ deployer.master_dict['pki_target_registry_cfg'])
+ # '*.profile'
+ deployer.file.copy(deployer.master_dict['pki_source_admincert_profile'],
+ deployer.master_dict['pki_target_admincert_profile'])
+ deployer.file.copy(deployer.master_dict['pki_source_caauditsigningcert_profile'],
+ deployer.master_dict['pki_target_caauditsigningcert_profile'])
+ deployer.file.copy(deployer.master_dict['pki_source_cacert_profile'],
+ deployer.master_dict['pki_target_cacert_profile'])
+ deployer.file.copy(deployer.master_dict['pki_source_caocspcert_profile'],
+ deployer.master_dict['pki_target_caocspcert_profile'])
+ deployer.file.copy(deployer.master_dict['pki_source_servercert_profile'],
+ deployer.master_dict['pki_target_servercert_profile'])
+ deployer.file.copy(deployer.master_dict['pki_source_subsystemcert_profile'],
+ deployer.master_dict['pki_target_subsystemcert_profile'])
+ elif deployer.master_dict['pki_subsystem'] == "KRA":
+ # '*.profile'
+ deployer.file.copy(deployer.master_dict['pki_source_servercert_profile'],
+ deployer.master_dict['pki_target_servercert_profile'])
+ deployer.file.copy(deployer.master_dict['pki_source_storagecert_profile'],
+ deployer.master_dict['pki_target_storagecert_profile'])
+ deployer.file.copy(deployer.master_dict['pki_source_subsystemcert_profile'],
+ deployer.master_dict['pki_target_subsystemcert_profile'])
+ deployer.file.copy(deployer.master_dict['pki_source_transportcert_profile'],
+ deployer.master_dict['pki_target_transportcert_profile'])
+ # establish instance-based Tomcat PKI subsystem registry
+ # establish instance-based Tomcat PKI subsystem convenience
+ # symbolic links
+ deployer.symlink.create(deployer.master_dict['pki_tomcat_webapps_path'],
+ deployer.master_dict['pki_subsystem_tomcat_webapps_link'])
+ # establish instance-based subsystem convenience symbolic links
+ deployer.symlink.create(deployer.master_dict['pki_instance_database_link'],
+ deployer.master_dict['pki_subsystem_database_link'])
+ deployer.symlink.create(deployer.master_dict['pki_subsystem_configuration_path'],
+ deployer.master_dict['pki_subsystem_conf_link'])
+ deployer.symlink.create(deployer.master_dict['pki_subsystem_log_path'],
+ deployer.master_dict['pki_subsystem_logs_link'])
+ deployer.symlink.create(deployer.master_dict['pki_instance_registry_path'],
+ deployer.master_dict['pki_subsystem_registry_link'])
+ return self.rv
+
+ def destroy(self, deployer):
+
+ config.pki_log.info(log.SUBSYSTEM_DESTROY_1, __name__,
+ extra=config.PKI_INDENTATION_LEVEL_1)
+ # remove instance-based subsystem base
+ if deployer.master_dict['pki_subsystem'] == "CA":
+ deployer.directory.delete(deployer.master_dict['pki_subsystem_emails_path'])
+ deployer.directory.delete(deployer.master_dict['pki_subsystem_profiles_path'])
+ deployer.directory.delete(deployer.master_dict['pki_subsystem_path'])
+ # remove instance-based subsystem logs
+ if deployer.master_dict['pki_subsystem'] in config.PKI_SIGNED_AUDIT_SUBSYSTEMS:
+ deployer.directory.delete(deployer.master_dict['pki_subsystem_signed_audit_log_path'])
+ deployer.directory.delete(deployer.master_dict['pki_subsystem_archive_log_path'])
+ deployer.directory.delete(deployer.master_dict['pki_subsystem_log_path'])
+ # remove instance-based subsystem configuration
+ deployer.directory.delete(deployer.master_dict['pki_subsystem_configuration_path'])
+ # remove instance-based subsystem registry
+ deployer.directory.delete(deployer.master_dict['pki_subsystem_registry_path'])
+ return self.rv
diff --git a/base/server/python/pki/server/deployment/scriptlets/webapp_deployment.py b/base/server/python/pki/server/deployment/scriptlets/webapp_deployment.py
new file mode 100644
index 000000000..ccbf4ea90
--- /dev/null
+++ b/base/server/python/pki/server/deployment/scriptlets/webapp_deployment.py
@@ -0,0 +1,165 @@
+#!/usr/bin/python -t
+# Authors:
+# Matthew Harmsen <mharmsen@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright (C) 2012 Red Hat, Inc.
+# All rights reserved.
+#
+
+# System Imports
+import os
+
+# PKI Deployment Imports
+from .. import pkiconfig as config
+from .. import pkimessages as log
+from .. import pkiscriptlet
+
+
+# PKI Web Application Deployment Scriptlet
+class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
+ rv = 0
+
+ def spawn(self, deployer):
+
+ if deployer.master_dict['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS:
+ if config.str2bool(deployer.master_dict['pki_skip_installation']):
+ config.pki_log.info(log.SKIP_WEBAPP_DEPLOYMENT_SPAWN_1,
+ __name__,
+ extra=config.PKI_INDENTATION_LEVEL_1)
+ return self.rv
+ config.pki_log.info(log.WEBAPP_DEPLOYMENT_SPAWN_1, __name__,
+ extra=config.PKI_INDENTATION_LEVEL_1)
+
+ # Copy /usr/share/pki/server/webapps/ROOT
+ # to <instance>/webapps/ROOT
+ deployer.directory.create(deployer.master_dict['pki_tomcat_webapps_root_path'])
+ deployer.directory.copy(
+ os.path.join(
+ config.PKI_DEPLOYMENT_SOURCE_ROOT,
+ "server",
+ "webapps",
+ "ROOT"),
+ deployer.master_dict['pki_tomcat_webapps_root_path'],
+ overwrite_flag=True)
+
+ deployer.directory.create(deployer.master_dict['pki_tomcat_webapps_common_path'])
+
+ # If desired and available,
+ # copy selected server theme
+ # to <instance>/webapps/pki
+ if config.str2bool(deployer.master_dict['pki_theme_enable']) and\
+ os.path.exists(deployer.master_dict['pki_theme_server_dir']):
+ deployer.directory.copy(deployer.master_dict['pki_theme_server_dir'],
+ deployer.master_dict['pki_tomcat_webapps_common_path'],
+ overwrite_flag=True)
+
+ # Copy /usr/share/pki/server/webapps/pki/js
+ # to <instance>/webapps/pki/js
+ deployer.directory.copy(
+ os.path.join(
+ config.PKI_DEPLOYMENT_SOURCE_ROOT,
+ "server",
+ "webapps",
+ "pki",
+ "js"),
+ os.path.join(
+ deployer.master_dict['pki_tomcat_webapps_common_path'],
+ "js"),
+ overwrite_flag=True)
+
+ # Copy /usr/share/pki/server/webapps/pki/META-INF
+ # to <instance>/webapps/pki/META-INF
+ deployer.directory.copy(
+ os.path.join(
+ config.PKI_DEPLOYMENT_SOURCE_ROOT,
+ "server",
+ "webapps",
+ "pki",
+ "META-INF"),
+ os.path.join(
+ deployer.master_dict['pki_tomcat_webapps_common_path'],
+ "META-INF"),
+ overwrite_flag=True)
+
+ # Copy /usr/share/pki/server/webapps/pki/admin
+ # to <instance>/webapps/<subsystem>/admin
+ # TODO: common templates should be deployed in common webapp
+ deployer.directory.create(deployer.master_dict['pki_tomcat_webapps_subsystem_path'])
+ deployer.directory.copy(
+ os.path.join(
+ config.PKI_DEPLOYMENT_SOURCE_ROOT,
+ "server",
+ "webapps",
+ "pki",
+ "admin"),
+ os.path.join(
+ deployer.master_dict['pki_tomcat_webapps_subsystem_path'],
+ "admin"),
+ overwrite_flag=True)
+
+ # Copy /usr/share/pki/<subsystem>/webapps/<subsystem>
+ # to <instance>/webapps/<subsystem>
+ deployer.directory.copy(
+ os.path.join(
+ config.PKI_DEPLOYMENT_SOURCE_ROOT,
+ deployer.master_dict['pki_subsystem'].lower(),
+ "webapps",
+ deployer.master_dict['pki_subsystem'].lower()),
+ deployer.master_dict['pki_tomcat_webapps_subsystem_path'],
+ overwrite_flag=True)
+
+ deployer.directory.create(
+ deployer.master_dict['pki_tomcat_webapps_subsystem_webinf_classes_path'])
+ deployer.directory.create(
+ deployer.master_dict['pki_tomcat_webapps_subsystem_webinf_lib_path'])
+ # establish Tomcat webapps subsystem WEB-INF lib symbolic links
+ deployer.symlink.create(deployer.master_dict['pki_certsrv_jar'],
+ deployer.master_dict['pki_certsrv_jar_link'])
+ deployer.symlink.create(deployer.master_dict['pki_cmsbundle'],
+ deployer.master_dict['pki_cmsbundle_jar_link'])
+ deployer.symlink.create(deployer.master_dict['pki_cmscore'],
+ deployer.master_dict['pki_cmscore_jar_link'])
+ deployer.symlink.create(deployer.master_dict['pki_cms'],
+ deployer.master_dict['pki_cms_jar_link'])
+ deployer.symlink.create(deployer.master_dict['pki_cmsutil'],
+ deployer.master_dict['pki_cmsutil_jar_link'])
+ deployer.symlink.create(deployer.master_dict['pki_nsutil'],
+ deployer.master_dict['pki_nsutil_jar_link'])
+ if deployer.master_dict['pki_subsystem'] == "CA":
+ deployer.symlink.create(deployer.master_dict['pki_ca_jar'],
+ deployer.master_dict['pki_ca_jar_link'])
+ elif deployer.master_dict['pki_subsystem'] == "KRA":
+ deployer.symlink.create(deployer.master_dict['pki_kra_jar'],
+ deployer.master_dict['pki_kra_jar_link'])
+ elif deployer.master_dict['pki_subsystem'] == "OCSP":
+ deployer.symlink.create(deployer.master_dict['pki_ocsp_jar'],
+ deployer.master_dict['pki_ocsp_jar_link'])
+ elif deployer.master_dict['pki_subsystem'] == "TKS":
+ deployer.symlink.create(deployer.master_dict['pki_tks_jar'],
+ deployer.master_dict['pki_tks_jar_link'])
+ elif deployer.master_dict['pki_subsystem'] == "TPS":
+ deployer.symlink.create(deployer.master_dict['pki_tps_jar'],
+ deployer.master_dict['pki_tps_jar_link'])
+ # set ownerships, permissions, and acls
+ deployer.directory.set_mode(deployer.master_dict['pki_tomcat_webapps_subsystem_path'])
+ return self.rv
+
+ def destroy(self, deployer):
+ if deployer.master_dict['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS:
+ config.pki_log.info(log.WEBAPP_DEPLOYMENT_DESTROY_1, __name__,
+ extra=config.PKI_INDENTATION_LEVEL_1)
+ deployer.directory.delete(deployer.master_dict['pki_tomcat_webapps_subsystem_path'])
+ return self.rv