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

Diff for /pegasus/src/Pegasus/Server/HTTPAuthenticatorDelegator.cpp between version 1.24 and 1.25

version 1.24, 2003/10/03 21:41:25 version 1.25, 2003/10/13 17:55:56
Line 243 
Line 243 
     //     //
     Uint32 queueId = httpMessage->queueId;     Uint32 queueId = httpMessage->queueId;
  
 #ifdef PEGASUS_KERBEROS_AUTHENTICATION  
     // TODO::KERBEROS complete and verify code  
     CIMKerberosSecurityAssociation *sa = httpMessage->authInfo->getSecurityAssociation();  
     if ( sa )  
     {  
         char* outmessage = NULL;  
         Uint64   outlength = 0;  
         Array<Sint8> final_buffer;  
         final_buffer.clear();  
         Array<Sint8> header_buffer;  
         header_buffer.clear();  
         Array<Sint8> wrapped_content_buffer;  
         wrapped_content_buffer.clear();  
         if (sa->getClientAuthenticated())  
         {  
             // TODO::KERBEROS Question - will parse be able to distinguish headers from  
             //     contents when the contents is wrapped??? I am thinking we are okay  
             //     because the code breaks out of the loop as soon as it finds the  
             //     double separator that terminates the headers.  
             // Parse the HTTP message:  
             String startLine;  
             Array<HTTPHeader> headers;  
             Uint32 contentLength;  
             httpMessage->parse(startLine, headers, contentLength);  
   
             for (Uint64 i = 0; i < (httpMessage->message.size()-contentLength); i++)  
             {  
                 header_buffer.append(httpMessage->message[i]);  
             }  
   
             for (Uint64 i = (httpMessage->message.size()-contentLength); i < httpMessage->message.size(); i++)  
             {  
                 wrapped_content_buffer.append(outmessage[i]);  
             }  
   
             if (sa->wrap_message((const char*)wrapped_content_buffer.getData(),  
                                  (Uint64)wrapped_content_buffer.size(),  
                                   outmessage,  
                                   outlength))  
             {  
                 // build a bad request  
                 final_buffer = XmlWriter::formatHttpErrorRspMessage(HTTP_STATUS_BADREQUEST);  
                 _sendResponse(queueId, final_buffer);  
                 if (outmessage)  
                     delete [] outmessage;  // outmessage is no longer needed  
                 PEG_METHOD_EXIT();  
                 return;  
             }  
         }  
         //  Note:  unwrap_message can result in the client no longer being authenticated so the  
         //  flag needs to be checked.  
         if (!sa->getClientAuthenticated())  
         {  
             // set authenticated flag in _authInfo to not authenticated because the  
             // wrap resulted in an expired token or credential.  
             httpMessage->authInfo->setAuthStatus(AuthenticationInfoRep::CHALLENGE_SENT);  
             // build a 401 response  
             // do we need to add a token here or just restart the negotiate again???  
             // authResponse.append(sa->getServerToken());  
             XmlWriter::appendUnauthorizedResponseHeader(final_buffer, KERBEROS_CHALLENGE_HEADER);  
             _sendResponse(queueId, final_buffer);  
             if (outmessage)  
                 delete [] outmessage;  // outmessage is no longer needed  
             PEG_METHOD_EXIT();  
             return;  
         }  
   
         if (outlength > 0)  
         {  
             Array<Sint8> unwrapped_content_buffer;  
             unwrapped_content_buffer.clear();  
             for (Uint64 i = 0; i < outlength; i++)  
             {  
                  unwrapped_content_buffer.append(outmessage[i]);  
             }  
             final_buffer.appendArray(header_buffer);  
             final_buffer.appendArray(unwrapped_content_buffer);  
   
             if (outmessage)  
                 delete [] outmessage;  // outmessage is no longer needed  
   
             httpMessage->message.clear();  
             httpMessage->message = final_buffer;  
         }  
     }  
 #endif  
   
     //     //
     // Parse the HTTP message:     // Parse the HTTP message:
     //     //
