version 1.76, 2007/05/09 19:18:00
|
version 1.77, 2007/08/22 07:43:39
|
|
|
# include <Pegasus/Common/CIMKerberosSecurityAssociation.h> | # include <Pegasus/Common/CIMKerberosSecurityAssociation.h> |
#endif | #endif |
| |
|
#ifdef PEGASUS_ZOS_SECURITY |
|
// This include file will not be provided in the OpenGroup CVS for now. |
|
// Do NOT try to include it in your compile |
|
#include <Pegasus/Common/safCheckzOS_inline.h> |
|
#endif |
|
|
|
#ifdef PEGASUS_OS_ZOS |
|
#include <sys/ps.h> |
|
#endif |
|
|
PEGASUS_USING_STD; | PEGASUS_USING_STD; |
| |
PEGASUS_NAMESPACE_BEGIN | PEGASUS_NAMESPACE_BEGIN |
|
|
String connectClose; | String connectClose; |
Boolean closeConnect = false; | Boolean closeConnect = false; |
| |
|
// |
|
// Process M-POST and POST messages: |
|
// |
|
|
|
PEG_LOGGER_TRACE(( |
|
Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE, |
|
"HTTPAuthenticatorDelegator - HTTP processing start")); |
|
|
|
|
httpMessage->parse(startLine, headers, contentLength); | httpMessage->parse(startLine, headers, contentLength); |
| |
// | // |
|
|
} | } |
| |
// | // |
|
// Check and set languages |
|
// |
|
AcceptLanguageList acceptLanguages; |
|
ContentLanguageList contentLanguages; |
|
try |
|
{ |
|
// Get and validate the Accept-Language header, if set |
|
String acceptLanguageHeader; |
|
if (HTTPMessage::lookupHeader( |
|
headers, |
|
_HTTP_HEADER_ACCEPT_LANGUAGE, |
|
acceptLanguageHeader, |
|
false)) |
|
{ |
|
acceptLanguages = LanguageParser::parseAcceptLanguageHeader( |
|
acceptLanguageHeader); |
|
httpMessage->acceptLanguagesDecoded = true; |
|
} |
|
|
|
// Get and validate the Content-Language header, if set |
|
String contentLanguageHeader; |
|
if (HTTPMessage::lookupHeader( |
|
headers, |
|
_HTTP_HEADER_CONTENT_LANGUAGE, |
|
contentLanguageHeader, |
|
false)) |
|
{ |
|
contentLanguages = LanguageParser::parseContentLanguageHeader( |
|
contentLanguageHeader); |
|
httpMessage->contentLanguagesDecoded = true; |
|
} |
|
} |
|
catch (Exception& e) |
|
{ |
|
// clear any existing languages to force messages to come from the |
|
// root bundle |
|
Thread::clearLanguages(); |
|
MessageLoaderParms msgParms( |
|
"Pegasus.Server.HTTPAuthenticatorDelegator.REQUEST_NOT_VALID", |
|
"request-not-valid"); |
|
String msg(MessageLoader::getMessage(msgParms)); |
|
|
|
_sendHttpError( |
|
queueId, |
|
HTTP_STATUS_BADREQUEST, |
|
msg, |
|
e.getMessage(), |
|
closeConnect); |
|
PEG_METHOD_EXIT(); |
|
return; |
|
} |
|
|
|
Thread::setLanguages(new AcceptLanguageList(acceptLanguages)); |
|
httpMessage->acceptLanguages = acceptLanguages; |
|
httpMessage->contentLanguages = contentLanguages; |
|
|
|
// |
|
// Parse the request line: |
|
// |
|
String methodName; |
|
String requestUri; |
|
String httpVersion; |
|
HttpMethod httpMethod = HTTP_METHOD__POST; |
|
|
|
HTTPMessage::parseRequestLine( |
|
startLine, methodName, requestUri, httpVersion); |
|
|
|
// |
|
// Set HTTP method for the request |
|
// |
|
if (methodName == _HTTP_METHOD_MPOST) |
|
{ |
|
httpMethod = HTTP_METHOD_M_POST; |
|
} |
|
|
|
if (methodName != _HTTP_METHOD_MPOST && methodName != _HTTP_METHOD) |
|
{ |
|
// Only POST and M-POST are implemented by this server |
|
_sendHttpError( |
|
queueId, |
|
HTTP_STATUS_NOTIMPLEMENTED, |
|
String::EMPTY, |
|
String::EMPTY, |
|
closeConnect); |
|
PEG_METHOD_EXIT(); |
|
return; |
|
} |
|
|
|
if ((httpMethod == HTTP_METHOD_M_POST) && |
|
(httpVersion == _HTTP_VERSION_1_0)) |
|
{ |
|
// |
|
// M-POST method is not valid with version 1.0 |
|
// |
|
_sendHttpError( |
|
queueId, |
|
HTTP_STATUS_BADREQUEST, |
|
String::EMPTY, |
|
String::EMPTY, |
|
closeConnect); |
|
PEG_METHOD_EXIT(); |
|
return; |
|
} |
|
|
|
PEG_LOGGER_TRACE(( |
|
Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE, |
|
"HTTPAuthenticatorDelegator - Authentication processing start")); |
|
|
|
// |
// Handle authentication: | // Handle authentication: |
// | // |
ConfigManager* configManager = ConfigManager::getInstance(); | ConfigManager* configManager = ConfigManager::getInstance(); |
Boolean enableAuthentication = false; |
Boolean enableAuthentication = |
|
ConfigManager::parseBooleanValue(configManager->getCurrentValue( |
|
_CONFIG_PARAM_ENABLEAUTHENTICATION)); |
| |
Boolean isRequestAuthenticated = | Boolean isRequestAuthenticated = |
httpMessage->authInfo->isConnectionAuthenticated(); | httpMessage->authInfo->isConnectionAuthenticated(); |
|
|
} | } |
#endif | #endif |
| |
if (ConfigManager::parseBooleanValue(configManager->getCurrentValue( |
if (enableAuthentication) |
_CONFIG_PARAM_ENABLEAUTHENTICATION))) |
|
{ | { |
enableAuthentication = true; |
|
#ifdef PEGASUS_KERBEROS_AUTHENTICATION | #ifdef PEGASUS_KERBEROS_AUTHENTICATION |
// If we are using Kerberos (sa pointer is set), the client has | // If we are using Kerberos (sa pointer is set), the client has |
// already authenticated, and the client is NOT attempting to | // already authenticated, and the client is NOT attempting to |
|
|
isRequestAuthenticated = true; | isRequestAuthenticated = true; |
} | } |
#endif | #endif |
|
if (isRequestAuthenticated) |
|
{ |
|
if (httpMessage->authInfo->getAuthType()== |
|
AuthenticationInfoRep::AUTH_TYPE_SSL) |
|
{ |
// Get the user name associated with the certificate (using the | // Get the user name associated with the certificate (using the |
// certificate chain, if necessary). | // certificate chain, if necessary). |
| |
|
|
String subjectName; | String subjectName; |
char serialNumber[32]; | char serialNumber[32]; |
| |
if (isRequestAuthenticated && |
|
(String::equal(httpMessage->authInfo->getAuthType(), |
|
AuthenticationInfoRep::AUTH_TYPE_SSL))) |
|
{ |
|
PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL3, | PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL3, |
"Client was authenticated via trusted SSL certificate."); | "Client was authenticated via trusted SSL certificate."); |
| |
|
|
"HTTPAuthenticatorDelegator - The trusted client certificate " | "HTTPAuthenticatorDelegator - The trusted client certificate " |
"is registered to $0.", | "is registered to $0.", |
certUserName); | certUserName); |
} |
} // end AuthenticationInfoRep::AUTH_TYPE_SSL |
} //end enableAuthentication |
|
|
|
PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL4, "Exited authentication loop"); |
|
| |
AcceptLanguageList acceptLanguages; |
#ifdef PEGASUS_OS_ZOS |
ContentLanguageList contentLanguages; |
if (httpMessage->authInfo->getAuthType()== |
try |
AuthenticationInfoRep::AUTH_TYPE_ZOS_ATTLS) |
{ |
|
// Get and validate the Accept-Language header, if set |
|
String acceptLanguageHeader; |
|
if (HTTPMessage::lookupHeader( |
|
headers, |
|
_HTTP_HEADER_ACCEPT_LANGUAGE, |
|
acceptLanguageHeader, |
|
false)) |
|
{ | { |
acceptLanguages = LanguageParser::parseAcceptLanguageHeader( |
String connectionUserName = |
acceptLanguageHeader); |
httpMessage->authInfo->getConnectionUser(); |
httpMessage->acceptLanguagesDecoded = true; |
|
} |
|
| |
// Get and validate the Content-Language header, if set |
// If authenticated user not the connected user |
String contentLanguageHeader; |
// then check CIMSERV profile. |
if (HTTPMessage::lookupHeader( |
if (!String::equalNoCase(connectionUserName, |
headers, |
httpMessage->authInfo->getAuthenticatedUser())) |
_HTTP_HEADER_CONTENT_LANGUAGE, |
|
contentLanguageHeader, |
|
false)) |
|
{ | { |
contentLanguages = LanguageParser::parseContentLanguageHeader( |
|
contentLanguageHeader); |
#ifdef PEGASUS_ZOS_SECURITY |
httpMessage->contentLanguagesDecoded = true; |
if ( !CheckProfileCIMSERVclassWBEM(connectionUserName, |
} |
__READ_RESOURCE)) |
} |
|
catch (Exception& e) |
|
{ | { |
// clear any existing languages to force messages to come from the |
Logger::put_l(Logger::STANDARD_LOG, ZOS_SECURITY_NAME, |
// root bundle |
Logger::WARNING, |
Thread::clearLanguages(); |
"Pegasus.Server.HTTPAuthenticatorDelegator." |
MessageLoaderParms msgParms( |
"ATTLS_NOREAD_CIMSERV_ACCESS.PEGASUS_OS_ZOS", |
"Pegasus.Server.HTTPAuthenticatorDelegator.REQUEST_NOT_VALID", |
"Request UserID $0 doesn't have READ permission" |
"request-not-valid"); |
" to profile CIMSERV CL(WBEM).", |
String msg(MessageLoader::getMessage(msgParms)); |
connectionUserName); |
| |
_sendHttpError( | _sendHttpError( |
queueId, | queueId, |
HTTP_STATUS_BADREQUEST, |
HTTP_STATUS_UNAUTHORIZED, |
msg, |
String::EMPTY, |
e.getMessage(), |
String::EMPTY, |
closeConnect); | closeConnect); |
|
|
PEG_METHOD_EXIT(); | PEG_METHOD_EXIT(); |
return; | return; |
} | } |
|
#endif |
|
PEG_TRACE((TRC_HTTP, Tracer::LEVEL4, |
|
"Client UserID '%s'was authenticated via AT-TLS.", |
|
(const char*)connectionUserName.getCString())); |
| |
Thread::setLanguages(new AcceptLanguageList(acceptLanguages)); |
httpMessage->authInfo->setAuthenticatedUser( |
httpMessage->acceptLanguages = acceptLanguages; |
connectionUserName); |
httpMessage->contentLanguages = contentLanguages; |
|
| |
// |
// For audit loging, only the mapping of the client IP to |
// Parse the request line: |
// the resolved user ID is from interest. |
// |
// The SAF facility logs the certificate validation and |
String methodName; |
// the mapping of certificate subject to a local userID. |
String requestUri; |
PEG_AUDIT_LOG(logCertificateBasedUserValidation( |
String httpVersion; |
connectionUserName, |
HttpMethod httpMethod = HTTP_METHOD__POST; |
String::EMPTY, |
|
String::EMPTY, |
|
String::EMPTY, |
|
httpMessage->ipAddress, |
|
true)); |
| |
HTTPMessage::parseRequestLine( |
}// end is authenticated ? |
startLine, methodName, requestUri, httpVersion); |
|
| |
// |
} // end AuthenticationInfoRep::AUTH_TYPE_ZOS_ATTLS |
// Set HTTP method for the request |
|
// |
if (httpMessage->authInfo->getAuthType()== |
if (methodName == _HTTP_METHOD_MPOST) |
AuthenticationInfoRep::AUTH_TYPE_ZOS_LOCAL_DOMIAN_SOCKET) |
{ | { |
httpMethod = HTTP_METHOD_M_POST; |
String connectionUserName = |
} |
httpMessage->authInfo->getConnectionUser(); |
| |
if (methodName != _HTTP_METHOD_MPOST && methodName != _HTTP_METHOD) |
String requestUserName; |
|
String authHeader; |
|
String authHttpType; |
|
String cookie; |
|
|
|
// if lookupHeader() is not successfull parseLocalAuthHeader() |
|
// must not be called !! |
|
if ( HTTPMessage::lookupHeader(headers, |
|
_HTTP_HEADER_PEGASUSAUTHORIZATION, authHeader, false)&& |
|
HTTPMessage::parseLocalAuthHeader(authHeader, |
|
authHttpType, requestUserName, cookie)) |
{ | { |
// Only POST and M-POST are implemented by this server |
String cimServerUserName = System::getEffectiveUserName(); |
|
|
|
PEG_TRACE((TRC_HTTP, Tracer::LEVEL4, |
|
"CIM server UserID = '%s', " |
|
"Request UserID = '%s', " |
|
"Local authenticated UserID = '%s'.", |
|
(const char*) cimServerUserName.getCString(), |
|
(const char*) requestUserName.getCString(), |
|
(const char*) connectionUserName.getCString() |
|
)); |
|
|
|
// if the request name and the user connected to the socket |
|
// are the same, or if the currnet user running the |
|
// cim server and the connected user are the same then |
|
// assign the request user id as authenticated user id. |
|
if( String::equalNoCase( |
|
requestUserName,connectionUserName) || |
|
String::equalNoCase( |
|
cimServerUserName,connectionUserName)) |
|
{ |
|
// If the designate new authenticated user, the user of |
|
// the request, is not already the authenticated user |
|
// then set the authenticated user and check CIMSERV. |
|
if (!String::equalNoCase(requestUserName, |
|
httpMessage->authInfo->getAuthenticatedUser())) |
|
{ |
|
|
|
#ifdef PEGASUS_ZOS_SECURITY |
|
if ( !CheckProfileCIMSERVclassWBEM(requestUserName, |
|
__READ_RESOURCE)) |
|
{ |
|
Logger::put_l(Logger::STANDARD_LOG, |
|
ZOS_SECURITY_NAME, |
|
Logger::WARNING, |
|
"Pegasus.Server.HTTPAuthenticatorDelegator." |
|
"UNIXSOCKET_NOREAD_CIMSERV_ACCESS." |
|
"PEGASUS_OS_ZOS", |
|
"Request UserID $0 doesn't have READ " |
|
"permission to profile " |
|
"CIMSERV CL(WBEM).", |
|
requestUserName); |
|
|
_sendHttpError( | _sendHttpError( |
queueId, | queueId, |
HTTP_STATUS_NOTIMPLEMENTED, |
HTTP_STATUS_UNAUTHORIZED, |
String::EMPTY, | String::EMPTY, |
String::EMPTY, | String::EMPTY, |
closeConnect); | closeConnect); |
|
|
|
PEG_METHOD_EXIT(); |
|
return ; |
} | } |
else if ((httpMethod == HTTP_METHOD_M_POST) && |
#endif |
(httpVersion == _HTTP_VERSION_1_0)) |
httpMessage->authInfo->setAuthenticatedUser( |
|
requestUserName); |
|
|
|
PEG_TRACE((TRC_HTTP, Tracer::LEVEL4, |
|
"New authenticated User = '%s'.", |
|
(const char*)requestUserName.getCString() |
|
)); |
|
|
|
// Write local authentication audit reckord. |
|
PEG_AUDIT_LOG(logLocalAuthentication( |
|
requestUserName,true)); |
|
|
|
} // end changed authenticated user |
|
|
|
} // end select authenticated user |
|
PEG_TRACE((TRC_HTTP, Tracer::LEVEL4, |
|
"User authenticated for request = '%s'.", |
|
(const char*)httpMessage->authInfo-> |
|
getAuthenticatedUser().getCString() |
|
)); |
|
} // end lookup header |
|
else |
{ | { |
// |
MessageLoaderParms msgParms( |
// M-POST method is not valid with version 1.0 |
"Pegasus.Server.HTTPAuthenticatorDelegator." |
// |
"AUTHORIZATION_HEADER_ERROR", |
|
"Authorization header error"); |
|
String msg(MessageLoader::getMessage(msgParms)); |
_sendHttpError( | _sendHttpError( |
queueId, | queueId, |
HTTP_STATUS_BADREQUEST, | HTTP_STATUS_BADREQUEST, |
String::EMPTY, | String::EMPTY, |
String::EMPTY, |
msg, |
closeConnect); | closeConnect); |
|
|
|
PEG_METHOD_EXIT(); |
|
return; |
} | } |
|
} // end AuthenticationInfoRep::AUTH_TYPE_ZOS_LOCAL_DOMIAN_SOCKET |
|
#endif |
|
} // end isRequestAuthenticated |
else | else |
{ |
{ // !isRequestAuthenticated |
// |
|
// Process M-POST and POST messages: |
|
// |
|
| |
PEG_LOGGER_TRACE(( |
String authorization; |
Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE, |
|
"HTTPAuthenticatorDelegator - M-POST/POST processing start")); |
|
| |
if (!isRequestAuthenticated && enableAuthentication) |
|
{ |
|
// | // |
// Search for Authorization header: |
// do Local/Pegasus authenticatio |
// | // |
String authorization; |
|
|
|
if (HTTPMessage::lookupHeader(headers, | if (HTTPMessage::lookupHeader(headers, |
_HTTP_HEADER_PEGASUSAUTHORIZATION, authorization, false) && |
_HTTP_HEADER_PEGASUSAUTHORIZATION, authorization, false)) |
enableAuthentication) |
|
{ | { |
try | try |
{ | { |
|
|
PEG_METHOD_EXIT(); | PEG_METHOD_EXIT(); |
return; | return; |
} | } |
} |
} // end PEGASUS/LOCAL authentication |
| |
if (HTTPMessage::lookupHeader( |
|
headers, _HTTP_HEADER_AUTHORIZATION, authorization, false) |
|
&& enableAuthentication) |
|
{ |
|
// | // |
// Do http authentication if not authenticated already |
// do HTTP authentication |
// | // |
if (!isRequestAuthenticated) |
if (HTTPMessage::lookupHeader( |
|
headers, _HTTP_HEADER_AUTHORIZATION, |
|
authorization, false)) |
{ | { |
isRequestAuthenticated = | isRequestAuthenticated = |
_authenticationManager->performHttpAuthentication( | _authenticationManager->performHttpAuthentication( |
|
|
PEG_METHOD_EXIT(); | PEG_METHOD_EXIT(); |
return; | return; |
} | } |
} // first not authenticated check |
} // End if HTTP Authorization |
} // "Authorization" header check |
|
} //end if (!authenticated && enableAuthentication) |
} //end if (!isRequestAuthenticated) |
|
|
|
} //end enableAuthentication |
|
|
|
PEG_LOGGER_TRACE(( |
|
Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE, |
|
"HTTPAuthenticatorDelegator - Authentication processing ended")); |
|
|
| |
#ifdef PEGASUS_KERBEROS_AUTHENTICATION | #ifdef PEGASUS_KERBEROS_AUTHENTICATION |
// The pointer to the sa is created in the authenticator so we need | // The pointer to the sa is created in the authenticator so we need |
|
|
closeConnect); | closeConnect); |
} | } |
} | } |
} // M-POST and POST processing |
|
| |
PEG_METHOD_EXIT(); | PEG_METHOD_EXIT(); |
} | } |