1 mike 1.2 //%/////////////////////////////////////////////////////////////////////////////
2 //
|
3 kumpf 1.9 // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM,
|
4 mike 1.2 // The Open Group, Tivoli Systems
5 //
|
6 kumpf 1.9 // 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 mike 1.2 //
22 //==============================================================================
23 //
24 // Author: Nag Boranna, Hewlett-Packard Company(nagaraja_boranna@hp.com)
25 //
|
26 david 1.11 // Modified By: Dave Rosckes (rosckes@us.ibm.com)
|
27 mike 1.2 //
28 //%/////////////////////////////////////////////////////////////////////////////
29
30 #include <Pegasus/Common/System.h>
31 #include <Pegasus/Common/XmlWriter.h>
32 #include <Pegasus/Common/Destroyer.h>
|
33 kumpf 1.3 #include <Pegasus/Common/Tracer.h>
|
34 kumpf 1.7 #include <Pegasus/Common/PegasusVersion.h>
35
|
36 mike 1.2 #include <Pegasus/Config/ConfigManager.h>
|
37 kumpf 1.6
38 #include "LocalAuthenticationHandler.h"
39 #include "BasicAuthenticationHandler.h"
|
40 mike 1.2 #include "AuthenticationManager.h"
41
|
42 gerarda 1.12 #ifdef PEGASUS_KERBEROS_AUTHENTICATION
43 #include "KerberosAuthenticationHandler.h"
44 #endif
45
46
|
47 mike 1.2 PEGASUS_USING_STD;
48
49 PEGASUS_NAMESPACE_BEGIN
50
51 //
52 // Constructor
53 //
54 AuthenticationManager::AuthenticationManager()
55 {
|
56 kumpf 1.6 PEG_METHOD_ENTER(
57 TRC_AUTHENTICATION, "AuthenticationManager::AuthenticationManager()");
|
58 kumpf 1.3
|
59 mike 1.2 //
|
60 kumpf 1.6 // get authentication handlers
|
61 mike 1.2 //
62 _localAuthHandler = _getLocalAuthHandler();
63
64 _httpAuthHandler = _getHttpAuthHandler();
65
|
66 kumpf 1.6 PEG_METHOD_EXIT();
|
67 mike 1.2 }
68
69 //
70 // Destructor
71 //
72 AuthenticationManager::~AuthenticationManager()
73 {
|
74 kumpf 1.6 PEG_METHOD_ENTER(
75 TRC_AUTHENTICATION, "AuthenticationManager::~AuthenticationManager()");
|
76 kumpf 1.3
|
77 mike 1.2 //
|
78 kumpf 1.6 // delete authentication handlers
|
79 mike 1.2 //
|
80 kumpf 1.6 if ( _localAuthHandler )
|
81 mike 1.2 {
82 delete _localAuthHandler;
83 }
|
84 kumpf 1.6 if ( _httpAuthHandler )
|
85 mike 1.2 {
86 delete _httpAuthHandler;
87 }
|
88 kumpf 1.3
|
89 kumpf 1.6 PEG_METHOD_EXIT();
|
90 mike 1.2 }
91
92 //
93 // Perform http authentication
94 //
95 Boolean AuthenticationManager::performHttpAuthentication
96 (
|
97 kumpf 1.3 const String& authHeader,
|
98 mike 1.2 AuthenticationInfo* authInfo
99 )
100 {
|
101 kumpf 1.6 PEG_METHOD_ENTER(
102 TRC_AUTHENTICATION, "AuthenticationManager::performHttpAuthentication()");
|
103 kumpf 1.3
|
104 kumpf 1.6 String authType = String::EMPTY;
|
105 kumpf 1.3
|
106 mike 1.2 String cookie = String::EMPTY;
107
|
108 david 1.11 Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,
109 "AuthenticationManager:: performHttpAuthentication - Authority Header: $0", authHeader);
110
|
111 mike 1.2 //
|
112 kumpf 1.6 // Parse the HTTP authentication header for authentication information
|
113 mike 1.2 //
|
114 kumpf 1.6 if ( !_parseHttpAuthHeader(authHeader, authType, cookie) )
|
115 mike 1.2 {
|
116 kumpf 1.6 PEG_METHOD_EXIT();
|
117 kumpf 1.5 return false;
|
118 mike 1.2 }
119
|
120 kumpf 1.6 Boolean authenticated = false;
|
121 mike 1.2
122 //
|
123 kumpf 1.6 // Check the authenticationinformation and do the authentication
|
124 mike 1.2 //
|
125 kumpf 1.6 if ( String::equalNoCase(authType, "Basic") &&
126 String::equalNoCase(_httpAuthType, "Basic") )
|
127 mike 1.2 {
128 authenticated = _httpAuthHandler->authenticate(cookie, authInfo);
129 }
|
130 gerarda 1.12 #ifdef PEGASUS_KERBEROS_AUTHENTICATION
131 else if ( String::equalNoCase(authType, "Negotiate") &&
132 String::equalNoCase(_httpAuthType, "Kerberos") )
133 {
134 authenticated = _httpAuthHandler->authenticate(cookie, authInfo);
135 }
136 #endif
|
137 kumpf 1.8 // FUTURE: Add code to check for "Digest" when digest
|
138 kumpf 1.6 // authentication is implemented.
|
139 mike 1.2
|
140 kumpf 1.6 if ( authenticated )
|
141 mike 1.2 {
|
142 kumpf 1.6 authInfo->setAuthStatus(AuthenticationInfoRep::AUTHENTICATED);
|
143 kumpf 1.4
|
144 kumpf 1.6 authInfo->setAuthType(authType);
|
145 mike 1.2 }
146
|
147 kumpf 1.6 PEG_METHOD_EXIT();
|
148 kumpf 1.3
|
149 mike 1.2 return ( authenticated );
150 }
151
152 //
153 // Perform pegasus sepcific local authentication
154 //
155 Boolean AuthenticationManager::performPegasusAuthentication
156 (
|
157 kumpf 1.3 const String& authHeader,
|
158 mike 1.2 AuthenticationInfo* authInfo
159 )
160 {
|
161 kumpf 1.6 PEG_METHOD_ENTER(
162 TRC_AUTHENTICATION, "AuthenticationManager::performPegasusAuthentication()");
|
163 kumpf 1.3
|
164 mike 1.2 Boolean authenticated = false;
165
166 String authType = String::EMPTY;
167 String userName = String::EMPTY;
168 String cookie = String::EMPTY;
|
169 david 1.11
170 Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,
171 "AuthenticationManager:: performPegasusAuthentication - Authority Header: $0",
172 authHeader);
|
173 mike 1.2
174 //
|
175 kumpf 1.6 // Parse the pegasus authentication header authentication information
|
176 mike 1.2 //
|
177 kumpf 1.6 if ( !_parseLocalAuthHeader(authHeader, authType, userName, cookie) )
178 {
179 PEG_METHOD_EXIT();
180 return false;
181 }
|
182 mike 1.2
|
183 kumpf 1.6 //
184 // Note: Pegasus LocalPrivileged authentication is not being used, but the
185 // code is kept here so that we can use it in the future if needed.
186 //
187 #if defined(PEGASUS_LOCAL_PRIVILEGED_AUTHENTICATION)
|
188 kumpf 1.5 if ( String::equalNoCase(authType, "LocalPrivileged") )
189 {
190 if (authInfo->isAuthenticated() && authInfo->isPrivileged() &&
191 String::equal(userName, authInfo->getAuthenticatedUser()))
192 {
|
193 kumpf 1.6 PEG_METHOD_EXIT();
|
194 kumpf 1.5 return true;
195 }
196 }
|
197 kumpf 1.6 #endif
198
199 if ( String::equalNoCase(authType, "Local") )
|
200 kumpf 1.5 {
201 if (authInfo->isAuthenticated() &&
202 String::equal(userName, authInfo->getAuthenticatedUser()))
203 {
|
204 kumpf 1.6 PEG_METHOD_EXIT();
|
205 kumpf 1.5 return true;
206 }
207 }
208 else
|
209 mike 1.2 {
|
210 kumpf 1.6 PEG_METHOD_EXIT();
|
211 kumpf 1.5 return false;
|
212 mike 1.2 }
213
214 //
215 // Check if the authentication information is present
216 //
|
217 kumpf 1.6 if ( String::equal(cookie, String::EMPTY) )
|
218 mike 1.2 {
|
219 kumpf 1.6 PEG_METHOD_EXIT();
|
220 mike 1.2 return false;
221 }
222
223 authenticated =
224 _localAuthHandler->authenticate(cookie, authInfo);
225
|
226 kumpf 1.6 if ( authenticated )
|
227 mike 1.2 {
|
228 kumpf 1.6 authInfo->setAuthStatus(AuthenticationInfoRep::AUTHENTICATED);
|
229 mike 1.2
|
230 kumpf 1.6 #if defined(PEGASUS_LOCAL_PRIVILEGED_AUTHENTICATION)
|
231 mike 1.2 if ( String::equal(authType, "LocalPrivileged") )
232 {
233 authInfo->setPrivileged(true);
234 }
235 else
236 {
237 authInfo->setPrivileged(false);
238 }
|
239 kumpf 1.6 #endif
|
240 kumpf 1.4
241 authInfo->setAuthType(authType);
|
242 mike 1.2 }
243
|
244 kumpf 1.6 PEG_METHOD_EXIT();
|
245 kumpf 1.3
|
246 mike 1.2 return ( authenticated );
247 }
248
249 //
250 // Get pegasus/local authentication response header
251 //
252 String AuthenticationManager::getPegasusAuthResponseHeader
253 (
|
254 kumpf 1.3 const String& authHeader,
|
255 mike 1.2 AuthenticationInfo* authInfo
256 )
257 {
|
258 kumpf 1.6 PEG_METHOD_ENTER(
259 TRC_AUTHENTICATION, "AuthenticationManager::getPegasusAuthResponseHeader()");
|
260 kumpf 1.3
|
261 kumpf 1.6 String respHeader = String::EMPTY;
|
262 kumpf 1.3
|
263 mike 1.2 String authType = String::EMPTY;
264 String userName = String::EMPTY;
265 String cookie = String::EMPTY;
266
267 //
|
268 kumpf 1.6 // Parse the pegasus authentication header authentication information
|
269 mike 1.2 //
|
270 kumpf 1.6 if ( !_parseLocalAuthHeader(authHeader, authType, userName, cookie) )
271 {
272 PEG_METHOD_EXIT();
273 return (respHeader);
274 }
|
275 mike 1.2
276 //
|
277 kumpf 1.6 // User name can not be empty
|
278 mike 1.2 //
|
279 kumpf 1.6 if ( String::equal(userName, String::EMPTY) )
|
280 mike 1.2 {
|
281 kumpf 1.6 PEG_METHOD_EXIT();
282 return (respHeader);
|
283 mike 1.2 }
284
|
285 kumpf 1.6 respHeader =
286 _localAuthHandler->getAuthResponseHeader(authType, userName, authInfo);
287
288 PEG_METHOD_EXIT();
289
290 return (respHeader);
|
291 kumpf 1.3
|
292 mike 1.2 }
293
294 //
295 // Get HTTP authentication response header
296 //
|
297 gerarda 1.12 #ifdef PEGASUS_KERBEROS_AUTHENTICATION
298 String AuthenticationManager::getHttpAuthResponseHeader( AuthenticationInfo* authInfo )
299 #else
|
300 mike 1.2 String AuthenticationManager::getHttpAuthResponseHeader()
|
301 gerarda 1.12 #endif
|
302 mike 1.2 {
|
303 kumpf 1.6 PEG_METHOD_ENTER(
304 TRC_AUTHENTICATION, "AuthenticationManager::getHttpAuthResponseHeader()");
|
305 kumpf 1.3
|
306 gerarda 1.12 #ifdef PEGASUS_KERBEROS_AUTHENTICATION
307 String respHeader = _httpAuthHandler->getAuthResponseHeader(
308 String::EMPTY, String::EMPTY, authInfo);
309 #else
|
310 kumpf 1.6 String respHeader = _httpAuthHandler->getAuthResponseHeader();
|
311 gerarda 1.12 #endif
|
312 kumpf 1.3
|
313 kumpf 1.6 PEG_METHOD_EXIT();
|
314 kumpf 1.3
|
315 kumpf 1.6 return (respHeader);
|
316 mike 1.2 }
317
318 //
|
319 kumpf 1.6 // parse the local authentication header
|
320 mike 1.2 //
|
321 kumpf 1.6 Boolean AuthenticationManager::_parseLocalAuthHeader(
|
322 kumpf 1.3 const String& authHeader, String& authType, String& userName, String& cookie)
|
323 mike 1.2 {
|
324 kumpf 1.6 PEG_METHOD_ENTER(
325 TRC_AUTHENTICATION, "AuthenticationManager::_parseLocalAuthHeader()");
|
326 kumpf 1.3
|
327 kumpf 1.6 //
328 // Extract the authentication type:
329 //
330 Uint32 space = authHeader.find(' ');
|
331 kumpf 1.3
|
332 kumpf 1.10 if ( space == PEG_NOT_FOUND )
|
333 mike 1.2 {
|
334 kumpf 1.6 PEG_METHOD_EXIT();
335 return false;
|
336 mike 1.2 }
337
|
338 kumpf 1.6 authType = authHeader.subString(0, space);
339
340 Uint32 startQuote = authHeader.find(space, '"');
341
342 if ( startQuote == PEG_NOT_FOUND )
|
343 mike 1.2 {
|
344 kumpf 1.6 PEG_METHOD_EXIT();
345 return false;
|
346 mike 1.2 }
347
348 Uint32 endQuote = authHeader.find(startQuote + 1, '"');
|
349 kumpf 1.6
350 if ( endQuote == PEG_NOT_FOUND )
|
351 mike 1.2 {
|
352 kumpf 1.6 PEG_METHOD_EXIT();
353 return false;
|
354 mike 1.2 }
355
356 String temp = authHeader.subString(
357 startQuote + 1, (endQuote - startQuote - 1));
358
|
359 kumpf 1.6 //
360 // Extract the user name and cookie:
361 //
362 Uint32 colon = temp.find(0, ':');
|
363 mike 1.2
|
364 kumpf 1.6 if ( colon == PEG_NOT_FOUND )
|
365 mike 1.2 {
366 userName = temp;
367 }
368 else
369 {
|
370 kumpf 1.6 userName = temp.subString(0, colon);
|
371 mike 1.2 cookie = temp;
372 }
|
373 kumpf 1.3
|
374 kumpf 1.6 PEG_METHOD_EXIT();
375
376 return true;
|
377 mike 1.2 }
378
379 //
|
380 kumpf 1.6 // parse the HTTP authentication header
381 //
382 Boolean AuthenticationManager::_parseHttpAuthHeader(
383 const String& authHeader, String& authType, String& cookie)
384 {
385 PEG_METHOD_ENTER(
386 TRC_AUTHENTICATION, "AuthenticationManager::_parseHttpAuthHeader()");
387
388 //
389 // Extract the authentication type:
390 //
391 Uint32 space = authHeader.find(' ');
392
|
393 kumpf 1.10 if ( space == PEG_NOT_FOUND )
|
394 kumpf 1.6 {
395 PEG_METHOD_EXIT();
396 return false;
397 }
398
399 authType = authHeader.subString(0, space);
400
401 //
402 // Extract the cookie:
403 //
404 cookie = authHeader.subString(space + 1);
405
406 PEG_METHOD_EXIT();
407
408 return true;
409 }
410 //
|
411 mike 1.2 // Get local authentication handler
412 //
413 Authenticator* AuthenticationManager::_getLocalAuthHandler()
414 {
|
415 kumpf 1.6 PEG_METHOD_ENTER(
416 TRC_AUTHENTICATION, "AuthenticationManager::_getLocalAuthHandler()");
|
417 kumpf 1.3
|
418 kumpf 1.6 PEG_METHOD_EXIT();
|
419 mike 1.2 //
420 // create and return a local authentication handler.
421 //
422 return (new LocalAuthenticationHandler());
423 }
424
425
426 //
427 // Get Http authentication handler
428 //
429 Authenticator* AuthenticationManager::_getHttpAuthHandler()
430 {
|
431 kumpf 1.6 PEG_METHOD_ENTER(
432 TRC_AUTHENTICATION, "AuthenticationManager::_getHttpAuthHandler()");
|
433 kumpf 1.3
|
434 mike 1.2 Authenticator* handler = 0;
435
436 //
|
437 kumpf 1.6 // get the configured authentication type
|
438 mike 1.2 //
439 ConfigManager* configManager = ConfigManager::getInstance();
440
|
441 kumpf 1.6 _httpAuthType = configManager->getCurrentValue("httpAuthType");
|
442 mike 1.2
443 //
|
444 kumpf 1.6 // create a authentication handler.
|
445 mike 1.2 //
|
446 kumpf 1.6 if ( String::equalNoCase(_httpAuthType, "Basic") )
|
447 mike 1.2 {
448 handler = (Authenticator* ) new BasicAuthenticationHandler( );
449 }
|
450 gerarda 1.12 #ifdef PEGASUS_KERBEROS_AUTHENTICATION
451 else if ( String::equalNoCase(_httpAuthType, "Kerberos") )
452 {
453 handler = (Authenticator* ) new KerberosAuthenticationHandler( );
454 KerberosAuthenticationHandler* kerberosHandler = (KerberosAuthenticationHandler *)handler;
455 int itFailed = kerberosHandler->initialize();
456 if (itFailed)
457 {
458 if (handler)
459 {
460 delete handler; // cleanup
461 handler = 0;
462 }
463 PEGASUS_ASSERT(0); // end the server because Kerberos could not
464 // initialized. will this really end the server?
465 }
466 }
467 #endif
|
468 kumpf 1.8 // FUTURE: uncomment these line when Digest authentication
|
469 kumpf 1.6 // is implemented.
470 //
471 //else if (String::equalNoCase(_httpAuthType, "Digest"))
|
472 mike 1.2 //{
473 // handler = (Authenticator* ) new DigestAuthenticationHandler( );
474 //}
|
475 kumpf 1.6 else
476 {
477 //
478 // This should never happen. Gets here only if Security Config
479 // property owner has not validated the configured http auth type.
480 //
481 PEGASUS_ASSERT(0);
482 }
|
483 mike 1.2
|
484 kumpf 1.6 PEG_METHOD_EXIT();
|
485 kumpf 1.3
|
486 mike 1.2 return ( handler );
487 }
488
489
490 PEGASUS_NAMESPACE_END
491
|