Branch: master

efb81441 2015-09-03 00:03:15 Timothy Pearson
Add CRL generation
M src/libtdeldap.cpp
M src/libtdeldap.h
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 @@
 	// 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 @@
 	// 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 @@
 	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 @@
 					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);
@@ -3711,6 +3709,23 @@
 	}
 
 	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) {
@@ -3916,6 +3931,25 @@
 	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 @@
 		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 @@
 	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 @@
 
 	// 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 @@
 		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,29 +4184,139 @@
 
 	// 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;
 		}
 	}
 
 	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;
+					}
 ** Diff limit reached (max: 250 lines) **