diff --git a/src/libtdeldap.cpp b/src/libtdeldap.cpp index dbb4b3f..6e965fb 100644 --- a/src/libtdeldap.cpp +++ b/src/libtdeldap.cpp @@ -623,6 +623,22 @@ LDAPUserInfo LDAPManager::parseLDAPUserRecord(LDAPMessage* entry) { else if (ldap_field == "notes") { userinfo.notes = vals[i]->bv_val; } + else if (ldap_field == "pkiCertificate") { + int cert_count = ldap_count_values_len(vals); + for (i=0; ibv_val, vals[i]->bv_len); + TQDataStream stream(ba, IO_ReadOnly); + stream.setPrintableData(true); + stream >> entry; + + // Append entry to list + userinfo.pkiCertificates.append(entry); + } + } ldap_value_free_len(vals); } ldap_memfree(attr); @@ -888,6 +904,24 @@ void add_multiple_attributes_operation(LDAPMod **mods, int *i, TQString attr, TQ (*i)++; } +void add_multiple_binary_attributes_operation(LDAPMod **mods, int *i, TQString attr, TQByteArrayList byteArrays) { + int j=0; + struct berval **values = (berval**)malloc((byteArrays.count()+1)*sizeof(berval*)); + for ( TQByteArrayList::Iterator it = byteArrays.begin(); it != byteArrays.end(); ++it ) { + if ((*it).size() > 0) { + values[j] = new berval; + values[j]->bv_len = (*it).size(); + values[j]->bv_val = (*it).data(); + j++; + } + } + values[j] = NULL; + mods[*i]->mod_op = LDAP_MOD_REPLACE|LDAP_MOD_BVALUES; + mods[*i]->mod_type = strdup(attr.ascii()); + mods[*i]->mod_bvalues = values; + (*i)++; +} + void delete_single_attribute_operation(LDAPMod **mods, int *i, TQString attr) { mods[*i]->mod_op = LDAP_MOD_DELETE; mods[*i]->mod_type = strdup(attr.ascii()); @@ -2678,6 +2712,65 @@ int LDAPManager::writeCertificateFileIntoDirectory(TQByteArray cert, TQString at } } +int LDAPManager::writePKICertificateFilesIntoDirectory(LDAPUserInfo user, TQString attr, TQString* errstr) { + int retcode; + int i; + + if (bind() < 0) { + return -1; + } + else { + // Assemble the LDAPMod structure + // We will replace any existing attributes with the new values + int number_of_parameters = 1; // 1 primary attribute + LDAPMod *mods[number_of_parameters+1]; + set_up_attribute_operations(mods, number_of_parameters); + + // Assemble list of serialized data structures + TQStringList serializedCertificateList; + PKICertificateEntryList::Iterator it; + for (it = user.pkiCertificates.begin(); it != user.pkiCertificates.end(); ++it) { + PKICertificateEntry certificateData = *it; + + // Serialize data + TQByteArray ba; + { + TQDataStream stream(ba, IO_WriteOnly); + stream.setPrintableData(true); + stream << certificateData; + } + ba.resize(ba.size()+1); + ba[ba.size()-1] = 0; + serializedCertificateList.append(TQString(ba)); + } + + // Load LDAP modification requests from provided data structure + i=0; + add_multiple_attributes_operation(mods, &i, attr, serializedCertificateList); + LDAPMod *prevterm = mods[i]; + mods[i] = NULL; + + // Perform LDAP update + retcode = ldap_modify_ext_s(m_ldap, user.distinguishedName.ascii(), mods, NULL, NULL); + + // Clean up + clean_up_attribute_operations(i, mods, prevterm, number_of_parameters); + + if (retcode != LDAP_SUCCESS) { + if (errstr) { + *errstr = i18n("LDAP modification failure

Reason: [%3] %4").arg(retcode).arg(ldap_err2string(retcode)); + } + else { + KMessageBox::error(0, i18n("LDAP modification failure

Reason: [%3] %4").arg(retcode).arg(ldap_err2string(retcode)), i18n("LDAP Error")); + } + return -2; + } + else { + return 0; + } + } +} + TQString LDAPManager::getRealmCAMaster(TQString* errstr) { int retcode; TQString realmCAMaster; @@ -3832,6 +3925,7 @@ TQDateTime LDAPManager::getCertificateExpiration(TQString certfile) { file.close(); TQCString ssldata(ba); + ssldata[ba.size()] = 0; ssldata.replace("-----BEGIN CERTIFICATE-----", ""); ssldata.replace("-----END CERTIFICATE-----", ""); ssldata.replace("\n", ""); @@ -3974,12 +4068,12 @@ int LDAPManager::generatePublicLDAPCertificate(LDAPCertConfig certinfo, LDAPReal return 0; } -int LDAPManager::generateClientCertificatePair(LDAPCertConfig certinfo, LDAPUserInfo user, LDAPRealmConfig realmcfg, TQString signingPrivateKeyFile, TQString privateKeyFile, TQString publicCertFile, TQString *errstr) { +int LDAPManager::generateClientCertificatePair(int expirydays, LDAPUserInfo user, LDAPRealmConfig realmcfg, TQString signingPrivateKeyFile, TQString privateKeyFile, TQString publicCertFile, TQString *errstr) { int ret; ret = generateClientCertificatePrivateKey(user, realmcfg, privateKeyFile, errstr); if (ret == 0) { - ret = generateClientCertificatePublicCertificate(certinfo, user, realmcfg, signingPrivateKeyFile, privateKeyFile, publicCertFile, errstr); + ret = generateClientCertificatePublicCertificate(expirydays, user, realmcfg, signingPrivateKeyFile, privateKeyFile, publicCertFile, errstr); } return ret; @@ -4026,7 +4120,7 @@ int LDAPManager::generateClientCertificatePrivateKey(LDAPUserInfo user, LDAPReal return 0; } -int LDAPManager::generateClientCertificatePublicCertificate(LDAPCertConfig certinfo, LDAPUserInfo user, LDAPRealmConfig realmcfg, TQString signingPrivateKeyFile, TQString privateKeyFile, TQString publicCertFile, TQString *errstr) { +int LDAPManager::generateClientCertificatePublicCertificate(int expirydays, LDAPUserInfo user, LDAPRealmConfig realmcfg, TQString signingPrivateKeyFile, TQString privateKeyFile, TQString publicCertFile, TQString *errstr) { TQString command; TQString subject; @@ -4051,13 +4145,13 @@ int LDAPManager::generateClientCertificatePublicCertificate(LDAPCertConfig certi common_name = TQString("/uid=%1").arg(user.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(openssldcForRealm(realmcfg.name)).arg(common_name); - command = TQString("openssl req -days %1 -new -out %2 -key %3 -config %4 -subj %5").arg(certinfo.kerberosExpiryDays).arg(client_reqfile).arg(client_keyfile).arg(OPENSSL_EXTENSIONS_FILE).arg(subject); + subject = TQString("\"/CN=%1%2%3\"").arg(user.name).arg(openssldcForRealm(realmcfg.name)).arg(common_name); + command = TQString("openssl req -days %1 -new -out %2 -key %3 -config %4 -subj %5").arg(expirydays).arg(client_reqfile).arg(client_keyfile).arg(OPENSSL_EXTENSIONS_FILE).arg(subject); if (system(command) < 0) { if (errstr) *errstr = TQString("Execution of \"%s\" failed").arg(command); return -1; } - command = TQString("openssl x509 -req -days %1 -in %2 -CAkey %3 -CA %4 -out %5 -extfile %6 -extensions pkinit_client_cert -CAcreateserial").arg(certinfo.kerberosExpiryDays).arg(client_reqfile).arg(signingPrivateKeyFile).arg(signing_public_certfile).arg(client_certfile).arg(OPENSSL_EXTENSIONS_FILE); + command = TQString("openssl x509 -req -days %1 -in %2 -CAkey %3 -CA %4 -out %5 -extfile %6 -extensions pkinit_client_cert -CAcreateserial").arg(expirydays).arg(client_reqfile).arg(signingPrivateKeyFile).arg(signing_public_certfile).arg(client_certfile).arg(OPENSSL_EXTENSIONS_FILE); if (system(command) < 0) { if (errstr) *errstr = TQString("Execution of \"%s\" failed").arg(command); return -1; diff --git a/src/libtdeldap.h b/src/libtdeldap.h index f472c6c..90b44af 100644 --- a/src/libtdeldap.h +++ b/src/libtdeldap.h @@ -21,6 +21,7 @@ #ifndef _LIBTDELDAP_H_ #define _LIBTDELDAP_H_ +#include #include #include #include @@ -149,6 +150,19 @@ inline KRB5TicketFlags operator&(KRB5TicketFlags a, KRB5TicketFlags b) typedef TQValueList UserList; typedef TQValueList GroupList; +namespace PKICertificateStatus { + enum PKICertificateStatusEnum { + Invalid = 0, + Valid = 1, + Revoked = 2 + }; +} + +typedef TQValueList TQByteArrayList; + +typedef TQPair PKICertificateEntry; +typedef TQValueList PKICertificateEntryList; + class LDAPCredentials { public: @@ -329,6 +343,9 @@ class LDAPUserInfo TQString businessCategory; TQString carLicense; TQString notes; + + // PKI + PKICertificateEntryList pkiCertificates; }; class LDAPGroupInfo @@ -501,6 +518,7 @@ class LDAPManager : public TQObject { int moveKerberosEntries(TQString newSuffix, TQString* errstr=0); int writeCertificateFileIntoDirectory(TQByteArray cert, TQString attr, TQString* errstr=0); + int writePKICertificateFilesIntoDirectory(LDAPUserInfo user, TQString attr, TQString* errstr=0); TQString getRealmCAMaster(TQString* errstr=0); int setRealmCAMaster(TQString masterFQDN, TQString* errstr=0); @@ -524,9 +542,9 @@ class LDAPManager : public TQObject { static int generatePublicKerberosCertificate(LDAPCertConfig certinfo, LDAPRealmConfig realmcfg); static int generatePublicLDAPCertificate(LDAPCertConfig certinfo, LDAPRealmConfig realmcfg, uid_t ldap_uid, gid_t ldap_gid); - static int generateClientCertificatePair(LDAPCertConfig certinfo, LDAPUserInfo user, LDAPRealmConfig realmcfg, TQString signingPrivateKeyFile, TQString privateKeyFile, TQString publicCertFile, TQString *errstr=0); + static int generateClientCertificatePair(int expirydays, LDAPUserInfo user, LDAPRealmConfig realmcfg, TQString signingPrivateKeyFile, TQString privateKeyFile, TQString publicCertFile, TQString *errstr=0); static int generateClientCertificatePrivateKey(LDAPUserInfo user, LDAPRealmConfig realmcfg, TQString privateKeyFile, TQString *errstr=0); - static int generateClientCertificatePublicCertificate(LDAPCertConfig certinfo, LDAPUserInfo user, LDAPRealmConfig realmcfg, TQString signingPrivateKeyFile, TQString privateKeyFile, TQString publicCertFile, TQString *errstr=0); + static int generateClientCertificatePublicCertificate(int expirydays, LDAPUserInfo user, LDAPRealmConfig realmcfg, TQString signingPrivateKeyFile, TQString privateKeyFile, TQString publicCertFile, TQString *errstr=0); static TQString ldapdnForRealm(TQString realm); static TQString openssldcForRealm(TQString realm);