(file) Return to HTTPAuthenticatorDelegator.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Server

   1 martin 1.91 //%LICENSE////////////////////////////////////////////////////////////////
   2 martin 1.92 //
   3 martin 1.91 // Licensed to The Open Group (TOG) under one or more contributor license
   4             // agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
   5             // this work for additional information regarding copyright ownership.
   6             // Each contributor licenses this file to you under the OpenPegasus Open
   7             // Source License; you may not use this file except in compliance with the
   8             // License.
   9 martin 1.92 //
  10 martin 1.91 // Permission is hereby granted, free of charge, to any person obtaining a
  11             // copy of this software and associated documentation files (the "Software"),
  12             // to deal in the Software without restriction, including without limitation
  13             // the rights to use, copy, modify, merge, publish, distribute, sublicense,
  14             // and/or sell copies of the Software, and to permit persons to whom the
  15             // Software is furnished to do so, subject to the following conditions:
  16 martin 1.92 //
  17 martin 1.91 // The above copyright notice and this permission notice shall be included
  18             // in all copies or substantial portions of the Software.
  19 martin 1.92 //
  20 martin 1.91 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  21 martin 1.92 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  22 martin 1.91 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  23             // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  24             // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  25             // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  26             // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  27 martin 1.92 //
  28 martin 1.91 //////////////////////////////////////////////////////////////////////////
  29 mike   1.2  //
  30             //%/////////////////////////////////////////////////////////////////////////////
  31             
  32 sushma.fernandes 1.76 #include <Pegasus/Common/AuditLogger.h>
  33 kumpf            1.10 #include <Pegasus/Common/Constants.h>
  34 mike             1.2  #include <Pegasus/Common/HTTPAcceptor.h>
  35                       #include <Pegasus/Common/HTTPConnection.h>
  36                       #include <Pegasus/Common/HTTPMessage.h>
  37                       #include <Pegasus/Common/XmlWriter.h>
  38 humberto         1.33 #include <Pegasus/Common/Thread.h>
  39                       #include <Pegasus/Common/MessageLoader.h>
  40 h.sterling       1.43 #include <Pegasus/Common/FileSystem.h>
  41 kumpf            1.58 #include <Pegasus/Common/LanguageParser.h>
  42 kumpf            1.82 #include <Pegasus/Config/ConfigManager.h>
  43                       #include "HTTPAuthenticatorDelegator.h"
  44 kumpf            1.68 
  45 gerarda          1.22 #ifdef PEGASUS_KERBEROS_AUTHENTICATION
  46 kumpf            1.68 # include <Pegasus/Common/CIMKerberosSecurityAssociation.h>
  47                       #endif
  48 mike             1.2  
  49 thilo.boehm      1.77 #ifdef PEGASUS_ZOS_SECURITY
  50                       // This include file will not be provided in the OpenGroup CVS for now.
  51                       // Do NOT try to include it in your compile
  52 kumpf            1.82 # include <Pegasus/Common/safCheckzOS_inline.h>
  53 thilo.boehm      1.77 #endif
  54                       
  55                       #ifdef PEGASUS_OS_ZOS
  56 kumpf            1.82 # include <sys/ps.h>
  57 thilo.boehm      1.77 #endif
  58                       
  59 mike             1.2  PEGASUS_USING_STD;
  60                       
  61                       PEGASUS_NAMESPACE_BEGIN
  62                       
  63 mike             1.56 static const String _HTTP_VERSION_1_0 = "HTTP/1.0";
  64                       
  65                       static const String _HTTP_METHOD_MPOST = "M-POST";
  66                       static const String _HTTP_METHOD = "POST";
  67                       
  68 kumpf            1.94 static const char* _HTTP_HEADER_CIMEXPORT = "CIMExport";
  69                       static const char* _HTTP_HEADER_CONNECTION = "Connection";
  70                       static const char* _HTTP_HEADER_CIMOPERATION = "CIMOperation";
  71                       static const char* _HTTP_HEADER_ACCEPT_LANGUAGE = "Accept-Language";
  72                       static const char* _HTTP_HEADER_CONTENT_LANGUAGE = "Content-Language";
  73                       static const char* _HTTP_HEADER_AUTHORIZATION = "Authorization";
  74                       static const char* _HTTP_HEADER_PEGASUSAUTHORIZATION = "PegasusAuthorization";
  75 mike             1.56 
  76                       static const String _CONFIG_PARAM_ENABLEAUTHENTICATION = "enableAuthentication";
  77                       
  78 mike             1.2  HTTPAuthenticatorDelegator::HTTPAuthenticatorDelegator(
  79 kumpf            1.83     Uint32 cimOperationMessageQueueId,
  80                           Uint32 cimExportMessageQueueId,
  81 kumpf            1.68     CIMRepository* repository)
  82 sahana.prabhakar 1.95     : Base(PEGASUS_QUEUENAME_HTTPAUTHDELEGATOR),
  83 kumpf            1.83       _cimOperationMessageQueueId(cimOperationMessageQueueId),
  84                             _cimExportMessageQueueId(cimExportMessageQueueId),
  85                             _wsmanOperationMessageQueueId(PEG_NOT_FOUND),
  86 kumpf            1.68       _repository(repository)
  87 mike             1.2  {
  88 kumpf            1.11     PEG_METHOD_ENTER(TRC_HTTP,
  89                               "HTTPAuthenticatorDelegator::HTTPAuthenticatorDelegator");
  90                       
  91 a.arora          1.36     _authenticationManager.reset(new AuthenticationManager());
  92 kumpf            1.11 
  93                           PEG_METHOD_EXIT();
  94 mike             1.2  }
  95                       
  96                       HTTPAuthenticatorDelegator::~HTTPAuthenticatorDelegator()
  97                       {
  98 kumpf            1.11     PEG_METHOD_ENTER(TRC_HTTP,
  99                               "HTTPAuthenticatorDelegator::~HTTPAuthenticatorDelegator");
 100                       
 101                           PEG_METHOD_EXIT();
 102 mike             1.2  }
 103                       
 104 kumpf            1.48 void HTTPAuthenticatorDelegator::enqueue(Message* message)
 105 kumpf            1.24 {
 106                           handleEnqueue(message);
 107                       }
 108                       
 109 mike             1.2  void HTTPAuthenticatorDelegator::_sendResponse(
 110                           Uint32 queueId,
 111 mike             1.54     Buffer& message,
 112 j.alex           1.52     Boolean closeConnect)
 113 mike             1.2  {
 114 kumpf            1.11     PEG_METHOD_ENTER(TRC_HTTP,
 115                               "HTTPAuthenticatorDelegator::_sendResponse");
 116                       
 117 mike             1.2      MessageQueue* queue = MessageQueue::lookup(queueId);
 118                       
 119                           if (queue)
 120                           {
 121                               HTTPMessage* httpMessage = new HTTPMessage(message);
 122 kumpf            1.68         httpMessage->dest = queue->getQueueId();
 123                       
 124 j.alex           1.52         httpMessage->setCloseConnect(closeConnect);
 125 kumpf            1.24 
 126 mike             1.2          queue->enqueue(httpMessage);
 127                           }
 128 kumpf            1.11 
 129                           PEG_METHOD_EXIT();
 130 mike             1.2  }
 131                       
 132 gerarda          1.22 #ifdef PEGASUS_KERBEROS_AUTHENTICATION
 133                       void HTTPAuthenticatorDelegator::_sendSuccess(
 134                           Uint32 queueId,
 135 j.alex           1.52     const String& authResponse,
 136                           Boolean closeConnect)
 137 gerarda          1.22 {
 138                           PEG_METHOD_ENTER(TRC_HTTP,
 139                               "HTTPAuthenticatorDelegator::_sendSuccess");
 140                       
 141                           //
 142                           // build OK (200) response message
 143                           //
 144                       
 145 mike             1.54     Buffer message;
 146 gerarda          1.22     XmlWriter::appendOKResponseHeader(message, authResponse);
 147                       
 148 j.alex           1.52     _sendResponse(queueId, message,closeConnect);
 149 gerarda          1.22 
 150                           PEG_METHOD_EXIT();
 151                       }
 152                       #endif
 153                       
 154 mike             1.2  void HTTPAuthenticatorDelegator::_sendChallenge(
 155                           Uint32 queueId,
 156 j.alex           1.52     const String& authResponse,
 157                           Boolean closeConnect)
 158 mike             1.2  {
 159 kumpf            1.11     PEG_METHOD_ENTER(TRC_HTTP,
 160                               "HTTPAuthenticatorDelegator::_sendChallenge");
 161                       
 162 mike             1.2      //
 163                           // build unauthorized (401) response message
 164                           //
 165                       
 166 mike             1.54     Buffer message;
 167 kumpf            1.7      XmlWriter::appendUnauthorizedResponseHeader(message, authResponse);
 168 mike             1.2  
 169 j.alex           1.52     _sendResponse(queueId, message,closeConnect);
 170 kumpf            1.11 
 171                           PEG_METHOD_EXIT();
 172 mike             1.2  }
 173                       
 174                       
 175 kumpf            1.30 void HTTPAuthenticatorDelegator::_sendHttpError(
 176 mike             1.2      Uint32 queueId,
 177 kumpf            1.30     const String& status,
 178                           const String& cimError,
 179 j.alex           1.52     const String& pegasusError,
 180                           Boolean closeConnect)
 181 mike             1.2  {
 182 kumpf            1.11     PEG_METHOD_ENTER(TRC_HTTP,
 183 kumpf            1.30         "HTTPAuthenticatorDelegator::_sendHttpError");
 184 kumpf            1.11 
 185 mike             1.2      //
 186 kumpf            1.11     // build error response message
 187 mike             1.2      //
 188                       
 189 mike             1.54     Buffer message;
 190 kumpf            1.30     message = XmlWriter::formatHttpErrorRspMessage(
 191                               status,
 192                               cimError,
 193                               pegasusError);
 194 mike             1.2  
 195 j.alex           1.52     _sendResponse(queueId, message,closeConnect);
 196 kumpf            1.11 
 197                           PEG_METHOD_EXIT();
 198 mike             1.2  }
 199                       
 200 mday             1.5  
 201                       void HTTPAuthenticatorDelegator::handleEnqueue(Message *message)
 202 mike             1.2  {
 203 kumpf            1.11     PEG_METHOD_ENTER(TRC_HTTP,
 204                               "HTTPAuthenticatorDelegator::handleEnqueue");
 205 mike             1.2  
 206 kumpf            1.11     if (!message)
 207                           {
 208                               PEG_METHOD_EXIT();
 209 mike             1.2          return;
 210 kumpf            1.11     }
 211 mike             1.2  
 212 kumpf            1.11     // Flag indicating whether the message should be deleted after handling.
 213                           // This should be set to false by handleHTTPMessage when the message is
 214                           // passed as is to another queue.
 215                           Boolean deleteMessage = true;
 216 kumpf            1.68 
 217 kumpf            1.93     try
 218 mike             1.2      {
 219 dmitry.mikulin   1.80         if (message->getType() == HTTP_MESSAGE)
 220                               {
 221                                   handleHTTPMessage((HTTPMessage*)message, deleteMessage);
 222                               }
 223                           }
 224                           catch (...)
 225                           {
 226                               if (deleteMessage)
 227                               {
 228 marek            1.86             PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL4,
 229 dmitry.mikulin   1.80                     "Exception caught, deleting Message in "
 230                                           "HTTPAuthenticator::handleEnqueue");
 231 kumpf            1.93 
 232 dmitry.mikulin   1.80             delete message;
 233                               }
 234                               throw;
 235 mike             1.2      }
 236                       
 237                           if (deleteMessage)
 238                           {
 239 marek            1.86         PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL4,
 240 j.alex           1.52                     "Deleting Message in HTTPAuthenticator::handleEnqueue");
 241                       
 242 mike             1.2          delete message;
 243                           }
 244 kumpf            1.11 
 245                           PEG_METHOD_EXIT();
 246 mday             1.5  }
 247                       
 248                       void HTTPAuthenticatorDelegator::handleEnqueue()
 249                       {
 250 kumpf            1.11     PEG_METHOD_ENTER(TRC_HTTP,
 251                               "HTTPAuthenticatorDelegator::handleEnqueue");
 252                       
 253 mday             1.5      Message* message = dequeue();
 254 kumpf            1.68     if (message)
 255 kumpf            1.82     {
 256                               handleEnqueue(message);
 257                           }
 258 kumpf            1.11 
 259                           PEG_METHOD_EXIT();
 260 mike             1.2  }
 261                       
 262                       void HTTPAuthenticatorDelegator::handleHTTPMessage(
 263                           HTTPMessage* httpMessage,
 264 kumpf            1.68     Boolean& deleteMessage)
 265                       {
 266 kumpf            1.11     PEG_METHOD_ENTER(TRC_HTTP,
 267                               "HTTPAuthenticatorDelegator::handleHTTPMessage");
 268                       
 269 kumpf            1.72     PEGASUS_ASSERT(httpMessage->message.size() != 0);
 270                       
 271 mike             1.2      deleteMessage = true;
 272                       
 273                           //
 274                           // Save queueId:
 275                           //
 276                           Uint32 queueId = httpMessage->queueId;
 277                       
 278                           //
 279                           // Parse the HTTP message:
 280                           //
 281                           String startLine;
 282                           Array<HTTPHeader> headers;
 283                           Uint32 contentLength;
 284 j.alex           1.52     Boolean closeConnect = false;
 285 mike             1.2  
 286 thilo.boehm      1.77     //
 287                           // Process M-POST and POST messages:
 288                           //
 289                       
 290 marek            1.84     PEG_TRACE_CSTRING(
 291                               TRC_HTTP,
 292 thilo.boehm      1.90         Tracer::LEVEL3,
 293 marek            1.84         "HTTPAuthenticatorDelegator - HTTP processing start");
 294 thilo.boehm      1.77 
 295 marek            1.98     // parse the received HTTPMessage
 296                           // parse function will return false if more than PEGASUS_MAXELEMENTS_NUM
 297                           // headers were detected in the message
 298                           if (!httpMessage->parse(startLine, headers, contentLength))
 299                           {
 300                               throw TooManyHTTPHeadersException();
 301                           }
 302 kumpf            1.68 
 303 j.alex           1.52     //
 304                           // Check for Connection: Close
 305                           //
 306 kumpf            1.94     const char* connectClose;
 307 kumpf            1.68     if (HTTPMessage::lookupHeader(
 308 kumpf            1.94             headers, _HTTP_HEADER_CONNECTION, connectClose, false))
 309 j.alex           1.52     {
 310 kumpf            1.94         if (System::strcasecmp(connectClose, "Close") == 0)
 311 kumpf            1.68         {
 312 marek            1.70             PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL3,
 313 kumpf            1.68                 "Header in HTTP Message Contains a Connection: Close");
 314 j.alex           1.52             closeConnect = true;
 315                                   httpMessage->setCloseConnect(closeConnect);
 316 kumpf            1.68         }
 317 j.alex           1.52     }
 318                       
 319 kumpf            1.35     //
 320 thilo.boehm      1.77     // Check and set languages
 321                           //
 322                           AcceptLanguageList acceptLanguages;
 323                           ContentLanguageList contentLanguages;
 324                           try
 325                           {
 326                               // Get and validate the Accept-Language header, if set
 327                               String acceptLanguageHeader;
 328                               if (HTTPMessage::lookupHeader(
 329                                       headers,
 330                                       _HTTP_HEADER_ACCEPT_LANGUAGE,
 331                                       acceptLanguageHeader,
 332                                       false))
 333                               {
 334                                   acceptLanguages = LanguageParser::parseAcceptLanguageHeader(
 335                                       acceptLanguageHeader);
 336                                   httpMessage->acceptLanguagesDecoded = true;
 337                               }
 338                       
 339                               // Get and validate the Content-Language header, if set
 340                               String contentLanguageHeader;
 341 thilo.boehm      1.77         if (HTTPMessage::lookupHeader(
 342                                       headers,
 343                                       _HTTP_HEADER_CONTENT_LANGUAGE,
 344                                       contentLanguageHeader,
 345                                       false))
 346                               {
 347                                   contentLanguages = LanguageParser::parseContentLanguageHeader(
 348                                       contentLanguageHeader);
 349                                   httpMessage->contentLanguagesDecoded = true;
 350                               }
 351                           }
 352                           catch (Exception& e)
 353                           {
 354                               // clear any existing languages to force messages to come from the
 355                               // root bundle
 356                               Thread::clearLanguages();
 357                               MessageLoaderParms msgParms(
 358                                   "Pegasus.Server.HTTPAuthenticatorDelegator.REQUEST_NOT_VALID",
 359                                   "request-not-valid");
 360                               String msg(MessageLoader::getMessage(msgParms));
 361                       
 362 thilo.boehm      1.77         _sendHttpError(
 363                                   queueId,
 364                                   HTTP_STATUS_BADREQUEST,
 365                                   msg,
 366                                   e.getMessage(),
 367                                   closeConnect);
 368                               PEG_METHOD_EXIT();
 369                               return;
 370                           }
 371                       
 372 kumpf            1.81     Thread::setLanguages(acceptLanguages);
 373 thilo.boehm      1.77     httpMessage->acceptLanguages = acceptLanguages;
 374                           httpMessage->contentLanguages = contentLanguages;
 375                       
 376                           //
 377                           // Parse the request line:
 378                           //
 379                           String methodName;
 380                           String requestUri;
 381                           String httpVersion;
 382                           HttpMethod httpMethod = HTTP_METHOD__POST;
 383                       
 384                           HTTPMessage::parseRequestLine(
 385                               startLine, methodName, requestUri, httpVersion);
 386                       
 387                           //
 388                           //  Set HTTP method for the request
 389                           //
 390                           if (methodName == _HTTP_METHOD_MPOST)
 391                           {
 392                               httpMethod = HTTP_METHOD_M_POST;
 393                           }
 394 thilo.boehm      1.77 
 395                           if (methodName != _HTTP_METHOD_MPOST && methodName != _HTTP_METHOD)
 396                           {
 397                               // Only POST and M-POST are implemented by this server
 398                               _sendHttpError(
 399                                   queueId,
 400                                   HTTP_STATUS_NOTIMPLEMENTED,
 401                                   String::EMPTY,
 402                                   String::EMPTY,
 403                                   closeConnect);
 404                               PEG_METHOD_EXIT();
 405                               return;
 406                           }
 407                       
 408                           if ((httpMethod == HTTP_METHOD_M_POST) &&
 409                                    (httpVersion == _HTTP_VERSION_1_0))
 410                           {
 411                               //
 412                               //  M-POST method is not valid with version 1.0
 413                               //
 414                               _sendHttpError(
 415 thilo.boehm      1.77             queueId,
 416                                   HTTP_STATUS_BADREQUEST,
 417                                   String::EMPTY,
 418                                   String::EMPTY,
 419                                   closeConnect);
 420                               PEG_METHOD_EXIT();
 421                               return;
 422                           }
 423                       
 424 marek            1.84     PEG_TRACE_CSTRING(
 425                               TRC_AUTHENTICATION,
 426 marek            1.86         Tracer::LEVEL3,
 427 marek            1.84         "HTTPAuthenticatorDelegator - Authentication processing start");
 428 thilo.boehm      1.77 
 429                           //
 430 h.sterling       1.34     // Handle authentication:
 431                           //
 432                           ConfigManager* configManager = ConfigManager::getInstance();
 433 kumpf            1.93     Boolean enableAuthentication =
 434 thilo.boehm      1.77         ConfigManager::parseBooleanValue(configManager->getCurrentValue(
 435                                   _CONFIG_PARAM_ENABLEAUTHENTICATION));
 436 sushma.fernandes 1.71 
 437 kumpf            1.93     Boolean isRequestAuthenticated =
 438 sushma.fernandes 1.71         httpMessage->authInfo->isConnectionAuthenticated();
 439 h.sterling       1.34 
 440 kumpf            1.68 #ifdef PEGASUS_KERBEROS_AUTHENTICATION
 441                           CIMKerberosSecurityAssociation* sa = NULL;
 442                           // The presence of a Security Association indicates that Kerberos is
 443                           // being used.
 444                           // Reset flag for subsequent calls to indicate that no Authorization
 445                           // record was sent. If one was sent the flag will be appropriately reset
 446                           // later.
 447                           // The sa is maintained while the connection is active.
 448                           sa = httpMessage->authInfo->getSecurityAssociation();
 449                           if (sa)
 450                           {
 451                               sa->setClientSentAuthorization(false);
 452                           }
 453                       #endif
 454 david            1.57 
 455 thilo.boehm      1.77     if (enableAuthentication)
 456 h.sterling       1.34     {
 457 thilo.boehm      1.77 
 458 kumpf            1.68 #ifdef PEGASUS_KERBEROS_AUTHENTICATION
 459                               // If we are using Kerberos (sa pointer is set), the client has
 460                               // already authenticated, and the client is NOT attempting to
 461                               // re-authenticate (dermined by an Authorization record being sent),
 462                               // then we want to set the local authenticate flag to true so that
 463                               // the authentication logic is skipped.
 464 kumpf            1.94         const char* authstr;
 465 david            1.57         if (sa && sa->getClientAuthenticated() &&
 466 kumpf            1.68             !HTTPMessage::lookupHeader(
 467                                        headers, "Authorization", authstr, false))
 468                               {
 469 sushma.fernandes 1.71             isRequestAuthenticated = true;
 470 kumpf            1.68         }
 471 david            1.57 #endif
 472 thilo.boehm      1.77         if (isRequestAuthenticated)
 473                               {
 474 kumpf            1.93             if (httpMessage->authInfo->getAuthType()==
 475 thilo.boehm      1.77                     AuthenticationInfoRep::AUTH_TYPE_SSL)
 476                                   {
 477 kumpf            1.82                 // Get the user name associated with the certificate (using the
 478                                       // certificate chain, if necessary).
 479 kumpf            1.63 
 480 kumpf            1.82                 String certUserName;
 481                                       String issuerName;
 482                                       String subjectName;
 483                                       char serialNumber[32];
 484 sushma.fernandes 1.76 
 485 kumpf            1.82                 PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL3,
 486                                           "Client was authenticated via trusted SSL certificate.");
 487 kumpf            1.68 
 488 kumpf            1.82                 String trustStore =
 489                                           configManager->getCurrentValue("sslTrustStore");
 490 h.sterling       1.59 
 491 kumpf            1.82                 if (FileSystem::isDirectory(
 492                                               ConfigManager::getHomedPath(trustStore)))
 493 h.sterling       1.59                 {
 494 kumpf            1.82                     PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL4,
 495                                               "Truststore is a directory, lookup username");
 496 kumpf            1.68 
 497 kumpf            1.82                     // Get the client certificate chain to determine the
 498                                           // correct username mapping.  Starting with the peer
 499                                           // certificate, work your way up the chain towards the
 500                                           // root certificate until a match is found in the
 501                                           // repository.
 502                                           Array<SSLCertificateInfo*> clientCertificateChain =
 503                                               httpMessage->authInfo->getClientCertificateChain();
 504                                           SSLCertificateInfo* clientCertificate = NULL;
 505 kumpf            1.68 
 506 kumpf            1.82                     PEG_TRACE((TRC_HTTP, Tracer::LEVEL4,
 507                                               "Client certificate chain length: %d.",
 508                                               clientCertificateChain.size()));
 509 kumpf            1.68 
 510 kumpf            1.82                     Uint32 loopCount = clientCertificateChain.size() - 1;
 511                                           for (Uint32 i = 0; i <= loopCount ; i++)
 512 kumpf            1.63                     {
 513 kumpf            1.82                         clientCertificate = clientCertificateChain[i];
 514                                               if (clientCertificate == NULL)
 515                                               {
 516                                                   MessageLoaderParms msgParms(
 517                                                       "Pegasus.Server.HTTPAuthenticatorDelegator."
 518                                                           "BAD_CERTIFICATE",
 519                                                       "The certificate used for authentication is "
 520                                                           "not valid.");
 521                                                   _sendHttpError(
 522                                                       queueId,
 523                                                       HTTP_STATUS_UNAUTHORIZED,
 524                                                       String::EMPTY,
 525                                                       MessageLoader::getMessage(msgParms),
 526                                                       closeConnect);
 527                                                   PEG_METHOD_EXIT();
 528                                                   return;
 529                                               }
 530 thilo.boehm      1.89                         PEG_TRACE((TRC_HTTP, Tracer::LEVEL4,
 531                                                   "Certificate toString %s",
 532                                                   (const char*)
 533                                                       clientCertificate->toString().getCString()));
 534 kumpf            1.82 
 535                                               // Get certificate properties
 536                                               issuerName = clientCertificate->getIssuerName();
 537                                               sprintf(serialNumber, "%lu",
 538 kumpf            1.87                             (unsigned long)
 539                                                       clientCertificate->getSerialNumber());
 540 kumpf            1.82                         subjectName = clientCertificate->getSubjectName();
 541                       
 542                                               //
 543                                               // The truststore type key property is deprecated. To
 544                                               // retain backward compatibility, add the truststore
 545                                               // type property to the key bindings and set it to
 546                                               // cimserver truststore.
 547                                               //
 548                       
 549                                               // Construct the corresponding PG_SSLCertificate
 550                                               // instance
 551                                               Array<CIMKeyBinding> keyBindings;
 552                                               keyBindings.append(CIMKeyBinding(
 553                                                   "IssuerName", issuerName, CIMKeyBinding::STRING));
 554                                               keyBindings.append(CIMKeyBinding(
 555                                                   "SerialNumber",
 556                                                   serialNumber,
 557                                                   CIMKeyBinding::STRING));
 558                                               keyBindings.append(CIMKeyBinding("TruststoreType",
 559                                                   PG_SSLCERTIFICATE_TSTYPE_VALUE_SERVER));
 560                       
 561 kumpf            1.82                         CIMObjectPath cimObjectPath(
 562                                                   "localhost",
 563                                                   PEGASUS_NAMESPACENAME_CERTIFICATE,
 564                                                   PEGASUS_CLASSNAME_CERTIFICATE,
 565                                                   keyBindings);
 566                       
 567 thilo.boehm      1.89                         PEG_TRACE((TRC_HTTP, Tracer::LEVEL4,
 568                                                   "Client Certificate COP: %s",
 569                                                   (const char*)
 570                                                       cimObjectPath.toString().getCString()));
 571 kumpf            1.82 
 572                                               CIMInstance cimInstance;
 573                                               CIMValue value;
 574                                               Uint32 pos;
 575                                               String userName;
 576                       
 577                                               // Attempt to get the username registered to the
 578                                               // certificate
 579                                               try
 580 h.sterling       1.59                         {
 581 kumpf            1.82                             cimInstance = _repository->getInstance(
 582                                                       PEGASUS_NAMESPACENAME_CERTIFICATE,
 583                                                       cimObjectPath);
 584                       
 585                                                   pos =
 586                                                       cimInstance.findProperty("RegisteredUserName");
 587                       
 588                                                   if (pos != PEG_NOT_FOUND &&
 589                                                       !(value = cimInstance.getProperty(pos).
 590                                                             getValue()).isNull())
 591                                                   {
 592                                                       value.get(userName);
 593 h.sterling       1.59 
 594 kumpf            1.82                                 //
 595                                                       // If a user name is specified, our search is
 596                                                       // complete
 597                                                       //
 598                                                       if (userName.size())
 599                                                       {
 600 thilo.boehm      1.89                                     PEG_TRACE((TRC_HTTP, Tracer::LEVEL3,
 601                                                               "User name for certificate is %s",
 602                                                               (const char*)userName.getCString()));
 603 kumpf            1.82                                     certUserName = userName;
 604                                                           break;
 605                                                       }
 606                       
 607                                                       // No user name is specified; continue up the
 608                                                       // chain
 609                                                       PEG_TRACE((TRC_HTTP, Tracer::LEVEL4,
 610                                                           "The certificate at level %u has no "
 611                                                               "associated username; moving up the "
 612                                                               "chain",
 613                                                           i));
 614                                                   }
 615                                                   else
 616 kumpf            1.63                             {
 617 marek            1.84                                 PEG_TRACE_CSTRING(
 618                                                           TRC_HTTP,
 619                                                           Tracer::LEVEL3,
 620 kumpf            1.82                                     "HTTPAuthenticatorDelegator - Bailing, no "
 621                                                               "username is registered to this "
 622                                                               "certificate.");
 623 kumpf            1.63                             }
 624 kumpf            1.68                         }
 625 kumpf            1.82                         catch (CIMException& e)
 626 h.sterling       1.59                         {
 627 kumpf            1.82                             // this certificate did not have a registration
 628                                                   // associated with it; continue up the chain
 629                                                   if (e.getCode() == CIM_ERR_NOT_FOUND)
 630                                                   {
 631                                                       PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL4,
 632                                                           "No registration for this certificate; "
 633                                                               "try next certificate in chain");
 634                                                       continue;
 635                                                   }
 636                                                   else
 637                                                   {
 638 harsha.bm        1.97                                 PEG_TRACE((TRC_HTTP,Tracer::LEVEL1,
 639                                                           "HTTPAuthenticatorDelegator- Bailing,the "
 640                                                               "certificate used for authentication "
 641                                                               "is not valid for client IP address "
 642                                                               "%s.",
 643                                                           (const char*)
 644                                                               httpMessage->ipAddress.getCString())
 645                                                           );
 646 marek            1.84 
 647 kumpf            1.82                                 MessageLoaderParms msgParms(
 648                                                           "Pegasus.Server.HTTPAuthenticatorDelegator."
 649                                                               "BAD_CERTIFICATE",
 650                                                           "The certificate used for authentication "
 651                                                               "is not valid.");
 652                                                       String msg(MessageLoader::getMessage(msgParms));
 653                                                       _sendHttpError(
 654                                                           queueId,
 655                                                           HTTP_STATUS_UNAUTHORIZED,
 656                                                           String::EMPTY,
 657                                                           msg,
 658                                                           closeConnect);
 659                                                       PEG_METHOD_EXIT();
 660                                                       return;
 661                                                   }
 662 kumpf            1.68                         }
 663 kumpf            1.82                         catch (...)
 664 h.sterling       1.59                         {
 665 kumpf            1.82                             // This scenario can occur if a certificate cached
 666                                                   // on the server was deleted openssl would not pick
 667                                                   // up the deletion but we would pick it up here
 668                                                   // when we went to look it up in the repository
 669 marek            1.84 
 670 harsha.bm        1.97                             PEG_TRACE((TRC_HTTP,Tracer::LEVEL1,
 671                                                       "HTTPAuthenticatorDelegator- Bailing,the "
 672 kumpf            1.82                                     "certificate used for authentication is "
 673 harsha.bm        1.97                                     "not valid for client IP address %s.",
 674                                                       (const char*)
 675                                                           httpMessage->ipAddress.getCString()));
 676                                                   
 677 kumpf            1.68                             MessageLoaderParms msgParms(
 678                                                       "Pegasus.Server.HTTPAuthenticatorDelegator."
 679                                                           "BAD_CERTIFICATE",
 680                                                       "The certificate used for authentication is "
 681                                                           "not valid.");
 682 kumpf            1.63                             String msg(MessageLoader::getMessage(msgParms));
 683 kumpf            1.68                             _sendHttpError(
 684                                                       queueId,
 685                                                       HTTP_STATUS_UNAUTHORIZED,
 686                                                       String::EMPTY,
 687                                                       msg,
 688                                                       closeConnect);
 689 kumpf            1.63                             PEG_METHOD_EXIT();
 690                                                   return;
 691 h.sterling       1.59                         }
 692 kumpf            1.82                     } //end for clientcertificatechain
 693                                       } //end sslTrustStore directory
 694                                       else
 695                                       {
 696                                           // trustStore is a single CA file, lookup username
 697                                           // user was already verified as a valid system user during
 698                                           // server startup
 699                                           certUserName =
 700                                               configManager->getCurrentValue("sslTrustStoreUserName");
 701                                       }
 702                       
 703                                       //
 704                                       // Validate user information
 705                                       //
 706 kumpf            1.63 
 707 kumpf            1.82                 if (certUserName == String::EMPTY)
 708                                       {
 709 harsha.bm        1.97                     PEG_TRACE((TRC_HTTP,Tracer::LEVEL1,
 710                                               "HTTPAuthenticatorDelegator-No username is registered "
 711                                                   "to this certificate for client IP address %s.",
 712                                               (const char*)httpMessage->ipAddress.getCString()));
 713                       
 714 kumpf            1.82                     MessageLoaderParms msgParms(
 715                                               "Pegasus.Server.HTTPAuthenticatorDelegator."
 716                                                   "BAD_CERTIFICATE_USERNAME",
 717                                               "No username is registered to this certificate.");
 718                                           _sendHttpError(
 719                                               queueId,
 720                                               HTTP_STATUS_UNAUTHORIZED,
 721                                               String::EMPTY,
 722                                               MessageLoader::getMessage(msgParms),
 723                                               closeConnect);
 724                                           PEG_METHOD_EXIT();
 725                                           return;
 726                                       }
 727 kumpf            1.63 
 728 kumpf            1.82                 if (!_authenticationManager->validateUserForHttpAuth(
 729                                               certUserName))
 730                                       {
 731                                           PEG_AUDIT_LOG(logCertificateBasedUserValidation(
 732                                               certUserName,
 733                                               issuerName,
 734                                               subjectName,
 735                                               serialNumber,
 736                                               httpMessage->ipAddress,
 737                                               false));
 738                                           MessageLoaderParms msgParms(
 739                                               "Pegasus.Server.HTTPAuthenticatorDelegator."
 740                                                   "CERTIFICATE_USER_NOT_VALID",
 741                                               "User '$0' registered to this certificate is not a "
 742                                                   "valid user.",
 743                                               certUserName);
 744                                           _sendHttpError(
 745                                               queueId,
 746                                               HTTP_STATUS_UNAUTHORIZED,
 747                                               String::EMPTY,
 748                                               MessageLoader::getMessage(msgParms),
 749 kumpf            1.82                         closeConnect);
 750                                           PEG_METHOD_EXIT();
 751                                           return;
 752                                       }
 753 sushma.fernandes 1.69 
 754 sushma.fernandes 1.76                 PEG_AUDIT_LOG(logCertificateBasedUserValidation(
 755                                           certUserName,
 756                                           issuerName,
 757                                           subjectName,
 758                                           serialNumber,
 759                                           httpMessage->ipAddress,
 760 kumpf            1.82                     true));
 761                       
 762                                       httpMessage->authInfo->setAuthenticatedUser(certUserName);
 763 h.sterling       1.44 
 764 marek            1.84                 PEG_TRACE((
 765 kumpf            1.82                     TRC_HTTP,
 766 marek            1.86                     Tracer::LEVEL4,
 767 kumpf            1.82                     "HTTPAuthenticatorDelegator - The trusted client "
 768 marek            1.84                         "certificate is registered to %s.",
 769                                           (const char*) certUserName.getCString()));
 770 thilo.boehm      1.77             } // end AuthenticationInfoRep::AUTH_TYPE_SSL
 771                       
 772                       #ifdef PEGASUS_OS_ZOS
 773 kumpf            1.93             if (httpMessage->authInfo->getAuthType()==
 774 thilo.boehm      1.77                     AuthenticationInfoRep::AUTH_TYPE_ZOS_ATTLS)
 775                                   {
 776 kumpf            1.93                 String connectionUserName =
 777 thilo.boehm      1.77                     httpMessage->authInfo->getConnectionUser();
 778                       
 779 kumpf            1.93                 // If authenticated user not the connected user
 780 thilo.boehm      1.77                 // then check CIMSERV profile.
 781                                       if (!String::equalNoCase(connectionUserName,
 782                                               httpMessage->authInfo->getAuthenticatedUser()))
 783                                       {
 784 h.sterling       1.43 
 785 thilo.boehm      1.77 #ifdef PEGASUS_ZOS_SECURITY
 786 kumpf            1.93                    if ( !CheckProfileCIMSERVclassWBEM(connectionUserName,
 787 thilo.boehm      1.77                              __READ_RESOURCE))
 788                                          {
 789 kumpf            1.93                        Logger::put_l(Logger::STANDARD_LOG, ZOS_SECURITY_NAME,
 790 thilo.boehm      1.77                            Logger::WARNING,
 791 kumpf            1.88                            MessageLoaderParms(
 792                                                      "Pegasus.Server.HTTPAuthenticatorDelegator."
 793                                                          "ATTLS_NOREAD_CIMSERV_ACCESS.PEGASUS_OS_ZOS",
 794                                                      "Request UserID $0 doesn't have READ permission"
 795                                                      " to profile CIMSERV CL(WBEM).",
 796                                                      connectionUserName));
 797 thilo.boehm      1.77 
 798 thilo.boehm      1.78                        PEG_AUDIT_LOG(logCertificateBasedUserValidation(
 799 kumpf            1.82                            connectionUserName,
 800                                                  String::EMPTY,
 801                                                  String::EMPTY,
 802                                                  String::EMPTY,
 803                                                  httpMessage->ipAddress,
 804                                                  false));
 805 thilo.boehm      1.78 
 806 thilo.boehm      1.77                        _sendHttpError(
 807                                                  queueId,
 808                                                  HTTP_STATUS_UNAUTHORIZED,
 809                                                  String::EMPTY,
 810                                                  String::EMPTY,
 811                                                  closeConnect);
 812                       
 813                                              PEG_METHOD_EXIT();
 814                                              return;
 815                                          }
 816                       #endif
 817                                          PEG_TRACE((TRC_HTTP, Tracer::LEVEL4,
 818 kumpf            1.82                        "Client UserID '%s' was authenticated via AT-TLS.",
 819 thilo.boehm      1.77                        (const char*)connectionUserName.getCString()));
 820                       
 821                                          httpMessage->authInfo->setAuthenticatedUser(
 822                                              connectionUserName);
 823                       
 824 kumpf            1.93                    // For audit loging, only the mapping of the client IP to
 825 thilo.boehm      1.77                    // the resolved user ID is from interest.
 826 kumpf            1.93                    // The SAF facility logs the certificate validation and
 827 thilo.boehm      1.77                    // the mapping of certificate subject to a local userID.
 828                                          PEG_AUDIT_LOG(logCertificateBasedUserValidation(
 829                                                           connectionUserName,
 830                                                           String::EMPTY,
 831                                                           String::EMPTY,
 832                                                           String::EMPTY,
 833                                                           httpMessage->ipAddress,
 834                                                           true));
 835 h.sterling       1.43 
 836 thilo.boehm      1.77                 }// end is authenticated ?
 837 h.sterling       1.34 
 838 thilo.boehm      1.77             } // end AuthenticationInfoRep::AUTH_TYPE_ZOS_ATTLS
 839 humberto         1.33 
 840 kumpf            1.93             if (httpMessage->authInfo->getAuthType()==
 841 thilo.boehm      1.77                     AuthenticationInfoRep::AUTH_TYPE_ZOS_LOCAL_DOMIAN_SOCKET)
 842                                   {
 843 kumpf            1.93                 String connectionUserName =
 844 thilo.boehm      1.77                     httpMessage->authInfo->getConnectionUser();
 845 kumpf            1.68 
 846 kumpf            1.93                 String requestUserName;
 847 thilo.boehm      1.77                 String authHeader;
 848                                       String authHttpType;
 849                                       String cookie;
 850                       
 851 kumpf            1.93                 // if lookupHeader() is not successfull parseLocalAuthHeader()
 852 thilo.boehm      1.77                 // must not be called !!
 853                                       if ( HTTPMessage::lookupHeader(headers,
 854                                               _HTTP_HEADER_PEGASUSAUTHORIZATION, authHeader, false)&&
 855                                            HTTPMessage::parseLocalAuthHeader(authHeader,
 856                                                authHttpType, requestUserName, cookie))
 857                                       {
 858                                           String cimServerUserName = System::getEffectiveUserName();
 859 humberto         1.33 
 860 thilo.boehm      1.77                     PEG_TRACE((TRC_HTTP, Tracer::LEVEL4,
 861                                                      "CIM server UserID = '%s', "
 862                                                      "Request UserID = '%s', "
 863                                                      "Local authenticated UserID = '%s'.",
 864                                                      (const char*) cimServerUserName.getCString(),
 865                                                      (const char*) requestUserName.getCString(),
 866                                                      (const char*) connectionUserName.getCString()
 867                                                    ));
 868                       
 869 kumpf            1.93                     // if the request name and the user connected to the socket
 870                                           // are the same, or if the currnet user running the
 871 thilo.boehm      1.77                     // cim server and the connected user are the same then
 872                                           // assign the request user id as authenticated user id.
 873                                           if( String::equalNoCase(
 874 kumpf            1.93                             requestUserName,connectionUserName) ||
 875 thilo.boehm      1.77                         String::equalNoCase(
 876                                                   cimServerUserName,connectionUserName))
 877                                           {
 878                                               // If the designate new authenticated user, the user of
 879 kumpf            1.93                         // the request, is not already the authenticated user
 880 thilo.boehm      1.77                         // then set the authenticated user and check CIMSERV.
 881                                               if (!String::equalNoCase(requestUserName,
 882                                                    httpMessage->authInfo->getAuthenticatedUser()))
 883                                               {
 884 mike             1.2  
 885 thilo.boehm      1.77 #ifdef PEGASUS_ZOS_SECURITY
 886 kumpf            1.93                            if ( !CheckProfileCIMSERVclassWBEM(requestUserName,
 887 thilo.boehm      1.77                                      __READ_RESOURCE))
 888                                                  {
 889 kumpf            1.93                                Logger::put_l(Logger::STANDARD_LOG,
 890                                                          ZOS_SECURITY_NAME,
 891 thilo.boehm      1.77                                    Logger::WARNING,
 892 kumpf            1.88                                    MessageLoaderParms(
 893 thilo.boehm      1.77                                    "Pegasus.Server.HTTPAuthenticatorDelegator."
 894                                                              "UNIXSOCKET_NOREAD_CIMSERV_ACCESS."
 895                                                              "PEGASUS_OS_ZOS",
 896                                                          "Request UserID $0 doesn't have READ "
 897                                                              "permission to profile "
 898                                                              "CIMSERV CL(WBEM).",
 899 kumpf            1.88                                    requestUserName));
 900 thilo.boehm      1.77 
 901                                                      _sendHttpError(
 902                                                          queueId,
 903                                                          HTTP_STATUS_UNAUTHORIZED,
 904                                                          String::EMPTY,
 905                                                          String::EMPTY,
 906                                                          closeConnect);
 907                       
 908                                                      PEG_METHOD_EXIT();
 909 kumpf            1.82                                return;
 910 thilo.boehm      1.77                            }
 911                       #endif
 912 kumpf            1.93                            // It is not necessary to check remote privileged
 913                                                  // user access for local connections;
 914 thilo.boehm      1.79                            // set the flag to "check done"
 915                                                  httpMessage->authInfo->
 916                                                      setRemotePrivilegedUserAccessChecked();
 917                       
 918 thilo.boehm      1.77                            httpMessage->authInfo->setAuthenticatedUser(
 919                                                      requestUserName);
 920 mike             1.2  
 921 thilo.boehm      1.77                            PEG_TRACE((TRC_HTTP, Tracer::LEVEL4,
 922                                                       "New authenticated User = '%s'.",
 923                                                       (const char*)requestUserName.getCString()
 924                                                       ));
 925                       
 926                                               } // end changed authenticated user
 927                       
 928                                           PEG_TRACE((TRC_HTTP, Tracer::LEVEL4,
 929                                                "User authenticated for request = '%s'.",
 930                                                (const char*)httpMessage->authInfo->
 931                                                      getAuthenticatedUser().getCString()
 932                                                ));
 933 thilo.boehm      1.78 
 934                                               // Write local authentication audit record.
 935                                               PEG_AUDIT_LOG(logLocalAuthentication(
 936                                                    requestUserName,true));
 937                       
 938                                           } // end select authenticated user
 939                                           else
 940                                           {
 941                                               PEG_AUDIT_LOG(logLocalAuthentication(
 942                                                    requestUserName,false));
 943                       
 944                                               PEG_TRACE((TRC_HTTP, Tracer::LEVEL4,
 945                                                    "User '%s' not authorized for request",
 946                                                    (const char*)requestUserName.getCString()));
 947                       
 948                                               _sendHttpError(
 949                                                   queueId,
 950                                                   HTTP_STATUS_UNAUTHORIZED,
 951                                                   String::EMPTY,
 952                                                   String::EMPTY,
 953                                                   closeConnect);
 954 thilo.boehm      1.78 
 955                                               PEG_METHOD_EXIT();
 956                                               return;
 957                                           }
 958 thilo.boehm      1.77                 } // end lookup header
 959                                       else
 960 kumpf            1.93                 {
 961 thilo.boehm      1.77                     MessageLoaderParms msgParms(
 962                                               "Pegasus.Server.HTTPAuthenticatorDelegator."
 963                                                   "AUTHORIZATION_HEADER_ERROR",
 964                                               "Authorization header error");
 965                                           String msg(MessageLoader::getMessage(msgParms));
 966                                           _sendHttpError(
 967                                               queueId,
 968                                               HTTP_STATUS_BADREQUEST,
 969                                               String::EMPTY,
 970                                               msg,
 971                                               closeConnect);
 972 kumpf            1.19 
 973 thilo.boehm      1.77                     PEG_METHOD_EXIT();
 974                                           return;
 975                                       }
 976                                   } // end AuthenticationInfoRep::AUTH_TYPE_ZOS_LOCAL_DOMIAN_SOCKET
 977                       #endif
 978                               } // end isRequestAuthenticated
 979 kumpf            1.82         else
 980 thilo.boehm      1.77         { // !isRequestAuthenticated
 981 mike             1.56 
 982 thilo.boehm      1.77             String authorization;
 983 mike             1.2  
 984 kumpf            1.68             //
 985 thilo.boehm      1.77             // do Local/Pegasus authenticatio
 986 kumpf            1.68             //
 987                                   if (HTTPMessage::lookupHeader(headers,
 988 thilo.boehm      1.77                     _HTTP_HEADER_PEGASUSAUTHORIZATION, authorization, false))
 989 kumpf            1.28             {
 990 kumpf            1.68                 try
 991                                       {
 992                                           //
 993                                           // Do pegasus/local authentication
 994                                           //
 995 sushma.fernandes 1.71                     isRequestAuthenticated =
 996 kumpf            1.68                         _authenticationManager->performPegasusAuthentication(
 997                                                   authorization,
 998                                                   httpMessage->authInfo);
 999 mike             1.2  
1000 sushma.fernandes 1.71                     if (!isRequestAuthenticated)
1001 kumpf            1.68                     {
1002                                               String authChallenge;
1003                                               String authResp;
1004 mike             1.2  
1005 kumpf            1.68                         authResp = _authenticationManager->
1006                                                   getPegasusAuthResponseHeader(
1007                                                       authorization,
1008                                                       httpMessage->authInfo);
1009 kumpf            1.28 
1010 kumpf            1.68                         if (!String::equal(authResp, String::EMPTY))
1011                                               {
1012                                                   _sendChallenge(queueId, authResp,closeConnect);
1013                                               }
1014                                               else
1015                                               {
1016                                                   MessageLoaderParms msgParms(
1017                                                       "Pegasus.Server.HTTPAuthenticatorDelegator."
1018                                                           "AUTHORIZATION_HEADER_ERROR",
1019                                                       "Authorization header error");
1020                                                   String msg(MessageLoader::getMessage(msgParms));
1021                                                   _sendHttpError(
1022                                                       queueId,
1023                                                       HTTP_STATUS_BADREQUEST,
1024                                                       String::EMPTY,
1025                                                       msg,
1026                                                       closeConnect);
1027                                               }
1028                       
1029                                               PEG_METHOD_EXIT();
1030                                               return;
1031 kumpf            1.28                     }
1032 kumpf            1.68                 }
1033                                       catch (const CannotOpenFile&)
1034                                       {
1035                                           _sendHttpError(
1036                                               queueId,
1037                                               HTTP_STATUS_INTERNALSERVERERROR,
1038                                               String::EMPTY,
1039                                               String::EMPTY,
1040                                               closeConnect);
1041 kumpf            1.28                     PEG_METHOD_EXIT();
1042                                           return;
1043 mike             1.2                  }
1044 thilo.boehm      1.77             } // end PEGASUS/LOCAL authentication
1045 mike             1.2  
1046 thilo.boehm      1.77             //
1047                                   // do HTTP authentication
1048                                   //
1049 kumpf            1.68             if (HTTPMessage::lookupHeader(
1050 kumpf            1.93                     headers, _HTTP_HEADER_AUTHORIZATION,
1051                                           authorization, false))
1052 mike             1.2              {
1053 kumpf            1.82                 isRequestAuthenticated =
1054                                           _authenticationManager->performHttpAuthentication(
1055                                               authorization,
1056                                               httpMessage->authInfo);
1057 kumpf            1.68 
1058 kumpf            1.82                 if (!isRequestAuthenticated)
1059                                       {
1060                                           //ATTN: the number of challenges get sent for a
1061                                           //      request on a connection can be pre-set.
1062 gerarda          1.22 #ifdef PEGASUS_KERBEROS_AUTHENTICATION
1063 kumpf            1.82                     // Kerberos authentication needs access to the
1064                                           // AuthenticationInfo object for this session in
1065                                           // order to set up the reference to the
1066                                           // CIMKerberosSecurityAssociation object for this
1067                                           // session.
1068 kumpf            1.68 
1069 kumpf            1.82                     String authResp =
1070                                               _authenticationManager->getHttpAuthResponseHeader(
1071                                                   httpMessage->authInfo);
1072 gerarda          1.22 #else
1073 kumpf            1.82                     String authResp =
1074                                               _authenticationManager->getHttpAuthResponseHeader();
1075 gerarda          1.22 #endif
1076 kumpf            1.82                     if (!String::equal(authResp, String::EMPTY))
1077                                           {
1078                                               _sendChallenge(queueId, authResp, closeConnect);
1079                                           }
1080                                           else
1081                                           {
1082                                               MessageLoaderParms msgParms(
1083                                                   "Pegasus.Server.HTTPAuthenticatorDelegator."
1084                                                       "AUTHORIZATION_HEADER_ERROR",
1085                                                   "Authorization header error");
1086                                               String msg(MessageLoader::getMessage(msgParms));
1087                                               _sendHttpError(
1088                                                   queueId,
1089                                                   HTTP_STATUS_BADREQUEST,
1090                                                   String::EMPTY,
1091                                                   msg,
1092                                                   closeConnect);
1093                                           }
1094 kumpf            1.68 
1095 kumpf            1.82                     PEG_METHOD_EXIT();
1096                                           return;
1097                                       }
1098 kumpf            1.93             }  // End if HTTP Authorization
1099 thilo.boehm      1.77 
1100                               } //end if (!isRequestAuthenticated)
1101                       
1102                           } //end enableAuthentication
1103                       
1104 marek            1.84     PEG_TRACE_CSTRING(
1105                               TRC_AUTHENTICATION,
1106 marek            1.86         Tracer::LEVEL3,
1107 marek            1.84         "HTTPAuthenticatorDelegator - Authentication processing ended");
1108 thilo.boehm      1.77 
1109 kumpf            1.68 
1110                       #ifdef PEGASUS_KERBEROS_AUTHENTICATION
1111 thilo.boehm      1.77     // The pointer to the sa is created in the authenticator so we need
1112                           // to also assign it here.
1113                           sa = httpMessage->authInfo->getSecurityAssociation();
1114                           if (sa)
1115                           {
1116                               // 0 - continue, 1 = send success, 2 = send response
1117                               Uint32 sendAction = 0;
1118                       
1119                               // The following is processing to unwrap (decrypt) the request
1120                               // from the client when using kerberos authentication.
1121                               sa->unwrapRequestMessage(
1122 kumpf            1.93             httpMessage->message,
1123                                   contentLength,
1124                                   isRequestAuthenticated,
1125 thilo.boehm      1.77             sendAction);
1126 kumpf            1.68 
1127 thilo.boehm      1.77         if (sendAction)  // send success or send response
1128                               {
1129                                   if (httpMessage->message.size() == 0)
1130 kumpf            1.68             {
1131 thilo.boehm      1.77                 MessageLoaderParms msgParms(
1132                                           "Pegasus.Server.HTTPAuthenticatorDelegator."
1133                                               "AUTHORIZATION_HEADER_ERROR",
1134                                           "Authorization header error");
1135                                       String msg(MessageLoader::getMessage(msgParms));
1136                                       _sendHttpError(
1137                                           queueId,
1138                                           HTTP_STATUS_BADREQUEST,
1139                                           String::EMPTY,
1140                                           msg,
1141                                           closeConnect);
1142                                   }
1143                                   else
1144                                   {
1145                                       if (sendAction == 1)  // Send success
1146 kumpf            1.68                 {
1147 thilo.boehm      1.77                     _sendSuccess(
1148 kumpf            1.68                         queueId,
1149 thilo.boehm      1.77                         String(
1150                                                   httpMessage->message.getData(),
1151                                                   httpMessage->message.size()),
1152 kumpf            1.68                         closeConnect);
1153                                       }
1154 thilo.boehm      1.77 
1155                                       if (sendAction == 2)  // Send response
1156 kumpf            1.68                 {
1157 thilo.boehm      1.77                     _sendResponse(
1158                                               queueId,
1159                                               httpMessage->message,
1160                                               closeConnect);
1161                                       }
1162                                   }
1163 mike             1.2  
1164 thilo.boehm      1.77             PEG_METHOD_EXIT();
1165                                   return;
1166                               }
1167                           }
1168                       #endif
1169 gerarda          1.26 
1170 thilo.boehm      1.77     if (isRequestAuthenticated || !enableAuthentication)
1171                           {
1172                               // Final bastion to ensure the remote privileged user access
1173                               // check is done as it should be
1174                               // check for remote privileged User Access
1175                               if (!httpMessage->authInfo->getRemotePrivilegedUserAccessChecked())
1176                               {
1177                                   // the AuthenticationHandler did not process the
1178                                   // enableRemotePrivilegedUserAccess check
1179                                   // time to do it ourselves
1180                                   String userName = httpMessage->authInfo->getAuthenticatedUser();
1181                                   if (!AuthenticationManager::isRemotePrivilegedUserAccessAllowed(
1182                                           userName))
1183                                   {
1184                                       // Send client a message that we can't proceed to talk
1185                                       // to him
1186                                       // HTTP 401 ?
1187                                       MessageLoaderParms msgParms(
1188                                           "Server.CIMOperationRequestAuthorizer."
1189                                               "REMOTE_NOT_ENABLED",
1190                                           "Remote privileged user access is not enabled.");
1191 thilo.boehm      1.77                 String msg(MessageLoader::getMessage(msgParms));
1192                                       _sendHttpError(
1193                                           queueId,
1194                                           HTTP_STATUS_UNAUTHORIZED,
1195                                           String::EMPTY,
1196                                           msg,
1197                                           closeConnect);
1198 kumpf            1.68                 PEG_METHOD_EXIT();
1199                                       return;
1200                                   }
1201 thilo.boehm      1.77             httpMessage->authInfo->setRemotePrivilegedUserAccessChecked();
1202 kumpf            1.68         }
1203 h.sterling       1.34 
1204 thilo.boehm      1.77         //
1205 kumpf            1.83         // Determine the type of this request:
1206 thilo.boehm      1.77         //
1207 kumpf            1.83         //   - A "CIMOperation" header indicates a CIM operation request
1208                               //   - A "CIMExport" header indicates a CIM export request
1209                               //   - A "/wsman" path in the start message indicates a WS-Man request
1210                               //
1211                       
1212 kumpf            1.94         const char* cimOperation;
1213 thilo.boehm      1.77 
1214                               if (HTTPMessage::lookupHeader(
1215 kumpf            1.94                 headers, _HTTP_HEADER_CIMOPERATION, cimOperation, true))
1216 mike             1.2          {
1217 marek            1.84             PEG_TRACE((
1218                                       TRC_HTTP,
1219                                       Tracer::LEVEL3,
1220 kumpf            1.94                 "HTTPAuthenticatorDelegator - CIMOperation: %s",
1221                                       cimOperation));
1222 thilo.boehm      1.77 
1223                                   MessageQueue* queue =
1224 kumpf            1.83                 MessageQueue::lookup(_cimOperationMessageQueueId);
1225 thilo.boehm      1.77 
1226                                   if (queue)
1227                                   {
1228                                       httpMessage->dest = queue->getQueueId();
1229                       
1230                                       try
1231                                       {
1232                                           queue->enqueue(httpMessage);
1233                                       }
1234                                       catch (const bad_alloc&)
1235 marek            1.67                 {
1236 thilo.boehm      1.77                     delete httpMessage;
1237 venkat.puvvada   1.96                     HTTPConnection *httpQueue =
1238                                               dynamic_cast<HTTPConnection*>(
1239                                                    MessageQueue::lookup(queueId));
1240                                           if (httpQueue)
1241                                           {
1242                                               httpQueue->handleInternalServerError(0, true);
1243                                           }
1244 marek            1.67                     PEG_METHOD_EXIT();
1245 thilo.boehm      1.77                     deleteMessage = false;
1246 marek            1.67                     return;
1247                                       }
1248 thilo.boehm      1.77                 deleteMessage = false;
1249 marek            1.67             }
1250 thilo.boehm      1.77         }
1251                               else if (HTTPMessage::lookupHeader(
1252 kumpf            1.94                      headers, _HTTP_HEADER_CIMEXPORT, cimOperation, true))
1253 thilo.boehm      1.77         {
1254 marek            1.84             PEG_TRACE((
1255                                       TRC_AUTHENTICATION,
1256                                       Tracer::LEVEL3,
1257 kumpf            1.94                 "HTTPAuthenticatorDelegator - CIMExport: %s",
1258                                       cimOperation));
1259 marek            1.67 
1260 thilo.boehm      1.77             MessageQueue* queue =
1261 kumpf            1.83                 MessageQueue::lookup(_cimExportMessageQueueId);
1262 mike             1.2  
1263 thilo.boehm      1.77             if (queue)
1264 mike             1.2              {
1265 thilo.boehm      1.77                 httpMessage->dest = queue->getQueueId();
1266 mike             1.2  
1267 thilo.boehm      1.77                 queue->enqueue(httpMessage);
1268                                       deleteMessage = false;
1269 mike             1.2              }
1270 thilo.boehm      1.77         }
1271 kumpf            1.83         else if ((_wsmanOperationMessageQueueId != PEG_NOT_FOUND) &&
1272                                        ((requestUri == "/wsman") ||
1273                                         ((requestUri == "/wsman-anon") && !enableAuthentication)))
1274                               {
1275                                   // Note: DSP0226 R5.3-1 specifies if /wsman is used,
1276                                   // unauthenticated access should not be allowed.  This "should"
1277                                   // requirement is not implemented here, because it is difficult
1278                                   // for a client to determine whether enableAuthentication=true.
1279                       
1280                                   // DSP0226 R5.3-2 specifies if /wsman-anon is used, authenticated
1281                                   // access shall not be required.  Unauthenticated access is
1282                                   // currently not allowed if enableAuthentication=true.  When
1283                                   // support for wsmid:Identify is added, it will be necessary to
1284                                   // respond to that request without requiring authentication,
1285                                   // regardless of the CIM Server configuration.
1286                       
1287                                   MessageQueue* queue =
1288                                       MessageQueue::lookup(_wsmanOperationMessageQueueId);
1289                       
1290                                   if (queue)
1291                                   {
1292 kumpf            1.83                 httpMessage->dest = queue->getQueueId();
1293                       
1294                                       try
1295                                       {
1296                                           queue->enqueue(httpMessage);
1297                                       }
1298                                       catch (const bad_alloc&)
1299                                       {
1300                                           delete httpMessage;
1301 venkat.puvvada   1.96                     HTTPConnection *httpQueue =
1302                                               dynamic_cast<HTTPConnection*>(
1303                                                    MessageQueue::lookup(queueId));
1304                                           if (httpQueue)
1305                                           {
1306                                               httpQueue->handleInternalServerError(0, true);
1307                                           }
1308 kumpf            1.83                     PEG_METHOD_EXIT();
1309                                           deleteMessage = false;
1310                                           return;
1311                                       }
1312                                       deleteMessage = false;
1313                                   }
1314                               }
1315 thilo.boehm      1.77         else
1316                               {
1317                                   // We don't recognize this request message type
1318 david            1.21 
1319 thilo.boehm      1.77             // The Specification for CIM Operations over HTTP reads:
1320                                   //
1321                                   //     3.3.4. CIMOperation
1322                                   //
1323                                   //     If a CIM Server receives a CIM Operation request without
1324                                   //     this [CIMOperation] header, it MUST NOT process it as if
1325                                   //     it were a CIM Operation Request.  The status code
1326                                   //     returned by the CIM Server in response to such a request
1327                                   //     is outside of the scope of this specification.
1328                                   //
1329                                   //     3.3.5. CIMExport
1330                                   //
1331                                   //     If a CIM Listener receives a CIM Export request without
1332                                   //     this [CIMExport] header, it MUST NOT process it.  The
1333                                   //     status code returned by the CIM Listener in response to
1334                                   //     such a request is outside of the scope of this
1335                                   //     specification.
1336                                   //
1337                                   // The author has chosen to send a 400 Bad Request error, but
1338                                   // without the CIMError header since this request must not be
1339                                   // processed as a CIM request.
1340 thilo.boehm      1.77 
1341                                   _sendHttpError(
1342                                       queueId,
1343                                       HTTP_STATUS_BADREQUEST,
1344                                       String::EMPTY,
1345                                       String::EMPTY,
1346                                       closeConnect);
1347                                   PEG_METHOD_EXIT();
1348                                   return;
1349                               } // bad request
1350                           } // isRequestAuthenticated and enableAuthentication check
1351                           else
1352                           {  // client not authenticated; send challenge
1353 gerarda          1.22 #ifdef PEGASUS_KERBEROS_AUTHENTICATION
1354 thilo.boehm      1.77         String authResp =
1355                                   _authenticationManager->getHttpAuthResponseHeader(
1356                                       httpMessage->authInfo);
1357 gerarda          1.22 #else
1358 thilo.boehm      1.77         String authResp =
1359                                   _authenticationManager->getHttpAuthResponseHeader();
1360 gerarda          1.22 #endif
1361 mike             1.2  
1362 thilo.boehm      1.77         if (!String::equal(authResp, String::EMPTY))
1363                               {
1364                                   _sendChallenge(queueId, authResp,closeConnect);
1365                               }
1366                               else
1367                               {
1368                                   MessageLoaderParms msgParms(
1369                                       "Pegasus.Server.HTTPAuthenticatorDelegator."
1370                                           "AUTHORIZATION_HEADER_ERROR",
1371                                       "Authorization header error");
1372                                   String msg(MessageLoader::getMessage(msgParms));
1373                                   _sendHttpError(
1374                                       queueId,
1375                                       HTTP_STATUS_BADREQUEST,
1376                                       String::EMPTY,
1377                                       msg,
1378                                       closeConnect);
1379 mike             1.2          }
1380 thilo.boehm      1.77     }
1381 kumpf            1.11 
1382 thilo.boehm      1.77 PEG_METHOD_EXIT();
1383 mike             1.2  }
1384                       
1385                       PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2