Line 470 
Line 383 
                     PEG_METHOD_EXIT();                     PEG_METHOD_EXIT();
                     return;                     return;
                 }                 }
               }  // first not authenticated check
           }  // "Authorization" header check
   
 #ifdef PEGASUS_KERBEROS_AUTHENTICATION #ifdef PEGASUS_KERBEROS_AUTHENTICATION
                 else if (String::equalNoCase(httpMessage->authInfo->getAuthType(),          // The following is processing to unwrap (unencrypt) the message received from the
                                              "Kerberos") &&          // client when using kerberos authentication.
                          httpMessage->authInfo->isAuthenticated() &&          // For Kerberos there should always be an "Authorization" record sent with the request
                          "Client requested mutual authentication")          // so the authenticated flag in the method should always be checked to verify that
           // the client is actually authenticated.  If no "Authoriztion" was sent then the
           // client can't be authenticated.  The "Authorization" record was processed above
           // and if the "Authorization" record was successfully processed then the client
           // is authenticated.
           CIMKerberosSecurityAssociation *sa = httpMessage->authInfo->getSecurityAssociation();
           if (sa  &&  authenticated)
                 {                 {
               Uint32 rc;  // return code for the wrap
               Array<Sint8> final_buffer;
               final_buffer.clear();
               Array<Sint8> header_buffer;
               header_buffer.clear();
               Array<Sint8> inWrappedMessage;
               inWrappedMessage.clear();
               Array<Sint8> outUnwrappedMessage;
               outUnwrappedMessage.clear();
   
               // The message needs to be parsed in order to distinguise between the
               // headers and content. The message was parsed earlier in this method
               // so we can use the contentLength set during that parse. When parsing
               // the code breaks out of the loop as soon as it finds the double
               // separator that terminates the headers so the headers and content
               // can be easily separated.
   
               // IMPORTANT - NOTE NOTE NOTE - IMPORTANT
               // Need to increase the content size by one because earlier a
               // NULL terminator was added causing the unwrap to think that the
               // wrapped message has a bad signature.  Anything that was added
               // to the content portion must be handled otherwise unwrap will
               // return an error.  So if additional characters are added in the
               // future the content size needs to be adjusted.
               int charsAdded = 1; // increase by the number of chars added to content
               contentLength = contentLength + charsAdded;
   
               // Extract the unwrapped headers
               for (Uint32 i = 0; i < (httpMessage->message.size()-contentLength); i++)
               {
                   header_buffer.append(httpMessage->message[i]);
               }
   
               // Extract the wrapped content
               // Note: Need to decrease the message size by the number of characters
               // added to content.  See important note above regarding content size.
               for (Uint32 i = (httpMessage->message.size()-contentLength);
                    i < (httpMessage->message.size()-charsAdded); i++)
               {
                   inWrappedMessage.append(httpMessage->message[i]);
               }
   
               rc = sa->unwrap_message(inWrappedMessage,
                                       outUnwrappedMessage);  // ASCII
   
               if (rc)
               {
                   // clear out the outUnwrappedMessage; if unwrapping is required
                   // and it fails we need to send back a bad request.  A message
                   // left in an wrapped state will be a severe failue later.  Reason
                   // for unwrap failing may be due to a problem with the credentials
                   // or context or some other failure may have occurred.
                   outUnwrappedMessage.clear();
                   // build a bad request.  We do not want to risk sending back
                   // data that can't be authenticated.
                   final_buffer =
                     XmlWriter::formatHttpErrorRspMessage(HTTP_STATUS_BADREQUEST);
                   //remove the last separater; the authentication record still
                   // needs to be added.
                   final_buffer.remove(final_buffer.size());  // "\n"
                   final_buffer.remove(final_buffer.size());  // "\r"
   
                   // Build the WWW_Authenticate record with token.  SPNEGO negotiation
                   // requires that a WWW_Authenticate record is always sent.
                     String authResp =                     String authResp =
                         _authenticationManager->getHttpAuthResponseHeader(httpMessage->authInfo);                         _authenticationManager->getHttpAuthResponseHeader(httpMessage->authInfo);
                     if (!String::equal(authResp, String::EMPTY))                  // error occurred on wrap so the final_buffer needs to be built
                   // differently
                   final_buffer << authResp;
                   // add double separaters to end
                   final_buffer << "\r\n";
                   final_buffer << "\r\n";
   
                   _sendResponse(queueId, final_buffer);
                   PEG_METHOD_EXIT();
                   return;
               }
   
               // If outUnwrappedMessage does not have any content data this is a result
               // of no data available.  This could be a result of the client not sending
               // any content data.  This is not unique to Kerberos so this will not be
               // handled here but it will be handled when the content is processed. Or,
               // the client did not wrap message...this is okay.
               // If the unwrap resulted in no data when there should have been data then
               // this should have been caught above when the unwrap returned a bad return
               // code
               if (final_buffer.size() == 0)
               {
                   // if outUnwrappedMessage is empty that indicates client did not
                   // wrap the message.  The original message will be used.
                   if (outUnwrappedMessage.size())
                     {                     {
                         _sendSuccess(queueId, authResp);                      final_buffer.appendArray(header_buffer);
                       final_buffer.appendArray(outUnwrappedMessage);
                       final_buffer.append('\0'); // add back char that was appended earlier
                       // Note: if additional characters added in future add back here
                   }
                     }                     }
                     else                     else
                     {                     {
                         /* Should never fall into here.  Add code to add a trace                  // The final buffer should not have any data at this point. If it
                            statement in the event that it does fall into this                  // does end the server because something bad happened.
                            else. */                  Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,
                               "HTTPAuthenticatorDelegator - the final buffer should not have data");
                   PEGASUS_ASSERT(0);
                     }                     }
   
               // replace the existing httpMessage with the headers and unwrapped message
               // If the final buffer has not been set then the original httpMessage will be used.
               if (final_buffer.size())
               {
                       httpMessage->message.clear();
                       httpMessage->message = final_buffer;
                 }                 }
           } // if not kerberos and client not authenticated
 #endif #endif
             }  
         }  
  
         if ( authenticated || !enableAuthentication )         if ( authenticated || !enableAuthentication )
         {         {
Line 566 
Line 588 
                 _sendResponse(queueId, message);                 _sendResponse(queueId, message);
                 PEG_METHOD_EXIT();                 PEG_METHOD_EXIT();
                 return;                 return;
             }              } // bad request
         }          } // authenticated and enableAuthentication check
         else         else
         {          {  // client not authenticated; send challenge
 #ifdef PEGASUS_KERBEROS_AUTHENTICATION #ifdef PEGASUS_KERBEROS_AUTHENTICATION
             String authResp =             String authResp =
                 _authenticationManager->getHttpAuthResponseHeader(httpMessage->authInfo);                 _authenticationManager->getHttpAuthResponseHeader(httpMessage->authInfo);
Line 585 
Line 607 
             else             else
             {             {
                 _sendError(queueId, "Invalid Request");                 _sendError(queueId, "Invalid Request");
 #ifdef PEGASUS_KERBEROS_AUTHENTICATION  
                 /* Should never fall into here.  Add code to add a trace  
                    statement in the event that it does fall into this  
                    else. */  
 #endif  
             }  
         }         }
     }     }
       } // M-POST and POST processing
  
     PEG_METHOD_EXIT();     PEG_METHOD_EXIT();
 } }


Legend:
Removed from v.1.24  
changed lines
  Added in v.1.25

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2