summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--install/conf/ipa-pki-proxy.conf4
-rw-r--r--install/restart_scripts/renew_ca_cert13
-rwxr-xr-xinstall/tools/ipa-ca-install2
-rwxr-xr-xinstall/tools/ipa-replica-install31
-rwxr-xr-xinstall/tools/ipa-server-install37
-rw-r--r--install/tools/ipa-upgradeconfig2
-rw-r--r--ipapython/dogtag.py1
-rw-r--r--ipaserver/install/cainstance.py410
-rw-r--r--ipaserver/install/dogtaginstance.py311
-rw-r--r--ipaserver/install/drminstance.py337
-rw-r--r--ipaserver/install/installutils.py17
-rw-r--r--ipaserver/install/ipa_replica_prepare.py1
12 files changed, 869 insertions, 297 deletions
diff --git a/install/conf/ipa-pki-proxy.conf b/install/conf/ipa-pki-proxy.conf
index 224cdd45b..9a6345898 100644
--- a/install/conf/ipa-pki-proxy.conf
+++ b/install/conf/ipa-pki-proxy.conf
@@ -11,7 +11,7 @@ ProxyRequests Off
</LocationMatch>
# matches for admin port and installer
-<LocationMatch "^/ca/admin/ca/getCertChain|^/ca/admin/ca/getConfigEntries|^/ca/admin/ca/getCookie|^/ca/admin/ca/getStatus|^/ca/admin/ca/securityDomainLogin|^/ca/admin/ca/getDomainXML|^/ca/rest/installer/installToken|^/ca/admin/ca/updateNumberRange|^/ca/rest/securityDomain/domainInfo|^/ca/rest/account/login|^/ca/admin/ca/tokenAuthenticate|^/ca/admin/ca/updateNumberRange|^/ca/admin/ca/updateDomainXML|^/ca/rest/account/logout|^/ca/rest/securityDomain/installToken">
+<LocationMatch "^/ca/admin/ca/getCertChain|^/ca/admin/ca/getConfigEntries|^/ca/admin/ca/getCookie|^/ca/admin/ca/getStatus|^/ca/admin/ca/securityDomainLogin|^/ca/admin/ca/getDomainXML|^/ca/rest/installer/installToken|^/ca/admin/ca/updateNumberRange|^/ca/rest/securityDomain/domainInfo|^/ca/rest/account/login|^/ca/admin/ca/tokenAuthenticate|^/ca/admin/ca/updateNumberRange|^/ca/admin/ca/updateDomainXML|^/ca/rest/account/logout|^/ca/rest/securityDomain/installToken|^/ca/admin/ca/updateConnector|^/ca/admin/ca/getSubsystemCert|^/kra/admin/kra/updateNumberRange|^/kra/admin/kra/getConfigEntries">
NSSOptions +StdEnvVars +ExportCertData +StrictRequire +OptRenegotiate
NSSVerifyClient none
ProxyPassMatch ajp://localhost:$DOGTAG_PORT
@@ -19,7 +19,7 @@ ProxyRequests Off
</LocationMatch>
# matches for agent port and eeca port
-<LocationMatch "^/ca/agent/ca/displayBySerial|^/ca/agent/ca/doRevoke|^/ca/agent/ca/doUnrevoke|^/ca/agent/ca/updateDomainXML|^/ca/eeca/ca/profileSubmitSSLClient">
+<LocationMatch "^/ca/agent/ca/displayBySerial|^/ca/agent/ca/doRevoke|^/ca/agent/ca/doUnrevoke|^/ca/agent/ca/updateDomainXML|^/ca/eeca/ca/profileSubmitSSLClient|^/kra/agent/kra/connector">
NSSOptions +StdEnvVars +ExportCertData +StrictRequire +OptRenegotiate
NSSVerifyClient require
ProxyPassMatch ajp://localhost:$DOGTAG_PORT
diff --git a/install/restart_scripts/renew_ca_cert b/install/restart_scripts/renew_ca_cert
index 2663887d6..d9c98d5ce 100644
--- a/install/restart_scripts/renew_ca_cert
+++ b/install/restart_scripts/renew_ca_cert
@@ -21,17 +21,13 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import sys
-import os
import syslog
-import tempfile
-import shutil
import traceback
-from ipapython import dogtag, certmonger, ipautil
+from ipapython import dogtag, ipautil
from ipapython import services as ipaservices
-from ipalib import api, errors, x509, util
-from ipaserver.install import certs, cainstance, installutils
-from ipaserver.plugins.ldap2 import ldap2
+from ipalib import api
+from ipaserver.install import certs, cainstance
def main():
nickname = sys.argv[1]
@@ -68,9 +64,8 @@ def main():
syslog.syslog(syslog.LOG_ERR, 'No certificate %s found.' % nickname)
sys.exit(1)
- cainstance.update_cert_config(nickname, cert, configured_constants)
-
ca = cainstance.CAInstance(api.env.realm, certs.NSS_DIR)
+ ca.update_cert_config(nickname, cert, configured_constants)
if ca.is_renewal_master():
cainstance.update_people_entry(cert)
diff --git a/install/tools/ipa-ca-install b/install/tools/ipa-ca-install
index 18c81dc1f..d4a287951 100755
--- a/install/tools/ipa-ca-install
+++ b/install/tools/ipa-ca-install
@@ -184,7 +184,7 @@ def main():
ipautil.realm_to_suffix(config.realm_name))
# This is done within stopped_service context, which restarts CA
- CA.enable_client_auth_to_db()
+ CA.enable_client_auth_to_db(CA.dogtag_constants.CS_CFG_PATH)
# Install CA DNS records
install_dns_records(config, options)
diff --git a/install/tools/ipa-replica-install b/install/tools/ipa-replica-install
index 41c1a0533..b79aeade2 100755
--- a/install/tools/ipa-replica-install
+++ b/install/tools/ipa-replica-install
@@ -38,9 +38,10 @@ from ipaserver.install import otpdinstance
from ipaserver.install.replication import replica_conn_check, ReplicationManager
from ipaserver.install.installutils import (ReplicaConfig, expand_replica_info,
read_replica_info, get_host_name, BadHostError, private_ccache,
- read_replica_info_dogtag_port)
+ read_replica_info_dogtag_port, read_replica_info_drm_enabled)
from ipaserver.plugins.ldap2 import ldap2
from ipaserver.install import cainstance
+from ipaserver.install import drminstance
from ipalib import api, errors, util
from ipalib.constants import CACERT
from ipapython import version
@@ -63,6 +64,8 @@ def parse_options():
basic_group = OptionGroup(parser, "basic options")
basic_group.add_option("--setup-ca", dest="setup_ca", action="store_true",
default=False, help="configure a dogtag CA")
+ basic_group.add_option("--setup-drm", dest="setup_drm", action="store_true",
+ default=False, help="configure a dogtag DRM")
basic_group.add_option("--ip-address", dest="ip_address",
type="ip", ip_local=True,
help="Replica server IP Address")
@@ -541,6 +544,15 @@ def main():
print 'CA cannot be installed in CA-less setup.'
sys.exit(1)
+ config.setup_drm = options.setup_drm
+ if config.setup_drm:
+ if not config.setup_ca:
+ print "CA must be installed with the KRA"
+ sys.exit(1)
+ if not read_replica_info_drm_enabled(config.dir):
+ print "DRM is not installed on the master system"
+ sys.exit(1)
+
installutils.verify_fqdn(config.master_host_name, options.no_host_dns)
# check connection
@@ -574,6 +586,10 @@ def main():
else:
fd.write("enable_ra=False\n")
fd.write("ra_plugin=none\n")
+ if config.setup_drm:
+ fd.write("enable_drm=True\n")
+ else:
+ fd.write("enable_drm=False\n")
fd.write("mode=production\n")
fd.close()
finally:
@@ -684,7 +700,7 @@ def main():
ipautil.realm_to_suffix(config.realm_name))
# This is done within stopped_service context, which restarts CA
- CA.enable_client_auth_to_db()
+ CA.enable_client_auth_to_db(CA.dogtag_constants.CS_CFG_PATH)
krb = install_krb(config, setup_pkinit=options.setup_pkinit)
http = install_http(config, auto_redirect=options.ui_redirect)
@@ -707,9 +723,14 @@ def main():
service.print_msg("Applying LDAP updates")
ds.apply_updates()
- # Restart ds and krb after configurations have been changed
- service.print_msg("Restarting the directory server")
- ds.restart()
+ if options.setup_drm:
+ drm = drminstance.install_replica_drm(config)
+ service.print_msg("Restarting the directory server")
+ ds.restart()
+ drm.enable_client_auth_to_db(drm.dogtag_constants.DRM_CS_CFG_PATH)
+ else:
+ service.print_msg("Restarting the directory server")
+ ds.restart()
service.print_msg("Restarting the KDC")
krb.restart()
diff --git a/install/tools/ipa-server-install b/install/tools/ipa-server-install
index 232d84a2c..4aa6fcca5 100755
--- a/install/tools/ipa-server-install
+++ b/install/tools/ipa-server-install
@@ -3,7 +3,7 @@
# Simo Sorce <ssorce@redhat.com>
# Rob Crittenden <rcritten@redhat.com>
#
-# Copyright (C) 2007-2010 Red Hat
+# Copyright (C) 2007-2014 Red Hat
# see file 'COPYING' for use and warranty information
#
# This program is free software; you can redistribute it and/or modify
@@ -53,6 +53,7 @@ from ipaserver.install import httpinstance
from ipaserver.install import ntpinstance
from ipaserver.install import certs
from ipaserver.install import cainstance
+from ipaserver.install import drminstance
from ipaserver.install import memcacheinstance
from ipaserver.install import otpdinstance
from ipaserver.install import sysupgrade
@@ -492,11 +493,19 @@ def uninstall():
dogtag_constants=dogtag_constants)
if cads_instance.is_configured():
cads_instance.uninstall()
- cainstance.stop_tracking_certificates(dogtag_constants)
+
+ drm_instance = drminstance.DRMInstance(
+ api.env.realm, dogtag_constants=dogtag_constants)
+ drm_instance.stop_tracking_certificates(dogtag_constants)
+ if drm_instance.is_installed():
+ drm_instance.uninstall()
+
ca_instance = cainstance.CAInstance(
api.env.realm, certs.NSS_DIR, dogtag_constants=dogtag_constants)
+ ca_instance.stop_tracking_certificates(dogtag_constants)
if ca_instance.is_configured():
ca_instance.uninstall()
+
bindinstance.BindInstance(fstore).uninstall()
httpinstance.HTTPInstance(fstore).uninstall()
krbinstance.KrbInstance(fstore).uninstall()
@@ -755,6 +764,7 @@ def main():
setup_ca = False
else:
setup_ca = True
+ setup_drm = True
# Figure out what external CA step we're in. See cainstance.py for more
# info on the 3 states.
@@ -771,6 +781,8 @@ def main():
print "This includes:"
if setup_ca:
print " * Configure a stand-alone CA (dogtag) for certificate management"
+ if setup_drm:
+ print " * Configure a stand-alone DRM (dogtag) for key storage"
if options.conf_ntp:
print " * Configure the Network Time Daemon (ntpd)"
print " * Create and configure an instance of Directory Server"
@@ -1017,6 +1029,7 @@ def main():
else:
fd.write("enable_ra=False\n")
fd.write("ra_plugin=none\n")
+ fd.write("enable_drm=%s\n" % setup_drm)
fd.write("mode=production\n")
fd.close()
@@ -1118,7 +1131,7 @@ def main():
ipautil.realm_to_suffix(realm_name), ['caRenewalMaster'])
# This is done within stopped_service context, which restarts CA
- ca.enable_client_auth_to_db()
+ ca.enable_client_auth_to_db(ca.dogtag_constants.CS_CFG_PATH)
krb = krbinstance.KrbInstance(fstore)
if options.pkinit_pkcs12:
@@ -1195,6 +1208,17 @@ def main():
service.print_msg("Restarting the web server")
http.restart()
+ if setup_drm:
+ # code to create drm here
+ drm = drminstance.DRMInstance(realm_name,
+ dogtag_constants=dogtag.install_constants)
+ drm.configure_instance(host_name, domain_name, dm_password,
+ dm_password, subject_base=options.subject)
+
+ # This is done within stopped_service context, which restarts DRM
+ ds.restart()
+ drm.enable_client_auth_to_db(drm.dogtag_constants.DRM_CS_CFG_PATH)
+
# Set the admin user kerberos password
ds.change_admin_password(admin_password)
@@ -1247,9 +1271,10 @@ def main():
print ""
if setup_ca:
- print "Be sure to back up the CA certificate stored in /root/cacert.p12"
- print "This file is required to create replicas. The password for this"
- print "file is the Directory Manager password"
+ print "Be sure to back up the CA certificates stored in /root/cacert.p12"
+ print "and the DRM certificates stored in /root/drmcert.p12"
+ print "These files are required to create replicas. The password for these"
+ print "files is the Directory Manager password"
else:
print "In order for Firefox autoconfiguration to work you will need to"
print "use a SSL signing certificate. See the IPA documentation for more details."
diff --git a/install/tools/ipa-upgradeconfig b/install/tools/ipa-upgradeconfig
index 265d71c33..5f751becb 100644
--- a/install/tools/ipa-upgradeconfig
+++ b/install/tools/ipa-upgradeconfig
@@ -675,7 +675,7 @@ def certificate_renewal_update(ca):
# Ok, now we need to stop tracking, then we can start tracking them
# again with new configuration:
- cainstance.stop_tracking_certificates(dogtag_constants)
+ ca.stop_tracking_certificates(dogtag_constants)
if not sysupgrade.get_upgrade_state('dogtag',
'certificate_renewal_update_1'):
diff --git a/ipapython/dogtag.py b/ipapython/dogtag.py
index f829b9340..8c6c8ff06 100644
--- a/ipapython/dogtag.py
+++ b/ipapython/dogtag.py
@@ -61,6 +61,7 @@ class Dogtag10Constants(object):
PASSWORD_CONF_PATH = '%s/conf/password.conf' % PKI_ROOT
SERVICE_PROFILE_DIR = '%s/ca/profiles/ca' % PKI_ROOT
ALIAS_DIR = '/etc/pki/pki-tomcat/alias'
+ DRM_CS_CFG_PATH = '%s/conf/kra/CS.cfg' % PKI_ROOT
SERVICE_NAME = 'pki_tomcatd'
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index f52870424..8d627efa3 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -19,51 +19,47 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
-import pwd
+import array
+import base64
+import binascii
+import ConfigParser
+import dbus
+import httplib
+import ldap
import os
-import sys
+import pwd
import re
+import shutil
+import stat
+import subprocess
+import sys
+import syslog
import time
-import ldap
-import base64
-import array
import tempfile
-import binascii
-import shutil
-import httplib
import urllib
import xml.dom.minidom
-import stat
-import syslog
-import ConfigParser
-import dbus
-from ipapython import dogtag
-from ipapython.certdb import get_ca_nickname
-from ipapython import certmonger
from ipalib import api
from ipalib import pkcs10, x509
from ipalib import errors
-from ipapython.dn import DN
-import subprocess
-import traceback
+from ipapython import dogtag
+from ipapython import certmonger
from ipapython import ipautil
from ipapython import services as ipaservices
from ipapython import ipaldap
-from ipaserver.install import service
-from ipaserver.install import installutils
-from ipaserver.install import dsinstance
-from ipaserver.install import certs
-from ipaserver.install.installutils import stopped_service
-from ipaserver.plugins import ldap2
+from ipapython.certdb import get_ca_nickname
+from ipapython.dn import DN
from ipapython.ipa_log_manager import *
-HTTPD_CONFD = "/etc/httpd/conf.d/"
-DEFAULT_DSPORT = dogtag.install_constants.DS_PORT
+from ipaserver.install import certs
+from ipaserver.install import dsinstance
+from ipaserver.install import installutils
+from ipaserver.install import service
+from ipaserver.install.dogtaginstance import DogtagInstance
+from ipaserver.install.dogtaginstance import PKI_USER, DEFAULT_DSPORT
+from ipaserver.plugins import ldap2
-PKI_USER = "pkiuser"
-PKI_DS_USER = dogtag.install_constants.DS_USER
# When IPA is installed with DNS support, this CNAME should hold all IPA
# replicas with CA configured
@@ -86,23 +82,6 @@ RootDNPwd= $PASSWORD
ConfigFile = /usr/share/pki/ca/conf/database.ldif
"""
-def check_inst():
- """
- Validate that the appropriate dogtag/RHCS packages have been installed.
- """
-
- # Check for a couple of binaries we need
- if not os.path.exists(dogtag.install_constants.SPAWN_BINARY):
- return False
- if not os.path.exists(dogtag.install_constants.DESTROY_BINARY):
- return False
-
- # This is the template tomcat file for a CA
- if not os.path.exists('/usr/share/pki/ca/conf/server.xml'):
- return False
-
- return True
-
def get_preop_pin(instance_root, instance_name):
# Only used for Dogtag 9
preop_pin = None
@@ -282,7 +261,7 @@ class CADSInstance(service.Service):
serverid = self.restore_state("serverid")
# Just eat this state if it exists
- running = self.restore_state("running")
+ _running = self.restore_state("running")
if not enabled is None and not enabled:
ipaservices.knownservices.dirsrv.disable()
@@ -295,40 +274,14 @@ class CADSInstance(service.Service):
dsdb.untrack_server_cert("Server-Cert")
dsinstance.erase_ds_instance_data(serverid)
- user_exists = self.restore_state("user_exists")
+ _user_exists = self.restore_state("user_exists")
# At one time we removed this user on uninstall. That can potentially
# orphan files, or worse, if another useradd runs in the intermim,
# cause files to have a new owner.
-def stop_tracking_certificates(dogtag_constants):
- """Stop tracking our certificates. Called on uninstall.
- """
- cmonger = ipaservices.knownservices.certmonger
- ipaservices.knownservices.messagebus.start()
- cmonger.start()
-
- for nickname in ['Server-Cert cert-pki-ca',
- 'auditSigningCert cert-pki-ca',
- 'ocspSigningCert cert-pki-ca',
- 'subsystemCert cert-pki-ca']:
- try:
- certmonger.stop_tracking(
- dogtag_constants.ALIAS_DIR, nickname=nickname)
- except (ipautil.CalledProcessError, RuntimeError), e:
- root_logger.error(
- "certmonger failed to stop tracking certificate: %s" % str(e))
-
- try:
- certmonger.stop_tracking('/etc/httpd/alias', nickname='ipaCert')
- except (ipautil.CalledProcessError, RuntimeError), e:
- root_logger.error(
- "certmonger failed to stop tracking certificate: %s" % str(e))
- cmonger.stop()
-
-
-class CAInstance(service.Service):
+class CAInstance(DogtagInstance):
"""
When using a dogtag CA the DS database contains just the
server cert for DS. The mod_nss database will contain the RA agent
@@ -349,19 +302,8 @@ class CAInstance(service.Service):
if dogtag_constants is None:
dogtag_constants = dogtag.configured_constants()
- service.Service.__init__(self,
- '%sd' % dogtag_constants.PKI_INSTANCE_NAME,
- service_desc="certificate server"
- )
-
- self.dogtag_constants = dogtag_constants
- self.realm = realm
- self.dm_password = None
- self.admin_password = None
- self.fqdn = None
- self.domain = None
- self.pkcs12_info = None
- self.clone = False
+ DogtagInstance.__init__(self, realm, "CA", "certificate server",
+ dogtag_constants)
# for external CAs
self.external = 0
@@ -370,23 +312,12 @@ class CAInstance(service.Service):
self.cert_chain_file = None
self.create_ra_agent_db = True
- # The same database is used for mod_nss because the NSS context
- # will already have been initialized by Apache by the time
- # mod_python wants to do things.
self.canickname = get_ca_nickname(realm)
- self.basedn = DN(('o', 'ipaca'))
- self.ca_agent_db = tempfile.mkdtemp(prefix = "tmp-")
self.ra_agent_db = ra_db
self.ra_agent_pwd = self.ra_agent_db + "/pwdfile.txt"
- self.ds_port = DEFAULT_DSPORT
- self.security_domain_name = "IPA"
- self.server_root = dogtag_constants.SERVER_ROOT
self.ra_cert = None
self.requestId = None
- def __del__(self):
- shutil.rmtree(self.ca_agent_db, ignore_errors=True)
-
def is_installed(self):
"""
Installing with an external CA is a two-step process. This
@@ -446,10 +377,10 @@ class CAInstance(service.Service):
if not ipautil.dir_exists("/var/lib/pki-ca"):
self.step("creating pki-ca instance", self.create_instance)
self.step("configuring certificate server instance", self.__configure_instance)
- self.step("stopping certificate server instance to update CS.cfg", self.__stop)
+ self.step("stopping certificate server instance to update CS.cfg", self.stop_instance)
self.step("disabling nonces", self.__disable_nonce)
self.step("set up CRL publishing", self.__enable_crl_publish)
- self.step("starting certificate server instance", self.__start)
+ self.step("starting certificate server instance", self.start_instance)
# Step 1 of external is getting a CSR so we don't need to do these
# steps until we get a cert back from the external CA.
if self.external != 1:
@@ -464,9 +395,10 @@ class CAInstance(service.Service):
self.step("enabling Subject Key Identifier", self.enable_subject_key_identifier)
self.step("enabling CRL and OCSP extensions for certificates", self.__set_crl_ocsp_extensions)
self.step("setting audit signing renewal to 2 years", self.set_audit_renewal)
- self.step("configuring certificate server to start on boot", self.__enable)
+ self.step("configuring certificate server to start on boot",
+ self.enable)
if not self.clone:
- self.step("restarting certificate server", self.__restart_instance)
+ self.step("restarting certificate server", self.restart_instance)
self.step("requesting RA certificate from CA", self.__request_ra_certificate)
self.step("issuing RA agent certificate", self.__issue_ra_cert)
self.step("adding RA agent as a trusted user", self.__configure_ra)
@@ -475,22 +407,31 @@ class CAInstance(service.Service):
if not self.clone:
self.step("configure RA certificate renewal", self.configure_agent_renewal)
self.step("configure Server-Cert certificate renewal", self.track_servercert)
- self.step("Configure HTTP to proxy connections", self.__http_proxy)
+ self.step("Configure HTTP to proxy connections",
+ self.http_proxy)
self.start_creation(runtime=210)
- def __stop(self):
- self.stop()
+ def enable(self):
+ DogtagInstance.enable(self)
+
+ def start_instance(self):
+ DogtagInstance.start_instance(self)
- def __start(self):
- self.start()
+ def stop_instance(self):
+ DogtagInstance.stop_instance(self)
+ def restart_instance(self):
+ DogtagInstance.restart_instance(self)
+
+ def http_proxy(self):
+ DogtagInstance.http_proxy(self)
def __spawn_instance(self):
"""
Create and configure a new CA instance using pkispawn.
- pkispawn requires a configuration file with IPA-specific
- parameters.
+ Creates the config file with IPA specific parameters
+ and passes it to the base class to call pkispawn
"""
# Create an empty and secured file
@@ -512,7 +453,7 @@ class CAInstance(service.Service):
config.set("CA", "pki_backup_password", self.admin_password)
# Client security database
- config.set("CA", "pki_client_database_dir", self.ca_agent_db)
+ config.set("CA", "pki_client_database_dir", self.agent_db)
config.set("CA", "pki_client_database_password", self.admin_password)
config.set("CA", "pki_client_database_purge", "False")
config.set("CA", "pki_client_pkcs12_password", self.admin_password)
@@ -589,21 +530,8 @@ class CAInstance(service.Service):
with open(cfg_file, "wb") as f:
config.write(f)
- # Define the things we don't want logged
- nolog = (self.admin_password, self.dm_password,)
-
- args = ["/usr/sbin/pkispawn", "-s", "CA", "-f", cfg_file ]
-
- with open(cfg_file) as f:
- root_logger.debug(
- 'Contents of pkispawn configuration file (%s):\n%s' %
- (cfg_file, ipautil.nolog_replace(f.read(), nolog)))
-
try:
- ipautil.run(args, nolog=nolog)
- except ipautil.CalledProcessError, e:
- root_logger.critical("failed to configure ca instance %s" % e)
- raise RuntimeError('Configuration of CA failed')
+ DogtagInstance.spawn_instance(self, cfg_file)
finally:
os.remove(cfg_file)
@@ -645,14 +573,6 @@ class CAInstance(service.Service):
]
ipautil.run(args, env={'PKI_HOSTNAME':self.fqdn})
- def __enable(self):
- self.backup_state("enabled", self.is_enabled())
- # We do not let the system start IPA components on its own,
- # Instead we reply on the IPA init script to start only enabled
- # components as found in our LDAP configuration tree
- # We need to install DS before we can actually ldap_enable a service.
- # so actual enablement is delayed.
-
def __create_ca_user(self):
try:
pwd.getpwnam(PKI_USER)
@@ -678,7 +598,7 @@ class CAInstance(service.Service):
args = ["/usr/bin/perl", "/usr/bin/pkisilent", "ConfigureCA",
"-cs_hostname", self.fqdn,
"-cs_port", str(self.dogtag_constants.ADMIN_SECURE_PORT),
- "-client_certdb_dir", self.ca_agent_db,
+ "-client_certdb_dir", self.agent_db,
"-client_certdb_pwd", self.admin_password,
"-preop_pin" , preop_pin,
"-domain_name", self.security_domain_name,
@@ -777,14 +697,6 @@ class CAInstance(service.Service):
root_logger.debug("completed creating ca instance")
- def __restart_instance(self):
- try:
- self.restart(self.dogtag_constants.PKI_INSTANCE_NAME)
- except Exception:
- # TODO: roll back here?
- root_logger.debug(traceback.format_exc())
- root_logger.critical("Failed to restart the certificate server. See the installation log for details.")
-
def __disable_nonce(self):
# Turn off Nonces
update_result = installutils.update_file(
@@ -804,7 +716,7 @@ class CAInstance(service.Service):
# Look thru the cert chain to get all the certs we need to add
# trust for
- p = subprocess.Popen(["/usr/bin/certutil", "-d", self.ca_agent_db,
+ p = subprocess.Popen(["/usr/bin/certutil", "-d", self.agent_db,
"-O", "-n", "ipa-ca-agent"], stdout=subprocess.PIPE)
chain = p.stdout.read()
@@ -823,7 +735,7 @@ class CAInstance(service.Service):
self.__run_certutil(
['-M', '-t', 'CT,C,C', '-n',
nick],
- database=self.ca_agent_db, pwd_file=self.admin_password)
+ database=self.agent_db, pwd_file=self.admin_password)
finally:
os.remove(admin_name)
@@ -839,12 +751,12 @@ class CAInstance(service.Service):
'-v',
'-n', 'ipa-ca-agent',
'-p', self.admin_password,
- '-d', self.ca_agent_db,
+ '-d', self.agent_db,
'-r', '/ca/agent/ca/profileReview?requestId=%s' % self.requestId,
'%s' % ipautil.format_netloc(
self.fqdn, self.dogtag_constants.AGENT_SECURE_PORT),
]
- (stdout, stderr, returncode) = ipautil.run(args, nolog=(self.admin_password,))
+ (stdout, _stderr, _returncode) = ipautil.run(args, nolog=(self.admin_password,))
data = stdout.split(self.dogtag_constants.RACERT_LINE_SEP)
params = get_defList(data)
@@ -860,13 +772,13 @@ class CAInstance(service.Service):
'-v',
'-n', 'ipa-ca-agent',
'-p', self.admin_password,
- '-d', self.ca_agent_db,
+ '-d', self.agent_db,
'-e', params,
'-r', '/ca/agent/ca/profileProcess',
'%s' % ipautil.format_netloc(
self.fqdn, self.dogtag_constants.AGENT_SECURE_PORT),
]
- (stdout, stderr, returncode) = ipautil.run(args, nolog=(self.admin_password,))
+ (stdout, _stderr, _returncode) = ipautil.run(args, nolog=(self.admin_password,))
data = stdout.split(self.dogtag_constants.RACERT_LINE_SEP)
outputList = get_outputList(data)
@@ -971,7 +883,7 @@ class CAInstance(service.Service):
os.close(f)
os.chmod(self.ra_agent_pwd, stat.S_IRUSR)
- (stdout, stderr, returncode) = self.__run_certutil(["-N"])
+ (_stdout, _stderr, _returncode) = self.__run_certutil(["-N"])
def __get_ca_chain(self):
try:
@@ -989,7 +901,7 @@ class CAInstance(service.Service):
ipautil.run(["/usr/bin/pk12util",
"-n", "ipa-ca-agent",
"-o", "/root/ca-agent.p12",
- "-d", self.ca_agent_db,
+ "-d", self.agent_db,
"-k", pwd_name,
"-w", pwd_name])
finally:
@@ -1007,7 +919,7 @@ class CAInstance(service.Service):
# makes openssl throw up.
data = base64.b64decode(chain)
- (certlist, stderr, returncode) = ipautil.run(["/usr/bin/openssl",
+ (certlist, _stderr, _returncode) = ipautil.run(["/usr/bin/openssl",
"pkcs7",
"-inform",
"DER",
@@ -1029,7 +941,7 @@ class CAInstance(service.Service):
(chain_fd, chain_name) = tempfile.mkstemp()
os.write(chain_fd, certlist[st:en+25])
os.close(chain_fd)
- (rdn, subject_dn) = certs.get_cert_nickname(certlist[st:en+25])
+ (_rdn, subject_dn) = certs.get_cert_nickname(certlist[st:en+25])
if subject_dn == ca_dn:
nick = get_ca_nickname(self.realm)
else:
@@ -1051,7 +963,10 @@ class CAInstance(service.Service):
# Generate our CSR. The result gets put into stdout
try:
- (stdout, stderr, returncode) = self.__run_certutil(["-R", "-k", "rsa", "-g", "2048", "-s", str(DN(('CN', 'IPA RA'), self.subject_base)), "-z", noise_name, "-a"])
+ (stdout, _stderr, _returncode) = self.__run_certutil(
+ ["-R", "-k", "rsa", "-g", "2048", "-s",
+ str(DN(('CN', 'IPA RA'), self.subject_base)),
+ "-z", noise_name, "-a"])
finally:
os.remove(noise_name)
@@ -1266,73 +1181,30 @@ class CAInstance(service.Service):
'OU=pki-ipa, O=IPA', str(self.subject_base)):
print "Updating subject_base in CA template failed"
- def enable_client_auth_to_db(self):
- """
- Enable client auth connection to the internal db.
- """
- caconfig = dogtag.install_constants.CS_CFG_PATH
-
- with stopped_service(self.dogtag_constants.SERVICE_NAME,
- instance_name=self.dogtag_constants.PKI_INSTANCE_NAME):
-
- # Enable file publishing, disable LDAP
- installutils.set_directive(caconfig,
- 'authz.instance.DirAclAuthz.ldap.ldapauth.authtype',
- 'SslClientAuth', quotes=False, separator='=')
- installutils.set_directive(caconfig,
- 'authz.instance.DirAclAuthz.ldap.ldapauth.bindDN',
- 'uid=pkidbuser,ou=people,o=ipa-ca', quotes=False, separator='=')
- installutils.set_directive(caconfig,
- 'authz.instance.DirAclAuthz.ldap.ldapauth.clientCertNickname',
- 'subsystemCert cert-pki-ca', quotes=False, separator='=')
- installutils.set_directive(caconfig,
- 'authz.instance.DirAclAuthz.ldap.ldapconn.port',
- str(dogtag.install_constants.DS_SECURE_PORT),
- quotes=False, separator='=')
- installutils.set_directive(caconfig,
- 'authz.instance.DirAclAuthz.ldap.ldapconn.secureConn',
- 'true', quotes=False, separator='=')
-
- installutils.set_directive(caconfig, 'internaldb.ldapauth.authtype',
- 'SslClientAuth', quotes=False, separator='=')
- installutils.set_directive(caconfig, 'internaldb.ldapauth.bindDN',
- 'uid=pkidbuser,ou=people,o=ipa-ca', quotes=False, separator='=')
- installutils.set_directive(caconfig,
- 'internaldb.ldapauth.clientCertNickname',
- 'subsystemCert cert-pki-ca', quotes=False, separator='=')
- installutils.set_directive(caconfig, 'internaldb.ldapconn.port',
- str(dogtag.install_constants.DS_SECURE_PORT),
- quotes=False, separator='=')
- installutils.set_directive(caconfig,
- 'internaldb.ldapconn.secureConn', 'true', quotes=False,
- separator='=')
-
def uninstall(self):
- if self.is_configured():
- self.print_msg("Unconfiguring CA")
-
enabled = self.restore_state("enabled")
if not enabled is None and not enabled:
self.disable()
- try:
- if self.dogtag_constants.DOGTAG_VERSION >= 10:
- ipautil.run(["/usr/sbin/pkidestroy", "-i",
- self.dogtag_constants.PKI_INSTANCE_NAME,
- "-s", "CA"])
- else:
+ if self.dogtag_constants.DOGTAG_VERSION >= 10:
+ DogtagInstance.uninstall(self)
+ else:
+ if self.is_configured():
+ self.print_msg("Unconfiguring CA")
+
+ try:
ipautil.run(["/usr/bin/pkiremove",
"-pki_instance_root=/var/lib",
"-pki_instance_name=%s" %
self.dogtag_constants.PKI_INSTANCE_NAME,
"--force"])
- except ipautil.CalledProcessError, e:
- root_logger.critical("failed to uninstall CA instance %s" % e)
+ except ipautil.CalledProcessError, e:
+ root_logger.critical("failed to uninstall CA instance %s" % e)
# At one time we removed this user on uninstall. That can potentially
# orphan files, or worse, if another useradd runs in the intermim,
# cause files to have a new owner.
- user_exists = self.restore_state("user_exists")
+ _user_exists = self.restore_state("user_exists")
ipaservices.knownservices.messagebus.start()
cmonger = ipaservices.knownservices.certmonger
@@ -1365,23 +1237,12 @@ class CAInstance(service.Service):
def publish_ca_cert(self, location):
args = ["-L", "-n", self.canickname, "-a"]
- (cert, err, returncode) = self.__run_certutil(args)
+ (cert, _err, _returncode) = self.__run_certutil(args)
fd = open(location, "w+")
fd.write(cert)
fd.close()
os.chmod(location, 0444)
- def __http_proxy(self):
- template_filename = ipautil.SHARE_DIR + "ipa-pki-proxy.conf"
- sub_dict = dict(
- DOGTAG_PORT=self.dogtag_constants.AJP_PORT,
- CLONE='' if self.clone else '#',
- FQDN=self.fqdn,
- )
- template = ipautil.template_file(template_filename, sub_dict)
- with open(HTTPD_CONFD + "ipa-pki-proxy.conf", "w") as fd:
- fd.write(template)
-
def configure_certmonger_renewal(self):
"""
Create a new CA type for certmonger that will retrieve updated
@@ -1425,24 +1286,14 @@ class CAInstance(service.Service):
'Unable to determine PIN for CA instance: %s' % e)
def configure_renewal(self):
- pin = self.__get_ca_pin()
+ """
+ Configure system certificates for renewal.
+ """
+ nicknames = ['auditSigningCert cert-pki-ca',
+ 'ocspSigningCert cert-pki-ca',
+ 'subsystemCert cert-pki-ca']
- # Server-Cert cert-pki-ca is renewed per-server
- for nickname in ['auditSigningCert cert-pki-ca',
- 'ocspSigningCert cert-pki-ca',
- 'subsystemCert cert-pki-ca']:
- try:
- certmonger.dogtag_start_tracking(
- ca='dogtag-ipa-ca-renew-agent',
- nickname=nickname,
- pin=pin,
- pinfile=None,
- secdir=self.dogtag_constants.ALIAS_DIR,
- pre_command='stop_pkicad',
- post_command='renew_ca_cert "%s"' % nickname)
- except (ipautil.CalledProcessError, RuntimeError), e:
- root_logger.error(
- "certmonger failed to start tracking certificate: %s" % e)
+ DogtagInstance.configure_renewal(self, nicknames)
def track_servercert(self):
"""
@@ -1464,6 +1315,26 @@ class CAInstance(service.Service):
root_logger.error(
"certmonger failed to start tracking certificate: %s" % e)
+ def stop_tracking_certificates(self, dogtag_constants):
+ """Stop tracking our certificates. Called on uninstall.
+ """
+ nicknames = ['Server-Cert cert-pki-ca',
+ 'auditSigningCert cert-pki-ca',
+ 'ocspSigningCert cert-pki-ca',
+ 'subsystemCert cert-pki-ca']
+ DogtagInstance.stop_tracking_certificates(
+ self, dogtag_constants, nicknames)
+
+ cmonger = ipaservices.knownservices.certmonger
+ ipaservices.knownservices.messagebus.start()
+ cmonger.start()
+ try:
+ certmonger.stop_tracking('/etc/httpd/alias', nickname='ipaCert')
+ except (ipautil.CalledProcessError, RuntimeError), e:
+ root_logger.error(
+ "certmonger failed to stop tracking certificate: %s" % str(e))
+ cmonger.stop()
+
def enable_subject_key_identifier(self):
"""
See if Subject Key Identifier is set in the profile and if not, add it.
@@ -1518,13 +1389,14 @@ class CAInstance(service.Service):
"""
# Check the default validity period of the audit signing cert
# and set it to 2 years if it is 6 months.
- range = installutils.get_directive(
+ cert_range = installutils.get_directive(
'%s/caSignedLogCert.cfg' % self.dogtag_constants.SERVICE_PROFILE_DIR,
'policyset.caLogSigningSet.2.default.params.range',
separator='='
)
- root_logger.debug('caSignedLogCert.cfg profile validity range is %s' % range)
- if range == "180":
+ root_logger.debug(
+ 'caSignedLogCert.cfg profile validity range is %s' % cert_range)
+ if cert_range == "180":
installutils.set_directive(
'%s/caSignedLogCert.cfg' % self.dogtag_constants.SERVICE_PROFILE_DIR,
'policyset.caLogSigningSet.2.default.params.range',
@@ -1549,15 +1421,39 @@ class CAInstance(service.Service):
dn = DN(('cn', 'CA'), ('cn', api.env.host), ('cn', 'masters'),
('cn', 'ipa'), ('cn', 'etc'), api.env.basedn)
- filter = '(ipaConfigString=caRenewalMaster)'
+ renewal_filter = '(ipaConfigString=caRenewalMaster)'
try:
- self.admin_conn.get_entries(base_dn=dn, filter=filter,
+ self.admin_conn.get_entries(base_dn=dn, filter=renewal_filter,
attrs_list=[])
except errors.NotFound:
return False
return True
+ def update_cert_config(self, nickname, cert, dogtag_constants=None):
+ """
+ When renewing a CA subsystem certificate the configuration file
+ needs to get the new certificate as well.
+
+ nickname is one of the known nicknames.
+ cert is a DER-encoded certificate.
+ """
+
+ if dogtag_constants is None:
+ dogtag_constants = dogtag.configured_constants()
+
+ # The cert directive to update per nickname
+ directives = {'auditSigningCert cert-pki-ca': 'ca.audit_signing.cert',
+ 'ocspSigningCert cert-pki-ca': 'ca.ocsp_signing.cert',
+ 'caSigningCert cert-pki-ca': 'ca.signing.cert',
+ 'subsystemCert cert-pki-ca': 'ca.subsystem.cert',
+ 'Server-Cert cert-pki-ca': 'ca.sslserver.cert'}
+
+ DogtagInstance.update_cert_config(
+ self, nickname, cert, directives,
+ dogtag.configured_constants().CS_CFG_PATH,
+ dogtag_constants)
+
def replica_ca_install_check(config):
if not config.setup_ca:
@@ -1644,11 +1540,6 @@ def install_replica_ca(config, postinstall=False):
if ca.is_installed():
sys.exit("A CA is already configured on this system.")
- pkcs12_info = None
- if ipautil.file_exists(config.dir + "/dogtagcert.p12"):
- pkcs12_info = (config.dir + "/dogtagcert.p12",
- config.dir + "/dirsrv_pin.txt")
-
ca = CAInstance(config.realm_name, certs.NSS_DIR,
dogtag_constants=dogtag.install_constants)
if postinstall:
@@ -1687,33 +1578,6 @@ def install_replica_ca(config, postinstall=False):
return ca
-def update_cert_config(nickname, cert, dogtag_constants=None):
- """
- When renewing a CA subsystem certificate the configuration file
- needs to get the new certificate as well.
-
- nickname is one of the known nicknames.
- cert is a DER-encoded certificate.
- """
-
- if dogtag_constants is None:
- dogtag_constants = dogtag.configured_constants()
-
- # The cert directive to update per nickname
- directives = {'auditSigningCert cert-pki-ca': 'ca.audit_signing.cert',
- 'ocspSigningCert cert-pki-ca': 'ca.ocsp_signing.cert',
- 'caSigningCert cert-pki-ca': 'ca.signing.cert',
- 'subsystemCert cert-pki-ca': 'ca.subsystem.cert',
- 'Server-Cert cert-pki-ca': 'ca.sslserver.cert'}
-
- with stopped_service(dogtag_constants.SERVICE_NAME,
- instance_name=dogtag_constants.PKI_INSTANCE_NAME):
-
- installutils.set_directive(dogtag.configured_constants().CS_CFG_PATH,
- directives[nickname],
- base64.b64encode(cert),
- quotes=False, separator='=')
-
def update_people_entry(dercert):
"""
Update the userCerticate for an entry in the dogtag ou=People. This
@@ -1749,11 +1613,11 @@ def update_people_entry(dercert):
conn.connect(
bind_dn=DN(('cn', 'directory manager')), bind_pw=dm_password)
- filter = conn.make_filter(
+ db_filter = conn.make_filter(
{'description': ';%s;%s' % (issuer, subject)},
exact=False, trailing_wildcard=False)
try:
- entries = conn.get_entries(base_dn, conn.SCOPE_SUBTREE, filter)
+ entries = conn.get_entries(base_dn, conn.SCOPE_SUBTREE, db_filter)
except errors.NotFound:
entries = []
diff --git a/ipaserver/install/dogtaginstance.py b/ipaserver/install/dogtaginstance.py
new file mode 100644
index 000000000..b482d8e08
--- /dev/null
+++ b/ipaserver/install/dogtaginstance.py
@@ -0,0 +1,311 @@
+# Authors: Ade Lee <alee@redhat.com>
+#
+# Copyright (C) 2014 Red Hat
+# see file 'COPYING' for use and warranty information
+#
+# 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, either version 3 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+import base64
+import os
+import shutil
+import tempfile
+import traceback
+
+from ipapython import certmonger
+from ipapython import dogtag
+from ipapython import ipautil
+from ipapython import services as ipaservices
+from ipapython.dn import DN
+from ipaserver.install import service
+from ipaserver.install import installutils
+from ipaserver.install.installutils import stopped_service
+from ipapython.ipa_log_manager import *
+
+HTTPD_CONFD = "/etc/httpd/conf.d/"
+DEFAULT_DSPORT = dogtag.install_constants.DS_PORT
+
+PKI_USER = "pkiuser"
+PKI_DS_USER = dogtag.install_constants.DS_USER
+
+
+def check_inst(subsystem):
+ """
+ Validate that the appropriate dogtag/RHCS packages have been installed.
+ """
+
+ # Check for a couple of binaries we need
+ if not os.path.exists(dogtag.install_constants.SPAWN_BINARY):
+ return False
+ if not os.path.exists(dogtag.install_constants.DESTROY_BINARY):
+ return False
+
+ # This is the template tomcat file for a DRM
+ if not os.path.exists('/usr/share/pki/%s/conf/server.xml' % subsystem):
+ return False
+
+ return True
+
+class DogtagInstance(service.Service):
+ """
+ This is the base class for a Dogtag 10+ instance, which uses a
+ shared tomcat instance and DS to host the relevant subsystems.
+
+ It contains functions that will be common to installations of the
+ CA, KRA, and eventually TKS and TPS.
+ """
+
+ def __init__(self, realm, subsystem, service_desc, dogtag_constants=None):
+ if dogtag_constants is None:
+ dogtag_constants = dogtag.configured_constants()
+
+ service.Service.__init__(self,
+ '%sd' % dogtag_constants.PKI_INSTANCE_NAME,
+ service_desc=service_desc
+ )
+
+ self.dogtag_constants = dogtag_constants
+ self.realm = realm
+ self.dm_password = None
+ self.admin_password = None
+ self.fqdn = None
+ self.domain = None
+ self.pkcs12_info = None
+ self.clone = False
+
+ self.basedn = DN(('o', 'ipa%s' % subsystem.lower()))
+ self.agent_db = tempfile.mkdtemp(prefix = "tmp-")
+ self.ds_port = DEFAULT_DSPORT
+ self.server_root = dogtag_constants.SERVER_ROOT
+ self.subsystem = subsystem
+ self.security_domain_name = "IPA"
+ self.tracking_nicknames = None
+
+ def __del__(self):
+ shutil.rmtree(self.agent_db, ignore_errors=True)
+
+ def is_installed(self):
+ """
+ Determine if subsystem instance has been installed.
+
+ Returns True/False
+ """
+ return os.path.exists(os.path.join(
+ self.server_root, self.dogtag_constants.PKI_INSTANCE_NAME,
+ self.subsystem.lower()))
+
+ def spawn_instance(self, cfg_file):
+ """
+ Create and configure a new Dogtag instance using pkispawn.
+ Passes in a configuration file with IPA-specific
+ parameters.
+ """
+ subsystem = self.subsystem
+
+ # Define the things we don't want logged
+ nolog = (self.admin_password, self.dm_password,)
+
+ args = ["/usr/sbin/pkispawn",
+ "-s", subsystem,
+ "-f", cfg_file ]
+
+ with open(cfg_file) as f:
+ root_logger.debug(
+ 'Contents of pkispawn configuration file (%s):\n%s' %
+ (cfg_file, ipautil.nolog_replace(f.read(), nolog)))
+
+ try:
+ ipautil.run(args, nolog=nolog)
+ except ipautil.CalledProcessError, e:
+ root_logger.critical("failed to configure %s instance %s" %
+ (subsystem, e))
+ raise RuntimeError('Configuration of %s failed' % subsystem)
+
+ def enable(self):
+ self.backup_state("enabled", self.is_enabled())
+
+ def restart_instance(self):
+ try:
+ self.restart(self.dogtag_constants.PKI_INSTANCE_NAME)
+ except Exception:
+ root_logger.debug(traceback.format_exc())
+ root_logger.critical(
+ "Failed to restart the Dogtag instance."
+ "See the installation log for details.")
+
+ def start_instance(self):
+ try:
+ self.start(self.dogtag_constants.PKI_INSTANCE_NAME)
+ except Exception:
+ root_logger.debug(traceback.format_exc())
+ root_logger.critical(
+ "Failed to restart the Dogtag instance."
+ "See the installation log for details.")
+
+ def stop_instance(self):
+ try:
+ self.stop(self.dogtag_constants.PKI_INSTANCE_NAME)
+ except Exception:
+ root_logger.debug(traceback.format_exc())
+ root_logger.critical(
+ "Failed to restart the Dogtag instance."
+ "See the installation log for details.")
+
+ def enable_client_auth_to_db(self, config):
+ """
+ Enable client auth connection to the internal db.
+ Path to CS.cfg config file passed in.
+ """
+
+ with stopped_service(self.dogtag_constants.SERVICE_NAME,
+ instance_name=self.dogtag_constants.PKI_INSTANCE_NAME):
+
+ installutils.set_directive(config,
+ 'authz.instance.DirAclAuthz.ldap.ldapauth.authtype',
+ 'SslClientAuth', quotes=False, separator='=')
+ installutils.set_directive(config,
+ 'authz.instance.DirAclAuthz.ldap.ldapauth.bindDN',
+ 'uid=pkidbuser,ou=people,o=ipaca', quotes=False, separator='=')
+ installutils.set_directive(config,
+ 'authz.instance.DirAclAuthz.ldap.ldapauth.clientCertNickname',
+ 'subsystemCert cert-pki-ca', quotes=False, separator='=')
+ installutils.set_directive(config,
+ 'authz.instance.DirAclAuthz.ldap.ldapconn.port',
+ str(dogtag.install_constants.DS_SECURE_PORT),
+ quotes=False, separator='=')
+ installutils.set_directive(config,
+ 'authz.instance.DirAclAuthz.ldap.ldapconn.secureConn',
+ 'true', quotes=False, separator='=')
+
+ installutils.set_directive(config, 'internaldb.ldapauth.authtype',
+ 'SslClientAuth', quotes=False, separator='=')
+ installutils.set_directive(config, 'internaldb.ldapauth.bindDN',
+ 'uid=pkidbuser,ou=people,o=ipaca', quotes=False, separator='=')
+ installutils.set_directive(config,
+ 'internaldb.ldapauth.clientCertNickname',
+ 'subsystemCert cert-pki-ca', quotes=False, separator='=')
+ installutils.set_directive(config, 'internaldb.ldapconn.port',
+ str(dogtag.install_constants.DS_SECURE_PORT),
+ quotes=False, separator='=')
+ installutils.set_directive(config,
+ 'internaldb.ldapconn.secureConn', 'true', quotes=False,
+ separator='=')
+
+ def uninstall(self):
+ if self.is_installed():
+ self.print_msg("Unconfiguring %s" % self.subsystem)
+
+ try:
+ ipautil.run(["/usr/sbin/pkidestroy", "-i",
+ self.dogtag_constants.PKI_INSTANCE_NAME,
+ "-s", self.subsystem])
+ except ipautil.CalledProcessError, e:
+ root_logger.critical("failed to uninstall %s instance %s"
+ % (self.subsystem,e))
+
+ def http_proxy(self):
+ ''' Update the http proxy file '''
+ template_filename = ipautil.SHARE_DIR + "ipa-pki-proxy.conf"
+ sub_dict = dict(
+ DOGTAG_PORT=self.dogtag_constants.AJP_PORT,
+ CLONE='' if self.clone else '#',
+ FQDN=self.fqdn,
+ )
+ template = ipautil.template_file(template_filename, sub_dict)
+ with open(HTTPD_CONFD + "ipa-pki-proxy.conf", "w") as fd:
+ fd.write(template)
+
+ def __get_pin(self):
+ try:
+ return certmonger.get_pin('internal',
+ dogtag_constants=self.dogtag_constants)
+ except IOError, e:
+ root_logger.debug(
+ 'Unable to determine PIN for DRM instance: %s' % str(e))
+ raise RuntimeError(e)
+
+ def configure_renewal(self, nicknames=None):
+ ''' Configure certmonger to renew system certs
+
+ @param nickname: list of nicknames
+ '''
+ cmonger = ipaservices.knownservices.certmonger
+ cmonger.enable()
+ ipaservices.knownservices.messagebus.start()
+ cmonger.start()
+
+ pin = self.__get_pin()
+
+ if nicknames is None:
+ nicknames = self.tracking_nicknames
+
+ for nickname in nicknames:
+ try:
+ certmonger.dogtag_start_tracking(
+ ca='dogtag-ipa-ca-renew-agent',
+ nickname=nickname,
+ pin=pin,
+ pinfile=None,
+ secdir=self.dogtag_constants.ALIAS_DIR,
+ pre_command='stop_pkicad',
+ post_command='renew_ca_cert "%s"' % nickname)
+ except (ipautil.CalledProcessError, RuntimeError), e:
+ root_logger.error(
+ "certmonger failed to start tracking certificate: %s" %
+ str(e))
+
+ def stop_tracking_certificates(self, dogtag_constants, nicknames = None):
+ """Stop tracking our certificates. Called on uninstall.
+ """
+ cmonger = ipaservices.knownservices.certmonger
+ ipaservices.knownservices.messagebus.start()
+ cmonger.start()
+
+ if nicknames is None:
+ nicknames = self.tracking_nicknames
+
+ for nickname in nicknames:
+ try:
+ certmonger.stop_tracking(
+ dogtag_constants.ALIAS_DIR, nickname=nickname)
+ except (ipautil.CalledProcessError, RuntimeError), e:
+ root_logger.error(
+ "certmonger failed to stop tracking certificate: %s"
+ % str(e))
+
+ cmonger.stop()
+
+ def update_cert_config(self, nickname, cert, directives, cs_cfg,
+ dogtag_constants=None):
+ """
+ When renewing a DRM subsystem certificate the configuration file
+ needs to get the new certificate as well.
+
+ nickname is one of the known nicknames.
+ cert is a DER-encoded certificate.
+ directives is the list of directives to be updated for the subsystem
+ cs_cfg is the path to the CS.cfg file
+ """
+
+ if dogtag_constants is None:
+ dogtag_constants = dogtag.configured_constants()
+
+ with stopped_service(dogtag_constants.SERVICE_NAME,
+ instance_name=dogtag_constants.PKI_INSTANCE_NAME):
+ installutils.set_directive(
+ cs_cfg,
+ directives[nickname],
+ base64.b64encode(cert),
+ quotes=False,
+ separator='=')
diff --git a/ipaserver/install/drminstance.py b/ipaserver/install/drminstance.py
new file mode 100644
index 000000000..744b0973d
--- /dev/null
+++ b/ipaserver/install/drminstance.py
@@ -0,0 +1,337 @@
+# Authors: Ade Lee <alee@redhat.com>
+#
+# Copyright (C) 2014 Red Hat
+# see file 'COPYING' for use and warranty information
+#
+# 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, either version 3 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+import ConfigParser
+import os
+import pwd
+import shutil
+import sys
+import tempfile
+
+from ipalib import api
+from ipapython import dogtag
+from ipapython import ipautil
+from ipapython import services as ipaservices
+from ipapython.dn import DN
+from ipaserver.install import certs
+from ipaserver.install import cainstance
+from ipaserver.install import dsinstance
+from ipaserver.install import service
+from ipaserver.install.dogtaginstance import DogtagInstance
+from ipaserver.install.dogtaginstance import DEFAULT_DSPORT, PKI_USER
+from ipapython.ipa_log_manager import *
+
+# When IPA is installed with DNS support, this CNAME should hold all IPA
+# replicas with DRM configured
+IPA_DRM_RECORD = "ipa-drm"
+
+class DRMInstance(DogtagInstance):
+ """
+ We assume that the CA has already been installed, and we use the
+ same tomcat instance to host both the CA and DRM.
+ The mod_nss database will contain the RA agent cert that will be used
+ to do authenticated requests against dogtag. The RA agent cert will
+ be the same for both the CA and DRM.
+ """
+
+ def __init__(self, realm, dogtag_constants=None):
+ if dogtag_constants is None:
+ dogtag_constants = dogtag.configured_constants()
+
+ DogtagInstance.__init__(self, realm, "KRA", "DRM server",
+ dogtag_constants)
+ self.basedn = DN(('o', 'ipadrm'))
+ self.tracking_nicknames = ['auditSigningCert cert-pki-drm',
+ 'transportCert cert-pki-drm',
+ 'storageCert cert-pki-drm']
+
+ def configure_instance(self, host_name, domain, dm_password,
+ admin_password, ds_port=DEFAULT_DSPORT,
+ pkcs12_info=None, master_host=None,
+ master_replication_port=None,
+ subject_base=None):
+ """Create a DRM instance.
+
+ To create a clone, pass in pkcs12_info.
+ """
+ self.fqdn = host_name
+ self.domain = domain
+ self.dm_password = dm_password
+ self.admin_password = admin_password
+ self.ds_port = ds_port
+ self.pkcs12_info = pkcs12_info
+ if self.pkcs12_info is not None:
+ self.clone = True
+ self.master_host = master_host
+ self.master_replication_port = master_replication_port
+ if subject_base is None:
+ self.subject_base = DN(('O', self.realm))
+ else:
+ self.subject_base = subject_base
+
+ # Confirm that a DRM does not already exist
+ if self.is_installed():
+ raise RuntimeError(
+ "DRM already installed.")
+ # Confirm that a Dogtag 10 CA instance already exists
+ ca = cainstance.CAInstance(
+ api.env.realm, certs.NSS_DIR,
+ dogtag_constants = dogtag.Dogtag10Constants)
+ if not ca.is_installed():
+ raise RuntimeError(
+ "DRM configuration failed. "
+ "A Dogtag CA must be installed first")
+
+ self.step("configuring DRM instance", self.__spawn_instance)
+ self.step("restarting DRM", self.restart_instance)
+ self.step("configure certificate renewals", self.configure_renewal)
+ self.step("Configure HTTP to proxy connections",
+ self.http_proxy)
+
+ self.start_creation(runtime=210)
+
+ def start_instance(self):
+ DogtagInstance.start_instance(self)
+
+ def stop_instance(self):
+ DogtagInstance.stop_instance(self)
+
+ def restart_instance(self):
+ DogtagInstance.restart_instance(self)
+
+ def http_proxy(self):
+ DogtagInstance.http_proxy(self)
+
+ def __spawn_instance(self):
+ """
+ Create and configure a new DRM instance using pkispawn.
+ Creates a configuration file with IPA-specific
+ parameters and passes it to the base class to call pkispawn
+ """
+
+ # Create an empty and secured file
+ (cfg_fd, cfg_file) = tempfile.mkstemp()
+ os.close(cfg_fd)
+ pent = pwd.getpwnam(PKI_USER)
+ os.chown(cfg_file, pent.pw_uid, pent.pw_gid)
+
+ # Create KRA configuration
+ config = ConfigParser.ConfigParser()
+ config.optionxform = str
+ config.add_section("KRA")
+
+ # Security Domain Authentication
+ config.set("KRA", "pki_security_domain_https_port", "443")
+ config.set("KRA", "pki_security_domain_password", self.admin_password)
+ config.set("KRA", "pki_security_domain_user", "admin")
+
+ # issuing ca
+ config.set("KRA", "pki_issuing_ca_uri", "https://%s" %
+ ipautil.format_netloc(self.fqdn, 443))
+
+ # Server
+ config.set("KRA", "pki_enable_proxy", "True")
+ config.set("KRA", "pki_restart_configured_instance", "False")
+ config.set("KRA", "pki_backup_keys", "True")
+ config.set("KRA", "pki_backup_password", self.admin_password)
+
+ # Client security database
+ config.set("KRA", "pki_client_database_dir", self.agent_db)
+ config.set("KRA", "pki_client_database_password", self.admin_password)
+ config.set("KRA", "pki_client_database_purge", "False")
+ config.set("KRA", "pki_client_pkcs12_password", self.admin_password)
+
+ # Administrator
+ config.set("KRA", "pki_admin_name", "admin")
+ config.set("KRA", "pki_admin_uid", "admin")
+ config.set("KRA", "pki_admin_email", "root@localhost")
+ config.set("KRA", "pki_admin_password", self.admin_password)
+ config.set("KRA", "pki_admin_nickname", "ipa-ca-agent")
+ config.set("KRA", "pki_admin_subject_dn",
+ str(DN(('cn', 'ipa-ca-agent'), self.subject_base)))
+ config.set("KRA", "pki_import_admin_cert", "True")
+ config.set("KRA", "pki_admin_cert_file",
+ "/root/.dogtag/pki-tomcat/ca_admin.cert")
+ config.set("KRA", "pki_client_admin_cert_p12", "/root/ca-agent.p12")
+
+ # Directory server
+ config.set("KRA", "pki_ds_ldap_port", str(self.ds_port))
+ config.set("KRA", "pki_ds_password", self.dm_password)
+ config.set("KRA", "pki_ds_base_dn", self.basedn)
+ config.set("KRA", "pki_ds_database", "ipakra")
+
+ # Certificate subject DN's
+ config.set("KRA", "pki_subsystem_subject_dn",
+ str(DN(('cn', 'CA Subsystem'), self.subject_base)))
+ config.set("KRA", "pki_ssl_server_subject_dn",
+ str(DN(('cn', self.fqdn), self.subject_base)))
+ config.set("KRA", "pki_audit_signing_subject_dn",
+ str(DN(('cn', 'DRM Audit'), self.subject_base)))
+ config.set("KRA", "pki_transport_subject_dn",
+ str(DN(('cn', 'DRM Transport Certificate'), self.subject_base)))
+ config.set("KRA", "pki_storage_subject_dn",
+ str(DN(('cn', 'DRM Storage Certificate'), self.subject_base)))
+
+ # Certificate nicknames
+ # Note that both the server certs and subsystem certs reuse
+ # the ca certs.
+ config.set("KRA", "pki_subsystem_nickname",
+ "subsystemCert cert-pki-ca")
+ config.set("KRA", "pki_ssl_server_nickname",
+ "Server-Cert cert-pki-ca")
+ config.set("KRA", "pki_audit_signing_nickname",
+ "auditSigningCert cert-pki-drm")
+ config.set("KRA", "pki_transport_nickname",
+ "transportCert cert-pki-drm")
+ config.set("KRA", "pki_storage_nickname",
+ "storageCert cert-pki-drm")
+
+ # Shared db settings
+ # Needed because CA and KRA share the same database
+ # We will use the dbuser created for the CA
+ config.set("KRA", "pki_share_db", "True")
+ config.set("KRA", "pki_share_dbuser_dn",
+ str(DN(('uid', 'pkidbuser'),('ou', 'people'),('o','ipaca'))))
+
+
+ if (self.clone):
+ drmfile = self.pkcs12_info[0]
+ shutil.copy(drmfile, "/tmp/drm.p12")
+ pent = pwd.getpwnam(PKI_USER)
+ os.chown("/tmp/drm.p12", pent.pw_uid, pent.pw_gid)
+
+ # Security domain registration
+ config.set("KRA", "pki_security_domain_hostname", self.master_host)
+ config.set("KRA", "pki_security_domain_https_port", "443")
+ config.set("KRA", "pki_security_domain_user", "admin")
+ config.set("KRA", "pki_security_domain_password",
+ self.admin_password)
+
+ # Clone
+ config.set("KRA", "pki_clone", "True")
+ config.set("KRA", "pki_clone_pkcs12_path", "/tmp/drm.p12")
+ config.set("KRA", "pki_clone_pkcs12_password", self.dm_password)
+ config.set("KRA", "pki_clone_replication_security", "TLS")
+ config.set("KRA", "pki_clone_replication_master_port",
+ str(self.master_replication_port))
+ config.set("KRA", "pki_clone_replication_clone_port",
+ dogtag.install_constants.DS_PORT)
+ config.set("KRA", "pki_clone_replicate_schema", "False")
+ config.set("KRA", "pki_clone_uri",
+ "https://%s" % ipautil.format_netloc(self.master_host, 443))
+
+ # Generate configuration file
+ with open(cfg_file, "wb") as f:
+ config.write(f)
+
+ try:
+ DogtagInstance.spawn_instance(self, cfg_file)
+ finally:
+ os.remove(cfg_file)
+
+ shutil.move("/var/lib/pki/pki-tomcat/alias/kra_backup_keys.p12",
+ "/root/kracert.p12")
+
+ root_logger.debug("completed creating DRM instance")
+
+ def update_cert_config(self, nickname, cert, dogtag_constants=None):
+ """
+ When renewing a DRM subsystem certificate the configuration file
+ needs to get the new certificate as well.
+
+ nickname is one of the known nicknames.
+ cert is a DER-encoded certificate.
+ """
+
+ if dogtag_constants is None:
+ dogtag_constants = dogtag.configured_constants()
+
+ # The cert directive to update per nickname
+ directives = {
+ 'auditSigningCert cert-pki-drm': 'kra.audit_signing.cert',
+ 'storageCert cert-pki-drm': 'kra.storage.cert',
+ 'transportCert cert-pki-drm': 'kra.transport.cert',
+ 'subsystemCert cert-pki-drm': 'kra.subsystem.cert',
+ 'Server-Cert cert-pki-ca': 'kra.sslserver.cert'}
+
+ DogtagInstance.update_cert_config(
+ self, nickname, cert, directives,
+ dogtag.configured_constants().DRM_CS_CFG_PATH,
+ dogtag_constants)
+
+
+def install_replica_drm(config, postinstall=False):
+ """
+ Install a DRM on a replica.
+
+ There are two modes of doing this controlled:
+ - While the replica is being installed
+ - Post-replica installation
+
+ config is a ReplicaConfig object
+
+ Returns a DRM instance
+ """
+ # note that the cacert.p12 file is regenerated during the
+ # ipa-replica-prepare process and should include all the certs
+ # for the CA and DRM
+ drmfile = config.dir + "/cacert.p12"
+
+ if not ipautil.file_exists(drmfile):
+ raise RuntimeError(
+ "Unable to clone DRM."
+ " cacert.p12 file not found in replica file")
+
+ drm = DRMInstance(config.realm_name,
+ dogtag_constants=dogtag.install_constants)
+ drm.dm_password = config.dirman_password
+ drm.subject_base = config.subject_base
+ if drm.is_installed():
+ sys.exit("A DRM is already configured on this system.")
+
+ drm.configure_instance(config.host_name, config.domain_name,
+ config.dirman_password, config.dirman_password,
+ pkcs12_info=(drmfile,),
+ master_host=config.master_host_name,
+ master_replication_port=config.ca_ds_port,
+ subject_base=config.subject_base)
+
+ # Restart httpd since we changed it's config and added ipa-pki-proxy.conf
+ if postinstall:
+ ipaservices.knownservices.httpd.restart()
+
+
+ # The dogtag DS instance needs to be restarted after installation.
+ # The procedure for this is: stop dogtag, stop DS, start DS, start
+ # dogtag
+
+ service.print_msg("Restarting the directory and DRM servers")
+ drm.stop(dogtag.install_constants.PKI_INSTANCE_NAME)
+ ipaservices.knownservices.dirsrv.restart()
+ drm.start(dogtag.install_constants.PKI_INSTANCE_NAME)
+
+ return drm
+
+if __name__ == "__main__":
+ standard_logging_setup("install.log")
+ ds = dsinstance.DsInstance()
+
+ drm = DRMInstance("EXAMPLE.COM")
+ drm.configure_instance("drmtest.example.com", "example.com",
+ "password", "password")
diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py
index 7f15d3769..32cf6bb70 100644
--- a/ipaserver/install/installutils.py
+++ b/ipaserver/install/installutils.py
@@ -554,6 +554,23 @@ def read_replica_info_dogtag_port(config_dir):
return dogtag_master_ds_port
+def read_replica_info_drm_enabled(config_dir):
+ """
+ Check the replica info to determine if a DRM has been installed
+ on the master
+ """
+ default_file = config_dir + "/default.conf"
+ if not ipautil.file_exists(default_file):
+ return False
+ else:
+ with open(default_file) as fd:
+ config = SafeConfigParser()
+ config.readfp(fd)
+
+ enable_drm = bool(config.get("global", "enable_drm"))
+ return enable_drm
+
+
def check_server_configuration():
"""
Check if IPA server is configured on the system.
diff --git a/ipaserver/install/ipa_replica_prepare.py b/ipaserver/install/ipa_replica_prepare.py
index e71dd22e4..df3c1a17b 100644
--- a/ipaserver/install/ipa_replica_prepare.py
+++ b/ipaserver/install/ipa_replica_prepare.py
@@ -370,6 +370,7 @@ class ReplicaPrepare(admintool.AdminTool):
cacert_filename = "/var/kerberos/krb5kdc/cacert.pem"
if ipautil.file_exists(cacert_filename):
self.copy_info_file(cacert_filename, "cacert.pem")
+ self.copy_info_file("/etc/ipa/default.conf", "default.conf")
def save_config(self):
self.log.info("Finalizing configuration")