Fix up Kerberos PKI certificate generation

pull/1/head
Timothy Pearson 9 years ago
parent d6f004658d
commit 6df22c8ca2

@ -24,6 +24,7 @@
#include <netdb.h>
#include <pwd.h>
#include <tqdir.h>
#include <tqfile.h>
#include <tqcheckbox.h>
#include <tdeapplication.h>
@ -124,6 +125,13 @@ TQString LDAPManager::ldapdnForRealm(TQString realm) {
return basedc;
}
TQString LDAPManager::openssldcForRealm(TQString realm) {
TQStringList domainChunks = TQStringList::split(".", realm.lower());
TQString basedc = "DC=" + domainChunks.join("/DC=");
basedc = "/" + basedc;
return basedc;
}
TQString LDAPManager::cnFromDn(TQString dn) {
int eqpos = dn.find("=")+1;
int cmpos = dn.find(",", eqpos);
@ -3803,12 +3811,17 @@ TQDateTime LDAPManager::getCertificateExpiration(TQString certfile) {
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,9 +3839,15 @@ int LDAPManager::generatePublicKerberosCACertificate(LDAPCertConfig certinfo) {
}
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;
TQString kdc_reqfile = KERBEROS_PKI_KDCREQ_FILE;
@ -3836,13 +3855,18 @@ int LDAPManager::generatePublicKerberosCertificate(LDAPCertConfig certinfo, LDAP
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,9 +3890,15 @@ int LDAPManager::generatePublicKerberosCertificate(LDAPCertConfig certinfo, LDAP
}
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;
TQString ldap_reqfile = LDAP_CERTREQ_FILE;
@ -3876,13 +3906,18 @@ int LDAPManager::generatePublicLDAPCertificate(LDAPCertConfig certinfo, LDAPReal
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 @@ int LDAPManager::writePAMFiles(LDAPPamConfig pamConfig, TQString *errstr) {
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";
stream << "[pkinitc_principal_seq]" << "\n";
stream << "name_type = EXP:0,INTEGER:1" << "\n";
stream << "name_string = EXP:1,SEQUENCE:pkinitc_principals" << "\n";
stream << "\n";
stream << "[pkinitc_princ_name]" << "\n";
stream << TQString("realm = EXP:0,GeneralString:%1").arg(realmcfg.name.upper()) << "\n";
stream << "principal_name = EXP:1,SEQUENCE:pkinitc_principal_seq" << "\n";
stream << "\n";
stream << "[pkinit_client_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 << "authorityKeyIdentifier=keyid,issuer" << "\n";
stream << "issuerAltName=issuer:copy" << "\n";
stream << "subjectAltName=otherName:1.3.6.1.5.2.2;SEQUENCE:pkinitc_princ_name" << "\n";
stream << "\n";
stream << "[https_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 << "extendedKeyUsage = https-server XXX" << "\n";
stream << "subjectKeyIdentifier = hash" << "\n";
stream << "\n";
stream << "[pkinit_kdc_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 << "extendedKeyUsage = 1.3.6.1.5.2.3.5" << "\n";
stream << "subjectKeyIdentifier = hash" << "\n";
stream << "authorityKeyIdentifier=keyid,issuer" << "\n";
stream << "issuerAltName=issuer:copy" << "\n";
stream << "subjectAltName=otherName:1.3.6.1.5.2.2;SEQUENCE:pkinitkdc_princ_name" << "\n";
stream << "\n";
stream << "[pkinitkdc_princ_name]" << "\n";
stream << TQString("realm = EXP:0,GeneralString:%1").arg(realmcfg.name.upper()) << "\n";
stream << "principal_name = EXP:1,SEQUENCE:pkinitkdc_principal_seq" << "\n";
stream << "\n";
stream << "[pkinitkdc_principal_seq]" << "\n";
stream << "name_type = EXP:0,INTEGER:1" << "\n";
stream << "name_string = EXP:1,SEQUENCE:pkinitkdc_principals" << "\n";
stream << "\n";
stream << "[pkinitkdc_principals]" << "\n";
stream << "princ1 = GeneralString:krbtgt" << "\n";
stream << TQString("princ2 = GeneralString:%1").arg(realmcfg.name.upper()) << "\n";
stream << "\n";
stream << "[proxy10_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:10,policy:text:foo" << "\n";
stream << "\n";
stream << "[usr_cert_ds]" << "\n";
stream << "basicConstraints=CA:FALSE" << "\n";
stream << "keyUsage = critical, nonRepudiation, digitalSignature" << "\n";
stream << TQString("crlDistributionPoints=URI:http://%1/crl.pem").arg(realmcfg.certificate_revocation_list_url);
stream << "subjectKeyIdentifier = hash" << "\n";
stream << "\n";
stream << "[ocsp_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 << "ocsp-nocheck and kp-OCSPSigning" << "\n";
stream << "extendedKeyUsage = 1.3.6.1.5.5.7.48.1.5, 1.3.6.1.5.5.7.3.9" << "\n";
stream << "subjectKeyIdentifier = hash" << "\n";
stream << "\n";
stream << "[req_distinguished_name]" << "\n";
stream << "countryName = Country Name (2 letter code)" << "\n";
stream << "countryName_min = 2" << "\n";
stream << "countryName_max = 2" << "\n";
stream << "organizationalName = Organizational Unit Name (eg, section)" << "\n";
stream << "commonName = Common Name (eg, YOUR name)" << "\n";
stream << "commonName_max = 64" << "\n";
stream << "\n";
// stream << "[req_attributes]" << "\n";
// stream << "challengePassword = A challenge password" << "\n";
// stream << "challengePassword_min = 4" << "\n";
// stream << "challengePassword_max = 20" << "\n";
// stream << "\n";
stream << "[policy_match]" << "\n";
stream << "countryName = match" << "\n";
stream << "commonName = supplied" << "\n";
stream << "\n";
file.close();
}
else {
if (errstr) {
*errstr = i18n("Could not open file '%1' for writing").arg(file.name());
}
return -1;
}
return 0;
}
int LDAPManager::bondRealm(TQString adminUserName, const char * adminPassword, TQString adminRealm, TQString *errstr) {
TQCString command = "kadmin";
QCStringList args;

@ -55,7 +55,7 @@
#define LDAP_CERTKEY_FILE KERBEROS_PKI_PRIVATEDIR "@@@ADMINSERVER@@@.ldap.key"
#define LDAP_CERTREQ_FILE KERBEROS_PKI_PRIVATEDIR "@@@ADMINSERVER@@@.ldap.req"
#define OPENSSL_EXTENSIONS_FILE TDE_CERTIFICATE_DIR "pki_extensions"
#define OPENSSL_EXTENSIONS_FILE TDE_CERTIFICATE_DIR "openssl.cfg"
#define DEFAULT_IGNORED_USERS_LIST "avahi,avahi-autoipd,backup,bin,colord,daemon,games,gnats,haldaemon,hplip,irc,klog,landscape,libuuid,list,lp,mail,man,messagebus,news,ntp,polkituser,postfix,proxy,pulse,root,rtkit,saned,sshd,statd,sync,sys,syslog,timidity,usbmux,uucp,www-data"
@ -180,6 +180,7 @@ class LDAPRealmConfig
bool pkinit_require_krbtgt_otherName;
bool win2k_pkinit;
bool win2k_pkinit_require_binding;
TQString certificate_revocation_list_url;
};
// PRIVATE
@ -512,11 +513,12 @@ class LDAPManager : public TQObject {
static LDAPRealmConfigList readTDERealmList(KSimpleConfig* config, bool disableAllBonds=false);
static TQDateTime getCertificateExpiration(TQString certfile);
static int generatePublicKerberosCACertificate(LDAPCertConfig certinfo);
static int generatePublicKerberosCACertificate(LDAPCertConfig certinfo, LDAPRealmConfig realmcfg);
static int generatePublicKerberosCertificate(LDAPCertConfig certinfo, LDAPRealmConfig realmcfg);
static int generatePublicLDAPCertificate(LDAPCertConfig certinfo, LDAPRealmConfig realmcfg, uid_t ldap_uid, gid_t ldap_gid);
static TQString ldapdnForRealm(TQString realm);
static TQString openssldcForRealm(TQString realm);
static TQString cnFromDn(TQString dn);
static KerberosTicketInfoList getKerberosTicketList(TQString cache=TQString::null, TQString *cacheFileName=0);
@ -533,6 +535,7 @@ class LDAPManager : public TQObject {
static int writeClientKrb5ConfFile(LDAPClientRealmConfig clientRealmConfig, LDAPRealmConfigList realmList, TQString *errstr=0);
static int writeLDAPConfFile(LDAPRealmConfig realmcfg, LDAPMachineRole machineRole, TQString *errstr=0);
static int writeNSSwitchFile(TQString *errstr=0);
static int writeOpenSSLConfigurationFile(LDAPRealmConfig realmcfg, TQString *errstr=0);
static int writeClientCronFiles(TQString *errstr=0);
static int writePAMFiles(LDAPPamConfig pamConfig, TQString *errstr=0);

Loading…
Cancel
Save