diff options
author | Timothy Pearson <[email protected]> | 2015-09-03 05:03:15 +0000 |
---|---|---|
committer | Timothy Pearson <[email protected]> | 2015-09-03 05:03:15 +0000 |
commit | efb81441defd8685d0db0cc143137e8a4e7a35b1 (patch) | |
tree | 63654daf6aee66b347b1235a7ec8c2144f93fca9 /src | |
parent | a97c0c3d5446361d30fd5ede922d81560c763e0c (diff) | |
download | libtdeldap-efb81441defd8685d0db0cc143137e8a4e7a35b1.tar.gz libtdeldap-efb81441defd8685d0db0cc143137e8a4e7a35b1.zip |
Add CRL generation
Diffstat (limited to 'src')
-rw-r--r-- | src/libtdeldap.cpp | 218 | ||||
-rw-r--r-- | src/libtdeldap.h | 10 |
2 files changed, 197 insertions, 31 deletions
diff --git a/src/libtdeldap.cpp b/src/libtdeldap.cpp index 6e965fb..8f6ad0c 100644 --- a/src/libtdeldap.cpp +++ b/src/libtdeldap.cpp @@ -2945,7 +2945,7 @@ int LDAPManager::writeLDAPConfFile(LDAPRealmConfig realmcfg, LDAPMachineRole mac // Create symbolic link to secondary LDAP configuration file if (fileExists(LDAP_SECONDARY_FILE)) { if (unlink(LDAP_SECONDARY_FILE) < 0) { - if (errstr) *errstr = TQString("Unable to unlink \"%s\"").arg(LDAP_SECONDARY_FILE); + if (errstr) *errstr = TQString("Unable to unlink \"%1\"").arg(LDAP_SECONDARY_FILE); return -1; } } @@ -2958,7 +2958,7 @@ int LDAPManager::writeLDAPConfFile(LDAPRealmConfig realmcfg, LDAPMachineRole mac // Create symbolic link to tertiary LDAP configuration file if (fileExists(LDAP_TERTIARY_FILE)) { if (unlink(LDAP_TERTIARY_FILE) < 0) { - if (errstr) *errstr = TQString("Unable to unlink \"%s\"").arg(LDAP_TERTIARY_FILE); + if (errstr) *errstr = TQString("Unable to unlink \"%1\"").arg(LDAP_TERTIARY_FILE); return -1; } } @@ -3643,15 +3643,15 @@ int LDAPManager::setLDAPMasterReplicationSettings(LDAPMasterReplicationInfo repl return -1; } -int LDAPManager::getTDECertificate(TQString certificateName, TQFile *fileHandle, TQString *errstr) { +int LDAPManager::getTDECertificate(TQString certificateName, TQByteArray *certificate, TQString *errstr) { int retcode; int returncode; LDAPTDEBuiltinsInfo builtininfo; TQString dn = TQString("cn=certificate store,o=tde,cn=tde realm data,ou=master services,ou=core,ou=realm,%1").arg(m_basedc); - if (!fileHandle) { - if (errstr) *errstr = i18n("Invalid file handle passed by host application"); + if (!certificate) { + if (errstr) *errstr = i18n("Invalid certificate handle passed by host application"); return -1; } @@ -3685,9 +3685,7 @@ int LDAPManager::getTDECertificate(TQString certificateName, TQFile *fileHandle, TQString ldap_field = attr; i=0; if (ldap_field == certificateName) { - TQByteArray ba; - ba.duplicate(vals[i]->bv_val, vals[i]->bv_len); - fileHandle->writeBlock(ba); + certificate->duplicate(vals[i]->bv_val, vals[i]->bv_len); returncode = 0; } ldap_value_free_len(vals); @@ -3713,6 +3711,23 @@ int LDAPManager::getTDECertificate(TQString certificateName, TQFile *fileHandle, return -1; } +int LDAPManager::getTDECertificate(TQString certificateName, TQFile *fileHandle, TQString *errstr) { + int returncode; + + if (!fileHandle) { + if (errstr) *errstr = i18n("Invalid file handle passed by host application"); + return -1; + } + + TQByteArray ba; + returncode = getTDECertificate(certificateName, &ba, errstr); + if (returncode == 0) { + fileHandle->writeBlock(ba); + } + + return returncode; +} + int LDAPManager::getTDECertificate(TQString certificateName, TQString fileName, TQString *errstr) { TQFile file(fileName); if (file.open(IO_WriteOnly)) { @@ -3916,6 +3931,25 @@ int LDAPManager::writeTDERealmList(LDAPRealmConfigList realms, KSimpleConfig* co return 0; } +TQDateTime LDAPManager::getCertificateExpiration(TQByteArray certfileContents) { + TQDateTime ret; + + TQCString ssldata(certfileContents); + ssldata[certfileContents.size()] = 0; + ssldata.replace("-----BEGIN CERTIFICATE-----", ""); + ssldata.replace("-----END CERTIFICATE-----", ""); + ssldata.replace("-----BEGIN X509 CRL-----", ""); + ssldata.replace("-----END X509 CRL-----", ""); + ssldata.replace("\n", ""); + KSSLCertificate* cert = KSSLCertificate::fromString(ssldata); + if (cert) { + ret = cert->getQDTNotAfter(); + delete cert; + } + + return ret; +} + TQDateTime LDAPManager::getCertificateExpiration(TQString certfile) { TQDateTime ret; @@ -3924,16 +3958,7 @@ TQDateTime LDAPManager::getCertificateExpiration(TQString certfile) { TQByteArray ba = file.readAll(); file.close(); - TQCString ssldata(ba); - ssldata[ba.size()] = 0; - ssldata.replace("-----BEGIN CERTIFICATE-----", ""); - ssldata.replace("-----END CERTIFICATE-----", ""); - ssldata.replace("\n", ""); - KSSLCertificate* cert = KSSLCertificate::fromString(ssldata); - if (cert) { - ret = cert->getQDTNotAfter(); - delete cert; - } + ret = getCertificateExpiration(ba); } return ret; @@ -4088,7 +4113,7 @@ int LDAPManager::generateClientCertificatePrivateKey(LDAPUserInfo user, LDAPReal TQString client_cfgfile = privateKeyFile + ".cfg"; unsigned int client_key_bit_length = 2048; - if (writeOpenSSLConfigurationFile(realmcfg, user, client_cfgfile, errstr) != 0) { + if (writeOpenSSLConfigurationFile(realmcfg, user, client_cfgfile, TQString::null, TQString::null, TQString::null, errstr) != 0) { return -1; } @@ -4101,18 +4126,18 @@ int LDAPManager::generateClientCertificatePrivateKey(LDAPUserInfo user, LDAPReal // Secure keyfile if (chmod(client_keyfile.ascii(), S_IRUSR|S_IWUSR) < 0) { - if (errstr) *errstr = TQString("Unable to change permissions of \"%s\"").arg(client_keyfile); + if (errstr) *errstr = TQString("Unable to change permissions of \"%1\"").arg(client_keyfile); return -1; } if (chown(client_keyfile.ascii(), 0, 0) < 0) { - if (errstr) *errstr = TQString("Unable to change owner of \"%s\"").arg(client_keyfile); + if (errstr) *errstr = TQString("Unable to change owner of \"%1\"").arg(client_keyfile); return -1; } // Clean up if (fileExists(client_cfgfile.ascii())) { if (unlink(client_cfgfile.ascii()) < 0) { - if (errstr) *errstr = TQString("Unable to unlink \"%s\"").arg(client_keyfile); + if (errstr) *errstr = TQString("Unable to unlink \"%1\"").arg(client_cfgfile); return -1; } } @@ -4136,7 +4161,7 @@ int LDAPManager::generateClientCertificatePublicCertificate(int expirydays, LDAP signing_public_certfile = KERBEROS_PKI_PEM_FILE; } - if (writeOpenSSLConfigurationFile(realmcfg, user, client_cfgfile, errstr) != 0) { + if (writeOpenSSLConfigurationFile(realmcfg, user, client_cfgfile, TQString::null, TQString::null, TQString::null, errstr) != 0) { return -1; } @@ -4159,24 +4184,24 @@ int LDAPManager::generateClientCertificatePublicCertificate(int expirydays, LDAP // Secure certificate if (chmod(client_certfile.ascii(), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) { - if (errstr) *errstr = TQString("Unable to change permissions of \"%s\"").arg(client_certfile); + if (errstr) *errstr = TQString("Unable to change permissions of \"%1\"").arg(client_certfile); return -1; } if (chown(client_certfile.ascii(), 0, 0) < 0) { - if (errstr) *errstr = TQString("Unable to change owner of \"%s\"").arg(client_certfile); + if (errstr) *errstr = TQString("Unable to change owner of \"%1\"").arg(client_certfile); return -1; } // Clean up if (fileExists(client_cfgfile.ascii())) { if (unlink(client_cfgfile.ascii()) < 0) { - if (errstr) *errstr = TQString("Unable to unlink \"%s\"").arg(client_certfile); + if (errstr) *errstr = TQString("Unable to unlink \"%1\"").arg(client_cfgfile); return -1; } } if (fileExists(client_reqfile.ascii())) { if (unlink(client_reqfile.ascii()) < 0) { - if (errstr) *errstr = TQString("Unable to unlink \"%s\"").arg(client_reqfile); + if (errstr) *errstr = TQString("Unable to unlink \"%1\"").arg(client_reqfile); return -1; } } @@ -4184,6 +4209,116 @@ int LDAPManager::generateClientCertificatePublicCertificate(int expirydays, LDAP return 0; } +int LDAPManager::generatePKICRL(int expirydays, LDAPRealmConfig realmcfg, TQString signingPrivateKeyFile, TQString revocationDatabaseFile, TQString *errstr) { + int retcode; + TQString command; + + LDAPUserInfoList userList = this->users(&retcode, errstr); + if (retcode == 0) { + // Generate base CRL + TQString crl_certfile = KERBEROS_PKI_CRL_FILE ".new"; + TQString revoked_certfile = KERBEROS_PKI_CRL_FILE ".rev"; + + // The public certificate location varies based on the machine role + // Prefer the bonded realm's certificate if available + TQString signing_public_certfile = KERBEROS_PKI_PUBLICDIR + realmcfg.admin_server + ".ldap.crt"; + if (!TQFile(signing_public_certfile).exists()) { + signing_public_certfile = KERBEROS_PKI_PEM_FILE; + } + + // Set up OpenSSL environment + if (writeOpenSSLConfigurationFile(realmcfg, LDAPUserInfo(), OPENSSL_EXTENSIONS_FILE, signingPrivateKeyFile, signing_public_certfile, revocationDatabaseFile, errstr) != 0) { + return -1; + } + command = TQString("rm -f %1").arg(revocationDatabaseFile); + if (system(command) < 0) { + if (errstr) *errstr = TQString("Execution of \"%s\" failed").arg(command); + return -1; + } + command = TQString("touch %1").arg(revocationDatabaseFile); + if (system(command) < 0) { + if (errstr) *errstr = TQString("Execution of \"%s\" failed").arg(command); + return -1; + } + + command = TQString("openssl ca -days %1 -crldays %2 -crlhours 0 -gencrl -out %3 -config %4").arg(expirydays).arg(expirydays).arg(crl_certfile).arg(OPENSSL_EXTENSIONS_FILE); + if (system(command) < 0) { + if (errstr) *errstr = TQString("Execution of \"%s\" failed").arg(command); + return -1; + } + + LDAPUserInfoList::Iterator it; + for (it = userList.begin(); it != userList.end(); ++it) { + LDAPUserInfo user = *it; + + PKICertificateEntryList::Iterator it; + for (it = user.pkiCertificates.begin(); it != user.pkiCertificates.end(); ++it) { + PKICertificateEntry certificateData = *it; + + TQCString ssldata(certificateData.second); + ssldata[certificateData.second.size()] = 0; + ssldata.replace("-----BEGIN CERTIFICATE-----", ""); + ssldata.replace("-----END CERTIFICATE-----", ""); + ssldata.replace("\n", ""); + KSSLCertificate* cert = KSSLCertificate::fromString(ssldata); + if (cert) { + bool expired = false; + if (TQDate::currentDate().daysTo(cert->getQDTNotAfter().date()) < 0) { + expired = true; + } + + if ((certificateData.first == PKICertificateStatus::Revoked) || expired) { + // Revoke this certificate + { + TQFile revokedCertFile(revoked_certfile); + if (revokedCertFile.open(IO_WriteOnly)) { + revokedCertFile.writeBlock(certificateData.second); + } + } + command = TQString("openssl ca -revoke %1 -config %2").arg(revoked_certfile).arg(OPENSSL_EXTENSIONS_FILE); + if (system(command) < 0) { + if (errstr) *errstr = TQString("Execution of \"%s\" failed").arg(command); + return -1; + } + } + } + } + } + + // Regenerate CRL certificate + command = TQString("openssl ca -days %1 -crldays %2 -crlhours 0 -gencrl -out %3 -config %4").arg(expirydays).arg(expirydays).arg(crl_certfile).arg(OPENSSL_EXTENSIONS_FILE); + if (system(command) < 0) { + if (errstr) *errstr = TQString("Execution of \"%s\" failed").arg(command); + return -1; + } + + // Upload certificate to LDAP + TQFile crlfile(crl_certfile); + if (crlfile.open(IO_ReadOnly)) { + TQByteArray crlfiledata = crlfile.readAll(); + if (this->writeCertificateFileIntoDirectory(crlfiledata, "publicRootCertificateRevocationList", errstr) != 0) { + return -1; + } + } + + // Clean up + if (fileExists(crl_certfile.ascii())) { + if (unlink(crl_certfile.ascii()) < 0) { + if (errstr) *errstr = TQString("Unable to unlink \"%1\"").arg(crl_certfile); + return -1; + } + } + if (fileExists(revoked_certfile.ascii())) { + if (unlink(revoked_certfile.ascii()) < 0) { + if (errstr) *errstr = TQString("Unable to unlink \"%1\"").arg(revoked_certfile); + return -1; + } + } + } + + return retcode; +} + TQString LDAPManager::getMachineFQDN() { struct addrinfo hints, *info, *p; int gai_result; @@ -4443,16 +4578,28 @@ int LDAPManager::writePAMFiles(LDAPPamConfig pamConfig, TQString *errstr) { } int LDAPManager::writeOpenSSLConfigurationFile(LDAPRealmConfig realmcfg, TQString *errstr) { - return writeOpenSSLConfigurationFile(realmcfg, LDAPUserInfo(), TQString::fromLatin1(OPENSSL_EXTENSIONS_FILE), errstr); + return writeOpenSSLConfigurationFile(realmcfg, LDAPUserInfo(), TQString::fromLatin1(OPENSSL_EXTENSIONS_FILE), TQString::null, TQString::null, TQString::null, errstr); } -int LDAPManager::writeOpenSSLConfigurationFile(LDAPRealmConfig realmcfg, LDAPUserInfo user, TQString opensslConfigFile, TQString *errstr) { +int LDAPManager::writeOpenSSLConfigurationFile(LDAPRealmConfig realmcfg, LDAPUserInfo user, TQString opensslConfigFile, TQString caRootKeyFile, TQString caRootCertFile, TQString caRootDatabaseFile, TQString *errstr) { TQString crl_url = realmcfg.certificate_revocation_list_url; if (crl_url == "") { // Use a default to preserve certificate validity // crl_url = TQString("http://%1/%2.crl").arg(realmcfg.name).arg(realmcfg.kdc); } + if (caRootKeyFile == "") { + caRootKeyFile = KERBEROS_PKI_PEMKEY_FILE; + } + + if (caRootCertFile == "") { + caRootCertFile = KERBEROS_PKI_PEM_FILE; + } + + if (caRootDatabaseFile == "") { + caRootDatabaseFile = KERBEROS_PKI_CRLDB_FILE; + } + TQString krb_principal = TQString::null; if (user.informationValid) { krb_principal = user.name + "@" + realmcfg.name.upper(); @@ -4478,7 +4625,7 @@ int LDAPManager::writeOpenSSLConfigurationFile(LDAPRealmConfig realmcfg, LDAPUse stream << "# All changes will be lost!\n"; stream << "\n"; stream << "[ca]" << "\n"; - stream << "default_ca = user" << "\n"; + stream << "default_ca = certificate_authority" << "\n"; stream << "\n"; stream << "[usr]" << "\n"; // stream << "database = index.txt" << "\n"; @@ -4489,6 +4636,16 @@ int LDAPManager::writeOpenSSLConfigurationFile(LDAPRealmConfig realmcfg, LDAPUse stream << "email_in_dn = no" << "\n"; stream << "certs = ." << "\n"; stream << "\n"; + stream << "[certificate_authority]" << "\n"; + stream << TQString("database = %1\n").arg(caRootDatabaseFile) << "\n"; + stream << TQString("certificate = %1\n").arg(caRootCertFile) << "\n"; + stream << TQString("private_key = %1\n").arg(caRootKeyFile) << "\n"; + // stream << TQString("crl = %1\n").arg(KERBEROS_PKI_CRL_FILE) << "\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"; @@ -5016,6 +5173,7 @@ KerberosTicketInfo::~KerberosTicketInfo() { } LDAPCertConfig::LDAPCertConfig() { + caCrlExpiryDays = KERBEROS_PKI_CRL_EXPIRY_DAYS; caExpiryDays = KERBEROS_PKI_PEMKEY_EXPIRY_DAYS; kerberosExpiryDays = KERBEROS_PKI_KRB_EXPIRY_DAYS; ldapExpiryDays = KERBEROS_PKI_LDAP_EXPIRY_DAYS; diff --git a/src/libtdeldap.h b/src/libtdeldap.h index 90b44af..d4c759f 100644 --- a/src/libtdeldap.h +++ b/src/libtdeldap.h @@ -49,6 +49,8 @@ #define KERBEROS_PKI_PEM_FILE KERBEROS_PKI_ANCHORDIR "tdeca.pem" #define KERBEROS_PKI_PEMKEY_FILE KERBEROS_PKI_ANCHORDIR "tdeca.key.pem" +#define KERBEROS_PKI_CRL_FILE KERBEROS_PKI_ANCHORDIR "tdecrl.pem" +#define KERBEROS_PKI_CRLDB_FILE KERBEROS_PKI_ANCHORDIR "tdecrl.db" #define KERBEROS_PKI_KDC_FILE KERBEROS_PKI_PUBLICDIR "@@@KDCSERVER@@@.pki.crt" #define KERBEROS_PKI_KDCKEY_FILE KERBEROS_PKI_PRIVATEDIR "@@@KDCSERVER@@@.pki.key" #define KERBEROS_PKI_KDCREQ_FILE KERBEROS_PKI_PRIVATEDIR "@@@KDCSERVER@@@.pki.req" @@ -68,6 +70,7 @@ #define KERBEROS_PKI_PEMKEY_EXPIRY_DAYS 365 // 1 month +#define KERBEROS_PKI_CRL_EXPIRY_DAYS 30 #define KERBEROS_PKI_KRB_EXPIRY_DAYS 30 #define KERBEROS_PKI_LDAP_EXPIRY_DAYS 30 @@ -215,6 +218,7 @@ class LDAPCertConfig TQString provided_ldap_key; int caExpiryDays; + int caCrlExpiryDays; int kerberosExpiryDays; int ldapExpiryDays; @@ -529,6 +533,7 @@ class LDAPManager : public TQObject { int writeSudoersConfFile(TQString *errstr=0); int getTDECertificate(TQString certificateName, TQFile *fileHandle, TQString *errstr=0); int getTDECertificate(TQString certificateName, TQString fileName, TQString *errstr=0); + int getTDECertificate(TQString certificateName, TQByteArray *certificate, TQString *errstr=0); int setPasswordForUser(LDAPUserInfo user, TQString *errstr); static int writePrimaryRealmCertificateUpdateCronFile(TQString *errstr=0); @@ -537,6 +542,7 @@ class LDAPManager : public TQObject { static LDAPRealmConfigList fetchAndReadTDERealmList(TQString *defaultRealm=0); static LDAPRealmConfigList readTDERealmList(KSimpleConfig* config, bool disableAllBonds=false); static TQDateTime getCertificateExpiration(TQString certfile); + static TQDateTime getCertificateExpiration(TQByteArray certfileContents); static int generatePublicKerberosCACertificate(LDAPCertConfig certinfo, LDAPRealmConfig realmcfg); static int generatePublicKerberosCertificate(LDAPCertConfig certinfo, LDAPRealmConfig realmcfg); @@ -546,6 +552,8 @@ class LDAPManager : public TQObject { static int generateClientCertificatePrivateKey(LDAPUserInfo user, LDAPRealmConfig realmcfg, TQString privateKeyFile, TQString *errstr=0); static int generateClientCertificatePublicCertificate(int expirydays, LDAPUserInfo user, LDAPRealmConfig realmcfg, TQString signingPrivateKeyFile, TQString privateKeyFile, TQString publicCertFile, TQString *errstr=0); + int generatePKICRL(int expirydays, LDAPRealmConfig realmcfg, TQString signingPrivateKeyFile, TQString revocationDatabaseFile, TQString *errstr=0); + static TQString ldapdnForRealm(TQString realm); static TQString openssldcForRealm(TQString realm); static TQString cnFromDn(TQString dn); @@ -565,7 +573,7 @@ class LDAPManager : public TQObject { 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 writeOpenSSLConfigurationFile(LDAPRealmConfig realmcfg, LDAPUserInfo user, TQString opensslConfigFile, TQString *errstr=0); + static int writeOpenSSLConfigurationFile(LDAPRealmConfig realmcfg, LDAPUserInfo user, TQString opensslConfigFile, TQString caRootKeyFile=TQString::null, TQString caRootCertFile=TQString::null, TQString caRootDatabaseFile=TQString::null, TQString *errstr=0); static int writeClientCronFiles(TQString *errstr=0); static int writePAMFiles(LDAPPamConfig pamConfig, TQString *errstr=0); |