(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                       
 296 mike             1.2      httpMessage->parse(startLine, headers, contentLength);
 297 kumpf            1.68 
 298 j.alex           1.52     //
 299                           // Check for Connection: Close
 300                           //
 301 kumpf            1.94     const char* connectClose;
 302 kumpf            1.68     if (HTTPMessage::lookupHeader(
 303 kumpf            1.94             headers, _HTTP_HEADER_CONNECTION, connectClose, false))
 304 j.alex           1.52     {
 305 kumpf            1.94         if (System::strcasecmp(connectClose, "Close") == 0)
 306 kumpf            1.68         {
 307 marek            1.70             PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL3,
 308 kumpf            1.68                 "Header in HTTP Message Contains a Connection: Close");
 309 j.alex           1.52             closeConnect = true;
 310                                   httpMessage->setCloseConnect(closeConnect);
 311 kumpf            1.68         }
 312 j.alex           1.52     }
 313                       
 314 kumpf            1.35     //
 315 thilo.boehm      1.77     // Check and set languages
 316                           //
 317                           AcceptLanguageList acceptLanguages;
 318                           ContentLanguageList contentLanguages;
 319                           try
 320                           {
 321                               // Get and validate the Accept-Language header, if set
 322                               String acceptLanguageHeader;
 323                               if (HTTPMessage::lookupHeader(
 324                                       headers,
 325                                       _HTTP_HEADER_ACCEPT_LANGUAGE,
 326                                       acceptLanguageHeader,
 327                                       false))
 328                               {
 329                                   acceptLanguages = LanguageParser::parseAcceptLanguageHeader(
 330                                       acceptLanguageHeader);
 331                                   httpMessage->acceptLanguagesDecoded = true;
 332                               }
 333                       
 334                               // Get and validate the Content-Language header, if set
 335                               String contentLanguageHeader;
 336 thilo.boehm      1.77         if (HTTPMessage::lookupHeader(
 337                                       headers,
 338                                       _HTTP_HEADER_CONTENT_LANGUAGE,
 339                                       contentLanguageHeader,
 340                                       false))
 341                               {
 342                                   contentLanguages = LanguageParser::parseContentLanguageHeader(
 343                                       contentLanguageHeader);
 344                                   httpMessage->contentLanguagesDecoded = true;
 345                               }
 346                           }
 347                           catch (Exception& e)
 348                           {
 349                               // clear any existing languages to force messages to come from the
 350                               // root bundle
 351                               Thread::clearLanguages();
 352                               MessageLoaderParms msgParms(
 353                                   "Pegasus.Server.HTTPAuthenticatorDelegator.REQUEST_NOT_VALID",
 354                                   "request-not-valid");
 355                               String msg(MessageLoader::getMessage(msgParms));
 356                       
 357 thilo.boehm      1.77         _sendHttpError(
 358                                   queueId,
 359                                   HTTP_STATUS_BADREQUEST,
 360                                   msg,
 361                                   e.getMessage(),
 362                                   closeConnect);
 363                               PEG_METHOD_EXIT();
 364                               return;
 365                           }
 366                       
 367 kumpf            1.81     Thread::setLanguages(acceptLanguages);
 368 thilo.boehm      1.77     httpMessage->acceptLanguages = acceptLanguages;
 369                           httpMessage->contentLanguages = contentLanguages;
 370                       
 371                           //
 372                           // Parse the request line:
 373                           //
 374                           String methodName;
 375                           String requestUri;
 376                           String httpVersion;
 377                           HttpMethod httpMethod = HTTP_METHOD__POST;
 378                       
 379                           HTTPMessage::parseRequestLine(
 380                               startLine, methodName, requestUri, httpVersion);
 381                       
 382                           //
 383                           //  Set HTTP method for the request
 384                           //
 385                           if (methodName == _HTTP_METHOD_MPOST)
 386                           {
 387                               httpMethod = HTTP_METHOD_M_POST;
 388                           }
 389 thilo.boehm      1.77 
 390                           if (methodName != _HTTP_METHOD_MPOST && methodName != _HTTP_METHOD)
 391                           {
 392                               // Only POST and M-POST are implemented by this server
 393                               _sendHttpError(
 394                                   queueId,
 395                                   HTTP_STATUS_NOTIMPLEMENTED,
 396                                   String::EMPTY,
 397                                   String::EMPTY,
 398                                   closeConnect);
 399                               PEG_METHOD_EXIT();
 400                               return;
 401                           }
 402                       
 403                           if ((httpMethod == HTTP_METHOD_M_POST) &&
 404                                    (httpVersion == _HTTP_VERSION_1_0))
 405                           {
 406                               //
 407                               //  M-POST method is not valid with version 1.0
 408                               //
 409                               _sendHttpError(
 410 thilo.boehm      1.77             queueId,
 411                                   HTTP_STATUS_BADREQUEST,
 412                                   String::EMPTY,
 413                                   String::EMPTY,
 414                                   closeConnect);
 415                               PEG_METHOD_EXIT();
 416                               return;
 417                           }
 418                       
 419 marek            1.84     PEG_TRACE_CSTRING(
 420                               TRC_AUTHENTICATION,
 421 marek            1.86         Tracer::LEVEL3,
 422 marek            1.84         "HTTPAuthenticatorDelegator - Authentication processing start");
 423 thilo.boehm      1.77 
 424                           //
 425 h.sterling       1.34     // Handle authentication:
 426                           //
 427                           ConfigManager* configManager = ConfigManager::getInstance();
 428 kumpf            1.93     Boolean enableAuthentication =
 429 thilo.boehm      1.77         ConfigManager::parseBooleanValue(configManager->getCurrentValue(
 430                                   _CONFIG_PARAM_ENABLEAUTHENTICATION));
 431 sushma.fernandes 1.71 
 432 kumpf            1.93     Boolean isRequestAuthenticated =
 433 sushma.fernandes 1.71         httpMessage->authInfo->isConnectionAuthenticated();
 434 h.sterling       1.34 
 435 kumpf            1.68 #ifdef PEGASUS_KERBEROS_AUTHENTICATION
 436                           CIMKerberosSecurityAssociation* sa = NULL;
 437                           // The presence of a Security Association indicates that Kerberos is
 438                           // being used.
 439                           // Reset flag for subsequent calls to indicate that no Authorization
 440                           // record was sent. If one was sent the flag will be appropriately reset
 441                           // later.
 442                           // The sa is maintained while the connection is active.
 443                           sa = httpMessage->authInfo->getSecurityAssociation();
 444                           if (sa)
 445                           {
 446                               sa->setClientSentAuthorization(false);
 447                           }
 448                       #endif
 449 david            1.57 
 450 thilo.boehm      1.77     if (enableAuthentication)
 451 h.sterling       1.34     {
 452 thilo.boehm      1.77 
 453 kumpf            1.68 #ifdef PEGASUS_KERBEROS_AUTHENTICATION
 454                               // If we are using Kerberos (sa pointer is set), the client has
 455                               // already authenticated, and the client is NOT attempting to
 456                               // re-authenticate (dermined by an Authorization record being sent),
 457                               // then we want to set the local authenticate flag to true so that
 458                               // the authentication logic is skipped.
 459 kumpf            1.94         const char* authstr;
 460 david            1.57         if (sa && sa->getClientAuthenticated() &&
 461 kumpf            1.68             !HTTPMessage::lookupHeader(
 462                                        headers, "Authorization", authstr, false))
 463                               {
 464 sushma.fernandes 1.71             isRequestAuthenticated = true;
 465 kumpf            1.68         }
 466 david            1.57 #endif
 467 thilo.boehm      1.77         if (isRequestAuthenticated)
 468                               {
 469 kumpf            1.93             if (httpMessage->authInfo->getAuthType()==
 470 thilo.boehm      1.77                     AuthenticationInfoRep::AUTH_TYPE_SSL)
 471                                   {
 472 kumpf            1.82                 // Get the user name associated with the certificate (using the
 473                                       // certificate chain, if necessary).
 474 kumpf            1.63 
 475 kumpf            1.82                 String certUserName;
 476                                       String issuerName;
 477                                       String subjectName;
 478                                       char serialNumber[32];
 479 sushma.fernandes 1.76 
 480 kumpf            1.82                 PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL3,
 481                                           "Client was authenticated via trusted SSL certificate.");
 482 kumpf            1.68 
 483 kumpf            1.82                 String trustStore =
 484                                           configManager->getCurrentValue("sslTrustStore");
 485 h.sterling       1.59 
 486 kumpf            1.82                 if (FileSystem::isDirectory(
 487                                               ConfigManager::getHomedPath(trustStore)))
 488 h.sterling       1.59                 {
 489 kumpf            1.82                     PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL4,
 490                                               "Truststore is a directory, lookup username");
 491 kumpf            1.68 
 492 kumpf            1.82                     // Get the client certificate chain to determine the
 493                                           // correct username mapping.  Starting with the peer
 494                                           // certificate, work your way up the chain towards the
 495                                           // root certificate until a match is found in the
 496                                           // repository.
 497                                           Array<SSLCertificateInfo*> clientCertificateChain =
 498                                               httpMessage->authInfo->getClientCertificateChain();
 499                                           SSLCertificateInfo* clientCertificate = NULL;
 500 kumpf            1.68 
 501 kumpf            1.82                     PEG_TRACE((TRC_HTTP, Tracer::LEVEL4,
 502                                               "Client certificate chain length: %d.",
 503                                               clientCertificateChain.size()));
 504 kumpf            1.68 
 505 kumpf            1.82                     Uint32 loopCount = clientCertificateChain.size() - 1;
 506                                           for (Uint32 i = 0; i <= loopCount ; i++)
 507 kumpf            1.63                     {
 508 kumpf            1.82                         clientCertificate = clientCertificateChain[i];
 509                                               if (clientCertificate == NULL)
 510                                               {
 511                                                   MessageLoaderParms msgParms(
 512                                                       "Pegasus.Server.HTTPAuthenticatorDelegator."
 513                                                           "BAD_CERTIFICATE",
 514                                                       "The certificate used for authentication is "
 515                                                           "not valid.");
 516                                                   _sendHttpError(
 517                                                       queueId,
 518                                                       HTTP_STATUS_UNAUTHORIZED,
 519                                                       String::EMPTY,
 520                                                       MessageLoader::getMessage(msgParms),
 521                                                       closeConnect);
 522                                                   PEG_METHOD_EXIT();
 523                                                   return;
 524                                               }
 525 thilo.boehm      1.89                         PEG_TRACE((TRC_HTTP, Tracer::LEVEL4,
 526                                                   "Certificate toString %s",
 527                                                   (const char*)
 528                                                       clientCertificate->toString().getCString()));
 529 kumpf            1.82 
 530                                               // Get certificate properties
 531                                               issuerName = clientCertificate->getIssuerName();
 532                                               sprintf(serialNumber, "%lu",
 533 kumpf            1.87                             (unsigned long)
 534                                                       clientCertificate->getSerialNumber());
 535 kumpf            1.82                         subjectName = clientCertificate->getSubjectName();
 536                       
 537                                               //
 538                                               // The truststore type key property is deprecated. To
 539                                               // retain backward compatibility, add the truststore
 540                                               // type property to the key bindings and set it to
 541                                               // cimserver truststore.
 542                                               //
 543                       
 544                                               // Construct the corresponding PG_SSLCertificate
 545                                               // instance
 546                                               Array<CIMKeyBinding> keyBindings;
 547                                               keyBindings.append(CIMKeyBinding(
 548                                                   "IssuerName", issuerName, CIMKeyBinding::STRING));
 549                                               keyBindings.append(CIMKeyBinding(
 550                                                   "SerialNumber",
 551                                                   serialNumber,
 552                                                   CIMKeyBinding::STRING));
 553                                               keyBindings.append(CIMKeyBinding("TruststoreType",
 554                                                   PG_SSLCERTIFICATE_TSTYPE_VALUE_SERVER));
 555                       
 556 kumpf            1.82                         CIMObjectPath cimObjectPath(
 557                                                   "localhost",
 558                                                   PEGASUS_NAMESPACENAME_CERTIFICATE,
 559                                                   PEGASUS_CLASSNAME_CERTIFICATE,
 560                                                   keyBindings);
 561                       
 562 thilo.boehm      1.89                         PEG_TRACE((TRC_HTTP, Tracer::LEVEL4,
 563                                                   "Client Certificate COP: %s",
 564                                                   (const char*)
 565                                                       cimObjectPath.toString().getCString()));
 566 kumpf            1.82 
 567                                               CIMInstance cimInstance;
 568                                               CIMValue value;
 569                                               Uint32 pos;
 570                                               String userName;
 571                       
 572                                               // Attempt to get the username registered to the
 573                                               // certificate
 574                                               try
 575 h.sterling       1.59                         {
 576 kumpf            1.82                             cimInstance = _repository->getInstance(
 577                                                       PEGASUS_NAMESPACENAME_CERTIFICATE,
 578                                                       cimObjectPath);
 579                       
 580                                                   pos =
 581                                                       cimInstance.findProperty("RegisteredUserName");
 582                       
 583                                                   if (pos != PEG_NOT_FOUND &&
 584                                                       !(value = cimInstance.getProperty(pos).
 585                                                             getValue()).isNull())
 586                                                   {
 587                                                       value.get(userName);
 588 h.sterling       1.59 
 589 kumpf            1.82                                 //
 590                                                       // If a user name is specified, our search is
 591                                                       // complete
 592                                                       //
 593                                                       if (userName.size())
 594                                                       {
 595 thilo.boehm      1.89                                     PEG_TRACE((TRC_HTTP, Tracer::LEVEL3,
 596                                                               "User name for certificate is %s",
 597                                                               (const char*)userName.getCString()));
 598 kumpf            1.82                                     certUserName = userName;
 599                                                           break;
 600                                                       }
 601                       
 602                                                       // No user name is specified; continue up the
 603                                                       // chain
 604                                                       PEG_TRACE((TRC_HTTP, Tracer::LEVEL4,
 605                                                           "The certificate at level %u has no "
 606                                                               "associated username; moving up the "
 607                                                               "chain",
 608                                                           i));
 609                                                   }
 610                                                   else
 611 kumpf            1.63                             {
 612 marek            1.84                                 PEG_TRACE_CSTRING(
 613                                                           TRC_HTTP,
 614                                                           Tracer::LEVEL3,
 615 kumpf            1.82                                     "HTTPAuthenticatorDelegator - Bailing, no "
 616                                                               "username is registered to this "
 617                                                               "certificate.");
 618 kumpf            1.63                             }
 619 kumpf            1.68                         }
 620 kumpf            1.82                         catch (CIMException& e)
 621 h.sterling       1.59                         {
 622 kumpf            1.82                             // this certificate did not have a registration
 623                                                   // associated with it; continue up the chain
 624                                                   if (e.getCode() == CIM_ERR_NOT_FOUND)
 625                                                   {
 626                                                       PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL4,
 627                                                           "No registration for this certificate; "
 628                                                               "try next certificate in chain");
 629                                                       continue;
 630                                                   }
 631                                                   else
 632                                                   {
 633 harsha.bm        1.97                                 PEG_TRACE((TRC_HTTP,Tracer::LEVEL1,
 634                                                           "HTTPAuthenticatorDelegator- Bailing,the "
 635                                                               "certificate used for authentication "
 636                                                               "is not valid for client IP address "
 637                                                               "%s.",
 638                                                           (const char*)
 639                                                               httpMessage->ipAddress.getCString())
 640                                                           );
 641 marek            1.84 
 642 kumpf            1.82                                 MessageLoaderParms msgParms(
 643                                                           "Pegasus.Server.HTTPAuthenticatorDelegator."
 644                                                               "BAD_CERTIFICATE",
 645                                                           "The certificate used for authentication "
 646                                                               "is not valid.");
 647                                                       String msg(MessageLoader::getMessage(msgParms));
 648                                                       _sendHttpError(
 649                                                           queueId,
 650                                                           HTTP_STATUS_UNAUTHORIZED,
 651                                                           String::EMPTY,
 652                                                           msg,
 653                                                           closeConnect);
 654                                                       PEG_METHOD_EXIT();
 655                                                       return;
 656                                                   }
 657 kumpf            1.68                         }
 658 kumpf            1.82                         catch (...)
 659 h.sterling       1.59                         {
 660 kumpf            1.82                             // This scenario can occur if a certificate cached
 661                                                   // on the server was deleted openssl would not pick
 662                                                   // up the deletion but we would pick it up here
 663                                                   // when we went to look it up in the repository
 664 marek            1.84 
 665 harsha.bm        1.97                             PEG_TRACE((TRC_HTTP,Tracer::LEVEL1,
 666                                                       "HTTPAuthenticatorDelegator- Bailing,the "
 667 kumpf            1.82                                     "certificate used for authentication is "
 668 harsha.bm        1.97                                     "not valid for client IP address %s.",
 669                                                       (const char*)
 670                                                           httpMessage->ipAddress.getCString()));
 671                                                   
 672 kumpf            1.68                             MessageLoaderParms msgParms(
 673                                                       "Pegasus.Server.HTTPAuthenticatorDelegator."
 674                                                           "BAD_CERTIFICATE",
 675                                                       "The certificate used for authentication is "
 676                                                           "not valid.");
 677 kumpf            1.63                             String msg(MessageLoader::getMessage(msgParms));
 678 kumpf            1.68                             _sendHttpError(
 679                                                       queueId,
 680                                                       HTTP_STATUS_UNAUTHORIZED,
 681                                                       String::EMPTY,
 682                                                       msg,
 683                                                       closeConnect);
 684 kumpf            1.63                             PEG_METHOD_EXIT();
 685                                                   return;
 686 h.sterling       1.59                         }
 687 kumpf            1.82                     } //end for clientcertificatechain
 688                                       } //end sslTrustStore directory
 689                                       else
 690                                       {
 691                                           // trustStore is a single CA file, lookup username
 692                                           // user was already verified as a valid system user during
 693                                           // server startup
 694                                           certUserName =
 695                                               configManager->getCurrentValue("sslTrustStoreUserName");
 696                                       }
 697                       
 698                                       //
 699                                       // Validate user information
 700                                       //
 701 kumpf            1.63 
 702 kumpf            1.82                 if (certUserName == String::EMPTY)
 703                                       {
 704 harsha.bm        1.97                     PEG_TRACE((TRC_HTTP,Tracer::LEVEL1,
 705                                               "HTTPAuthenticatorDelegator-No username is registered "
 706                                                   "to this certificate for client IP address %s.",
 707                                               (const char*)httpMessage->ipAddress.getCString()));
 708                       
 709 kumpf            1.82                     MessageLoaderParms msgParms(
 710                                               "Pegasus.Server.HTTPAuthenticatorDelegator."
 711                                                   "BAD_CERTIFICATE_USERNAME",
 712                                               "No username is registered to this certificate.");
 713                                           _sendHttpError(
 714                                               queueId,
 715                                               HTTP_STATUS_UNAUTHORIZED,
 716                                               String::EMPTY,
 717                                               MessageLoader::getMessage(msgParms),
 718                                               closeConnect);
 719                                           PEG_METHOD_EXIT();
 720                                           return;
 721                                       }
 722 kumpf            1.63 
 723 kumpf            1.82                 if (!_authenticationManager->validateUserForHttpAuth(
 724                                               certUserName))
 725                                       {
 726                                           PEG_AUDIT_LOG(logCertificateBasedUserValidation(
 727                                               certUserName,
 728                                               issuerName,
 729                                               subjectName,
 730                                               serialNumber,
 731                                               httpMessage->ipAddress,
 732                                               false));
 733                                           MessageLoaderParms msgParms(
 734                                               "Pegasus.Server.HTTPAuthenticatorDelegator."
 735                                                   "CERTIFICATE_USER_NOT_VALID",
 736                                               "User '$0' registered to this certificate is not a "
 737                                                   "valid user.",
 738                                               certUserName);
 739                                           _sendHttpError(
 740                                               queueId,
 741                                               HTTP_STATUS_UNAUTHORIZED,
 742                                               String::EMPTY,
 743                                               MessageLoader::getMessage(msgParms),
 744 kumpf            1.82                         closeConnect);
 745                                           PEG_METHOD_EXIT();
 746                                           return;
 747                                       }
 748 sushma.fernandes 1.69 
 749 sushma.fernandes 1.76                 PEG_AUDIT_LOG(logCertificateBasedUserValidation(
 750                                           certUserName,
 751                                           issuerName,
 752                                           subjectName,
 753                                           serialNumber,
 754                                           httpMessage->ipAddress,
 755 kumpf            1.82                     true));
 756                       
 757                                       httpMessage->authInfo->setAuthenticatedUser(certUserName);
 758 h.sterling       1.44 
 759 marek            1.84                 PEG_TRACE((
 760 kumpf            1.82                     TRC_HTTP,
 761 marek            1.86                     Tracer::LEVEL4,
 762 kumpf            1.82                     "HTTPAuthenticatorDelegator - The trusted client "
 763 marek            1.84                         "certificate is registered to %s.",
 764                                           (const char*) certUserName.getCString()));
 765 thilo.boehm      1.77             } // end AuthenticationInfoRep::AUTH_TYPE_SSL
 766                       
 767                       #ifdef PEGASUS_OS_ZOS
 768 kumpf            1.93             if (httpMessage->authInfo->getAuthType()==
 769 thilo.boehm      1.77                     AuthenticationInfoRep::AUTH_TYPE_ZOS_ATTLS)
 770                                   {
 771 kumpf            1.93                 String connectionUserName =
 772 thilo.boehm      1.77                     httpMessage->authInfo->getConnectionUser();
 773                       
 774 kumpf            1.93                 // If authenticated user not the connected user
 775 thilo.boehm      1.77                 // then check CIMSERV profile.
 776                                       if (!String::equalNoCase(connectionUserName,
 777                                               httpMessage->authInfo->getAuthenticatedUser()))
 778                                       {
 779 h.sterling       1.43 
 780 thilo.boehm      1.77 #ifdef PEGASUS_ZOS_SECURITY
 781 kumpf            1.93                    if ( !CheckProfileCIMSERVclassWBEM(connectionUserName,
 782 thilo.boehm      1.77                              __READ_RESOURCE))
 783                                          {
 784 kumpf            1.93                        Logger::put_l(Logger::STANDARD_LOG, ZOS_SECURITY_NAME,
 785 thilo.boehm      1.77                            Logger::WARNING,
 786 kumpf            1.88                            MessageLoaderParms(
 787                                                      "Pegasus.Server.HTTPAuthenticatorDelegator."
 788                                                          "ATTLS_NOREAD_CIMSERV_ACCESS.PEGASUS_OS_ZOS",
 789                                                      "Request UserID $0 doesn't have READ permission"
 790                                                      " to profile CIMSERV CL(WBEM).",
 791                                                      connectionUserName));
 792 thilo.boehm      1.77 
 793 thilo.boehm      1.78                        PEG_AUDIT_LOG(logCertificateBasedUserValidation(
 794 kumpf            1.82                            connectionUserName,
 795                                                  String::EMPTY,
 796                                                  String::EMPTY,
 797                                                  String::EMPTY,
 798                                                  httpMessage->ipAddress,
 799                                                  false));
 800 thilo.boehm      1.78 
 801 thilo.boehm      1.77                        _sendHttpError(
 802                                                  queueId,
 803                                                  HTTP_STATUS_UNAUTHORIZED,
 804                                                  String::EMPTY,
 805                                                  String::EMPTY,
 806                                                  closeConnect);
 807                       
 808                                              PEG_METHOD_EXIT();
 809                                              return;
 810                                          }
 811                       #endif
 812                                          PEG_TRACE((TRC_HTTP, Tracer::LEVEL4,
 813 kumpf            1.82                        "Client UserID '%s' was authenticated via AT-TLS.",
 814 thilo.boehm      1.77                        (const char*)connectionUserName.getCString()));
 815                       
 816                                          httpMessage->authInfo->setAuthenticatedUser(
 817                                              connectionUserName);
 818                       
 819 kumpf            1.93                    // For audit loging, only the mapping of the client IP to
 820 thilo.boehm      1.77                    // the resolved user ID is from interest.
 821 kumpf            1.93                    // The SAF facility logs the certificate validation and
 822 thilo.boehm      1.77                    // the mapping of certificate subject to a local userID.
 823                                          PEG_AUDIT_LOG(logCertificateBasedUserValidation(
 824                                                           connectionUserName,
 825                                                           String::EMPTY,
 826                                                           String::EMPTY,
 827                                                           String::EMPTY,
 828                                                           httpMessage->ipAddress,
 829                                                           true));
 830 h.sterling       1.43 
 831 thilo.boehm      1.77                 }// end is authenticated ?
 832 h.sterling       1.34 
 833 thilo.boehm      1.77             } // end AuthenticationInfoRep::AUTH_TYPE_ZOS_ATTLS
 834 humberto         1.33 
 835 kumpf            1.93             if (httpMessage->authInfo->getAuthType()==
 836 thilo.boehm      1.77                     AuthenticationInfoRep::AUTH_TYPE_ZOS_LOCAL_DOMIAN_SOCKET)
 837                                   {
 838 kumpf            1.93                 String connectionUserName =
 839 thilo.boehm      1.77                     httpMessage->authInfo->getConnectionUser();
 840 kumpf            1.68 
 841 kumpf            1.93                 String requestUserName;
 842 thilo.boehm      1.77                 String authHeader;
 843                                       String authHttpType;
 844                                       String cookie;
 845                       
 846 kumpf            1.93                 // if lookupHeader() is not successfull parseLocalAuthHeader()
 847 thilo.boehm      1.77                 // must not be called !!
 848                                       if ( HTTPMessage::lookupHeader(headers,
 849                                               _HTTP_HEADER_PEGASUSAUTHORIZATION, authHeader, false)&&
 850                                            HTTPMessage::parseLocalAuthHeader(authHeader,
 851                                                authHttpType, requestUserName, cookie))
 852                                       {
 853                                           String cimServerUserName = System::getEffectiveUserName();
 854 humberto         1.33 
 855 thilo.boehm      1.77                     PEG_TRACE((TRC_HTTP, Tracer::LEVEL4,
 856                                                      "CIM server UserID = '%s', "
 857                                                      "Request UserID = '%s', "
 858                                                      "Local authenticated UserID = '%s'.",
 859                                                      (const char*) cimServerUserName.getCString(),
 860                                                      (const char*) requestUserName.getCString(),
 861                                                      (const char*) connectionUserName.getCString()
 862                                                    ));
 863                       
 864 kumpf            1.93                     // if the request name and the user connected to the socket
 865                                           // are the same, or if the currnet user running the
 866 thilo.boehm      1.77                     // cim server and the connected user are the same then
 867                                           // assign the request user id as authenticated user id.
 868                                           if( String::equalNoCase(
 869 kumpf            1.93                             requestUserName,connectionUserName) ||
 870 thilo.boehm      1.77                         String::equalNoCase(
 871                                                   cimServerUserName,connectionUserName))
 872                                           {
 873                                               // If the designate new authenticated user, the user of
 874 kumpf            1.93                         // the request, is not already the authenticated user
 875 thilo.boehm      1.77                         // then set the authenticated user and check CIMSERV.
 876                                               if (!String::equalNoCase(requestUserName,
 877                                                    httpMessage->authInfo->getAuthenticatedUser()))
 878                                               {
 879 mike             1.2  
 880 thilo.boehm      1.77 #ifdef PEGASUS_ZOS_SECURITY
 881 kumpf            1.93                            if ( !CheckProfileCIMSERVclassWBEM(requestUserName,
 882 thilo.boehm      1.77                                      __READ_RESOURCE))
 883                                                  {
 884 kumpf            1.93                                Logger::put_l(Logger::STANDARD_LOG,
 885                                                          ZOS_SECURITY_NAME,
 886 thilo.boehm      1.77                                    Logger::WARNING,
 887 kumpf            1.88                                    MessageLoaderParms(
 888 thilo.boehm      1.77                                    "Pegasus.Server.HTTPAuthenticatorDelegator."
 889                                                              "UNIXSOCKET_NOREAD_CIMSERV_ACCESS."
 890                                                              "PEGASUS_OS_ZOS",
 891                                                          "Request UserID $0 doesn't have READ "
 892                                                              "permission to profile "
 893                                                              "CIMSERV CL(WBEM).",
 894 kumpf            1.88                                    requestUserName));
 895 thilo.boehm      1.77 
 896                                                      _sendHttpError(
 897                                                          queueId,
 898                                                          HTTP_STATUS_UNAUTHORIZED,
 899                                                          String::EMPTY,
 900                                                          String::EMPTY,
 901                                                          closeConnect);
 902                       
 903                                                      PEG_METHOD_EXIT();
 904 kumpf            1.82                                return;
 905 thilo.boehm      1.77                            }
 906                       #endif
 907 kumpf            1.93                            // It is not necessary to check remote privileged
 908                                                  // user access for local connections;
 909 thilo.boehm      1.79                            // set the flag to "check done"
 910                                                  httpMessage->authInfo->
 911                                                      setRemotePrivilegedUserAccessChecked();
 912                       
 913 thilo.boehm      1.77                            httpMessage->authInfo->setAuthenticatedUser(
 914                                                      requestUserName);
 915 mike             1.2  
 916 thilo.boehm      1.77                            PEG_TRACE((TRC_HTTP, Tracer::LEVEL4,
 917                                                       "New authenticated User = '%s'.",
 918                                                       (const char*)requestUserName.getCString()
 919                                                       ));
 920                       
 921                                               } // end changed authenticated user
 922                       
 923                                           PEG_TRACE((TRC_HTTP, Tracer::LEVEL4,
 924                                                "User authenticated for request = '%s'.",
 925                                                (const char*)httpMessage->authInfo->
 926                                                      getAuthenticatedUser().getCString()
 927                                                ));
 928 thilo.boehm      1.78 
 929                                               // Write local authentication audit record.
 930                                               PEG_AUDIT_LOG(logLocalAuthentication(
 931                                                    requestUserName,true));
 932                       
 933                                           } // end select authenticated user
 934                                           else
 935                                           {
 936                                               PEG_AUDIT_LOG(logLocalAuthentication(
 937                                                    requestUserName,false));
 938                       
 939                                               PEG_TRACE((TRC_HTTP, Tracer::LEVEL4,
 940                                                    "User '%s' not authorized for request",
 941                                                    (const char*)requestUserName.getCString()));
 942                       
 943                                               _sendHttpError(
 944                                                   queueId,
 945                                                   HTTP_STATUS_UNAUTHORIZED,
 946                                                   String::EMPTY,
 947                                                   String::EMPTY,
 948                                                   closeConnect);
 949 thilo.boehm      1.78 
 950                                               PEG_METHOD_EXIT();
 951                                               return;
 952                                           }
 953 thilo.boehm      1.77                 } // end lookup header
 954                                       else
 955 kumpf            1.93                 {
 956 thilo.boehm      1.77                     MessageLoaderParms msgParms(
 957                                               "Pegasus.Server.HTTPAuthenticatorDelegator."
 958                                                   "AUTHORIZATION_HEADER_ERROR",
 959                                               "Authorization header error");
 960                                           String msg(MessageLoader::getMessage(msgParms));
 961                                           _sendHttpError(
 962                                               queueId,
 963                                               HTTP_STATUS_BADREQUEST,
 964                                               String::EMPTY,
 965                                               msg,
 966                                               closeConnect);
 967 kumpf            1.19 
 968 thilo.boehm      1.77                     PEG_METHOD_EXIT();
 969                                           return;
 970                                       }
 971                                   } // end AuthenticationInfoRep::AUTH_TYPE_ZOS_LOCAL_DOMIAN_SOCKET
 972                       #endif
 973                               } // end isRequestAuthenticated
 974 kumpf            1.82         else
 975 thilo.boehm      1.77         { // !isRequestAuthenticated
 976 mike             1.56 
 977 thilo.boehm      1.77             String authorization;
 978 mike             1.2  
 979 kumpf            1.68             //
 980 thilo.boehm      1.77             // do Local/Pegasus authenticatio
 981 kumpf            1.68             //
 982                                   if (HTTPMessage::lookupHeader(headers,
 983 thilo.boehm      1.77                     _HTTP_HEADER_PEGASUSAUTHORIZATION, authorization, false))
 984 kumpf            1.28             {
 985 kumpf            1.68                 try
 986                                       {
 987                                           //
 988                                           // Do pegasus/local authentication
 989                                           //
 990 sushma.fernandes 1.71                     isRequestAuthenticated =
 991 kumpf            1.68                         _authenticationManager->performPegasusAuthentication(
 992                                                   authorization,
 993                                                   httpMessage->authInfo);
 994 mike             1.2  
 995 sushma.fernandes 1.71                     if (!isRequestAuthenticated)
 996 kumpf            1.68                     {
 997                                               String authChallenge;
 998                                               String authResp;
 999 mike             1.2  
1000 kumpf            1.68                         authResp = _authenticationManager->
1001                                                   getPegasusAuthResponseHeader(
1002                                                       authorization,
1003                                                       httpMessage->authInfo);
1004 kumpf            1.28 
1005 kumpf            1.68                         if (!String::equal(authResp, String::EMPTY))
1006                                               {
1007                                                   _sendChallenge(queueId, authResp,closeConnect);
1008                                               }
1009                                               else
1010                                               {
1011                                                   MessageLoaderParms msgParms(
1012                                                       "Pegasus.Server.HTTPAuthenticatorDelegator."
1013                                                           "AUTHORIZATION_HEADER_ERROR",
1014                                                       "Authorization header error");
1015                                                   String msg(MessageLoader::getMessage(msgParms));
1016                                                   _sendHttpError(
1017                                                       queueId,
1018                                                       HTTP_STATUS_BADREQUEST,
1019                                                       String::EMPTY,
1020                                                       msg,
1021                                                       closeConnect);
1022                                               }
1023                       
1024                                               PEG_METHOD_EXIT();
1025                                               return;
1026 kumpf            1.28                     }
1027 kumpf            1.68                 }
1028                                       catch (const CannotOpenFile&)
1029                                       {
1030                                           _sendHttpError(
1031                                               queueId,
1032                                               HTTP_STATUS_INTERNALSERVERERROR,
1033                                               String::EMPTY,
1034                                               String::EMPTY,
1035                                               closeConnect);
1036 kumpf            1.28                     PEG_METHOD_EXIT();
1037                                           return;
1038 mike             1.2                  }
1039 thilo.boehm      1.77             } // end PEGASUS/LOCAL authentication
1040 mike             1.2  
1041 thilo.boehm      1.77             //
1042                                   // do HTTP authentication
1043                                   //
1044 kumpf            1.68             if (HTTPMessage::lookupHeader(
1045 kumpf            1.93                     headers, _HTTP_HEADER_AUTHORIZATION,
1046                                           authorization, false))
1047 mike             1.2              {
1048 kumpf            1.82                 isRequestAuthenticated =
1049                                           _authenticationManager->performHttpAuthentication(
1050                                               authorization,
1051                                               httpMessage->authInfo);
1052 kumpf            1.68 
1053 kumpf            1.82                 if (!isRequestAuthenticated)
1054                                       {
1055                                           //ATTN: the number of challenges get sent for a
1056                                           //      request on a connection can be pre-set.
1057 gerarda          1.22 #ifdef PEGASUS_KERBEROS_AUTHENTICATION
1058 kumpf            1.82                     // Kerberos authentication needs access to the
1059                                           // AuthenticationInfo object for this session in
1060                                           // order to set up the reference to the
1061                                           // CIMKerberosSecurityAssociation object for this
1062                                           // session.
1063 kumpf            1.68 
1064 kumpf            1.82                     String authResp =
1065                                               _authenticationManager->getHttpAuthResponseHeader(
1066                                                   httpMessage->authInfo);
1067 gerarda          1.22 #else
1068 kumpf            1.82                     String authResp =
1069                                               _authenticationManager->getHttpAuthResponseHeader();
1070 gerarda          1.22 #endif
1071 kumpf            1.82                     if (!String::equal(authResp, String::EMPTY))
1072                                           {
1073                                               _sendChallenge(queueId, authResp, closeConnect);
1074                                           }
1075                                           else
1076                                           {
1077                                               MessageLoaderParms msgParms(
1078                                                   "Pegasus.Server.HTTPAuthenticatorDelegator."
1079                                                       "AUTHORIZATION_HEADER_ERROR",
1080                                                   "Authorization header error");
1081                                               String msg(MessageLoader::getMessage(msgParms));
1082                                               _sendHttpError(
1083                                                   queueId,
1084                                                   HTTP_STATUS_BADREQUEST,
1085                                                   String::EMPTY,
1086                                                   msg,
1087                                                   closeConnect);
1088                                           }
1089 kumpf            1.68 
1090 kumpf            1.82                     PEG_METHOD_EXIT();
1091                                           return;
1092                                       }
1093 kumpf            1.93             }  // End if HTTP Authorization
1094 thilo.boehm      1.77 
1095                               } //end if (!isRequestAuthenticated)
1096                       
1097                           } //end enableAuthentication
1098                       
1099 marek            1.84     PEG_TRACE_CSTRING(
1100                               TRC_AUTHENTICATION,
1101 marek            1.86         Tracer::LEVEL3,
1102 marek            1.84         "HTTPAuthenticatorDelegator - Authentication processing ended");
1103 thilo.boehm      1.77 
1104 kumpf            1.68 
1105                       #ifdef PEGASUS_KERBEROS_AUTHENTICATION
1106 thilo.boehm      1.77     // The pointer to the sa is created in the authenticator so we need
1107                           // to also assign it here.
1108                           sa = httpMessage->authInfo->getSecurityAssociation();
1109                           if (sa)
1110                           {
1111                               // 0 - continue, 1 = send success, 2 = send response
1112                               Uint32 sendAction = 0;
1113                       
1114                               // The following is processing to unwrap (decrypt) the request
1115                               // from the client when using kerberos authentication.
1116                               sa->unwrapRequestMessage(
1117 kumpf            1.93             httpMessage->message,
1118                                   contentLength,
1119                                   isRequestAuthenticated,
1120 thilo.boehm      1.77             sendAction);
1121 kumpf            1.68 
1122 thilo.boehm      1.77         if (sendAction)  // send success or send response
1123                               {
1124                                   if (httpMessage->message.size() == 0)
1125 kumpf            1.68             {
1126 thilo.boehm      1.77                 MessageLoaderParms msgParms(
1127                                           "Pegasus.Server.HTTPAuthenticatorDelegator."
1128                                               "AUTHORIZATION_HEADER_ERROR",
1129                                           "Authorization header error");
1130                                       String msg(MessageLoader::getMessage(msgParms));
1131                                       _sendHttpError(
1132                                           queueId,
1133                                           HTTP_STATUS_BADREQUEST,
1134                                           String::EMPTY,
1135                                           msg,
1136                                           closeConnect);
1137                                   }
1138                                   else
1139                                   {
1140                                       if (sendAction == 1)  // Send success
1141 kumpf            1.68                 {
1142 thilo.boehm      1.77                     _sendSuccess(
1143 kumpf            1.68                         queueId,
1144 thilo.boehm      1.77                         String(
1145                                                   httpMessage->message.getData(),
1146                                                   httpMessage->message.size()),
1147 kumpf            1.68                         closeConnect);
1148                                       }
1149 thilo.boehm      1.77 
1150                                       if (sendAction == 2)  // Send response
1151 kumpf            1.68                 {
1152 thilo.boehm      1.77                     _sendResponse(
1153                                               queueId,
1154                                               httpMessage->message,
1155                                               closeConnect);
1156                                       }
1157                                   }
1158 mike             1.2  
1159 thilo.boehm      1.77             PEG_METHOD_EXIT();
1160                                   return;
1161                               }
1162                           }
1163                       #endif
1164 gerarda          1.26 
1165 thilo.boehm      1.77     if (isRequestAuthenticated || !enableAuthentication)
1166                           {
1167                               // Final bastion to ensure the remote privileged user access
1168                               // check is done as it should be
1169                               // check for remote privileged User Access
1170                               if (!httpMessage->authInfo->getRemotePrivilegedUserAccessChecked())
1171                               {
1172                                   // the AuthenticationHandler did not process the
1173                                   // enableRemotePrivilegedUserAccess check
1174                                   // time to do it ourselves
1175                                   String userName = httpMessage->authInfo->getAuthenticatedUser();
1176                                   if (!AuthenticationManager::isRemotePrivilegedUserAccessAllowed(
1177                                           userName))
1178                                   {
1179                                       // Send client a message that we can't proceed to talk
1180                                       // to him
1181                                       // HTTP 401 ?
1182                                       MessageLoaderParms msgParms(
1183                                           "Server.CIMOperationRequestAuthorizer."
1184                                               "REMOTE_NOT_ENABLED",
1185                                           "Remote privileged user access is not enabled.");
1186 thilo.boehm      1.77                 String msg(MessageLoader::getMessage(msgParms));
1187                                       _sendHttpError(
1188                                           queueId,
1189                                           HTTP_STATUS_UNAUTHORIZED,
1190                                           String::EMPTY,
1191                                           msg,
1192                                           closeConnect);
1193 kumpf            1.68                 PEG_METHOD_EXIT();
1194                                       return;
1195                                   }
1196 thilo.boehm      1.77             httpMessage->authInfo->setRemotePrivilegedUserAccessChecked();
1197 kumpf            1.68         }
1198 h.sterling       1.34 
1199 thilo.boehm      1.77         //
1200 kumpf            1.83         // Determine the type of this request:
1201 thilo.boehm      1.77         //
1202 kumpf            1.83         //   - A "CIMOperation" header indicates a CIM operation request
1203                               //   - A "CIMExport" header indicates a CIM export request
1204                               //   - A "/wsman" path in the start message indicates a WS-Man request
1205                               //
1206                       
1207 kumpf            1.94         const char* cimOperation;
1208 thilo.boehm      1.77 
1209                               if (HTTPMessage::lookupHeader(
1210 kumpf            1.94                 headers, _HTTP_HEADER_CIMOPERATION, cimOperation, true))
1211 mike             1.2          {
1212 marek            1.84             PEG_TRACE((
1213                                       TRC_HTTP,
1214                                       Tracer::LEVEL3,
1215 kumpf            1.94                 "HTTPAuthenticatorDelegator - CIMOperation: %s",
1216                                       cimOperation));
1217 thilo.boehm      1.77 
1218                                   MessageQueue* queue =
1219 kumpf            1.83                 MessageQueue::lookup(_cimOperationMessageQueueId);
1220 thilo.boehm      1.77 
1221                                   if (queue)
1222                                   {
1223                                       httpMessage->dest = queue->getQueueId();
1224                       
1225                                       try
1226                                       {
1227                                           queue->enqueue(httpMessage);
1228                                       }
1229                                       catch (const bad_alloc&)
1230 marek            1.67                 {
1231 thilo.boehm      1.77                     delete httpMessage;
1232 venkat.puvvada   1.96                     HTTPConnection *httpQueue =
1233                                               dynamic_cast<HTTPConnection*>(
1234                                                    MessageQueue::lookup(queueId));
1235                                           if (httpQueue)
1236                                           {
1237                                               httpQueue->handleInternalServerError(0, true);
1238                                           }
1239 marek            1.67                     PEG_METHOD_EXIT();
1240 thilo.boehm      1.77                     deleteMessage = false;
1241 marek            1.67                     return;
1242                                       }
1243 thilo.boehm      1.77                 deleteMessage = false;
1244 marek            1.67             }
1245 thilo.boehm      1.77         }
1246                               else if (HTTPMessage::lookupHeader(
1247 kumpf            1.94                      headers, _HTTP_HEADER_CIMEXPORT, cimOperation, true))
1248 thilo.boehm      1.77         {
1249 marek            1.84             PEG_TRACE((
1250                                       TRC_AUTHENTICATION,
1251                                       Tracer::LEVEL3,
1252 kumpf            1.94                 "HTTPAuthenticatorDelegator - CIMExport: %s",
1253                                       cimOperation));
1254 marek            1.67 
1255 thilo.boehm      1.77             MessageQueue* queue =
1256 kumpf            1.83                 MessageQueue::lookup(_cimExportMessageQueueId);
1257 mike             1.2  
1258 thilo.boehm      1.77             if (queue)
1259 mike             1.2              {
1260 thilo.boehm      1.77                 httpMessage->dest = queue->getQueueId();
1261 mike             1.2  
1262 thilo.boehm      1.77                 queue->enqueue(httpMessage);
1263                                       deleteMessage = false;
1264 mike             1.2              }
1265 thilo.boehm      1.77         }
1266 kumpf            1.83         else if ((_wsmanOperationMessageQueueId != PEG_NOT_FOUND) &&
1267                                        ((requestUri == "/wsman") ||
1268                                         ((requestUri == "/wsman-anon") && !enableAuthentication)))
1269                               {
1270                                   // Note: DSP0226 R5.3-1 specifies if /wsman is used,
1271                                   // unauthenticated access should not be allowed.  This "should"
1272                                   // requirement is not implemented here, because it is difficult
1273                                   // for a client to determine whether enableAuthentication=true.
1274                       
1275                                   // DSP0226 R5.3-2 specifies if /wsman-anon is used, authenticated
1276                                   // access shall not be required.  Unauthenticated access is
1277                                   // currently not allowed if enableAuthentication=true.  When
1278                                   // support for wsmid:Identify is added, it will be necessary to
1279                                   // respond to that request without requiring authentication,
1280                                   // regardless of the CIM Server configuration.
1281                       
1282                                   MessageQueue* queue =
1283                                       MessageQueue::lookup(_wsmanOperationMessageQueueId);
1284                       
1285                                   if (queue)
1286                                   {
1287 kumpf            1.83                 httpMessage->dest = queue->getQueueId();
1288                       
1289                                       try
1290                                       {
1291                                           queue->enqueue(httpMessage);
1292                                       }
1293                                       catch (const bad_alloc&)
1294                                       {
1295                                           delete httpMessage;
1296 venkat.puvvada   1.96                     HTTPConnection *httpQueue =
1297                                               dynamic_cast<HTTPConnection*>(
1298                                                    MessageQueue::lookup(queueId));
1299                                           if (httpQueue)
1300                                           {
1301                                               httpQueue->handleInternalServerError(0, true);
1302                                           }
1303 kumpf            1.83                     PEG_METHOD_EXIT();
1304                                           deleteMessage = false;
1305                                           return;
1306                                       }
1307                                       deleteMessage = false;
1308                                   }
1309                               }
1310 thilo.boehm      1.77         else
1311                               {
1312                                   // We don't recognize this request message type
1313 david            1.21 
1314 thilo.boehm      1.77             // The Specification for CIM Operations over HTTP reads:
1315                                   //
1316                                   //     3.3.4. CIMOperation
1317                                   //
1318                                   //     If a CIM Server receives a CIM Operation request without
1319                                   //     this [CIMOperation] header, it MUST NOT process it as if
1320                                   //     it were a CIM Operation Request.  The status code
1321                                   //     returned by the CIM Server in response to such a request
1322                                   //     is outside of the scope of this specification.
1323                                   //
1324                                   //     3.3.5. CIMExport
1325                                   //
1326                                   //     If a CIM Listener receives a CIM Export request without
1327                                   //     this [CIMExport] header, it MUST NOT process it.  The
1328                                   //     status code returned by the CIM Listener in response to
1329                                   //     such a request is outside of the scope of this
1330                                   //     specification.
1331                                   //
1332                                   // The author has chosen to send a 400 Bad Request error, but
1333                                   // without the CIMError header since this request must not be
1334                                   // processed as a CIM request.
1335 thilo.boehm      1.77 
1336                                   _sendHttpError(
1337                                       queueId,
1338                                       HTTP_STATUS_BADREQUEST,
1339                                       String::EMPTY,
1340                                       String::EMPTY,
1341                                       closeConnect);
1342                                   PEG_METHOD_EXIT();
1343                                   return;
1344                               } // bad request
1345                           } // isRequestAuthenticated and enableAuthentication check
1346                           else
1347                           {  // client not authenticated; send challenge
1348 gerarda          1.22 #ifdef PEGASUS_KERBEROS_AUTHENTICATION
1349 thilo.boehm      1.77         String authResp =
1350                                   _authenticationManager->getHttpAuthResponseHeader(
1351                                       httpMessage->authInfo);
1352 gerarda          1.22 #else
1353 thilo.boehm      1.77         String authResp =
1354                                   _authenticationManager->getHttpAuthResponseHeader();
1355 gerarda          1.22 #endif
1356 mike             1.2  
1357 thilo.boehm      1.77         if (!String::equal(authResp, String::EMPTY))
1358                               {
1359                                   _sendChallenge(queueId, authResp,closeConnect);
1360                               }
1361                               else
1362                               {
1363                                   MessageLoaderParms msgParms(
1364                                       "Pegasus.Server.HTTPAuthenticatorDelegator."
1365                                           "AUTHORIZATION_HEADER_ERROR",
1366                                       "Authorization header error");
1367                                   String msg(MessageLoader::getMessage(msgParms));
1368                                   _sendHttpError(
1369                                       queueId,
1370                                       HTTP_STATUS_BADREQUEST,
1371                                       String::EMPTY,
1372                                       msg,
1373                                       closeConnect);
1374 mike             1.2          }
1375 thilo.boehm      1.77     }
1376 kumpf            1.11 
1377 thilo.boehm      1.77 PEG_METHOD_EXIT();
1378 mike             1.2  }
1379                       
1380                       PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2