summaryrefslogtreecommitdiffstats
path: root/ipaserver/install/cainstance.py
diff options
context:
space:
mode:
authorRob Crittenden <rcritten@redhat.com>2009-04-13 13:39:15 -0400
committerRob Crittenden <rcritten@redhat.com>2009-04-20 14:01:00 -0400
commit9182c10b03a7841c9318ad64ae6c5deda77d93d1 (patch)
tree75f7d73a2d1bab18686ddc9e31fe876401c633fe /ipaserver/install/cainstance.py
parentfdf03cb07b6d75eb3cdffbe4cf21cb510134c26d (diff)
downloadfreeipa-9182c10b03a7841c9318ad64ae6c5deda77d93d1.tar.gz
freeipa-9182c10b03a7841c9318ad64ae6c5deda77d93d1.tar.xz
freeipa-9182c10b03a7841c9318ad64ae6c5deda77d93d1.zip
Issue DS and Apache server certs during CA installation.
Notes: - will create a CA instance (pki-ca) if it doesn't exist - maintains support for a self-signed CA - A signing cert is still not created so Firefox autoconfig still won't work
Diffstat (limited to 'ipaserver/install/cainstance.py')
-rw-r--r--ipaserver/install/cainstance.py128
1 files changed, 89 insertions, 39 deletions
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index c402fb04c..088744a48 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -34,11 +34,6 @@ import shutil
import httplib
import urllib
import xml.dom.minidom
-import getopt
-import urlparse
-import getpass
-import socket
-import errno
from nss.error import NSPRError
import nss.nss as nss
@@ -309,7 +304,7 @@ class CADSInstance(service.Service):
if not dsinstance.is_ds_running():
logging.critical("Failed to restart the directory server. See the installation log for details.")
sys.exit(1)
- except Exception, e:
+ except Exception:
# TODO: roll back here?
logging.critical("Failed to restart the directory server. See the installation log for details.")
@@ -341,6 +336,18 @@ class CADSInstance(service.Service):
class CAInstance(service.Service):
+ """
+ In the self-signed case (all done in certs.py) the CA exists in the DS
+ database. When using a dogtag CA the DS database contains just the
+ server cert for DS. The mod_nss database will contain the RA agent
+ cert that will be used to do authenticated requests against dogtag.
+
+ This is done because we use python-nss and will inherit the opened
+ NSS database in mod_python. In nsslib.py we do an nssinit but this will
+ return success if the database is already initialized. It doesn't care
+ if the database is different or not.
+ """
+
def __init__(self):
service.Service.__init__(self, "pki-ca")
self.pki_user = None
@@ -348,10 +355,14 @@ class CAInstance(service.Service):
self.admin_password = None
self.host_name = None
+ # 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 = "CA certificate"
self.basedn = "o=ipaca"
self.ca_agent_db = tempfile.mkdtemp(prefix = "tmp-")
- self.ra_agent_db = "/etc/ipa/ra/alias"
- self.ra_agent_pwd = self.ra_agent_db + "/.pwd"
+ self.ra_agent_db = "/etc/httpd/alias"
+ self.ra_agent_pwd = self.ra_agent_db + "/pwdfile.txt"
self.ds_port = DEFAULT_DSPORT
self.domain_name = "IPA"
self.server_root = "/var/lib"
@@ -368,6 +379,8 @@ class CAInstance(service.Service):
self.admin_password = admin_password
self.ds_port = ds_port
+ if not ipautil.dir_exists("/var/lib/pki-ca"):
+ self.step("creating pki-ca instance", self.create_instance)
self.step("creating certificate server user", self.__create_ca_user)
self.step("configuring certificate server instance", self.__configure_instance)
self.step("creating CA agent PKCS#12 file in /root", self.__create_ca_agent_pkcs12)
@@ -382,6 +395,33 @@ class CAInstance(service.Service):
self.start_creation("Configuring certificate server:")
+ def create_instance(self):
+ """
+ If for some reason the instance doesn't exist, create a new one."
+
+ These values come from /usr/share/pki/ca/setup/postinstall
+ """
+ PKI_INSTANCE_NAME="pki-ca"
+ AGENT_SECURE_PORT="9443"
+ EE_SECURE_PORT="9444"
+ ADMIN_SECURE_PORT="9445"
+ UNSECURE_PORT="9180"
+ TOMCAT_SERVER_PORT="9701"
+
+ args = ['/usr/bin/pkicreate',
+ '-pki_instance_root', '/var/lib',
+ '-pki_instance_name', PKI_INSTANCE_NAME,
+ '-subsystem_type', 'ca',
+ '-agent_secure_port', AGENT_SECURE_PORT,
+ '-ee_secure_port', EE_SECURE_PORT,
+ '-admin_secure_port', ADMIN_SECURE_PORT,
+ '-unsecure_port', UNSECURE_PORT,
+ '-tomcat_server_port', TOMCAT_SERVER_PORT,
+ '-redirect', 'conf=/etc/pki-ca',
+ '-redirect', 'logs=/var/log/pki-ca',
+ ]
+ ipautil.run(args)
+
def __enable(self):
self.backup_state("enabled", self.is_enabled())
self.chkconfig_on()
@@ -500,7 +540,7 @@ class CAInstance(service.Service):
def __restart_instance(self):
try:
self.restart()
- except Exception, e:
+ except Exception:
# TODO: roll back here?
logging.critical("Failed to restart the certificate server. See the installation log for details.")
@@ -526,35 +566,43 @@ class CAInstance(service.Service):
os.remove(admin_name)
# Retrieve the certificate request so we can get the values needed
- # to issue a certificate.
- conn = nsslib.NSSConnection(self.host_name,9443,dbdir=self.ca_agent_db)
- conn.sslsock.set_client_auth_data_callback(client_auth_data_callback, "ipa-ca-agent", self.admin_password, nss.get_default_certdb())
- conn.set_debuglevel(0)
- conn.request("GET", "/ca/agent/ca/profileReview?requestId=7")
- res = conn.getresponse()
- data = res.read()
- if res.status != 200:
- raise RuntimeError("Unable to retrieve certificate request from CA")
-
- data = data.split('\r\n')
+ # to issue a certificate. Use sslget here because this is a
+ # temporary database and nsslib doesn't currently support gracefully
+ # opening and closing an NSS database. This would leave the installer
+ # process stuck using this database during the entire cycle. We need
+ # to use the final RA agent database when issuing certs for DS and
+ # mod_nss.
+ args = [
+ '/usr/bin/sslget',
+ '-n', 'ipa-ca-agent',
+ '-p', self.admin_password,
+ '-d', self.ca_agent_db,
+ '-r', '/ca/agent/ca/profileReview?requestId=7',
+ '%s:%d' % (self.host_name, 9443),
+ ]
+ (stdout, stderr) = ipautil.run(args)
+
+ data = stdout.split('\r\n')
params = get_defList(data)
params['requestId'] = find_substring(data, "requestId")
params['op'] = 'approve'
params['submit'] = 'submit'
params['requestNotes'] = ''
params = urllib.urlencode(params)
- headers = {"Content-type": "application/x-www-form-urlencoded",
- "Accept": "text/plain"}
# Now issue the RA certificate.
- conn.request("POST", "/ca/agent/ca/profileProcess", params, headers)
- res = conn.getresponse()
- data = res.read()
- conn.close()
- if res.status != 200:
- raise RuntimeError("Unable to issue RA certificate")
-
- data = data.split('\r\n')
+ args = [
+ '/usr/bin/sslget',
+ '-n', 'ipa-ca-agent',
+ '-p', self.admin_password,
+ '-d', self.ca_agent_db,
+ '-e', params,
+ '-r', '/ca/agent/ca/profileProcess',
+ '%s:%d' % (self.host_name, 9443),
+ ]
+ (stdout, stderr) = ipautil.run(args)
+
+ data = stdout.split('\r\n')
outputList = get_outputList(data)
self.ra_cert = outputList['b64_cert']
@@ -562,7 +610,7 @@ class CAInstance(service.Service):
self.ra_cert = self.ra_cert.replace('-----BEGIN CERTIFICATE-----','')
self.ra_cert = self.ra_cert.replace('-----END CERTIFICATE-----','')
- # Add the new RA cert to the database in /etc/ipa/ra
+ # Add the new RA cert to the database in /etc/httpd/alias
(agent_fd, agent_name) = tempfile.mkstemp()
os.write(agent_fd, self.ra_cert)
os.close(agent_fd)
@@ -618,8 +666,10 @@ class CAInstance(service.Service):
def __create_ra_agent_db(self):
if ipautil.file_exists(self.ra_agent_db + "/cert8.db"):
- # FIXME, use proper exception
- raise ValueError("The RA Agent database already exists: %s" % self.ra_agent_db)
+ ipautil.backup_file(self.ra_agent_db + "/cert8.db")
+ ipautil.backup_file(self.ra_agent_db + "/key3.db")
+ ipautil.backup_file(self.ra_agent_db + "/secmod.db")
+ ipautil.backup_file(self.ra_agent_db + "/pwdfile.txt")
if not ipautil.dir_exists(self.ra_agent_db):
os.mkdir(self.ra_agent_db)
@@ -647,9 +697,8 @@ class CAInstance(service.Service):
return chain
else:
- # FIXME: raise proper exception
conn.close()
- raise ValueError("Unable to retrieve CA chain")
+ raise RuntimeError("Unable to retrieve CA chain")
def __create_ca_agent_pkcs12(self):
(pwd_fd, pwd_name) = tempfile.mkstemp()
@@ -672,7 +721,7 @@ class CAInstance(service.Service):
os.close(chain_fd)
try:
self.__run_certutil(
- ['-A', '-t', 'CT,C,C', '-n', 'caCert', '-a',
+ ['-A', '-t', 'CT,C,C', '-n', self.canickname, '-a',
'-i', chain_name]
)
finally:
@@ -709,13 +758,14 @@ class CAInstance(service.Service):
res = conn.getresponse()
if res.status == 200:
data = res.read()
+ # FIXME: pull the requestId out so of the response so it isn't
+ # later hard-coded at 7
# print data
conn.close()
else:
conn.close()
- # FIXME: raise proper exception
- raise ValueError("Unable to submit RA cert request")
+ raise RuntimeError("Unable to submit RA cert request")
def __fix_ra_perms(self):
os.chmod(self.ra_agent_db + "/cert8.db", 0640)
@@ -731,7 +781,7 @@ class CAInstance(service.Service):
def uninstall(self):
try:
ipautil.run(["/usr/bin/pkiremove", "-pki_instance_root=/var/lib",
- "-pki_instance_name=pki-ca", "-force"])
+ "-pki_instance_name=pki-ca", "--force"])
except ipautil.CalledProcessError, e:
logging.critical("failed to uninstall CA instance %s" % e)