version 1.58, 2005/12/19 21:51:43
|
version 1.59, 2006/01/03 17:30:34
|
|
|
| |
if (FileSystem::isDirectory(ConfigManager::getHomedPath(trustStore))) | if (FileSystem::isDirectory(ConfigManager::getHomedPath(trustStore))) |
{ | { |
//get the authenticated client certificate |
PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL4, "Truststore is a directory, lookup username"); |
SSLCertificateInfo* clientCertificate = httpMessage->authInfo->getClientCertificate(); |
|
| |
if (!clientCertificate) |
//Get the client certificate chain to determine the correct username mapping. |
|
//Starting with the peer certificate, work your way up the chain |
|
//towards the root certificate until a match is found in the repository. |
|
Array<SSLCertificateInfo*> clientCertificateChain = httpMessage->authInfo->getClientCertificateChain(); |
|
SSLCertificateInfo* clientCertificate = NULL; |
|
|
|
Tracer::trace(TRC_HTTP, Tracer::LEVEL4, "Client certificate chain length: %d.", clientCertificateChain.size()); |
|
|
|
for (Uint32 i = 0; i < clientCertificateChain.size(); i++) |
|
{ |
|
clientCertificate = clientCertificateChain[i]; |
|
if (clientCertificate == NULL) |
{ | { |
MessageLoaderParms msgParms("Pegasus.Server.HTTPAuthenticatorDelegator.BAD_CERTIFICATE", | MessageLoaderParms msgParms("Pegasus.Server.HTTPAuthenticatorDelegator.BAD_CERTIFICATE", |
"The certificate used for authentication is not valid."); | "The certificate used for authentication is not valid."); |
|
|
PEG_METHOD_EXIT(); | PEG_METHOD_EXIT(); |
return; | return; |
} | } |
|
PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL4, "Certificate toString " + clientCertificate->toString()); |
| |
//get certificate properties | //get certificate properties |
String issuerName = clientCertificate->getIssuerName(); | String issuerName = clientCertificate->getIssuerName(); |
|
|
{ | { |
cimInstance = _repository->getInstance(PEGASUS_NAMESPACENAME_CERTIFICATE, cimObjectPath); | cimInstance = _repository->getInstance(PEGASUS_NAMESPACENAME_CERTIFICATE, cimObjectPath); |
| |
} catch (CIMException& e) |
Boolean isValidUser = false; |
{ |
pos = cimInstance.findProperty("RegisteredUserName"); |
//currently, we have an issue with the scenario of a root CA being added to the truststore and |
|
//authenticating a user certificate that the CA signed. The SSL client verification works correctly, |
|
//but when we try to get the instance here, it fails because the serial number is that of the user |
|
//and not that of the CA. We need to work out how to go about getting the correct serial number. |
|
//Complications also include the possibility of an intermediate CA or that a certificate for a root CA |
|
//and a user cert are registered for different usernames. At any rate, this issue is being tracked by |
|
//Heather Sterling as part of PEP187. |
|
| |
//For now, try a serial number of "0" to attempt to get the root CA |
if (pos != PEG_NOT_FOUND && !(value = cimInstance.getProperty(pos).getValue()).isNull()) |
try |
|
{ | { |
keyBindings.remove(1); |
value.get(userName); |
keyBindings.append(CIMKeyBinding("SerialNumber", "0", CIMKeyBinding::STRING)); |
isValidUser = _validateUser(userName, queueId); |
|
} |
CIMObjectPath rootCAPath("localhost", |
else |
PEGASUS_NAMESPACENAME_CERTIFICATE, |
{ |
PEGASUS_CLASSNAME_CERTIFICATE, |
Logger::put(Logger::ERROR_LOG, System::CIMSERVER, Logger::TRACE, |
keyBindings); |
"HTTPAuthenticatorDelegator - Bailing, no username is registered to this certificate."); |
|
} |
PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL4, "Trying root CA path: " + rootCAPath.toString()); |
|
| |
|
if (isValidUser) |
|
{ |
|
httpMessage->authInfo->setAuthenticatedUser(userName); |
| |
cimInstance = _repository->getInstance(PEGASUS_NAMESPACENAME_CERTIFICATE, rootCAPath); |
PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL3, "User name for certificate is " + userName); |
|
Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE, |
|
"HTTPAuthenticatorDelegator - The trusted client certificate is registered to $0.", userName); |
|
break; |
| |
} catch (...) |
} else |
{ | { |
//this scenario can occur if a certificate cached on the server was deleted |
MessageLoaderParms msgParms("Pegasus.Server.HTTPAuthenticatorDelegator.BAD_CERTIFICATE_USERNAME", |
//openssl would not pick up the deletion but we would pick it up here when we went to look it up |
"No username is registered to this certificate."); |
//in the repository |
|
Logger::put(Logger::ERROR_LOG, System::CIMSERVER, Logger::TRACE, |
|
"HTTPAuthenticatorDelegator - Bailing, the certificate used for authentication is not valid."); |
|
MessageLoaderParms msgParms("Pegasus.Server.HTTPAuthenticatorDelegator.BAD_CERTIFICATE", |
|
"The certificate used for authentication is not valid."); |
|
String msg(MessageLoader::getMessage(msgParms)); | String msg(MessageLoader::getMessage(msgParms)); |
PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL3, msg); | PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL3, msg); |
_sendHttpError( | _sendHttpError( |
|
|
PEG_METHOD_EXIT(); | PEG_METHOD_EXIT(); |
return; | return; |
} | } |
} |
|
| |
pos = cimInstance.findProperty("RegisteredUserName"); |
|
| |
if (pos != PEG_NOT_FOUND && !(value = cimInstance.getProperty(pos).getValue()).isNull()) |
} catch (CIMException& e) |
{ | { |
value.get(userName); |
//this certificate did not have a registration associated with it; continue up the chain |
|
if (e.getCode() == CIM_ERR_NOT_FOUND) |
// |
{ |
// Validate user information |
PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL4, "No registration for this certificate, try next certificate in chain"); |
// |
continue; |
| |
if (!_validateUser(userName, queueId)) |
} else |
{ | { |
|
Logger::put(Logger::ERROR_LOG, System::CIMSERVER, Logger::TRACE, |
|
"HTTPAuthenticatorDelegator - Bailing, Bailing, the certificate used for authentication is not valid."); |
|
MessageLoaderParms msgParms("Pegasus.Server.HTTPAuthenticatorDelegator.BAD_CERTIFICATE", |
|
"The certificate used for authentication is not valid."); |
|
String msg(MessageLoader::getMessage(msgParms)); |
|
PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL3, msg); |
|
_sendHttpError( |
|
queueId, |
|
HTTP_STATUS_UNAUTHORIZED, |
|
String::EMPTY, |
|
msg, |
|
closeConnect); |
PEG_METHOD_EXIT(); | PEG_METHOD_EXIT(); |
return; | return; |
} | } |
| |
httpMessage->authInfo->setAuthenticatedUser(userName); |
} catch (...) |
|
|
PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL3, "User name for certificate is " + userName); |
|
Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE, |
|
"HTTPAuthenticatorDelegator - The trusted client certificate is registered to $0.", userName); |
|
} |
|
else |
|
{ | { |
|
//this scenario can occur if a certificate cached on the server was deleted |
|
//openssl would not pick up the deletion but we would pick it up here when we went to look it up |
|
//in the repository |
Logger::put(Logger::ERROR_LOG, System::CIMSERVER, Logger::TRACE, | Logger::put(Logger::ERROR_LOG, System::CIMSERVER, Logger::TRACE, |
"HTTPAuthenticatorDelegator - Bailing, no username is registered to this certificate."); |
"HTTPAuthenticatorDelegator - Bailing, the certificate used for authentication is not valid."); |
MessageLoaderParms msgParms("Pegasus.Server.HTTPAuthenticatorDelegator.BAD_CERTIFICATE_USERNAME", |
MessageLoaderParms msgParms("Pegasus.Server.HTTPAuthenticatorDelegator.BAD_CERTIFICATE", |
"No username is registered to this certificate."); |
"The certificate used for authentication is not valid."); |
String msg(MessageLoader::getMessage(msgParms)); | String msg(MessageLoader::getMessage(msgParms)); |
PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL3, msg); | PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL3, msg); |
_sendHttpError( | _sendHttpError( |
|
|
PEG_METHOD_EXIT(); | PEG_METHOD_EXIT(); |
return; | return; |
} | } |
|
} //end for clientcertificatechain |
} |
} //end sslTrustStore directory |
else | else |
{ | { |
//trustStore is a single CA file, lookup username | //trustStore is a single CA file, lookup username |