summaryrefslogtreecommitdiffstats
path: root/ipa-server/ipaserver
diff options
context:
space:
mode:
authorRob Crittenden <rcrit@ipa.greyoak.com>2008-07-11 11:34:29 -0400
committerRob Crittenden <rcrit@ipa.greyoak.com>2008-07-14 09:06:52 -0400
commit6980b073035cdd43b30b58aba3ce7f84f16a14ad (patch)
tree2e291b420d42ad02df9221fb4036bb22698463df /ipa-server/ipaserver
parentb95c05f5c6a9977e6bb02d091a601efb3bcf360e (diff)
downloadfreeipa.git-6980b073035cdd43b30b58aba3ce7f84f16a14ad.tar.gz
freeipa.git-6980b073035cdd43b30b58aba3ce7f84f16a14ad.tar.xz
freeipa.git-6980b073035cdd43b30b58aba3ce7f84f16a14ad.zip
Rework the way SSL certificates are imported from PKCS#12 files.
Add the ability to provide PKCS#12 files during initial installation Add the ability to provide PKCS#12 files when preparing a replica Correct some issues with ipa-server-certinstall 452402
Diffstat (limited to 'ipa-server/ipaserver')
-rw-r--r--ipa-server/ipaserver/certs.py53
-rw-r--r--ipa-server/ipaserver/dsinstance.py9
-rw-r--r--ipa-server/ipaserver/httpinstance.py13
-rw-r--r--ipa-server/ipaserver/installutils.py18
4 files changed, 78 insertions, 15 deletions
diff --git a/ipa-server/ipaserver/certs.py b/ipa-server/ipaserver/certs.py
index 12fb354b..ca2db228 100644
--- a/ipa-server/ipaserver/certs.py
+++ b/ipa-server/ipaserver/certs.py
@@ -128,13 +128,13 @@ class CertDB(object):
f.write(self.gen_password())
self.set_perms(self.noise_fname)
- def create_passwd_file(self, passwd=True):
+ def create_passwd_file(self, passwd=None):
ipautil.backup_file(self.passwd_fname)
f = open(self.passwd_fname, "w")
- if passwd:
- f.write(self.gen_password())
+ if passwd is not None:
+ f.write("%s\n" % passwd)
else:
- f.write("\n")
+ f.write(self.gen_password())
f.close()
self.set_perms(self.passwd_fname)
@@ -159,14 +159,14 @@ class CertDB(object):
"-z", self.noise_fname,
"-f", self.passwd_fname])
- def export_ca_cert(self, create_pkcs12=False):
+ def export_ca_cert(self, nickname, create_pkcs12=False):
"""create_pkcs12 tells us whether we should create a PKCS#12 file
of the CA or not. If we are running on a replica then we won't
have the private key to make a PKCS#12 file so we don't need to
do that step."""
# export the CA cert for use with other apps
ipautil.backup_file(self.cacert_fname)
- self.run_certutil(["-L", "-n", "CA certificate",
+ self.run_certutil(["-L", "-n", nickname,
"-a",
"-o", self.cacert_fname])
self.set_perms(self.cacert_fname)
@@ -174,7 +174,7 @@ class CertDB(object):
ipautil.backup_file(self.pk12_fname)
ipautil.run(["/usr/bin/pk12util", "-d", self.secdir,
"-o", self.pk12_fname,
- "-n", "CA certificate",
+ "-n", self.cacert_name,
"-w", self.passwd_fname,
"-k", self.passwd_fname])
self.set_perms(self.pk12_fname)
@@ -296,7 +296,7 @@ class CertDB(object):
f.close()
self.set_perms(self.pin_fname)
- def trust_root_cert(self, nickname):
+ def find_root_cert(self, nickname):
p = subprocess.Popen(["/usr/bin/certutil", "-d", self.secdir,
"-O", "-n", nickname], stdout=subprocess.PIPE)
@@ -305,6 +305,11 @@ class CertDB(object):
root_nickname = re.match('\ *"(.*)".*', chain[0]).groups()[0]
+ return root_nickname
+
+ def trust_root_cert(self, nickname):
+ root_nickname = self.find_root_cert(nickname)
+
self.run_certutil(["-M", "-n", root_nickname,
"-t", "CT,CT,"])
@@ -350,28 +355,50 @@ class CertDB(object):
"-k", self.passwd_fname,
"-w", pkcs12_pwd_fname])
- def create_self_signed(self, passwd=True):
+ def create_self_signed(self, passwd=None):
self.create_noise_file()
self.create_passwd_file(passwd)
self.create_certdbs()
self.create_ca_cert()
- self.export_ca_cert(True)
+ self.export_ca_cert(self.cacert_name, True)
self.create_pin_file()
- def create_from_cacert(self, cacert_fname, passwd=False):
+ def create_from_cacert(self, cacert_fname, passwd=""):
self.create_noise_file()
self.create_passwd_file(passwd)
self.create_certdbs()
self.load_cacert(cacert_fname)
- def create_from_pkcs12(self, pkcs12_fname, pkcs12_pwd_fname, nickname="CA certificate", passwd=True):
+ def create_from_pkcs12(self, pkcs12_fname, pkcs12_pwd_fname, passwd=None):
+ """Create a new NSS database using the certificates in a PKCS#12 file.
+
+ pkcs12_fname: the filename of the PKCS#12 file
+ pkcs12_pwd_fname: the file containing the pin for the PKCS#12 file
+ nickname: the nickname/friendly-name of the cert we are loading
+ passwd: The password to use for the new NSS database we are creating
+ """
self.create_noise_file()
self.create_passwd_file(passwd)
self.create_certdbs()
self.import_pkcs12(pkcs12_fname, pkcs12_pwd_fname)
+ server_certs = self.find_server_certs()
+ if len(server_certs) == 0:
+ raise RuntimeError("Could not find a suitable server cert in import in %s" % pkcs12_fname)
+
+ # We only handle one server cert
+ nickname = server_certs[0][0]
+
+ self.cacert_name = self.find_root_cert(nickname)
self.trust_root_cert(nickname)
self.create_pin_file()
- self.export_ca_cert(False)
+ self.export_ca_cert(self.cacert_name, False)
+
+ # This file implies that we have our own self-signed CA. Ensure
+ # that it no longer exists (from previous installs, for example).
+ try:
+ os.remove("/usr/share/ipa/serial")
+ except:
+ pass
def backup_files(self):
self.fstore.backup_file(self.noise_fname)
diff --git a/ipa-server/ipaserver/dsinstance.py b/ipa-server/ipaserver/dsinstance.py
index 540ff686..d313b4ed 100644
--- a/ipa-server/ipaserver/dsinstance.py
+++ b/ipa-server/ipaserver/dsinstance.py
@@ -324,9 +324,16 @@ class DsInstance(service.Service):
ca = certs.CertDB(dirname)
if self.pkcs12_info:
ca.create_from_pkcs12(self.pkcs12_info[0], self.pkcs12_info[1])
+ server_certs = ca.find_server_certs()
+ if len(server_certs) == 0:
+ raise RuntimeError("Could not find a suitable server cert in import in %s" % pkcs12_info[0])
+
+ # We only handle one server cert
+ nickname = server_certs[0][0]
else:
ca.create_self_signed()
ca.create_server_cert("Server-Cert", "cn=%s,ou=Fedora Directory Server" % self.host_name)
+ nickname = "Server-Cert"
conn = ipaldap.IPAdmin("127.0.0.1")
conn.simple_bind_s("cn=directory manager", self.dm_password)
@@ -347,7 +354,7 @@ class DsInstance(service.Service):
entry.setValues("objectclass", "top", "nsEncryptionModule")
entry.setValues("cn", "RSA")
- entry.setValues("nsSSLPersonalitySSL", "Server-Cert")
+ entry.setValues("nsSSLPersonalitySSL", nickname)
entry.setValues("nsSSLToken", "internal (software)")
entry.setValues("nsSSLActivation", "on")
diff --git a/ipa-server/ipaserver/httpinstance.py b/ipa-server/ipaserver/httpinstance.py
index c5f8b50f..f5a903b3 100644
--- a/ipa-server/ipaserver/httpinstance.py
+++ b/ipa-server/ipaserver/httpinstance.py
@@ -145,6 +145,9 @@ class HTTPInstance(service.Service):
if installutils.update_file(NSS_CONF, '8443', '443') != 0:
print "Updating port in %s failed." % NSS_CONF
+ def __set_mod_nss_nickname(self, nickname):
+ installutils.set_directive(NSS_CONF, 'NSSNickname', nickname)
+
def __add_include(self):
"""This should run after __set_mod_nss_port so is already backed up"""
if installutils.update_file(NSS_CONF, '</VirtualHost>', 'Include conf.d/ipa-rewrite.conf\n</VirtualHost>') != 0:
@@ -154,7 +157,15 @@ class HTTPInstance(service.Service):
ds_ca = certs.CertDB(dsinstance.config_dirname(dsinstance.realm_to_serverid(self.realm)))
ca = certs.CertDB(NSS_DIR)
if self.pkcs12_info:
- ca.create_from_pkcs12(self.pkcs12_info[0], self.pkcs12_info[1], passwd=False)
+ ca.create_from_pkcs12(self.pkcs12_info[0], self.pkcs12_info[1], passwd="")
+ server_certs = ca.find_server_certs()
+ if len(server_certs) == 0:
+ raise RuntimeError("Could not find a suitable server cert in import in %s" % pkcs12_info[0])
+
+ # We only handle one server cert
+ nickname = server_certs[0][0]
+
+ self.__set_mod_nss_nickname(nickname)
else:
ca.create_from_cacert(ds_ca.cacert_fname)
ca.create_server_cert("Server-Cert", "cn=%s,ou=Apache Web Server" % self.fqdn, ds_ca)
diff --git a/ipa-server/ipaserver/installutils.py b/ipa-server/ipaserver/installutils.py
index ee3c1c77..674cf7d0 100644
--- a/ipa-server/ipaserver/installutils.py
+++ b/ipa-server/ipaserver/installutils.py
@@ -200,6 +200,24 @@ def update_file(filename, orig, subst):
print "File %s doesn't exist." % filename
return 1
+def set_directive(filename, directive, value):
+ """Set a name/value pair directive in a configuration file.
+
+ This has only been tested with nss.conf
+ """
+ fd = open(filename)
+ file = []
+ for line in fd:
+ if directive in line:
+ file.append('%s "%s"\n' % (directive, value))
+ else:
+ file.append(line)
+ fd.close()
+
+ fd = open(filename, "w")
+ fd.write("".join(file))
+ fd.close()
+
def kadmin(command):
ipautil.run(["/usr/kerberos/sbin/kadmin.local", "-q", command])