6df22c8c | 2015-08-31 16:29:22 | Timothy Pearson |
Fix up Kerberos PKI certificate generation |
||
M src/libtdeldap.cpp M src/libtdeldap.h |
||
diff --git a/src/libtdeldap.cpp b/src/libtdeldap.cpp index f009297..e113114 100644 --- a/src/libtdeldap.cpp +++ b/src/libtdeldap.cpp @@ -24,6 +24,7 @@ #include <netdb.h> #include <pwd.h> +#include <tqdir.h> #include <tqfile.h> #include <tqcheckbox.h> #include <tdeapplication.h> @@ -121,6 +122,13 @@ TQString LDAPManager::ldapdnForRealm(TQString realm) { TQStringList domainChunks = TQStringList::split(".", realm.lower()); TQString basedc = "dc=" + domainChunks.join(",dc="); + return basedc; +} + +TQString LDAPManager::openssldcForRealm(TQString realm) { + TQStringList domainChunks = TQStringList::split(".", realm.lower()); + TQString basedc = "DC=" + domainChunks.join("/DC="); + basedc = "/" + basedc; return basedc; } @@ -3803,12 +3811,17 @@ return ret; } -int LDAPManager::generatePublicKerberosCACertificate(LDAPCertConfig certinfo) { +int LDAPManager::generatePublicKerberosCACertificate(LDAPCertConfig certinfo, LDAPRealmConfig realmcfg) { + TQString errstr; TQString command; TQString subject; + if (writeOpenSSLConfigurationFile(realmcfg, &errstr) != 0) { + printf("ERROR: Unable to generate OpenSSL configuration file! Details: '%s'\n", errstr.ascii()); + return -1; + } subject = TQString("\"/C=%1/ST=%2/L=%3/O=%4/OU=%5/CN=%6/emailAddress=%7\"").arg(certinfo.countryName).arg(certinfo.stateOrProvinceName).arg(certinfo.localityName).arg(certinfo.organizationName).arg(certinfo.orgUnitName).arg(certinfo.commonName).arg(certinfo.emailAddress); - command = TQString("openssl req -days %1 -key %2 -new -x509 -out %3 -subj %4").arg(certinfo.caExpiryDays).arg(KERBEROS_PKI_PEMKEY_FILE).arg(KERBEROS_PKI_PEM_FILE).arg(subject); + command = TQString("openssl req -days %1 -key %2 -new -x509 -out %3 -config %4 -subj %5").arg(certinfo.caExpiryDays).arg(KERBEROS_PKI_PEMKEY_FILE).arg(KERBEROS_PKI_PEM_FILE).arg(OPENSSL_EXTENSIONS_FILE).arg(subject); if (system(command) < 0) { printf("ERROR: Execution of \"%s\" failed!\n", command.ascii()); return -1; @@ -3826,8 +3839,14 @@ } int LDAPManager::generatePublicKerberosCertificate(LDAPCertConfig certinfo, LDAPRealmConfig realmcfg) { + TQString errstr; TQString command; TQString subject; + + if (writeOpenSSLConfigurationFile(realmcfg, &errstr) != 0) { + printf("ERROR: Unable to generate OpenSSL configuration file! Details: '%s'\n", errstr.ascii()); + return -1; + } TQString kdc_certfile = KERBEROS_PKI_KDC_FILE; TQString kdc_keyfile = KERBEROS_PKI_KDCKEY_FILE; @@ -3836,13 +3855,18 @@ kdc_keyfile.replace("@@@KDCSERVER@@@", realmcfg.name.lower()); kdc_reqfile.replace("@@@KDCSERVER@@@", realmcfg.name.lower()); - subject = TQString("\"/C=%1/ST=%2/L=%3/O=%4/OU=%5/CN=%6/emailAddress=%7\"").arg(certinfo.countryName).arg(certinfo.stateOrProvinceName).arg(certinfo.localityName).arg(certinfo.organizationName).arg(certinfo.orgUnitName).arg(certinfo.commonName).arg(certinfo.emailAddress); - command = TQString("openssl req -days %1 -new -out %2 -key %3 -subj %4").arg(certinfo.kerberosExpiryDays).arg(kdc_reqfile).arg(kdc_keyfile).arg(subject); + TQString common_name = TQString::null; + if (realmcfg.kdc != "") { + common_name = TQString("/CN=%1").arg(common_name); + } + + subject = TQString("\"/C=%1/ST=%2/L=%3/O=%4/OU=%5/%6%7\"").arg(certinfo.countryName).arg(certinfo.stateOrProvinceName).arg(certinfo.localityName).arg(certinfo.organizationName).arg(certinfo.orgUnitName).arg(common_name).arg(openssldcForRealm(realmcfg.name)); + command = TQString("openssl req -days %1 -new -out %2 -key %3 -config %4 -subj %5").arg(certinfo.kerberosExpiryDays).arg(kdc_reqfile).arg(kdc_keyfile).arg(OPENSSL_EXTENSIONS_FILE).arg(subject); if (system(command) < 0) { printf("ERROR: Execution of \"%s\" failed!\n", command.ascii()); return -1; } - command = TQString("openssl x509 -req -in %1 -CAkey %2 -CA %3 -out %4 -extfile %5 -extensions kdc_cert -CAcreateserial").arg(kdc_reqfile).arg(KERBEROS_PKI_PEMKEY_FILE).arg(KERBEROS_PKI_PEM_FILE).arg(kdc_certfile).arg(OPENSSL_EXTENSIONS_FILE); + command = TQString("openssl x509 -req -days %1 -in %2 -CAkey %3 -CA %4 -out %5 -extfile %6 -extensions pkinit_kdc_cert -CAcreateserial").arg(certinfo.kerberosExpiryDays).arg(kdc_reqfile).arg(KERBEROS_PKI_PEMKEY_FILE).arg(KERBEROS_PKI_PEM_FILE).arg(kdc_certfile).arg(OPENSSL_EXTENSIONS_FILE); if (system(command) < 0) { printf("ERROR: Execution of \"%s\" failed!\n", command.ascii()); return -1; @@ -3866,8 +3890,14 @@ } int LDAPManager::generatePublicLDAPCertificate(LDAPCertConfig certinfo, LDAPRealmConfig realmcfg, uid_t ldap_uid, gid_t ldap_gid) { + TQString errstr; TQString command; TQString subject; + + if (writeOpenSSLConfigurationFile(realmcfg, &errstr) != 0) { + printf("ERROR: Unable to generate OpenSSL configuration file! Details: '%s'\n", errstr.ascii()); + return -1; + } TQString ldap_certfile = LDAP_CERT_FILE; TQString ldap_keyfile = LDAP_CERTKEY_FILE; @@ -3876,13 +3906,18 @@ ldap_keyfile.replace("@@@ADMINSERVER@@@", realmcfg.name.lower()); ldap_reqfile.replace("@@@ADMINSERVER@@@", realmcfg.name.lower()); - subject = TQString("\"/C=%1/ST=%2/L=%3/O=%4/OU=%5/CN=%6/emailAddress=%7\"").arg(certinfo.countryName).arg(certinfo.stateOrProvinceName).arg(certinfo.localityName).arg(certinfo.organizationName).arg(certinfo.orgUnitName).arg(certinfo.commonName).arg(certinfo.emailAddress); - command = TQString("openssl req -days %1 -new -out %2 -key %3 -subj %4").arg(certinfo.ldapExpiryDays).arg(ldap_reqfile).arg(ldap_keyfile).arg(subject); + TQString common_name = TQString::null; + if (realmcfg.kdc != "") { + common_name = TQString("/CN=%1").arg(common_name); + } + + subject = TQString("\"/C=%1/ST=%2/L=%3/O=%4/OU=%5/%6%7\"").arg(certinfo.countryName).arg(certinfo.stateOrProvinceName).arg(certinfo.localityName).arg(certinfo.organizationName).arg(certinfo.orgUnitName).arg(common_name).arg(openssldcForRealm(realmcfg.name)); + command = TQString("openssl req -days %1 -new -out %2 -key %3 -config %4 -subj %5").arg(certinfo.ldapExpiryDays).arg(ldap_reqfile).arg(ldap_keyfile).arg(OPENSSL_EXTENSIONS_FILE).arg(subject); if (system(command) < 0) { printf("ERROR: Execution of \"%s\" failed!\n", command.ascii()); return -1; } - command = TQString("openssl x509 -req -in %1 -CAkey %2 -CA %3 -out %4 -CAcreateserial").arg(ldap_reqfile).arg(KERBEROS_PKI_PEMKEY_FILE).arg(KERBEROS_PKI_PEM_FILE).arg(ldap_certfile); + command = TQString("openssl x509 -req -days %1 -in %2 -CAkey %3 -CA %4 -out %5 -CAcreateserial").arg(certinfo.ldapExpiryDays).arg(ldap_reqfile).arg(KERBEROS_PKI_PEMKEY_FILE).arg(KERBEROS_PKI_PEM_FILE).arg(ldap_certfile); if (system(command) < 0) { printf("ERROR: Execution of \"%s\" failed!\n", command.ascii()); return -1; @@ -4163,6 +4198,228 @@ return 0; } +int LDAPManager::writeOpenSSLConfigurationFile(LDAPRealmConfig realmcfg, TQString *errstr) { + TQDir tde_cert_dir(TDE_CERTIFICATE_DIR); + if (!tde_cert_dir.exists()) { + TQString command = TQString("mkdir -p %1").arg(TDE_CERTIFICATE_DIR); + if (system(command) < 0) { + if (errstr) { + *errstr = i18n("Could not create directory '%1'").arg(TDE_CERTIFICATE_DIR); + } + return 1; + } + } + TQFile file(TQString::fromLatin1(OPENSSL_EXTENSIONS_FILE)); + if (file.open(IO_WriteOnly)) { + TQTextStream stream( &file ); + + stream << "# This file was automatically generated by TDE\n"; + stream << "# All changes will be lost!\n"; + stream << "\n"; + stream << "[ca]" << "\n"; + stream << "default_ca = user" << "\n"; + stream << "\n"; + stream << "[usr]" << "\n"; + // stream << "database = index.txt" << "\n"; + // stream << "serial = serial" << "\n"; + stream << "x509_extensions = usr_cert" << "\n"; + stream << "default_md = sha1" << "\n"; + stream << "policy = policy_match" << "\n"; + stream << "email_in_dn = no" << "\n"; + stream << "certs = ." << "\n"; + stream << "\n"; + stream << "[ocsp]" << "\n"; + // stream << "database = index.txt" << "\n"; + // stream << "serial = serial" << "\n"; + stream << "x509_extensions = ocsp_cert" << "\n"; + stream << "default_md = sha1" << "\n"; + stream << "policy = policy_match" << "\n"; + stream << "email_in_dn = no" << "\n"; + stream << "certs = ." << "\n"; + stream << "\n"; + stream << "[usr_ke]" << "\n"; + // stream << "database = index.txt" << "\n"; + // stream << "serial = serial" << "\n"; + stream << "x509_extensions = usr_cert_ke" << "\n"; + stream << "default_md = sha1" << "\n"; + stream << "policy = policy_match" << "\n"; + stream << "email_in_dn = no" << "\n"; + stream << "certs = ." << "\n"; + stream << "\n"; + stream << "[usr_ds]" << "\n"; + // stream << "database = index.txt" << "\n"; + // stream << "serial = serial" << "\n"; + stream << "x509_extensions = usr_cert_ds" << "\n"; + stream << "default_md = sha1" << "\n"; + stream << "policy = policy_match" << "\n"; + stream << "email_in_dn = no" << "\n"; + stream << "certs = ." << "\n"; + stream << "\n"; + stream << "[pkinit_client]" << "\n"; + // stream << "database = index.txt" << "\n"; + // stream << "serial = serial" << "\n"; + stream << "x509_extensions = pkinit_client_cert" << "\n"; + stream << "default_md = sha1" << "\n"; + stream << "policy = policy_match" << "\n"; + stream << "email_in_dn = no" << "\n"; + stream << "certs = ." << "\n"; + stream << "\n"; + stream << "[pkinit_kdc]" << "\n"; + // stream << "database = index.txt" << "\n"; + // stream << "serial = serial" << "\n"; + stream << "x509_extensions = pkinit_kdc_cert" << "\n"; + stream << "default_md = sha1" << "\n"; + stream << "policy = policy_match" << "\n"; + stream << "email_in_dn = no" << "\n"; + stream << "certs = ." << "\n"; + stream << "\n"; + stream << "[https]" << "\n"; + // stream << "database = index.txt" << "\n"; + // stream << "serial = serial" << "\n"; + stream << "x509_extensions = https_cert" << "\n"; + stream << "default_md = sha1" << "\n"; + stream << "policy = policy_match" << "\n"; + stream << "email_in_dn = no" << "\n"; + stream << "certs = ." << "\n"; + stream << "\n"; + stream << "[subca]" << "\n"; + // stream << "database = index.txt" << "\n"; + // stream << "serial = serial" << "\n"; + stream << "x509_extensions = v3_ca" << "\n"; + stream << "default_md = sha1" << "\n"; + stream << "policy = policy_match" << "\n"; + stream << "email_in_dn = no" << "\n"; + stream << "certs = ." << "\n"; + stream << "\n"; + stream << "[req]" << "\n"; + stream << "distinguished_name = req_distinguished_name" << "\n"; + stream << "x509_extensions = v3_ca" << "\n"; + stream << "string_mask = utf8only" << "\n"; + stream << "\n"; + stream << "[v3_ca]" << "\n"; + stream << "subjectKeyIdentifier=hash" << "\n"; + stream << "authorityKeyIdentifier=keyid:always,issuer:always" << "\n"; + stream << "basicConstraints = CA:true" << "\n"; + stream << "keyUsage = critical, cRLSign, keyCertSign, keyEncipherment, nonRepudiation, digitalSignature" << "\n"; + stream << "\n"; + stream << "[usr_cert]" << "\n"; + stream << "basicConstraints=CA:FALSE" << "\n"; + stream << "keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment" << "\n"; + stream << TQString("crlDistributionPoints=URI:http://%1/crl.pem").arg(realmcfg.certificate_revocation_list_url); + stream << "subjectKeyIdentifier = hash" << "\n"; + stream << "\n"; + stream << "[usr_cert_ke]" << "\n"; + stream << "basicConstraints=CA:FALSE" << "\n"; + stream << "keyUsage = critical, nonRepudiation, keyEncipherment" << "\n"; + stream << TQString("crlDistributionPoints=URI:http://%1/crl.pem").arg(realmcfg.certificate_revocation_list_url); + stream << "subjectKeyIdentifier = hash" << "\n"; + stream << "\n"; + stream << "[proxy_cert]" << "\n"; + stream << "basicConstraints=CA:FALSE" << "\n"; + stream << "keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment" << "\n"; + stream << TQString("crlDistributionPoints=URI:http://%1/crl.pem").arg(realmcfg.certificate_revocation_list_url); + stream << "subjectKeyIdentifier = hash" << "\n"; + // stream << "proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:0,policy:text:foo" << "\n"; + stream << "\n"; + stream << "[pkinitc_principals]" << "\n"; + // stream << "princ1 = GeneralString:bar" << "\n"; + stream << "\n"; ** Diff limit reached (max: 250 lines) ** |