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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2