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

  1 mike  1.2 //%/////////////////////////////////////////////////////////////////////////////
  2           //
  3 kumpf 1.13 // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM,
  4 mike  1.2  // The Open Group, Tivoli Systems
  5            //
  6            // Permission is hereby granted, free of charge, to any person obtaining a copy
  7            // of this software and associated documentation files (the "Software"), to
  8            // deal in the Software without restriction, including without limitation the
  9            // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 10            // sell copies of the Software, and to permit persons to whom the Software is
 11            // furnished to do so, subject to the following conditions:
 12 kumpf 1.13 // 
 13 mike  1.2  // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 14            // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 15            // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 16            // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 17            // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 18            // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 19            // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 20            // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 21            //
 22            //==============================================================================
 23            //
 24            // Author: Nag Boranna, Hewlett-Packard Company (nagaraja_boranna@hp.com)
 25            //
 26 chip  1.7  // Modified By:
 27 mike  1.2  //
 28            //%/////////////////////////////////////////////////////////////////////////////
 29            
 30            #include <Pegasus/Common/Config.h>
 31            #include <Pegasus/Common/System.h>
 32            #include <Pegasus/Common/FileSystem.h>
 33            #include <Pegasus/Common/Destroyer.h>
 34 kumpf 1.4  #include <Pegasus/Common/Base64.h>
 35 mike  1.2  #include "ClientAuthenticator.h"
 36            
 37 chip  1.7  #include <ctype.h>
 38 kumpf 1.6  
 39 kumpf 1.4  //
 40 kumpf 1.6  // Constants used to parse the authentication challenge header
 41 kumpf 1.4  //
 42 kumpf 1.6  #define CHAR_BLANK     ' '
 43            
 44            #define CHAR_QUOTE     '"'
 45            
 46 kumpf 1.4  
 47 mike  1.2  PEGASUS_USING_STD;
 48            
 49            PEGASUS_NAMESPACE_BEGIN
 50            
 51 kumpf 1.4  /**
 52                The constant represeting the authentication challenge header.
 53            */
 54            static const String WWW_AUTHENTICATE            = "WWW-Authenticate";
 55            
 56            /**
 57                Constant representing the Basic authentication header.
 58            */
 59            static const String BASIC_AUTH_HEADER           = "Authorization: Basic ";
 60            
 61            /**
 62                Constant representing the Digest authentication header.
 63            */
 64            static const String DIGEST_AUTH_HEADER          = "Authorization: Digest ";
 65            
 66            /**
 67                Constant representing the local authentication header.
 68            */
 69 chip  1.7  static const String LOCAL_AUTH_HEADER           =
 70 kumpf 1.4                               "PegasusAuthorization: Local";
 71            
 72            /**
 73                Constant representing the local privileged authentication header.
 74            */
 75 chip  1.7  static const String LOCALPRIVILEGED_AUTH_HEADER =
 76 kumpf 1.4                               "PegasusAuthorization: LocalPrivileged";
 77            
 78            
 79            
 80 kumpf 1.11 ClientAuthenticator::ClientAuthenticator(): _challengeReceived(false)
 81 mike  1.2  {
 82 kumpf 1.4      clearRequest(true);
 83 mike  1.2  }
 84            
 85            ClientAuthenticator::~ClientAuthenticator()
 86            {
 87            
 88            }
 89            
 90 kumpf 1.4  void ClientAuthenticator::clearRequest(Boolean closeConnection)
 91 mike  1.2  {
 92                _requestMessage = 0;
 93 chip  1.7  
 94 kumpf 1.4      if (closeConnection)
 95                {
 96                    _userName = String::EMPTY;
 97                    _password = String::EMPTY;
 98                    _realm = String::EMPTY;
 99                }
100 mike  1.2  }
101            
102 kumpf 1.4  Boolean ClientAuthenticator::checkResponseHeaderForChallenge(
103                Array<HTTPHeader> headers)
104 mike  1.2  {
105                //
106                // Search for "WWW-Authenticate" header:
107                //
108                String authHeader;
109 kumpf 1.6      String authType;
110                String authRealm;
111 mike  1.2  
112                if (!HTTPMessage::lookupHeader(
113 kumpf 1.4          headers, WWW_AUTHENTICATE, authHeader, false))
114 mike  1.2      {
115                    return false;
116                }
117            
118 kumpf 1.10     if (_challengeReceived)
119 kumpf 1.6      {
120 kumpf 1.11         throw UnauthorizedAccess();
121 kumpf 1.6      }
122 kumpf 1.4      else
123                {
124 kumpf 1.10        _challengeReceived = true;
125            
126                   //
127                   // Parse the authentication challenge header
128                   //
129                   if(!_parseAuthHeader(authHeader, authType, authRealm))
130                   {
131                       throw InvalidAuthHeader();
132                   }
133            
134                   if ( String::equal(authType, "LocalPrivileged"))
135                   {
136                       _authType = ClientAuthenticator::LOCALPRIVILEGED;
137                   }
138                   else if ( String::equal(authType, "Local"))
139                   {
140                       _authType = ClientAuthenticator::LOCAL;
141                   }
142                   else if ( String::equal(authType, "Basic"))
143                   {
144                       _authType = ClientAuthenticator::BASIC;
145 kumpf 1.10        }
146                   else if ( String::equal(authType, "Digest"))
147                   {
148                       _authType = ClientAuthenticator::DIGEST;
149                   }
150                   else
151                   {
152                       throw InvalidAuthHeader();
153                   }
154 kumpf 1.4  
155 kumpf 1.10        _realm = authRealm;
156 mike  1.2  
157 kumpf 1.10        return true;
158               }
159 mike  1.2  }
160            
161            
162            String ClientAuthenticator::buildRequestAuthHeader()
163            {
164 kumpf 1.6      String challengeResponse = String::EMPTY;
165            
166 mike  1.2      switch (_authType)
167                {
168 kumpf 1.4          case ClientAuthenticator::BASIC:
169            
170                        if (_challengeReceived)
171                        {
172 kumpf 1.6                  challengeResponse = BASIC_AUTH_HEADER;
173            
174 kumpf 1.4                  //
175                            // build the credentials string using the
176                            // user name and password
177                            //
178                            String userPass =  _userName;
179            
180                            userPass.append(":");
181            
182                            userPass.append(_password);
183            
184                            //
185                            // copy userPass string content to Uint8 array for encoding
186                            //
187                            Array <Uint8>  userPassArray;
188            
189                            Uint32 userPassLength = userPass.size();
190            
191                            userPassArray.reserve( userPassLength );
192                            userPassArray.clear();
193            
194                            for( Uint32 i = 0; i < userPassLength; i++ )
195 kumpf 1.4                  {
196                                userPassArray.append( (Uint8)userPass[i] );
197                            }
198            
199                            //
200                            // base64 encode the user name and password
201                            //
202                            Array <Sint8>  encodedArray;
203            
204                            encodedArray = Base64::encode( userPassArray );
205            
206 kumpf 1.6                  challengeResponse.append(
207 kumpf 1.4                      String( encodedArray.getData(), encodedArray.size() ) );
208                        }
209                        break;
210            
211 chip  1.7          //
212 kumpf 1.4          //ATTN: Implement Digest Auth challenge handling code here
213 chip  1.7          //
214 kumpf 1.9          case ClientAuthenticator::DIGEST:
215 chip  1.7          //    if (_challengeReceived)
216 mike  1.2          //    {
217 kumpf 1.6          //        challengeResponse = DIGEST_AUTH_HEADER;
218 chip  1.7          //
219 mike  1.2          //    }
220 kumpf 1.9              break;
221 mike  1.2  
222                    case ClientAuthenticator::LOCALPRIVILEGED:
223            
224 kumpf 1.6              challengeResponse = LOCALPRIVILEGED_AUTH_HEADER;
225                        challengeResponse.append(" \"");
226            
227 chip  1.7              if (_userName.size())
228 kumpf 1.6              {
229                             challengeResponse.append(_userName);
230                        }
231                        else
232 mike  1.2              {
233 kumpf 1.4                  //
234 kumpf 1.6                  // Get the privileged user name on the system
235 kumpf 1.4                  //
236 kumpf 1.6                  challengeResponse.append(System::getPrivilegedUserName());
237                        }
238            
239                        challengeResponse.append(_buildLocalAuthResponse());
240            
241                        break;
242            
243                    case ClientAuthenticator::LOCAL:
244 mike  1.2  
245 kumpf 1.6              challengeResponse = LOCAL_AUTH_HEADER;
246                        challengeResponse.append(" \"");
247 mike  1.2  
248 chip  1.7              if (_userName.size())
249 kumpf 1.6              {
250                             challengeResponse.append(_userName);
251                        }
252                        else
253                        {
254 mike  1.2                  //
255 kumpf 1.6                  // Get the current login user name
256 mike  1.2                  //
257 kumpf 1.12                 challengeResponse.append(System::getEffectiveUserName());
258 mike  1.2              }
259 kumpf 1.6  
260                        challengeResponse.append(_buildLocalAuthResponse());
261 mike  1.2  
262                        break;
263            
264 kumpf 1.9          case ClientAuthenticator::NONE:
265 chip  1.7              //
266 kumpf 1.4              // Gets here only when no authType was set.
267 chip  1.7              //
268 kumpf 1.6              challengeResponse.clear();
269 mike  1.2              break;
270 kumpf 1.9  
271                    default:
272                        PEGASUS_ASSERT(0);
273                        break;
274 mike  1.2      }
275            
276 kumpf 1.6      return (challengeResponse);
277 mike  1.2  }
278            
279            void ClientAuthenticator::setRequestMessage(Message* message)
280            {
281                _requestMessage = message;
282            }
283            
284            
285            Message* ClientAuthenticator::getRequestMessage()
286            {
287 mday  1.3     return _requestMessage;
288 chip  1.7  
289 mike  1.2  }
290            
291            void ClientAuthenticator::setUserName(const String& userName)
292            {
293                _userName = userName;
294            }
295            
296            String ClientAuthenticator::getUserName()
297            {
298                return (_userName);
299            }
300            
301            void ClientAuthenticator::setPassword(const String& password)
302            {
303                _password = password;
304            }
305            
306            void ClientAuthenticator::setAuthType(ClientAuthenticator::AuthType type)
307            {
308 kumpf 1.5      PEGASUS_ASSERT( (type == ClientAuthenticator::BASIC) ||
309                     (type == ClientAuthenticator::DIGEST) ||
310                     (type == ClientAuthenticator::LOCAL) ||
311 kumpf 1.9           (type == ClientAuthenticator::LOCALPRIVILEGED) ||
312                     (type == ClientAuthenticator::NONE) );
313 kumpf 1.5  
314 mike  1.2      _authType = type;
315            }
316            
317            ClientAuthenticator::AuthType ClientAuthenticator::getAuthType()
318            {
319                return (_authType);
320            }
321            
322            String ClientAuthenticator::_getFileContent(String filePath)
323            {
324                String challenge = String::EMPTY;
325            
326                //
327 kumpf 1.4      // Check whether the file exists or not
328 mike  1.2      //
329 kumpf 1.4      if (!FileSystem::exists(filePath))
330                {
331                    throw NoSuchFile(filePath);
332                }
333 mike  1.2  
334                //
335                // Open the challenge file and read the challenge data
336                //
337                ArrayDestroyer<char> p(filePath.allocateCString());
338                ifstream ifs(p.getPointer());
339                if (!ifs)
340                {
341 chip  1.7         //ATTN: Log error message
342 mike  1.2          return (challenge);
343                }
344            
345                String line;
346            
347                while (GetLine(ifs, line))
348                {
349                    challenge.append(line);
350                }
351            
352                ifs.close();
353            
354                return (challenge);
355            }
356            
357 kumpf 1.6  String ClientAuthenticator::_buildLocalAuthResponse()
358            {
359                String authResponse = String::EMPTY;
360            
361 chip  1.7      if (_challengeReceived)
362 kumpf 1.6      {
363                    authResponse.append(":");
364            
365                    //
366                    // Append the file path that is in the realm sent by the server
367                    //
368                    authResponse.append(_realm);
369            
370                    authResponse.append(":");
371            
372                    //
373 chip  1.7          // Read and append the challenge file content
374 kumpf 1.6          //
375                    String fileContent = String::EMPTY;
376                    try
377                    {
378                        fileContent = _getFileContent(_realm);
379                    }
380                    catch(NoSuchFile& e)
381                    {
382                        //ATTN-NB-04-20000305: Log error message to log file
383                    }
384                    authResponse.append(fileContent);
385                }
386                authResponse.append("\"");
387            
388                return (authResponse);
389            }
390            
391            Boolean ClientAuthenticator::_parseAuthHeader(
392 chip  1.7      const String authHeader,
393                String& authType,
394 kumpf 1.6      String& authRealm)
395            {
396                ArrayDestroyer<char> header(authHeader.allocateCString());
397            
398                const char* pAuthHeader = header.getPointer();
399            
400                //
401                // Skip the white spaces in the begining of the header
402                //
403                while (*pAuthHeader && isspace(*pAuthHeader))
404                {
405                    *pAuthHeader++;
406                }
407            
408                //
409                // Get the authentication type
410                //
411                String type = _getSubStringUptoMarker(&pAuthHeader, CHAR_BLANK);
412            
413                if (!type.size())
414                {
415 kumpf 1.6          return false;
416                }
417            
418                //
419                // Ignore the start quote
420                //
421                _getSubStringUptoMarker(&pAuthHeader, CHAR_QUOTE);
422            
423            
424                //
425                // Get the realm ending with a quote
426                //
427                String realm = _getSubStringUptoMarker(&pAuthHeader, CHAR_QUOTE);
428            
429                if (!realm.size())
430                {
431                    return false;
432                }
433            
434                authType = type;
435            
436 kumpf 1.6      authRealm = realm;
437            
438                return true;
439            }
440            
441            
442            String ClientAuthenticator::_getSubStringUptoMarker(
443 chip  1.7      const char** line,
444 kumpf 1.6      char marker)
445            {
446                String result = String::EMPTY;
447            
448                //
449                // Look for the marker
450                //
451 kumpf 1.8      const char *pos = strchr(*line, marker);
452 kumpf 1.6  
453                if (pos)
454                {
455                    if (*line != NULL)
456                    {
457                        Uint32 length = pos - *line;
458            
459                        result.assign(*line, length);
460                    }
461            
462                    while (*pos == marker)
463                    {
464                        ++pos;
465                    }
466            
467                    *line = pos;
468                }
469                else
470                {
471                    result.assign(strdup(*line));
472            
473 kumpf 1.6          *line += strlen(*line);
474                }
475            
476                return result;
477            }
478 mike  1.2  
479            PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2