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