mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2024-12-23 15:40:01 -06:00
User-defined certificate subjects
Let the user, upon installation, set the certificate subject base for the dogtag CA. Certificate requests will automatically be given this subject base, regardless of what is in the CSR. The selfsign plugin does not currently support this dynamic name re-assignment and will reject any incoming requests that don't conform to the subject base. The certificate subject base is stored in cn=ipaconfig but it does NOT dynamically update the configuration, for dogtag at least. The file /var/lib/pki-ca/profiles/ca/caIPAserviceCert.cfg would need to be updated and pki-cad restarted.
This commit is contained in:
parent
2955c955ac
commit
e4470f8165
@ -39,9 +39,11 @@ attributeTypes: ( 2.16.840.1.113730.3.8.3.51 NAME 'ipaEscrowKeyCertificate' DESC
|
|||||||
attributeTypes: ( 2.16.840.1.113730.3.8.3.52 NAME 'ipaEscrowKey' DESC 'PKCS#12-formatted encrypted certificate and private key for encrypting escrow packets' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5)
|
attributeTypes: ( 2.16.840.1.113730.3.8.3.52 NAME 'ipaEscrowKey' DESC 'PKCS#12-formatted encrypted certificate and private key for encrypting escrow packets' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5)
|
||||||
# ipaMigrationEnabled - if TRUE allow adding user entries with pre-hashed passwords
|
# ipaMigrationEnabled - if TRUE allow adding user entries with pre-hashed passwords
|
||||||
attributeTypes: ( 2.16.840.1.113730.3.8.1.16 NAME 'ipaMigrationEnabled' DESC 'Enable adding user entries with pre-hashed passwords.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
|
attributeTypes: ( 2.16.840.1.113730.3.8.1.16 NAME 'ipaMigrationEnabled' DESC 'Enable adding user entries with pre-hashed passwords.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
|
||||||
|
attributetypes: ( 2.16.840.1.113730.3.8.1.14 NAME 'ipaCertificateSubjectBase' S
|
||||||
|
YNTAX 1.3.6.1.4.1.1466.115.121.1.15)
|
||||||
###############################################
|
###############################################
|
||||||
##
|
##
|
||||||
## ObjectClasses
|
## ObjectClasses
|
||||||
##
|
##
|
||||||
## ipaGuiConfig - GUI config parameters objectclass
|
## ipaGuiConfig - GUI config parameters objectclass
|
||||||
objectClasses: ( 2.16.840.1.113730.3.8.2.1 NAME 'ipaGuiConfig' AUXILIARY MAY ( ipaUserSearchFields $ ipaGroupSearchFields $ ipaSearchTimeLimit $ ipaSearchRecordsLimit $ ipaCustomFields $ ipaHomesRootDir $ ipaDefaultLoginShell $ ipaDefaultPrimaryGroup $ ipaMaxUsernameLength $ ipaPwdExpAdvNotify $ ipaUserObjectClasses $ ipaGroupObjectClasses $ ipaDefaultEmailDomain $ ipaObsoleteEscrowPacketLifetime $ ipaEscrowKeyCertificate $ ipaEscrowKey $ ipaMigrationEnabled ) )
|
objectClasses: ( 2.16.840.1.113730.3.8.2.1 NAME 'ipaGuiConfig' AUXILIARY MAY ( ipaUserSearchFields $ ipaGroupSearchFields $ ipaSearchTimeLimit $ ipaSearchRecordsLimit $ ipaCustomFields $ ipaHomesRootDir $ ipaDefaultLoginShell $ ipaDefaultPrimaryGroup $ ipaMaxUsernameLength $ ipaPwdExpAdvNotify $ ipaUserObjectClasses $ ipaGroupObjectClasses $ ipaDefaultEmailDomain $ ipaObsoleteEscrowPacketLifetime $ ipaEscrowKeyCertificate $ ipaEscrowKey $ ipaMigrationEnabled $ ipaCertificateSubjectBase) )
|
||||||
|
@ -48,6 +48,7 @@ class ReplicaConfig:
|
|||||||
self.host_name = ""
|
self.host_name = ""
|
||||||
self.repl_password = ""
|
self.repl_password = ""
|
||||||
self.dir = ""
|
self.dir = ""
|
||||||
|
self.subject_base = "O=IPA"
|
||||||
|
|
||||||
def parse_options():
|
def parse_options():
|
||||||
from optparse import OptionParser
|
from optparse import OptionParser
|
||||||
@ -106,6 +107,7 @@ def read_info(dir, rconfig):
|
|||||||
rconfig.ds_user = config.get("realm", "ds_user")
|
rconfig.ds_user = config.get("realm", "ds_user")
|
||||||
rconfig.domain_name = config.get("realm", "domain_name")
|
rconfig.domain_name = config.get("realm", "domain_name")
|
||||||
rconfig.host_name = config.get("realm", "destination_host")
|
rconfig.host_name = config.get("realm", "destination_host")
|
||||||
|
rconfig.subject_base = config.get("realm", "subject_base")
|
||||||
|
|
||||||
def get_host_name():
|
def get_host_name():
|
||||||
hostname = installutils.get_fqdn()
|
hostname = installutils.get_fqdn()
|
||||||
@ -150,9 +152,8 @@ def install_ca(config):
|
|||||||
|
|
||||||
cs = cainstance.CADSInstance()
|
cs = cainstance.CADSInstance()
|
||||||
cs.create_instance(config.ds_user, config.realm_name, config.host_name, config.domain_name, config.dirman_password)
|
cs.create_instance(config.ds_user, config.realm_name, config.host_name, config.domain_name, config.dirman_password)
|
||||||
|
|
||||||
ca = cainstance.CAInstance()
|
ca = cainstance.CAInstance()
|
||||||
ca.configure_instance("pkiuser", config.host_name, config.dirman_password, config.dirman_password, pkcs12_info=(cafile,), master_host=config.master_host_name)
|
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
|
return ca
|
||||||
|
|
||||||
@ -346,6 +347,8 @@ def main():
|
|||||||
CA.import_ra_cert(dir + "/ra.p12")
|
CA.import_ra_cert(dir + "/ra.p12")
|
||||||
CA.fix_ra_perms()
|
CA.fix_ra_perms()
|
||||||
service.restart("httpd")
|
service.restart("httpd")
|
||||||
|
service.print_msg("Setting the certificate subject base")
|
||||||
|
CA.set_subject_in_config(util.realm_to_suffix(config.realm_name))
|
||||||
|
|
||||||
# The DS instance is created before the keytab, add the SSL cert we
|
# The DS instance is created before the keytab, add the SSL cert we
|
||||||
# generated
|
# generated
|
||||||
@ -370,6 +373,7 @@ def main():
|
|||||||
|
|
||||||
service.restart("dirsrv")
|
service.restart("dirsrv")
|
||||||
service.restart("krb5kdc")
|
service.restart("krb5kdc")
|
||||||
|
service.restart("httpd")
|
||||||
|
|
||||||
if options.setup_dns:
|
if options.setup_dns:
|
||||||
api.Backend.ldap2.connect(bind_dn="cn=Directory Manager",
|
api.Backend.ldap2.connect(bind_dn="cn=Directory Manager",
|
||||||
|
@ -33,6 +33,7 @@ from ipaserver import ipaldap
|
|||||||
from ipapython import version
|
from ipapython import version
|
||||||
from ipalib.constants import DEFAULT_CONFIG
|
from ipalib.constants import DEFAULT_CONFIG
|
||||||
from ipalib import api
|
from ipalib import api
|
||||||
|
from ipalib import util
|
||||||
import ldap
|
import ldap
|
||||||
|
|
||||||
def parse_options():
|
def parse_options():
|
||||||
@ -94,13 +95,23 @@ def get_domain_name():
|
|||||||
|
|
||||||
return domain_name
|
return domain_name
|
||||||
|
|
||||||
|
def get_subject_base(host_name, dm_password, suffix):
|
||||||
|
try:
|
||||||
|
conn = ipaldap.IPAdmin(host_name)
|
||||||
|
conn.do_simple_bind(bindpw=dm_password)
|
||||||
|
except Exception, e:
|
||||||
|
logging.critical("Could not connect to the Directory Server on %s" % host_name)
|
||||||
|
raise e
|
||||||
|
entry = conn.getEntry("cn=ipaConfig, cn=etc, %s" % suffix, ldap.SCOPE_SUBTREE)
|
||||||
|
return entry.getValue('ipacertificatesubjectbase')
|
||||||
|
|
||||||
def check_ipa_configuration(realm_name):
|
def check_ipa_configuration(realm_name):
|
||||||
config_dir = dsinstance.config_dirname(dsinstance.realm_to_serverid(realm_name))
|
config_dir = dsinstance.config_dirname(dsinstance.realm_to_serverid(realm_name))
|
||||||
if not ipautil.dir_exists(config_dir):
|
if not ipautil.dir_exists(config_dir):
|
||||||
logging.error("could not find directory instance: %s" % config_dir)
|
logging.error("could not find directory instance: %s" % config_dir)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
def export_certdb(realm_name, ds_dir, dir, passwd_fname, fname, hostname):
|
def export_certdb(realm_name, ds_dir, dir, passwd_fname, fname, hostname, subject_base=None):
|
||||||
"""realm is the kerberos realm for the IPA server.
|
"""realm is the kerberos realm for the IPA server.
|
||||||
ds_dir is the location of the master DS we are creating a replica for.
|
ds_dir is the location of the master DS we are creating a replica for.
|
||||||
dir is the location of the files for the replica we are creating.
|
dir is the location of the files for the replica we are creating.
|
||||||
@ -113,14 +124,14 @@ def export_certdb(realm_name, ds_dir, dir, passwd_fname, fname, hostname):
|
|||||||
try:
|
try:
|
||||||
self_signed = certs.ipa_self_signed()
|
self_signed = certs.ipa_self_signed()
|
||||||
|
|
||||||
db = certs.CertDB(dir)
|
db = certs.CertDB(dir, subject_base=subject_base)
|
||||||
db.create_passwd_file()
|
db.create_passwd_file()
|
||||||
# if self_signed:
|
# if self_signed:
|
||||||
# ca_db = certs.CertDB(dsinstance.config_dirname(dsinstance.realm_to_serverid(realm_name)))
|
# ca_db = certs.CertDB(dsinstance.config_dirname(dsinstance.realm_to_serverid(realm_name)))
|
||||||
# db.create_from_cacert(ca_db.cacert_fname)
|
# db.create_from_cacert(ca_db.cacert_fname)
|
||||||
# else:
|
# else:
|
||||||
# ca_db = certs.CertDB(httpinstance.NSS_DIR, host_name=get_host_name())
|
# ca_db = certs.CertDB(httpinstance.NSS_DIR, host_name=get_host_name())
|
||||||
ca_db = certs.CertDB(httpinstance.NSS_DIR, host_name=get_host_name())
|
ca_db = certs.CertDB(httpinstance.NSS_DIR, host_name=get_host_name(), subject_base=subject_base)
|
||||||
db.create_from_cacert(ca_db.cacert_fname)
|
db.create_from_cacert(ca_db.cacert_fname)
|
||||||
db.create_server_cert("Server-Cert", hostname, ca_db)
|
db.create_server_cert("Server-Cert", hostname, ca_db)
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
@ -174,7 +185,8 @@ def get_ds_user(ds_dir):
|
|||||||
|
|
||||||
return user
|
return user
|
||||||
|
|
||||||
def save_config(dir, realm_name, host_name, ds_user, domain_name, dest_host):
|
def save_config(dir, realm_name, host_name, ds_user, domain_name, dest_host,
|
||||||
|
subject_base):
|
||||||
config = SafeConfigParser()
|
config = SafeConfigParser()
|
||||||
config.add_section("realm")
|
config.add_section("realm")
|
||||||
config.set("realm", "realm_name", realm_name)
|
config.set("realm", "realm_name", realm_name)
|
||||||
@ -182,6 +194,7 @@ def save_config(dir, realm_name, host_name, ds_user, domain_name, dest_host):
|
|||||||
config.set("realm", "ds_user", ds_user)
|
config.set("realm", "ds_user", ds_user)
|
||||||
config.set("realm", "domain_name", domain_name)
|
config.set("realm", "domain_name", domain_name)
|
||||||
config.set("realm", "destination_host", dest_host)
|
config.set("realm", "destination_host", dest_host)
|
||||||
|
config.set("realm", "subject_base", subject_base)
|
||||||
fd = open(dir + "/realm_info", "w")
|
fd = open(dir + "/realm_info", "w")
|
||||||
config.write(fd)
|
config.write(fd)
|
||||||
|
|
||||||
@ -265,6 +278,8 @@ def main():
|
|||||||
|
|
||||||
print "Preparing replica for %s from %s" % (replica_fqdn, host_name)
|
print "Preparing replica for %s from %s" % (replica_fqdn, host_name)
|
||||||
|
|
||||||
|
subject_base = get_subject_base(host_name, dirman_password, util.realm_to_suffix(realm_name))
|
||||||
|
|
||||||
top_dir = tempfile.mkdtemp("ipa")
|
top_dir = tempfile.mkdtemp("ipa")
|
||||||
dir = top_dir + "/realm_info"
|
dir = top_dir + "/realm_info"
|
||||||
os.mkdir(dir, 0700)
|
os.mkdir(dir, 0700)
|
||||||
@ -298,7 +313,7 @@ def main():
|
|||||||
print "Copy failed %s" % e
|
print "Copy failed %s" % e
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
print "Creating SSL certificate for the Directory Server"
|
print "Creating SSL certificate for the Directory Server"
|
||||||
export_certdb(realm_name, ds_dir, dir, passwd_fname, "dscert", replica_fqdn)
|
export_certdb(realm_name, ds_dir, dir, passwd_fname, "dscert", replica_fqdn, subject_base)
|
||||||
|
|
||||||
if options.http_pin:
|
if options.http_pin:
|
||||||
passwd = options.http_pin
|
passwd = options.http_pin
|
||||||
@ -319,13 +334,15 @@ def main():
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
else:
|
else:
|
||||||
print "Creating SSL certificate for the Web Server"
|
print "Creating SSL certificate for the Web Server"
|
||||||
export_certdb(realm_name, ds_dir, dir, passwd_fname, "httpcert", replica_fqdn)
|
export_certdb(realm_name, ds_dir, dir, passwd_fname, "httpcert", replica_fqdn, subject_base)
|
||||||
print "Exporting RA certificate"
|
print "Exporting RA certificate"
|
||||||
export_ra_pkcs12(dir, dirman_password)
|
export_ra_pkcs12(dir, dirman_password)
|
||||||
|
|
||||||
print "Copying additional files"
|
print "Copying additional files"
|
||||||
copy_files(realm_name, dir)
|
copy_files(realm_name, dir)
|
||||||
|
|
||||||
print "Finalizing configuration"
|
print "Finalizing configuration"
|
||||||
save_config(dir, realm_name, host_name, ds_user, domain_name, replica_fqdn)
|
save_config(dir, realm_name, host_name, ds_user, domain_name, replica_fqdn, subject_base)
|
||||||
|
|
||||||
replicafile = "/var/lib/ipa/replica-info-" + replica_fqdn
|
replicafile = "/var/lib/ipa/replica-info-" + replica_fqdn
|
||||||
encfile = replicafile+".gpg"
|
encfile = replicafile+".gpg"
|
||||||
|
@ -35,6 +35,7 @@ import signal
|
|||||||
import shutil
|
import shutil
|
||||||
import glob
|
import glob
|
||||||
import traceback
|
import traceback
|
||||||
|
import ldap
|
||||||
from optparse import OptionParser
|
from optparse import OptionParser
|
||||||
from ConfigParser import RawConfigParser
|
from ConfigParser import RawConfigParser
|
||||||
import random
|
import random
|
||||||
@ -49,6 +50,7 @@ from ipaserver.install import certs
|
|||||||
from ipaserver.install import service
|
from ipaserver.install import service
|
||||||
from ipapython import version
|
from ipapython import version
|
||||||
from ipaserver.install.installutils import *
|
from ipaserver.install.installutils import *
|
||||||
|
from ipaserver import ipaldap
|
||||||
|
|
||||||
from ipapython import sysrestore
|
from ipapython import sysrestore
|
||||||
from ipapython.ipautil import *
|
from ipapython.ipautil import *
|
||||||
@ -117,6 +119,8 @@ def parse_options():
|
|||||||
help="The starting uid value (default random)")
|
help="The starting uid value (default random)")
|
||||||
parser.add_option("--gidstart", dest="gidstart", default=namespace, type=int,
|
parser.add_option("--gidstart", dest="gidstart", default=namespace, type=int,
|
||||||
help="The starting gid value (default random)")
|
help="The starting gid value (default random)")
|
||||||
|
parser.add_option("--subject", dest="subject", default="O=IPA",
|
||||||
|
help="The certificate subject base (default O=IPA)")
|
||||||
options, args = parser.parse_args()
|
options, args = parser.parse_args()
|
||||||
|
|
||||||
if not options.setup_dns:
|
if not options.setup_dns:
|
||||||
@ -456,6 +460,20 @@ def render_assets():
|
|||||||
ui = ipawebui.create_wsgi_app(api)
|
ui = ipawebui.create_wsgi_app(api)
|
||||||
ui.render_assets()
|
ui.render_assets()
|
||||||
|
|
||||||
|
def set_subject_in_config(host_name, dm_password, suffix, subject_base):
|
||||||
|
try:
|
||||||
|
conn = ipaldap.IPAdmin(host_name)
|
||||||
|
conn.do_simple_bind(bindpw=dm_password)
|
||||||
|
except Exception, e:
|
||||||
|
logging.critical("Could not connect to the Directory Server on %s" % host_name)
|
||||||
|
raise e
|
||||||
|
entry = conn.getEntry("cn=ipaConfig, cn=etc, %s" % suffix, ldap.SCOPE_SUBTREE)
|
||||||
|
if entry.getValue('ipaCertificateSubjectBase') is None:
|
||||||
|
newentry = entry.toDict()
|
||||||
|
newentry['ipaCertificateSubjectBase'] = subject_base
|
||||||
|
conn.updateEntry(entry.dn, entry.toDict(), newentry)
|
||||||
|
|
||||||
|
conn.unbind()
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
global ds
|
global ds
|
||||||
@ -502,7 +520,7 @@ def main():
|
|||||||
print "Aborting uninstall operation."
|
print "Aborting uninstall operation."
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
return uninstall(not certs.ipa_self_signed())
|
return uninstall(not certs.ipa_self_signed() or options.ca)
|
||||||
|
|
||||||
# This will override any settings passed in on the cmdline
|
# This will override any settings passed in on the cmdline
|
||||||
options._update_loose(read_cache())
|
options._update_loose(read_cache())
|
||||||
@ -702,12 +720,12 @@ def main():
|
|||||||
cs.create_instance(ds_user, realm_name, host_name, domain_name, dm_password)
|
cs.create_instance(ds_user, realm_name, host_name, domain_name, dm_password)
|
||||||
ca = cainstance.CAInstance()
|
ca = cainstance.CAInstance()
|
||||||
if external == 0:
|
if external == 0:
|
||||||
ca.configure_instance("pkiuser", host_name, dm_password, dm_password)
|
ca.configure_instance("pkiuser", host_name, dm_password, dm_password, subject_base=options.subject)
|
||||||
elif external == 1:
|
elif external == 1:
|
||||||
write_cache(options)
|
write_cache(options)
|
||||||
ca.configure_instance("pkiuser", host_name, dm_password, dm_password, csr_file="/root/ipa.csr")
|
ca.configure_instance("pkiuser", host_name, dm_password, dm_password, csr_file="/root/ipa.csr", subject_base=options.subject)
|
||||||
else:
|
else:
|
||||||
ca.configure_instance("pkiuser", host_name, dm_password, dm_password, cert_file=options.external_cert_file, cert_chain_file=options.external_ca_file)
|
ca.configure_instance("pkiuser", host_name, dm_password, dm_password, cert_file=options.external_cert_file, cert_chain_file=options.external_ca_file, subject_base=options.subject)
|
||||||
|
|
||||||
# Configure ntpd
|
# Configure ntpd
|
||||||
if options.conf_ntp:
|
if options.conf_ntp:
|
||||||
@ -719,11 +737,11 @@ def main():
|
|||||||
if options.dirsrv_pkcs12:
|
if options.dirsrv_pkcs12:
|
||||||
pkcs12_info = (options.dirsrv_pkcs12, pw_name)
|
pkcs12_info = (options.dirsrv_pkcs12, pw_name)
|
||||||
try:
|
try:
|
||||||
ds.create_instance(ds_user, realm_name, host_name, domain_name, dm_password, pkcs12_info)
|
ds.create_instance(ds_user, realm_name, host_name, domain_name, dm_password, pkcs12_info, subject_base=options.subject)
|
||||||
finally:
|
finally:
|
||||||
os.remove(pw_name)
|
os.remove(pw_name)
|
||||||
else:
|
else:
|
||||||
ds.create_instance(ds_user, realm_name, host_name, domain_name, dm_password, self_signed_ca=not options.ca, uidstart=options.uidstart, gidstart=options.gidstart)
|
ds.create_instance(ds_user, realm_name, host_name, domain_name, dm_password, self_signed_ca=not options.ca, uidstart=options.uidstart, gidstart=options.gidstart, subject_base=options.subject)
|
||||||
|
|
||||||
# Create a kerberos instance
|
# Create a kerberos instance
|
||||||
krb = krbinstance.KrbInstance(fstore)
|
krb = krbinstance.KrbInstance(fstore)
|
||||||
@ -747,10 +765,10 @@ def main():
|
|||||||
http = httpinstance.HTTPInstance(fstore)
|
http = httpinstance.HTTPInstance(fstore)
|
||||||
if options.http_pkcs12:
|
if options.http_pkcs12:
|
||||||
pkcs12_info = (options.http_pkcs12, pw_name)
|
pkcs12_info = (options.http_pkcs12, pw_name)
|
||||||
http.create_instance(realm_name, host_name, domain_name, dm_password, autoconfig=False, pkcs12_info=pkcs12_info)
|
http.create_instance(realm_name, host_name, domain_name, dm_password, autoconfig=False, pkcs12_info=pkcs12_info, subject_base=options.subject)
|
||||||
os.remove(pw_name)
|
os.remove(pw_name)
|
||||||
else:
|
else:
|
||||||
http.create_instance(realm_name, host_name, domain_name, dm_password, autoconfig=True, self_signed_ca=not options.ca)
|
http.create_instance(realm_name, host_name, domain_name, dm_password, autoconfig=True, self_signed_ca=not options.ca, subject_base=options.subject)
|
||||||
ipautil.run(["/sbin/restorecon", "/var/cache/ipa/sessions"])
|
ipautil.run(["/sbin/restorecon", "/var/cache/ipa/sessions"])
|
||||||
|
|
||||||
# Create the management framework config file
|
# Create the management framework config file
|
||||||
@ -768,6 +786,11 @@ def main():
|
|||||||
fd.write('webui_assets_dir=' + ASSETS_DIR + '\n')
|
fd.write('webui_assets_dir=' + ASSETS_DIR + '\n')
|
||||||
fd.close()
|
fd.close()
|
||||||
|
|
||||||
|
set_subject_in_config(host_name, dm_password, util.realm_to_suffix(realm_name), options.subject)
|
||||||
|
if options.ca:
|
||||||
|
service.print_msg("Setting the certificate subject base")
|
||||||
|
ca.set_subject_in_config(util.realm_to_suffix(realm_name))
|
||||||
|
|
||||||
# Apply any LDAP updates. Needs to be done after the configuration file
|
# Apply any LDAP updates. Needs to be done after the configuration file
|
||||||
# is created
|
# is created
|
||||||
service.print_msg("Applying LDAP updates")
|
service.print_msg("Applying LDAP updates")
|
||||||
|
@ -35,7 +35,7 @@ class config(LDAPObject):
|
|||||||
'ipamaxusernamelength', 'ipahomesrootdir', 'ipadefaultloginshell',
|
'ipamaxusernamelength', 'ipahomesrootdir', 'ipadefaultloginshell',
|
||||||
'ipadefaultprimarygroup', 'ipadefaultdomain', 'ipasearchtimelimit',
|
'ipadefaultprimarygroup', 'ipadefaultdomain', 'ipasearchtimelimit',
|
||||||
'ipasearchrecordslimit', 'ipausersearchfields', 'ipagroupsearchfields',
|
'ipasearchrecordslimit', 'ipausersearchfields', 'ipagroupsearchfields',
|
||||||
'ipamigrationenabled',
|
'ipamigrationenabled', 'ipacertificatesubjectbase',
|
||||||
]
|
]
|
||||||
attribute_names = {
|
attribute_names = {
|
||||||
'ipamaxusernamelength': 'maximum username length',
|
'ipamaxusernamelength': 'maximum username length',
|
||||||
@ -48,52 +48,68 @@ class config(LDAPObject):
|
|||||||
'ipausersearchfields': 'search fields for users',
|
'ipausersearchfields': 'search fields for users',
|
||||||
'ipagroupsearchfields': 'search fields for groups',
|
'ipagroupsearchfields': 'search fields for groups',
|
||||||
'ipamigrationenabled': 'enable migration mode',
|
'ipamigrationenabled': 'enable migration mode',
|
||||||
|
'ipacertificatesubjectbase': 'base for certificate subjects',
|
||||||
}
|
}
|
||||||
|
|
||||||
takes_params = (
|
takes_params = (
|
||||||
Int('ipamaxusernamelength?',
|
Int('ipamaxusernamelength?',
|
||||||
cli_name='maxusername',
|
cli_name='maxusername',
|
||||||
|
label='Max. Username length',
|
||||||
doc='Max. Username length',
|
doc='Max. Username length',
|
||||||
minvalue=1,
|
minvalue=1,
|
||||||
),
|
),
|
||||||
Str('ipahomesrootdir?',
|
Str('ipahomesrootdir?',
|
||||||
cli_name='homedirectory',
|
cli_name='homedirectory',
|
||||||
|
label='Home Directory base',
|
||||||
doc='Default location of home directories',
|
doc='Default location of home directories',
|
||||||
),
|
),
|
||||||
Str('ipadefaultloginshell?',
|
Str('ipadefaultloginshell?',
|
||||||
cli_name='defaultshell',
|
cli_name='defaultshell',
|
||||||
|
label='Default shell',
|
||||||
doc='Default shell for new users',
|
doc='Default shell for new users',
|
||||||
),
|
),
|
||||||
Str('ipadefaultprimarygroup?',
|
Str('ipadefaultprimarygroup?',
|
||||||
cli_name='defaultgroup',
|
cli_name='defaultgroup',
|
||||||
|
label='Default users group',
|
||||||
doc='Default group for new users',
|
doc='Default group for new users',
|
||||||
),
|
),
|
||||||
Str('ipadefaultemaildomain?',
|
Str('ipadefaultemaildomain?',
|
||||||
cli_name='emaildomain',
|
cli_name='emaildomain',
|
||||||
|
label='Default e-mail domain',
|
||||||
doc='Default e-mail domain new users',
|
doc='Default e-mail domain new users',
|
||||||
),
|
),
|
||||||
Int('ipasearchtimelimit?',
|
Int('ipasearchtimelimit?',
|
||||||
cli_name='searchtimelimit',
|
cli_name='searchtimelimit',
|
||||||
|
label='Search time limit',
|
||||||
doc='Max. amount of time (sec.) for a search (-1 is unlimited)',
|
doc='Max. amount of time (sec.) for a search (-1 is unlimited)',
|
||||||
minvalue=-1,
|
minvalue=-1,
|
||||||
),
|
),
|
||||||
Int('ipasearchrecordslimit?',
|
Int('ipasearchrecordslimit?',
|
||||||
cli_name='searchrecordslimit',
|
cli_name='searchrecordslimit',
|
||||||
|
label='Search size limit',
|
||||||
doc='Max. number of records to search (-1 is unlimited)',
|
doc='Max. number of records to search (-1 is unlimited)',
|
||||||
minvalue=-1,
|
minvalue=-1,
|
||||||
),
|
),
|
||||||
Str('ipausersearchfields?',
|
Str('ipausersearchfields?',
|
||||||
cli_name='usersearch',
|
cli_name='usersearch',
|
||||||
|
label='User search fields',
|
||||||
doc='A comma-separated list of fields to search when searching for users',
|
doc='A comma-separated list of fields to search when searching for users',
|
||||||
),
|
),
|
||||||
Str('ipagroupsearchfields?',
|
Str('ipagroupsearchfields?',
|
||||||
cli_name='groupsearch',
|
cli_name='groupsearch',
|
||||||
|
label='Group search fields',
|
||||||
doc='A comma-separated list of fields to search when searching for groups',
|
doc='A comma-separated list of fields to search when searching for groups',
|
||||||
),
|
),
|
||||||
Bool('ipamigrationenabled?',
|
Bool('ipamigrationenabled?',
|
||||||
|
doc='Migration mode',
|
||||||
cli_name='enable_migration',
|
cli_name='enable_migration',
|
||||||
doc='Enabled migration mode',
|
doc='Enabled migration mode',
|
||||||
),
|
),
|
||||||
|
Str('ipacertificatesubjectbase?',
|
||||||
|
label='Certificate Subject base',
|
||||||
|
cli_name='subject',
|
||||||
|
doc='base for certificate subjects (OU=Test,O=Example)',
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_dn(self, *keys, **kwargs):
|
def get_dn(self, *keys, **kwargs):
|
||||||
|
@ -46,7 +46,6 @@ from ipapython import nsslib
|
|||||||
|
|
||||||
from ipaserver.install import service
|
from ipaserver.install import service
|
||||||
from ipaserver.install import installutils
|
from ipaserver.install import installutils
|
||||||
from ipaserver import ipaldap
|
|
||||||
from ipaserver.install import dsinstance
|
from ipaserver.install import dsinstance
|
||||||
from ipalib import util
|
from ipalib import util
|
||||||
|
|
||||||
@ -414,7 +413,8 @@ class CAInstance(service.Service):
|
|||||||
def configure_instance(self, pki_user, host_name, dm_password,
|
def configure_instance(self, pki_user, host_name, dm_password,
|
||||||
admin_password, ds_port=DEFAULT_DSPORT,
|
admin_password, ds_port=DEFAULT_DSPORT,
|
||||||
pkcs12_info=None, master_host=None, csr_file=None,
|
pkcs12_info=None, master_host=None, csr_file=None,
|
||||||
cert_file=None, cert_chain_file=None):
|
cert_file=None, cert_chain_file=None,
|
||||||
|
subject_base="O=IPA"):
|
||||||
"""Create a CA instance. This may involve creating the pki-ca instance
|
"""Create a CA instance. This may involve creating the pki-ca instance
|
||||||
dogtag instance.
|
dogtag instance.
|
||||||
|
|
||||||
@ -434,6 +434,7 @@ class CAInstance(service.Service):
|
|||||||
if self.pkcs12_info is not None:
|
if self.pkcs12_info is not None:
|
||||||
self.clone = True
|
self.clone = True
|
||||||
self.master_host = master_host
|
self.master_host = master_host
|
||||||
|
self.subject_base = subject_base
|
||||||
|
|
||||||
# Determine if we are installing as an externally-signed CA and
|
# Determine if we are installing as an externally-signed CA and
|
||||||
# what stage we're in.
|
# what stage we're in.
|
||||||
@ -540,7 +541,7 @@ class CAInstance(service.Service):
|
|||||||
"-agent_name", "ipa-ca-agent",
|
"-agent_name", "ipa-ca-agent",
|
||||||
"-agent_key_size", "2048",
|
"-agent_key_size", "2048",
|
||||||
"-agent_key_type", "rsa",
|
"-agent_key_type", "rsa",
|
||||||
"-agent_cert_subject", "\"CN=ipa-ca-agent,O=" + self.domain_name + "\"",
|
"-agent_cert_subject", "\"CN=ipa-ca-agent,%s\"" % self.subject_base,
|
||||||
"-ldap_host", self.host_name,
|
"-ldap_host", self.host_name,
|
||||||
"-ldap_port", str(self.ds_port),
|
"-ldap_port", str(self.ds_port),
|
||||||
"-bind_dn", "\"cn=Directory Manager\"",
|
"-bind_dn", "\"cn=Directory Manager\"",
|
||||||
@ -553,11 +554,11 @@ class CAInstance(service.Service):
|
|||||||
"-backup_pwd", self.admin_password,
|
"-backup_pwd", self.admin_password,
|
||||||
"-subsystem_name", self.service_name,
|
"-subsystem_name", self.service_name,
|
||||||
"-token_name", "internal",
|
"-token_name", "internal",
|
||||||
"-ca_subsystem_cert_subject_name", "\"CN=CA Subsystem Certificate,O=" + self.domain_name + "\"",
|
"-ca_subsystem_cert_subject_name", "\"CN=CA Subsystem,%s\"" % self.subject_base,
|
||||||
"-ca_ocsp_cert_subject_name", "\"CN=OCSP Signing Certificate,O=" + self.domain_name + "\"",
|
"-ca_ocsp_cert_subject_name", "\"CN=OCSP Subsystem,%s\"" % self.subject_base,
|
||||||
"-ca_server_cert_subject_name", "CN=" + self.host_name + ",O=" + self.domain_name,
|
"-ca_server_cert_subject_name", "\"CN=%s,%s\"" % (self.host_name, self.subject_base),
|
||||||
"-ca_audit_signing_cert_subject_name", "\"CN=CA Audit Signing Certificate,O=" + self.domain_name + "\"",
|
"-ca_audit_signing_cert_subject_name", "\"CN=CA Audit,%s\"" % self.subject_base,
|
||||||
"-ca_sign_cert_subject_name", "\"CN=Certificate Authority,O=" + self.domain_name + "\"" ]
|
"-ca_sign_cert_subject_name", "\"CN=Certificate Authority,%s\"" % self.subject_base ]
|
||||||
if self.external == 1:
|
if self.external == 1:
|
||||||
args.append("-external")
|
args.append("-external")
|
||||||
args.append("true")
|
args.append("true")
|
||||||
@ -770,7 +771,7 @@ class CAInstance(service.Service):
|
|||||||
('usertype', "agentType"),
|
('usertype', "agentType"),
|
||||||
('userstate', "1"),
|
('userstate', "1"),
|
||||||
('userCertificate', decoded),
|
('userCertificate', decoded),
|
||||||
('description', '2;%s;CN=Certificate Authority,O=%s;CN=RA Subsystem Certificate,OU=pki-ipa,O=%s' % (str(self.requestId), self.domain_name, self.domain_name)),]
|
('description', '2;%s;CN=Certificate Authority,%s;CN=RA Subsystem,%s' % (str(self.requestId), self.subject_base, self.subject_base)),]
|
||||||
|
|
||||||
ld.add_s(entry_dn, entry)
|
ld.add_s(entry_dn, entry)
|
||||||
|
|
||||||
@ -886,7 +887,7 @@ class CAInstance(service.Service):
|
|||||||
|
|
||||||
# Generate our CSR. The result gets put into stdout
|
# Generate our CSR. The result gets put into stdout
|
||||||
try:
|
try:
|
||||||
(stdout, stderr, returncode) = self.__run_certutil(["-R", "-k", "rsa", "-g", "2048", "-s", "CN=RA Subsystem Certificate,OU=pki-ipa,O=%s" % self.domain_name, "-z", noise_name, "-a"])
|
(stdout, stderr, returncode) = self.__run_certutil(["-R", "-k", "rsa", "-g", "2048", "-s", "CN=RA Subsystem,%s" % self.subject_base, "-z", noise_name, "-a"])
|
||||||
finally:
|
finally:
|
||||||
os.remove(noise_name)
|
os.remove(noise_name)
|
||||||
|
|
||||||
@ -1000,6 +1001,13 @@ class CAInstance(service.Service):
|
|||||||
|
|
||||||
ipautil.run(["/usr/sbin/semodule", "-i", "/usr/share/selinux/targeted/ipa_dogtag.pp"])
|
ipautil.run(["/usr/sbin/semodule", "-i", "/usr/share/selinux/targeted/ipa_dogtag.pp"])
|
||||||
|
|
||||||
|
def set_subject_in_config(self, suffix):
|
||||||
|
# dogtag ships with an IPA-specific profile that forces a subject
|
||||||
|
# format. We need to update that template with our base subject
|
||||||
|
if installutils.update_file("/var/lib/%s/profiles/ca/caIPAserviceCert.cfg" % PKI_INSTANCE_NAME, 'OU=pki-ipa, O=IPA', self.subject_base):
|
||||||
|
print "Updating subject_base in CA template failed"
|
||||||
|
self.__restart_instance()
|
||||||
|
|
||||||
def uninstall(self):
|
def uninstall(self):
|
||||||
try:
|
try:
|
||||||
ipautil.run(["/usr/bin/pkiremove", "-pki_instance_root=/var/lib",
|
ipautil.run(["/usr/bin/pkiremove", "-pki_instance_root=/var/lib",
|
||||||
|
@ -173,7 +173,7 @@ def next_replica(serial_file=CA_SERIALNO):
|
|||||||
return str(serial)
|
return str(serial)
|
||||||
|
|
||||||
class CertDB(object):
|
class CertDB(object):
|
||||||
def __init__(self, nssdir, fstore=None, host_name=None):
|
def __init__(self, nssdir, fstore=None, host_name=None, subject_base=None):
|
||||||
self.secdir = nssdir
|
self.secdir = nssdir
|
||||||
|
|
||||||
self.noise_fname = self.secdir + "/noise.txt"
|
self.noise_fname = self.secdir + "/noise.txt"
|
||||||
@ -189,13 +189,14 @@ class CertDB(object):
|
|||||||
self.certreq_fname = None
|
self.certreq_fname = None
|
||||||
self.certder_fname = None
|
self.certder_fname = None
|
||||||
self.host_name = host_name
|
self.host_name = host_name
|
||||||
|
self.cwd = os.getcwd()
|
||||||
|
|
||||||
self.self_signed_ca = ipa_self_signed()
|
self.self_signed_ca = ipa_self_signed()
|
||||||
|
|
||||||
if self.self_signed_ca:
|
if subject_base:
|
||||||
self.subject_format = "CN=%s,ou=test-ipa,O=IPA"
|
self.subject_format = "CN=%%s,%s" % subject_base
|
||||||
else:
|
else:
|
||||||
self.subject_format = "CN=%s,OU=pki-ipa,O=IPA"
|
self.subject_format = "CN=%s,O=IPA"
|
||||||
|
|
||||||
self.cacert_name = "CA certificate"
|
self.cacert_name = "CA certificate"
|
||||||
self.valid_months = "120"
|
self.valid_months = "120"
|
||||||
@ -218,6 +219,10 @@ class CertDB(object):
|
|||||||
def __del__(self):
|
def __del__(self):
|
||||||
if self.reqdir is not None:
|
if self.reqdir is not None:
|
||||||
shutil.rmtree(self.reqdir, ignore_errors=True)
|
shutil.rmtree(self.reqdir, ignore_errors=True)
|
||||||
|
try:
|
||||||
|
os.chdir(self.cwd)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
def setup_cert_request(self):
|
def setup_cert_request(self):
|
||||||
"""
|
"""
|
||||||
@ -234,6 +239,10 @@ class CertDB(object):
|
|||||||
self.certreq_fname = self.reqdir + "/tmpcertreq"
|
self.certreq_fname = self.reqdir + "/tmpcertreq"
|
||||||
self.certder_fname = self.reqdir + "/tmpcert.der"
|
self.certder_fname = self.reqdir + "/tmpcert.der"
|
||||||
|
|
||||||
|
# When certutil makes a request it creates a file in the cwd, make
|
||||||
|
# sure we are in a unique place when this happens
|
||||||
|
os.chdir(self.reqdir)
|
||||||
|
|
||||||
def set_serial_from_pkcs12(self):
|
def set_serial_from_pkcs12(self):
|
||||||
"""A CA cert was loaded from a PKCS#12 file. Set up our serial file"""
|
"""A CA cert was loaded from a PKCS#12 file. Set up our serial file"""
|
||||||
|
|
||||||
@ -584,6 +593,9 @@ class CertDB(object):
|
|||||||
doc.unlink()
|
doc.unlink()
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
|
# base64-decode the result
|
||||||
|
cert = base64.b64decode(cert)
|
||||||
|
|
||||||
# Write the certificate to a file. It will be imported in a later
|
# Write the certificate to a file. It will be imported in a later
|
||||||
# step.
|
# step.
|
||||||
f = open(cert_fname, "w")
|
f = open(cert_fname, "w")
|
||||||
@ -670,6 +682,9 @@ class CertDB(object):
|
|||||||
doc.unlink()
|
doc.unlink()
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
|
# base64-decode the cert
|
||||||
|
cert = base64.b64decode(cert)
|
||||||
|
|
||||||
f = open(cert_fname, "w")
|
f = open(cert_fname, "w")
|
||||||
f.write(cert)
|
f.write(cert)
|
||||||
f.close()
|
f.close()
|
||||||
@ -684,8 +699,6 @@ class CertDB(object):
|
|||||||
"-t", "u,u,u",
|
"-t", "u,u,u",
|
||||||
"-i", cert_fname,
|
"-i", cert_fname,
|
||||||
"-f", self.passwd_fname]
|
"-f", self.passwd_fname]
|
||||||
if not self.self_signed_ca:
|
|
||||||
args.append("-a")
|
|
||||||
self.run_certutil(args)
|
self.run_certutil(args)
|
||||||
|
|
||||||
def create_pin_file(self):
|
def create_pin_file(self):
|
||||||
|
@ -153,7 +153,7 @@ class DsInstance(service.Service):
|
|||||||
else:
|
else:
|
||||||
self.suffix = None
|
self.suffix = None
|
||||||
|
|
||||||
def create_instance(self, ds_user, realm_name, host_name, domain_name, dm_password, pkcs12_info=None, self_signed_ca=False, uidstart=1100, gidstart=1100):
|
def create_instance(self, ds_user, realm_name, host_name, domain_name, dm_password, pkcs12_info=None, self_signed_ca=False, uidstart=1100, gidstart=1100, subject_base=None):
|
||||||
self.ds_user = ds_user
|
self.ds_user = ds_user
|
||||||
self.realm_name = realm_name.upper()
|
self.realm_name = realm_name.upper()
|
||||||
self.serverid = realm_to_serverid(self.realm_name)
|
self.serverid = realm_to_serverid(self.realm_name)
|
||||||
@ -166,6 +166,7 @@ class DsInstance(service.Service):
|
|||||||
self.uidstart = uidstart
|
self.uidstart = uidstart
|
||||||
self.gidstart = gidstart
|
self.gidstart = gidstart
|
||||||
self.principal = "ldap/%s@%s" % (self.host_name, self.realm_name)
|
self.principal = "ldap/%s@%s" % (self.host_name, self.realm_name)
|
||||||
|
self.subject_base = subject_base
|
||||||
self.__setup_sub_dict()
|
self.__setup_sub_dict()
|
||||||
|
|
||||||
self.step("creating directory server user", self.__create_ds_user)
|
self.step("creating directory server user", self.__create_ds_user)
|
||||||
@ -328,7 +329,7 @@ class DsInstance(service.Service):
|
|||||||
|
|
||||||
def __enable_ssl(self):
|
def __enable_ssl(self):
|
||||||
dirname = config_dirname(self.serverid)
|
dirname = config_dirname(self.serverid)
|
||||||
dsdb = certs.CertDB(dirname)
|
dsdb = certs.CertDB(dirname, subject_base=self.subject_base)
|
||||||
if self.pkcs12_info:
|
if self.pkcs12_info:
|
||||||
dsdb.create_from_pkcs12(self.pkcs12_info[0], self.pkcs12_info[1])
|
dsdb.create_from_pkcs12(self.pkcs12_info[0], self.pkcs12_info[1])
|
||||||
server_certs = dsdb.find_server_certs()
|
server_certs = dsdb.find_server_certs()
|
||||||
@ -340,7 +341,7 @@ class DsInstance(service.Service):
|
|||||||
self.dercert = dsdb.get_cert_from_db(nickname)
|
self.dercert = dsdb.get_cert_from_db(nickname)
|
||||||
else:
|
else:
|
||||||
nickname = "Server-Cert"
|
nickname = "Server-Cert"
|
||||||
cadb = certs.CertDB(httpinstance.NSS_DIR, host_name=self.host_name)
|
cadb = certs.CertDB(httpinstance.NSS_DIR, host_name=self.host_name, subject_base=self.subject_base)
|
||||||
if self.self_signed_ca:
|
if self.self_signed_ca:
|
||||||
cadb.create_self_signed()
|
cadb.create_self_signed()
|
||||||
dsdb.create_from_cacert(cadb.cacert_fname, passwd=None)
|
dsdb.create_from_cacert(cadb.cacert_fname, passwd=None)
|
||||||
@ -466,7 +467,7 @@ class DsInstance(service.Service):
|
|||||||
self.stop()
|
self.stop()
|
||||||
|
|
||||||
dirname = config_dirname(realm_to_serverid(self.realm_name))
|
dirname = config_dirname(realm_to_serverid(self.realm_name))
|
||||||
certdb = certs.CertDB(dirname)
|
certdb = certs.CertDB(dirname, subject_base=self.subject_base)
|
||||||
if not cacert_name or len(cacert_name) == 0:
|
if not cacert_name or len(cacert_name) == 0:
|
||||||
cacert_name = "Imported CA"
|
cacert_name = "Imported CA"
|
||||||
# we can't pass in the nickname, so we set the instance variable
|
# we can't pass in the nickname, so we set the instance variable
|
||||||
|
@ -56,7 +56,7 @@ class HTTPInstance(service.Service):
|
|||||||
else:
|
else:
|
||||||
self.fstore = sysrestore.FileStore('/var/lib/ipa/sysrestore')
|
self.fstore = sysrestore.FileStore('/var/lib/ipa/sysrestore')
|
||||||
|
|
||||||
def create_instance(self, realm, fqdn, domain_name, dm_password=None, autoconfig=True, pkcs12_info=None, self_signed_ca=False):
|
def create_instance(self, realm, fqdn, domain_name, dm_password=None, autoconfig=True, pkcs12_info=None, self_signed_ca=False, subject_base=None):
|
||||||
self.fqdn = fqdn
|
self.fqdn = fqdn
|
||||||
self.realm = realm
|
self.realm = realm
|
||||||
self.domain = domain_name
|
self.domain = domain_name
|
||||||
@ -66,6 +66,7 @@ class HTTPInstance(service.Service):
|
|||||||
self.self_signed_ca = self_signed_ca
|
self.self_signed_ca = self_signed_ca
|
||||||
self.principal = "HTTP/%s@%s" % (self.fqdn, self.realm)
|
self.principal = "HTTP/%s@%s" % (self.fqdn, self.realm)
|
||||||
self.dercert = None
|
self.dercert = None
|
||||||
|
self.subject_base = subject_base
|
||||||
self.sub_dict = { "REALM" : realm, "FQDN": fqdn, "DOMAIN" : self.domain }
|
self.sub_dict = { "REALM" : realm, "FQDN": fqdn, "DOMAIN" : self.domain }
|
||||||
|
|
||||||
self.step("disabling mod_ssl in httpd", self.__disable_mod_ssl)
|
self.step("disabling mod_ssl in httpd", self.__disable_mod_ssl)
|
||||||
@ -164,10 +165,10 @@ class HTTPInstance(service.Service):
|
|||||||
|
|
||||||
def __setup_ssl(self):
|
def __setup_ssl(self):
|
||||||
if self.self_signed_ca:
|
if self.self_signed_ca:
|
||||||
ca_db = certs.CertDB(NSS_DIR)
|
ca_db = certs.CertDB(NSS_DIR, subject_base=self.subject_base)
|
||||||
else:
|
else:
|
||||||
ca_db = certs.CertDB(NSS_DIR, host_name=self.fqdn)
|
ca_db = certs.CertDB(NSS_DIR, host_name=self.fqdn, subject_base=self.subject_base)
|
||||||
db = certs.CertDB(NSS_DIR)
|
db = certs.CertDB(NSS_DIR, subject_base=self.subject_base)
|
||||||
if self.pkcs12_info:
|
if self.pkcs12_info:
|
||||||
db.create_from_pkcs12(self.pkcs12_info[0], self.pkcs12_info[1], passwd="")
|
db.create_from_pkcs12(self.pkcs12_info[0], self.pkcs12_info[1], passwd="")
|
||||||
server_certs = db.find_server_certs()
|
server_certs = db.find_server_certs()
|
||||||
@ -221,7 +222,7 @@ class HTTPInstance(service.Service):
|
|||||||
prefs_fd.close()
|
prefs_fd.close()
|
||||||
|
|
||||||
# The signing cert is generated in __setup_ssl
|
# The signing cert is generated in __setup_ssl
|
||||||
db = certs.CertDB(NSS_DIR)
|
db = certs.CertDB(NSS_DIR, subject_base=self.subject_base)
|
||||||
|
|
||||||
pwdfile = open(db.passwd_fname)
|
pwdfile = open(db.passwd_fname)
|
||||||
pwd = pwdfile.read()
|
pwd = pwdfile.read()
|
||||||
|
@ -160,9 +160,15 @@ class Service:
|
|||||||
Add a certificate to a service
|
Add a certificate to a service
|
||||||
|
|
||||||
This should be passed in DER format but we'll be nice and convert
|
This should be passed in DER format but we'll be nice and convert
|
||||||
a base64-encoded cert if needed.
|
a base64-encoded cert if needed (like when we add certs that come
|
||||||
|
from PKCS#12 files.)
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
|
s = self.dercert.find('-----BEGIN CERTIFICATE-----')
|
||||||
|
if s > -1:
|
||||||
|
e = self.dercert.find('-----END CERTIFICATE-----')
|
||||||
|
s = s + 27
|
||||||
|
self.dercert = self.dercert[s:e]
|
||||||
self.dercert = base64.b64decode(self.dercert)
|
self.dercert = base64.b64decode(self.dercert)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
@ -38,13 +38,18 @@ if api.env.ra_plugin != 'selfsign':
|
|||||||
from ipalib import Backend
|
from ipalib import Backend
|
||||||
from ipalib import errors
|
from ipalib import errors
|
||||||
from ipalib import x509
|
from ipalib import x509
|
||||||
|
from ipalib import pkcs10
|
||||||
import subprocess
|
import subprocess
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
from ipaserver.plugins import rabase
|
from ipaserver.plugins import rabase
|
||||||
from ipaserver.install import certs
|
from ipaserver.install import certs
|
||||||
import tempfile
|
import tempfile
|
||||||
from pyasn1 import error
|
from pyasn1 import error
|
||||||
from ipalib.request import ugettext as _
|
from ipalib.request import ugettext as _
|
||||||
|
from pyasn1.codec.der import encoder
|
||||||
|
import base64
|
||||||
|
from ipalib.plugins.cert import get_csr_hostname
|
||||||
|
|
||||||
class ra(rabase.rabase):
|
class ra(rabase.rabase):
|
||||||
"""
|
"""
|
||||||
@ -79,6 +84,28 @@ class ra(rabase.rabase):
|
|||||||
.. [2] Base64 encoded
|
.. [2] Base64 encoded
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
try:
|
||||||
|
config = api.Command['config_show']()['result']
|
||||||
|
subject_base = config.get('ipacertificatesubjectbase')[0]
|
||||||
|
hostname = get_csr_hostname(csr)
|
||||||
|
request = pkcs10.load_certificate_request(csr)
|
||||||
|
base = re.split(',\s*(?=\w+=)', subject_base)
|
||||||
|
base.reverse()
|
||||||
|
base.append("CN=%s" % hostname)
|
||||||
|
request_subject = request.get_subject().get_components()
|
||||||
|
new_request = []
|
||||||
|
for r in request_subject:
|
||||||
|
new_request.append("%s=%s" % (r[0], r[1]))
|
||||||
|
|
||||||
|
if str(base).lower() != str(new_request).lower():
|
||||||
|
subject_base='CN=%s, %s' % (hostname, subject_base)
|
||||||
|
new_request.reverse()
|
||||||
|
raise errors.CertificateOperationError(error=_('Request subject \'%s\' does not match the form \'%s\'' % (", ".join(new_request), subject_base)))
|
||||||
|
except errors.CertificateOperationError, e:
|
||||||
|
raise e
|
||||||
|
except Exception, e:
|
||||||
|
raise errors.CertificateOperationError(error=_('unable to decode csr: %s' % e))
|
||||||
|
|
||||||
# certutil wants the CSR to have have a header and footer. Add one
|
# certutil wants the CSR to have have a header and footer. Add one
|
||||||
# if it isn't there.
|
# if it isn't there.
|
||||||
s = csr.find('-----BEGIN NEW CERTIFICATE REQUEST-----')
|
s = csr.find('-----BEGIN NEW CERTIFICATE REQUEST-----')
|
||||||
@ -86,7 +113,7 @@ class ra(rabase.rabase):
|
|||||||
s = csr.find('-----BEGIN CERTIFICATE REQUEST-----')
|
s = csr.find('-----BEGIN CERTIFICATE REQUEST-----')
|
||||||
if s == -1:
|
if s == -1:
|
||||||
csr = '-----BEGIN NEW CERTIFICATE REQUEST-----\n' + csr + \
|
csr = '-----BEGIN NEW CERTIFICATE REQUEST-----\n' + csr + \
|
||||||
'-----END NEW CERTIFICATE REQUEST-----\n'
|
'\n-----END NEW CERTIFICATE REQUEST-----\n'
|
||||||
|
|
||||||
try:
|
try:
|
||||||
(csr_fd, csr_name) = tempfile.mkstemp()
|
(csr_fd, csr_name) = tempfile.mkstemp()
|
||||||
|
Loading…
Reference in New Issue
Block a user