Move Selfsigned CA creation out of dsinstance

This allows us to have the CA ready to serve out certs for any operation even
before the dsinstance is created. The CA is independent of the dsinstance
anyway.

Also fixes: https://fedorahosted.org/freeipa/ticket/544
This commit is contained in:
Simo Sorce 2010-12-08 16:35:12 -05:00
parent 2efc08a6fc
commit bfaea1dd78
9 changed files with 62 additions and 62 deletions

View File

@ -158,7 +158,7 @@ def install_ca(config):
cs = cainstance.CADSInstance()
cs.create_instance(config.ds_user, config.realm_name, config.host_name, config.domain_name, config.dirman_password)
ca = cainstance.CAInstance(config.realm_name)
ca = cainstance.CAInstance(config.realm_name, certs.NSS_DIR)
ca.configure_instance("pkiuser", config.host_name, config.dirman_password, config.dirman_password, pkcs12_info=(cafile,), master_host=config.master_host_name, subject_base=config.subject_base)
return ca

View File

@ -27,7 +27,7 @@ import krbV
from optparse import OptionParser
from ipapython import ipautil
from ipaserver.install import bindinstance, dsinstance, installutils, certs, httpinstance
from ipaserver.install import bindinstance, dsinstance, installutils, certs
from ipaserver.install.bindinstance import add_zone, add_reverze_zone, add_rr, add_ptr_rr
from ipaserver.plugins.ldap2 import ldap2
from ipapython import version
@ -123,14 +123,9 @@ def export_certdb(realm_name, ds_dir, dir, passwd_fname, fname, hostname, subjec
try:
self_signed = certs.ipa_self_signed()
db = certs.CertDB(dir, realm_name, subject_base=subject_base)
db = certs.CertDB(realm_name, nssdir=dir, subject_base=subject_base)
db.create_passwd_file()
# if self_signed:
# ca_db = certs.CertDB(dsinstance.config_dirname(dsinstance.realm_to_serverid(realm_name)))
# db.create_from_cacert(ca_db.cacert_fname)
# else:
# ca_db = certs.CertDB(httpinstance.NSS_DIR, host_name=api.env.host)
ca_db = certs.CertDB(httpinstance.NSS_DIR, realm_name, host_name=api.env.host, subject_base=subject_base)
ca_db = certs.CertDB(realm_name, host_name=api.env.host, subject_base=subject_base)
if is_kdc:
ca_db.create_kdc_cert("KDC-Cert", hostname, dir)
else:
@ -177,7 +172,7 @@ def export_ra_pkcs12(dir, dm_password):
try:
try:
db = certs.CertDB(httpinstance.NSS_DIR, api.env.realm, host_name=api.env.host)
db = certs.CertDB(api.env.realm, host_name=api.env.host)
if db.has_nickname("ipaCert"):
pkcs12_fname = "%s/ra.p12" % dir

View File

@ -89,7 +89,7 @@ def choose_server_cert(server_certs):
return server_certs[num - 1]
def import_cert(dirname, pkcs12_fname, pkcs12_passwd, db_password):
cdb = certs.CertDB(dirname, api.env.realm)
cdb = certs.CertDB(api.env.realm, nssdir=dirname)
cdb.create_passwd_file(db_password)
cdb.create_certdbs()
[pw_fd, pw_name] = tempfile.mkstemp()

View File

@ -420,8 +420,8 @@ def uninstall():
ntpinstance.NTPInstance(fstore).uninstall()
if cainstance.CADSInstance().is_configured():
cainstance.CADSInstance().uninstall()
if cainstance.CAInstance(api.env.realm).is_configured():
cainstance.CAInstance(api.env.realm).uninstall()
if cainstance.CAInstance(api.env.realm, certs.NSS_DIR).is_configured():
cainstance.CAInstance(api.env.realm, certs.NSS_DIR).uninstall()
bindinstance.BindInstance(fstore).uninstall()
httpinstance.HTTPInstance(fstore).uninstall()
krbinstance.KrbInstance(fstore).uninstall()
@ -693,7 +693,12 @@ def main():
ntp = ntpinstance.NTPInstance(fstore)
ntp.create_instance()
if not options.selfsign:
if options.selfsign:
ca = certs.CertDB(realm_name, host_name=host_name,
subject_base=options.subject)
ca.create_self_signed()
ca.publish_ca_cert("/etc/ipa/ca.crt")
else:
# Clean up any previous self-signed CA that may exist
try:
os.remove(certs.CA_SERIALNO)
@ -720,7 +725,7 @@ def main():
if options.external_cert_file is None:
cs = cainstance.CADSInstance()
cs.create_instance("pkisrv", realm_name, host_name, domain_name, dm_password)
ca = cainstance.CAInstance(realm_name)
ca = cainstance.CAInstance(realm_name, certs.NSS_DIR)
if external == 0:
ca.configure_instance("pkiuser", host_name, dm_password, dm_password, subject_base=options.subject)
elif external == 1:

View File

@ -341,8 +341,8 @@ 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
In the self-signed case the CA exists in the NSS_DB 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.
@ -357,7 +357,7 @@ class CAInstance(service.Service):
2 = have signed cert, continue installation
"""
def __init__(self, realm):
def __init__(self, realm, ra_db):
service.Service.__init__(self, "pki-cad")
self.realm = realm
self.pki_user = "pkiuser"
@ -378,7 +378,7 @@ class CAInstance(service.Service):
self.canickname = get_ca_nickname(realm)
self.basedn = "o=ipaca"
self.ca_agent_db = tempfile.mkdtemp(prefix = "tmp-")
self.ra_agent_db = "/etc/httpd/alias"
self.ra_agent_db = ra_db
self.ra_agent_pwd = self.ra_agent_db + "/pwdfile.txt"
self.ds_port = DEFAULT_DSPORT
self.domain_name = "IPA"
@ -1000,5 +1000,5 @@ if __name__ == "__main__":
installutils.standard_logging_setup("install.log", False)
cs = CADSInstance()
cs.create_instance("dirsrv", "EXAMPLE.COM", "catest.example.com", "example.com", "password")
ca = CAInstance("EXAMPLE.COM")
ca = CAInstance("EXAMPLE.COM", "/etc/httpd/alias")
ca.configure_instance("pkiuser", "catest.example.com", "password", "password")

View File

@ -47,6 +47,10 @@ from ipalib import api
from ipalib.compat import sha1
# Apache needs access to this database so we need to create it
# where apache can reach
NSS_DIR = "/etc/httpd/alias"
CA_SERIALNO="/var/lib/ipa/ca_serialno"
def ipa_self_signed():
@ -163,7 +167,7 @@ def next_replica(serial_file=CA_SERIALNO):
return str(serial)
class CertDB(object):
def __init__(self, nssdir, realm, fstore=None, host_name=None, subject_base=None):
def __init__(self, realm, nssdir=NSS_DIR, fstore=None, host_name=None, subject_base=None):
self.secdir = nssdir
self.realm = realm
@ -1040,3 +1044,7 @@ class CertDB(object):
self.fstore.backup_file(self.pin_fname)
self.fstore.backup_file(self.certreq_fname)
self.fstore.backup_file(self.certder_fname)
def publish_ca_cert(self, location):
shutil.copy(self.cacert_fname, location)
os.chmod(location, 0444)

View File

@ -469,7 +469,7 @@ class DsInstance(service.Service):
def __enable_ssl(self):
dirname = config_dirname(self.serverid)
dsdb = certs.CertDB(dirname, self.realm_name, subject_base=self.subject_base)
dsdb = certs.CertDB(self.realm_name, nssdir=dirname, subject_base=self.subject_base)
if self.pkcs12_info:
dsdb.create_from_pkcs12(self.pkcs12_info[0], self.pkcs12_info[1])
server_certs = dsdb.find_server_certs()
@ -481,9 +481,8 @@ class DsInstance(service.Service):
self.dercert = dsdb.get_cert_from_db(nickname)
else:
nickname = "Server-Cert"
cadb = certs.CertDB(httpinstance.NSS_DIR, self.realm_name, host_name=self.fqdn, subject_base=self.subject_base)
cadb = certs.CertDB(self.realm_name, host_name=self.fqdn, subject_base=self.subject_base)
if self.self_signed_ca:
cadb.create_self_signed()
dsdb.create_from_cacert(cadb.cacert_fname, passwd=None)
self.dercert = dsdb.create_server_cert("Server-Cert", self.fqdn, cadb)
dsdb.track_server_cert("Server-Cert", self.principal, dsdb.passwd_fname)
@ -601,7 +600,7 @@ class DsInstance(service.Service):
# drop the trailing / off the config_dirname so the directory
# will match what is in certmonger
dirname = config_dirname(serverid)[:-1]
dsdb = certs.CertDB(dirname, self.realm_name)
dsdb = certs.CertDB(self.realm_name, nssdir=dirname)
dsdb.untrack_server_cert("Server-Cert")
erase_ds_instance_data(serverid)
@ -643,7 +642,7 @@ class DsInstance(service.Service):
self.stop()
dirname = config_dirname(realm_to_serverid(self.realm_name))
certdb = certs.CertDB(dirname, self.realm_name, subject_base=self.subject_base)
certdb = certs.CertDB(self.realm_name, nssdir=dirname, subject_base=self.subject_base)
if not cacert_name or len(cacert_name) == 0:
cacert_name = "Imported CA"
# we can't pass in the nickname, so we set the instance variable

View File

@ -35,7 +35,6 @@ from ipalib import util, api
HTTPD_DIR = "/etc/httpd"
SSL_CONF = HTTPD_DIR + "/conf.d/ssl.conf"
NSS_CONF = HTTPD_DIR + "/conf.d/nss.conf"
NSS_DIR = HTTPD_DIR + "/alias"
selinux_warning = """WARNING: could not set selinux boolean httpd_can_network_connect to true.
The web interface may not function correctly until this boolean is
@ -166,11 +165,13 @@ class HTTPInstance(service.Service):
print "Adding Include conf.d/ipa-rewrite to %s failed." % NSS_CONF
def __setup_ssl(self):
if self.self_signed_ca:
ca_db = certs.CertDB(NSS_DIR, self.realm, subject_base=self.subject_base)
else:
ca_db = certs.CertDB(NSS_DIR, self.realm, host_name=self.fqdn, subject_base=self.subject_base)
db = certs.CertDB(NSS_DIR, self.realm, subject_base=self.subject_base)
fqdn = None
if not self.self_signed_ca:
fqdn = self.fqdn
ca_db = certs.CertDB(self.realm, host_name=fqdn, subject_base=self.subject_base)
db = certs.CertDB(self.realm, subject_base=self.subject_base)
if self.pkcs12_info:
db.create_from_pkcs12(self.pkcs12_info[0], self.pkcs12_info[1], passwd="")
server_certs = db.find_server_certs()
@ -186,31 +187,27 @@ class HTTPInstance(service.Service):
else:
if self.self_signed_ca:
db.create_from_cacert(ca_db.cacert_fname)
db.create_password_conf()
self.dercert = db.create_server_cert("Server-Cert", self.fqdn, ca_db)
db.track_server_cert("Server-Cert", self.principal, db.passwd_fname)
db.create_signing_cert("Signing-Cert", "Object Signing Cert", ca_db)
else:
self.dercert = db.create_server_cert("Server-Cert", self.fqdn, ca_db)
db.track_server_cert("Server-Cert", self.principal, db.passwd_fname)
db.create_signing_cert("Signing-Cert", "Object Signing Cert", ca_db)
db.create_password_conf()
db.create_password_conf()
self.dercert = db.create_server_cert("Server-Cert", self.fqdn, ca_db)
db.track_server_cert("Server-Cert", self.principal, db.passwd_fname)
db.create_signing_cert("Signing-Cert", "Object Signing Cert", ca_db)
# Fix the database permissions
os.chmod(NSS_DIR + "/cert8.db", 0660)
os.chmod(NSS_DIR + "/key3.db", 0660)
os.chmod(NSS_DIR + "/secmod.db", 0660)
os.chmod(NSS_DIR + "/pwdfile.txt", 0660)
os.chmod(certs.NSS_DIR + "/cert8.db", 0660)
os.chmod(certs.NSS_DIR + "/key3.db", 0660)
os.chmod(certs.NSS_DIR + "/secmod.db", 0660)
os.chmod(certs.NSS_DIR + "/pwdfile.txt", 0660)
pent = pwd.getpwnam("apache")
os.chown(NSS_DIR + "/cert8.db", 0, pent.pw_gid )
os.chown(NSS_DIR + "/key3.db", 0, pent.pw_gid )
os.chown(NSS_DIR + "/secmod.db", 0, pent.pw_gid )
os.chown(NSS_DIR + "/pwdfile.txt", 0, pent.pw_gid )
os.chown(certs.NSS_DIR + "/cert8.db", 0, pent.pw_gid )
os.chown(certs.NSS_DIR + "/key3.db", 0, pent.pw_gid )
os.chown(certs.NSS_DIR + "/secmod.db", 0, pent.pw_gid )
os.chown(certs.NSS_DIR + "/pwdfile.txt", 0, pent.pw_gid )
# Fix SELinux permissions on the database
ipautil.run(["/sbin/restorecon", NSS_DIR + "/cert8.db"])
ipautil.run(["/sbin/restorecon", NSS_DIR + "/key3.db"])
ipautil.run(["/sbin/restorecon", certs.NSS_DIR + "/cert8.db"])
ipautil.run(["/sbin/restorecon", certs.NSS_DIR + "/key3.db"])
# In case this got generated as part of the install, reset the
# context
@ -226,7 +223,7 @@ class HTTPInstance(service.Service):
prefs_fd.close()
# The signing cert is generated in __setup_ssl
db = certs.CertDB(NSS_DIR, self.realm, subject_base=self.subject_base)
db = certs.CertDB(self.realm, subject_base=self.subject_base)
pwdfile = open(db.passwd_fname)
pwd = pwdfile.read()
@ -241,9 +238,8 @@ class HTTPInstance(service.Service):
shutil.rmtree(tmpdir)
def __publish_ca_cert(self):
ca_db = certs.CertDB(NSS_DIR, self.realm)
shutil.copy(ca_db.cacert_fname, "/usr/share/ipa/html/ca.crt")
os.chmod("/usr/share/ipa/html/ca.crt", 0444)
ca_db = certs.CertDB(self.realm)
ca_db.publish_ca_cert("/usr/share/ipa/html/ca.crt")
def uninstall(self):
if self.is_configured():
@ -255,7 +251,7 @@ class HTTPInstance(service.Service):
if not running is None:
self.stop()
db = certs.CertDB(NSS_DIR, api.env.realm)
db = certs.CertDB(api.env.realm)
db.untrack_server_cert("Server-Cert")
if not enabled is None and not enabled:
self.chkconfig_off()

View File

@ -45,7 +45,6 @@ import pyasn1.codec.ber.decoder
import struct
import certs
import httpinstance
from distutils import version
KRBMKEY_DENY_ACI = '(targetattr = "krbMKey")(version 3.0; acl "No external access"; deny (read,write,search,compare) userdn != "ldap:///uid=kdc,cn=sysaccounts,cn=etc,$SUFFIX";)'
@ -544,11 +543,10 @@ class KrbInstance(service.Service):
def __setup_pkinit(self):
if self.self_signed_ca:
ca_db = certs.CertDB(httpinstance.NSS_DIR, self.realm,
ca_db = certs.CertDB(self.realm,
subject_base=self.subject_base)
else:
ca_db = certs.CertDB(httpinstance.NSS_DIR, self.realm,
host_name=self.fqdn,
ca_db = certs.CertDB(self.realm, host_name=self.fqdn,
subject_base=self.subject_base)
if self.pkcs12_info:
@ -564,8 +562,7 @@ class KrbInstance(service.Service):
# Finally copy the cacert in the krb directory so we don't
# have any selinux issues with the file context
shutil.copyfile("/usr/share/ipa/html/ca.crt",
"/var/kerberos/krb5kdc/cacert.pem")
shutil.copyfile("/etc/ipa/ca.crt", "/var/kerberos/krb5kdc/cacert.pem")
def __add_anonymous_pkinit_principal(self):
princ = "WELLKNOWN/ANONYMOUS"