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