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

  1 karl  1.1 //%/////////////////////////////////////////////////////////////////////////////
  2           //
  3           // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM,
  4           // 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           // 
 13           // 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 karl  1.1 //==============================================================================
 23           //
 24           // Author: Nag Boranna, Hewlett-Packard Company (nagaraja_boranna@hp.com)
 25           //
 26           // Modified By:
 27           //
 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           #include <Pegasus/Common/Base64.h>
 35           #include <Pegasus/Common/Exception.h>
 36           #include "ClientAuthenticator.h"
 37           
 38           #include <ctype.h>
 39           
 40           //
 41           // Constants used to parse the authentication challenge header
 42           //
 43 karl  1.1 #define CHAR_BLANK     ' '
 44           
 45           #define CHAR_QUOTE     '"'
 46           
 47           
 48           PEGASUS_USING_STD;
 49           
 50           PEGASUS_NAMESPACE_BEGIN
 51           
 52           /**
 53               The constant represeting the authentication challenge header.
 54           */
 55           static const String WWW_AUTHENTICATE            = "WWW-Authenticate";
 56           
 57           /**
 58               Constant representing the Basic authentication header.
 59           */
 60           static const String BASIC_AUTH_HEADER           = "Authorization: Basic ";
 61           
 62           /**
 63               Constant representing the Digest authentication header.
 64 karl  1.1 */
 65           static const String DIGEST_AUTH_HEADER          = "Authorization: Digest ";
 66           
 67           /**
 68               Constant representing the local authentication header.
 69           */
 70           static const String LOCAL_AUTH_HEADER           =
 71                                        "PegasusAuthorization: Local";
 72           
 73           /**
 74               Constant representing the local privileged authentication header.
 75           */
 76           static const String LOCALPRIVILEGED_AUTH_HEADER =
 77                                        "PegasusAuthorization: LocalPrivileged";
 78           
 79           
 80           
 81           ClientAuthenticator::ClientAuthenticator(): _challengeReceived(false)
 82           {
 83               clearRequest(true);
 84           }
 85 karl  1.1 
 86           ClientAuthenticator::~ClientAuthenticator()
 87           {
 88           
 89           }
 90           
 91           void ClientAuthenticator::clearRequest(Boolean closeConnection)
 92           {
 93               _requestMessage = 0;
 94           
 95               if (closeConnection)
 96               {
 97                   _userName = String::EMPTY;
 98                   _password = String::EMPTY;
 99                   _realm = String::EMPTY;
100               }
101           }
102           
103           Boolean ClientAuthenticator::checkResponseHeaderForChallenge(
104               Array<HTTPHeader> headers)
105           {
106 karl  1.1     //
107               // Search for "WWW-Authenticate" header:
108               //
109               String authHeader;
110               String authType;
111               String authRealm;
112           
113               if (!HTTPMessage::lookupHeader(
114                   headers, WWW_AUTHENTICATE, authHeader, false))
115               {
116                   return false;
117               }
118           
119               if (_challengeReceived)
120               {
121                   throw UnauthorizedAccess();
122               }
123               else
124               {
125                  _challengeReceived = true;
126           
127 karl  1.1        //
128                  // Parse the authentication challenge header
129                  //
130                  if(!_parseAuthHeader(authHeader, authType, authRealm))
131                  {
132                      throw InvalidAuthHeader();
133                  }
134           
135                  if ( String::equal(authType, "LocalPrivileged"))
136                  {
137                      _authType = ClientAuthenticator::LOCALPRIVILEGED;
138                  }
139                  else if ( String::equal(authType, "Local"))
140                  {
141                      _authType = ClientAuthenticator::LOCAL;
142                  }
143                  else if ( String::equal(authType, "Basic"))
144                  {
145                      _authType = ClientAuthenticator::BASIC;
146                  }
147                  else if ( String::equal(authType, "Digest"))
148 karl  1.1        {
149                      _authType = ClientAuthenticator::DIGEST;
150                  }
151                  else
152                  {
153                      throw InvalidAuthHeader();
154                  }
155           
156                  _realm = authRealm;
157           
158                  return true;
159              }
160           }
161           
162           
163           String ClientAuthenticator::buildRequestAuthHeader()
164           {
165               String challengeResponse = String::EMPTY;
166           
167               switch (_authType)
168               {
169 karl  1.1         case ClientAuthenticator::BASIC:
170           
171                       if (_challengeReceived)
172                       {
173                           challengeResponse = BASIC_AUTH_HEADER;
174           
175                           //
176                           // build the credentials string using the
177                           // user name and password
178                           //
179                           String userPass =  _userName;
180           
181                           userPass.append(":");
182           
183                           userPass.append(_password);
184           
185                           //
186                           // copy userPass string content to Uint8 array for encoding
187                           //
188                           Array <Uint8>  userPassArray;
189           
190 karl  1.1                 Uint32 userPassLength = userPass.size();
191           
192                           userPassArray.reserveCapacity( userPassLength );
193                           userPassArray.clear();
194           
195                           for( Uint32 i = 0; i < userPassLength; i++ )
196                           {
197                               userPassArray.append( (Uint8)userPass[i] );
198                           }
199           
200                           //
201                           // base64 encode the user name and password
202                           //
203                           Array <Sint8>  encodedArray;
204           
205                           encodedArray = Base64::encode( userPassArray );
206           
207                           challengeResponse.append(
208                               String( encodedArray.getData(), encodedArray.size() ) );
209                       }
210                       break;
211 karl  1.1 
212                   //
213                   //ATTN: Implement Digest Auth challenge handling code here
214                   //
215                   case ClientAuthenticator::DIGEST:
216                   //    if (_challengeReceived)
217                   //    {
218                   //        challengeResponse = DIGEST_AUTH_HEADER;
219                   //
220                   //    }
221                       break;
222           
223                   case ClientAuthenticator::LOCALPRIVILEGED:
224           
225                       challengeResponse = LOCALPRIVILEGED_AUTH_HEADER;
226                       challengeResponse.append(" \"");
227           
228                       if (_userName.size())
229                       {
230                            challengeResponse.append(_userName);
231                       }
232 karl  1.1             else
233                       {
234                           //
235                           // Get the privileged user name on the system
236                           //
237                           challengeResponse.append(System::getPrivilegedUserName());
238                       }
239           
240                       challengeResponse.append(_buildLocalAuthResponse());
241           
242                       break;
243           
244                   case ClientAuthenticator::LOCAL:
245           
246                       challengeResponse = LOCAL_AUTH_HEADER;
247                       challengeResponse.append(" \"");
248           
249                       if (_userName.size())
250                       {
251                            challengeResponse.append(_userName);
252                       }
253 karl  1.1             else
254                       {
255                           //
256                           // Get the current login user name
257                           //
258                           challengeResponse.append(System::getEffectiveUserName());
259                       }
260           
261                       challengeResponse.append(_buildLocalAuthResponse());
262           
263                       break;
264           
265                   case ClientAuthenticator::NONE:
266                       //
267                       // Gets here only when no authType was set.
268                       //
269                       challengeResponse.clear();
270                       break;
271           
272                   default:
273                       PEGASUS_ASSERT(0);
274 karl  1.1             break;
275               }
276           
277               return (challengeResponse);
278           }
279           
280           void ClientAuthenticator::setRequestMessage(Message* message)
281           {
282               _requestMessage = message;
283           }
284           
285           
286           Message* ClientAuthenticator::getRequestMessage()
287           {
288              return _requestMessage;
289           
290           }
291           
292           void ClientAuthenticator::setUserName(const String& userName)
293           {
294               _userName = userName;
295 karl  1.1 }
296           
297           String ClientAuthenticator::getUserName()
298           {
299               return (_userName);
300           }
301           
302           void ClientAuthenticator::setPassword(const String& password)
303           {
304               _password = password;
305           }
306           
307           void ClientAuthenticator::setAuthType(ClientAuthenticator::AuthType type)
308           {
309               PEGASUS_ASSERT( (type == ClientAuthenticator::BASIC) ||
310                    (type == ClientAuthenticator::DIGEST) ||
311                    (type == ClientAuthenticator::LOCAL) ||
312                    (type == ClientAuthenticator::LOCALPRIVILEGED) ||
313                    (type == ClientAuthenticator::NONE) );
314           
315               _authType = type;
316 karl  1.1 }
317           
318           ClientAuthenticator::AuthType ClientAuthenticator::getAuthType()
319           {
320               return (_authType);
321           }
322           
323           String ClientAuthenticator::_getFileContent(String filePath)
324           {
325               String challenge = String::EMPTY;
326           
327               //
328               // Check whether the file exists or not
329               //
330               if (!FileSystem::exists(filePath))
331               {
332                   throw NoSuchFile(filePath);
333               }
334           
335               //
336               // Open the challenge file and read the challenge data
337 karl  1.1     //
338               ifstream ifs(filePath.getCString());
339               if (!ifs)
340               {
341                  //ATTN: Log error message
342                   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           String ClientAuthenticator::_buildLocalAuthResponse()
358 karl  1.1 {
359               String authResponse = String::EMPTY;
360           
361               if (_challengeReceived)
362               {
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                   // Read and append the challenge file content
374                   //
375                   String fileContent = String::EMPTY;
376                   try
377                   {
378                       fileContent = _getFileContent(_realm);
379 karl  1.1         }
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               const String authHeader,
393               String& authType,
394               String& authRealm)
395           {
396               CString header = authHeader.getCString();
397               const char* pAuthHeader = header;
398           
399               //
400 karl  1.1     // Skip the white spaces in the begining of the header
401               //
402               while (*pAuthHeader && isspace(*pAuthHeader))
403               {
404                   *pAuthHeader++;
405               }
406           
407               //
408               // Get the authentication type
409               //
410               String type = _getSubStringUptoMarker(&pAuthHeader, CHAR_BLANK);
411           
412               if (!type.size())
413               {
414                   return false;
415               }
416           
417               //
418               // Ignore the start quote
419               //
420               _getSubStringUptoMarker(&pAuthHeader, CHAR_QUOTE);
421 karl  1.1 
422           
423               //
424               // Get the realm ending with a quote
425               //
426               String realm = _getSubStringUptoMarker(&pAuthHeader, CHAR_QUOTE);
427           
428               if (!realm.size())
429               {
430                   return false;
431               }
432           
433               authType = type;
434           
435               authRealm = realm;
436           
437               return true;
438           }
439           
440           
441           String ClientAuthenticator::_getSubStringUptoMarker(
442 karl  1.1     const char** line,
443               char marker)
444           {
445               String result = String::EMPTY;
446           
447               //
448               // Look for the marker
449               //
450               const char *pos = strchr(*line, marker);
451           
452               if (pos)
453               {
454                   if (*line != NULL)
455                   {
456                       Uint32 length = pos - *line;
457           
458                       result.assign(*line, length);
459                   }
460           
461                   while (*pos == marker)
462                   {
463 karl  1.1             ++pos;
464                   }
465           
466                   *line = pos;
467               }
468               else
469               {
470                   result.assign(*line);
471           
472                   *line += strlen(*line);
473               }
474           
475               return result;
476           }
477           
478           PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2