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
|
296 mike 1.2 httpMessage->parse(startLine, headers, contentLength);
|
297 kumpf 1.68
|
298 j.alex 1.52 //
299 // Check for Connection: Close
300 //
|
301 kumpf 1.94 const char* connectClose;
|
302 kumpf 1.68 if (HTTPMessage::lookupHeader(
|
303 kumpf 1.94 headers, _HTTP_HEADER_CONNECTION, connectClose, false))
|
304 j.alex 1.52 {
|
305 kumpf 1.94 if (System::strcasecmp(connectClose, "Close") == 0)
|
306 kumpf 1.68 {
|
307 marek 1.70 PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL3,
|
308 kumpf 1.68 "Header in HTTP Message Contains a Connection: Close");
|
309 j.alex 1.52 closeConnect = true;
310 httpMessage->setCloseConnect(closeConnect);
|
311 kumpf 1.68 }
|
312 j.alex 1.52 }
313
|
314 kumpf 1.35 //
|
315 thilo.boehm 1.77 // Check and set languages
316 //
317 AcceptLanguageList acceptLanguages;
318 ContentLanguageList contentLanguages;
319 try
320 {
321 // Get and validate the Accept-Language header, if set
322 String acceptLanguageHeader;
323 if (HTTPMessage::lookupHeader(
324 headers,
325 _HTTP_HEADER_ACCEPT_LANGUAGE,
326 acceptLanguageHeader,
327 false))
328 {
329 acceptLanguages = LanguageParser::parseAcceptLanguageHeader(
330 acceptLanguageHeader);
331 httpMessage->acceptLanguagesDecoded = true;
332 }
333
334 // Get and validate the Content-Language header, if set
335 String contentLanguageHeader;
336 thilo.boehm 1.77 if (HTTPMessage::lookupHeader(
337 headers,
338 _HTTP_HEADER_CONTENT_LANGUAGE,
339 contentLanguageHeader,
340 false))
341 {
342 contentLanguages = LanguageParser::parseContentLanguageHeader(
343 contentLanguageHeader);
344 httpMessage->contentLanguagesDecoded = true;
345 }
346 }
347 catch (Exception& e)
348 {
349 // clear any existing languages to force messages to come from the
350 // root bundle
351 Thread::clearLanguages();
352 MessageLoaderParms msgParms(
353 "Pegasus.Server.HTTPAuthenticatorDelegator.REQUEST_NOT_VALID",
354 "request-not-valid");
355 String msg(MessageLoader::getMessage(msgParms));
356
357 thilo.boehm 1.77 _sendHttpError(
358 queueId,
359 HTTP_STATUS_BADREQUEST,
360 msg,
361 e.getMessage(),
362 closeConnect);
363 PEG_METHOD_EXIT();
364 return;
365 }
366
|
367 kumpf 1.81 Thread::setLanguages(acceptLanguages);
|
368 thilo.boehm 1.77 httpMessage->acceptLanguages = acceptLanguages;
369 httpMessage->contentLanguages = contentLanguages;
370
371 //
372 // Parse the request line:
373 //
374 String methodName;
375 String requestUri;
376 String httpVersion;
377 HttpMethod httpMethod = HTTP_METHOD__POST;
378
379 HTTPMessage::parseRequestLine(
380 startLine, methodName, requestUri, httpVersion);
381
382 //
383 // Set HTTP method for the request
384 //
385 if (methodName == _HTTP_METHOD_MPOST)
386 {
387 httpMethod = HTTP_METHOD_M_POST;
388 }
389 thilo.boehm 1.77
390 if (methodName != _HTTP_METHOD_MPOST && methodName != _HTTP_METHOD)
391 {
392 // Only POST and M-POST are implemented by this server
393 _sendHttpError(
394 queueId,
395 HTTP_STATUS_NOTIMPLEMENTED,
396 String::EMPTY,
397 String::EMPTY,
398 closeConnect);
399 PEG_METHOD_EXIT();
400 return;
401 }
402
403 if ((httpMethod == HTTP_METHOD_M_POST) &&
404 (httpVersion == _HTTP_VERSION_1_0))
405 {
406 //
407 // M-POST method is not valid with version 1.0
408 //
409 _sendHttpError(
410 thilo.boehm 1.77 queueId,
411 HTTP_STATUS_BADREQUEST,
412 String::EMPTY,
413 String::EMPTY,
414 closeConnect);
415 PEG_METHOD_EXIT();
416 return;
417 }
418
|
419 marek 1.84 PEG_TRACE_CSTRING(
420 TRC_AUTHENTICATION,
|
421 marek 1.86 Tracer::LEVEL3,
|
422 marek 1.84 "HTTPAuthenticatorDelegator - Authentication processing start");
|
423 thilo.boehm 1.77
424 //
|
425 h.sterling 1.34 // Handle authentication:
426 //
427 ConfigManager* configManager = ConfigManager::getInstance();
|
428 kumpf 1.93 Boolean enableAuthentication =
|
429 thilo.boehm 1.77 ConfigManager::parseBooleanValue(configManager->getCurrentValue(
430 _CONFIG_PARAM_ENABLEAUTHENTICATION));
|
431 sushma.fernandes 1.71
|
432 kumpf 1.93 Boolean isRequestAuthenticated =
|
433 sushma.fernandes 1.71 httpMessage->authInfo->isConnectionAuthenticated();
|
434 h.sterling 1.34
|
435 kumpf 1.68 #ifdef PEGASUS_KERBEROS_AUTHENTICATION
436 CIMKerberosSecurityAssociation* sa = NULL;
437 // The presence of a Security Association indicates that Kerberos is
438 // being used.
439 // Reset flag for subsequent calls to indicate that no Authorization
440 // record was sent. If one was sent the flag will be appropriately reset
441 // later.
442 // The sa is maintained while the connection is active.
443 sa = httpMessage->authInfo->getSecurityAssociation();
444 if (sa)
445 {
446 sa->setClientSentAuthorization(false);
447 }
448 #endif
|
449 david 1.57
|
450 thilo.boehm 1.77 if (enableAuthentication)
|
451 h.sterling 1.34 {
|
452 thilo.boehm 1.77
|
453 kumpf 1.68 #ifdef PEGASUS_KERBEROS_AUTHENTICATION
454 // If we are using Kerberos (sa pointer is set), the client has
455 // already authenticated, and the client is NOT attempting to
456 // re-authenticate (dermined by an Authorization record being sent),
457 // then we want to set the local authenticate flag to true so that
458 // the authentication logic is skipped.
|
459 kumpf 1.94 const char* authstr;
|
460 david 1.57 if (sa && sa->getClientAuthenticated() &&
|
461 kumpf 1.68 !HTTPMessage::lookupHeader(
462 headers, "Authorization", authstr, false))
463 {
|
464 sushma.fernandes 1.71 isRequestAuthenticated = true;
|
465 kumpf 1.68 }
|
466 david 1.57 #endif
|
467 thilo.boehm 1.77 if (isRequestAuthenticated)
468 {
|
469 kumpf 1.93 if (httpMessage->authInfo->getAuthType()==
|
470 thilo.boehm 1.77 AuthenticationInfoRep::AUTH_TYPE_SSL)
471 {
|
472 kumpf 1.82 // Get the user name associated with the certificate (using the
473 // certificate chain, if necessary).
|
474 kumpf 1.63
|
475 kumpf 1.82 String certUserName;
476 String issuerName;
477 String subjectName;
478 char serialNumber[32];
|
479 sushma.fernandes 1.76
|
480 kumpf 1.82 PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL3,
481 "Client was authenticated via trusted SSL certificate.");
|
482 kumpf 1.68
|
483 kumpf 1.82 String trustStore =
484 configManager->getCurrentValue("sslTrustStore");
|
485 h.sterling 1.59
|
486 kumpf 1.82 if (FileSystem::isDirectory(
487 ConfigManager::getHomedPath(trustStore)))
|
488 h.sterling 1.59 {
|
489 kumpf 1.82 PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL4,
490 "Truststore is a directory, lookup username");
|
491 kumpf 1.68
|
492 kumpf 1.82 // Get the client certificate chain to determine the
493 // correct username mapping. Starting with the peer
494 // certificate, work your way up the chain towards the
495 // root certificate until a match is found in the
496 // repository.
497 Array<SSLCertificateInfo*> clientCertificateChain =
498 httpMessage->authInfo->getClientCertificateChain();
499 SSLCertificateInfo* clientCertificate = NULL;
|
500 kumpf 1.68
|
501 kumpf 1.82 PEG_TRACE((TRC_HTTP, Tracer::LEVEL4,
502 "Client certificate chain length: %d.",
503 clientCertificateChain.size()));
|
504 kumpf 1.68
|
505 kumpf 1.82 Uint32 loopCount = clientCertificateChain.size() - 1;
506 for (Uint32 i = 0; i <= loopCount ; i++)
|
507 kumpf 1.63 {
|
508 kumpf 1.82 clientCertificate = clientCertificateChain[i];
509 if (clientCertificate == NULL)
510 {
511 MessageLoaderParms msgParms(
512 "Pegasus.Server.HTTPAuthenticatorDelegator."
513 "BAD_CERTIFICATE",
514 "The certificate used for authentication is "
515 "not valid.");
516 _sendHttpError(
517 queueId,
518 HTTP_STATUS_UNAUTHORIZED,
519 String::EMPTY,
520 MessageLoader::getMessage(msgParms),
521 closeConnect);
522 PEG_METHOD_EXIT();
523 return;
524 }
|
525 thilo.boehm 1.89 PEG_TRACE((TRC_HTTP, Tracer::LEVEL4,
526 "Certificate toString %s",
527 (const char*)
528 clientCertificate->toString().getCString()));
|
529 kumpf 1.82
530 // Get certificate properties
531 issuerName = clientCertificate->getIssuerName();
532 sprintf(serialNumber, "%lu",
|
533 kumpf 1.87 (unsigned long)
534 clientCertificate->getSerialNumber());
|
535 kumpf 1.82 subjectName = clientCertificate->getSubjectName();
536
537 //
538 // The truststore type key property is deprecated. To
539 // retain backward compatibility, add the truststore
540 // type property to the key bindings and set it to
541 // cimserver truststore.
542 //
543
544 // Construct the corresponding PG_SSLCertificate
545 // instance
546 Array<CIMKeyBinding> keyBindings;
547 keyBindings.append(CIMKeyBinding(
548 "IssuerName", issuerName, CIMKeyBinding::STRING));
549 keyBindings.append(CIMKeyBinding(
550 "SerialNumber",
551 serialNumber,
552 CIMKeyBinding::STRING));
553 keyBindings.append(CIMKeyBinding("TruststoreType",
554 PG_SSLCERTIFICATE_TSTYPE_VALUE_SERVER));
555
556 kumpf 1.82 CIMObjectPath cimObjectPath(
557 "localhost",
558 PEGASUS_NAMESPACENAME_CERTIFICATE,
559 PEGASUS_CLASSNAME_CERTIFICATE,
560 keyBindings);
561
|
562 thilo.boehm 1.89 PEG_TRACE((TRC_HTTP, Tracer::LEVEL4,
563 "Client Certificate COP: %s",
564 (const char*)
565 cimObjectPath.toString().getCString()));
|
566 kumpf 1.82
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 thilo.boehm 1.89 PEG_TRACE((TRC_HTTP, Tracer::LEVEL3,
596 "User name for certificate is %s",
597 (const char*)userName.getCString()));
|
598 kumpf 1.82 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 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 harsha.bm 1.97 PEG_TRACE((TRC_HTTP,Tracer::LEVEL1,
634 "HTTPAuthenticatorDelegator- Bailing,the "
635 "certificate used for authentication "
636 "is not valid for client IP address "
637 "%s.",
638 (const char*)
639 httpMessage->ipAddress.getCString())
640 );
|
641 marek 1.84
|
642 kumpf 1.82 MessageLoaderParms msgParms(
643 "Pegasus.Server.HTTPAuthenticatorDelegator."
644 "BAD_CERTIFICATE",
645 "The certificate used for authentication "
646 "is not valid.");
647 String msg(MessageLoader::getMessage(msgParms));
648 _sendHttpError(
649 queueId,
650 HTTP_STATUS_UNAUTHORIZED,
651 String::EMPTY,
652 msg,
653 closeConnect);
654 PEG_METHOD_EXIT();
655 return;
656 }
|
657 kumpf 1.68 }
|
658 kumpf 1.82 catch (...)
|
659 h.sterling 1.59 {
|
660 kumpf 1.82 // This scenario can occur if a certificate cached
661 // on the server was deleted openssl would not pick
662 // up the deletion but we would pick it up here
663 // when we went to look it up in the repository
|
664 marek 1.84
|
665 harsha.bm 1.97 PEG_TRACE((TRC_HTTP,Tracer::LEVEL1,
666 "HTTPAuthenticatorDelegator- Bailing,the "
|
667 kumpf 1.82 "certificate used for authentication is "
|
668 harsha.bm 1.97 "not valid for client IP address %s.",
669 (const char*)
670 httpMessage->ipAddress.getCString()));
671
|
672 kumpf 1.68 MessageLoaderParms msgParms(
673 "Pegasus.Server.HTTPAuthenticatorDelegator."
674 "BAD_CERTIFICATE",
675 "The certificate used for authentication is "
676 "not valid.");
|
677 kumpf 1.63 String msg(MessageLoader::getMessage(msgParms));
|
678 kumpf 1.68 _sendHttpError(
679 queueId,
680 HTTP_STATUS_UNAUTHORIZED,
681 String::EMPTY,
682 msg,
683 closeConnect);
|
684 kumpf 1.63 PEG_METHOD_EXIT();
685 return;
|
686 h.sterling 1.59 }
|
687 kumpf 1.82 } //end for clientcertificatechain
688 } //end sslTrustStore directory
689 else
690 {
691 // trustStore is a single CA file, lookup username
692 // user was already verified as a valid system user during
693 // server startup
694 certUserName =
695 configManager->getCurrentValue("sslTrustStoreUserName");
696 }
697
698 //
699 // Validate user information
700 //
|
701 kumpf 1.63
|
702 kumpf 1.82 if (certUserName == String::EMPTY)
703 {
|
704 harsha.bm 1.97 PEG_TRACE((TRC_HTTP,Tracer::LEVEL1,
705 "HTTPAuthenticatorDelegator-No username is registered "
706 "to this certificate for client IP address %s.",
707 (const char*)httpMessage->ipAddress.getCString()));
708
|
709 kumpf 1.82 MessageLoaderParms msgParms(
710 "Pegasus.Server.HTTPAuthenticatorDelegator."
711 "BAD_CERTIFICATE_USERNAME",
712 "No username is registered to this certificate.");
713 _sendHttpError(
714 queueId,
715 HTTP_STATUS_UNAUTHORIZED,
716 String::EMPTY,
717 MessageLoader::getMessage(msgParms),
718 closeConnect);
719 PEG_METHOD_EXIT();
720 return;
721 }
|
722 kumpf 1.63
|
723 kumpf 1.82 if (!_authenticationManager->validateUserForHttpAuth(
724 certUserName))
725 {
726 PEG_AUDIT_LOG(logCertificateBasedUserValidation(
727 certUserName,
728 issuerName,
729 subjectName,
730 serialNumber,
731 httpMessage->ipAddress,
732 false));
733 MessageLoaderParms msgParms(
734 "Pegasus.Server.HTTPAuthenticatorDelegator."
735 "CERTIFICATE_USER_NOT_VALID",
736 "User '$0' registered to this certificate is not a "
737 "valid user.",
738 certUserName);
739 _sendHttpError(
740 queueId,
741 HTTP_STATUS_UNAUTHORIZED,
742 String::EMPTY,
743 MessageLoader::getMessage(msgParms),
744 kumpf 1.82 closeConnect);
745 PEG_METHOD_EXIT();
746 return;
747 }
|
748 sushma.fernandes 1.69
|
749 sushma.fernandes 1.76 PEG_AUDIT_LOG(logCertificateBasedUserValidation(
750 certUserName,
751 issuerName,
752 subjectName,
753 serialNumber,
754 httpMessage->ipAddress,
|
755 kumpf 1.82 true));
756
757 httpMessage->authInfo->setAuthenticatedUser(certUserName);
|
758 h.sterling 1.44
|
759 marek 1.84 PEG_TRACE((
|
760 kumpf 1.82 TRC_HTTP,
|
761 marek 1.86 Tracer::LEVEL4,
|
762 kumpf 1.82 "HTTPAuthenticatorDelegator - The trusted client "
|
763 marek 1.84 "certificate is registered to %s.",
764 (const char*) certUserName.getCString()));
|
765 thilo.boehm 1.77 } // end AuthenticationInfoRep::AUTH_TYPE_SSL
766
767 #ifdef PEGASUS_OS_ZOS
|
768 kumpf 1.93 if (httpMessage->authInfo->getAuthType()==
|
769 thilo.boehm 1.77 AuthenticationInfoRep::AUTH_TYPE_ZOS_ATTLS)
770 {
|
771 kumpf 1.93 String connectionUserName =
|
772 thilo.boehm 1.77 httpMessage->authInfo->getConnectionUser();
773
|
774 kumpf 1.93 // If authenticated user not the connected user
|
775 thilo.boehm 1.77 // then check CIMSERV profile.
776 if (!String::equalNoCase(connectionUserName,
777 httpMessage->authInfo->getAuthenticatedUser()))
778 {
|
779 h.sterling 1.43
|
780 thilo.boehm 1.77 #ifdef PEGASUS_ZOS_SECURITY
|
781 kumpf 1.93 if ( !CheckProfileCIMSERVclassWBEM(connectionUserName,
|
782 thilo.boehm 1.77 __READ_RESOURCE))
783 {
|
784 kumpf 1.93 Logger::put_l(Logger::STANDARD_LOG, ZOS_SECURITY_NAME,
|
785 thilo.boehm 1.77 Logger::WARNING,
|
786 kumpf 1.88 MessageLoaderParms(
787 "Pegasus.Server.HTTPAuthenticatorDelegator."
788 "ATTLS_NOREAD_CIMSERV_ACCESS.PEGASUS_OS_ZOS",
789 "Request UserID $0 doesn't have READ permission"
790 " to profile CIMSERV CL(WBEM).",
791 connectionUserName));
|
792 thilo.boehm 1.77
|
793 thilo.boehm 1.78 PEG_AUDIT_LOG(logCertificateBasedUserValidation(
|
794 kumpf 1.82 connectionUserName,
795 String::EMPTY,
796 String::EMPTY,
797 String::EMPTY,
798 httpMessage->ipAddress,
799 false));
|
800 thilo.boehm 1.78
|
801 thilo.boehm 1.77 _sendHttpError(
802 queueId,
803 HTTP_STATUS_UNAUTHORIZED,
804 String::EMPTY,
805 String::EMPTY,
806 closeConnect);
807
808 PEG_METHOD_EXIT();
809 return;
810 }
811 #endif
812 PEG_TRACE((TRC_HTTP, Tracer::LEVEL4,
|
813 kumpf 1.82 "Client UserID '%s' was authenticated via AT-TLS.",
|
814 thilo.boehm 1.77 (const char*)connectionUserName.getCString()));
815
816 httpMessage->authInfo->setAuthenticatedUser(
817 connectionUserName);
818
|
819 kumpf 1.93 // For audit loging, only the mapping of the client IP to
|
820 thilo.boehm 1.77 // the resolved user ID is from interest.
|
821 kumpf 1.93 // The SAF facility logs the certificate validation and
|
822 thilo.boehm 1.77 // the mapping of certificate subject to a local userID.
823 PEG_AUDIT_LOG(logCertificateBasedUserValidation(
824 connectionUserName,
825 String::EMPTY,
826 String::EMPTY,
827 String::EMPTY,
828 httpMessage->ipAddress,
829 true));
|
830 h.sterling 1.43
|
831 thilo.boehm 1.77 }// end is authenticated ?
|
832 h.sterling 1.34
|
833 thilo.boehm 1.77 } // end AuthenticationInfoRep::AUTH_TYPE_ZOS_ATTLS
|
834 humberto 1.33
|
835 kumpf 1.93 if (httpMessage->authInfo->getAuthType()==
|
836 thilo.boehm 1.77 AuthenticationInfoRep::AUTH_TYPE_ZOS_LOCAL_DOMIAN_SOCKET)
837 {
|
838 kumpf 1.93 String connectionUserName =
|
839 thilo.boehm 1.77 httpMessage->authInfo->getConnectionUser();
|
840 kumpf 1.68
|
841 kumpf 1.93 String requestUserName;
|
842 thilo.boehm 1.77 String authHeader;
843 String authHttpType;
844 String cookie;
845
|
846 kumpf 1.93 // if lookupHeader() is not successfull parseLocalAuthHeader()
|
847 thilo.boehm 1.77 // must not be called !!
848 if ( HTTPMessage::lookupHeader(headers,
849 _HTTP_HEADER_PEGASUSAUTHORIZATION, authHeader, false)&&
850 HTTPMessage::parseLocalAuthHeader(authHeader,
851 authHttpType, requestUserName, cookie))
852 {
853 String cimServerUserName = System::getEffectiveUserName();
|
854 humberto 1.33
|
855 thilo.boehm 1.77 PEG_TRACE((TRC_HTTP, Tracer::LEVEL4,
856 "CIM server UserID = '%s', "
857 "Request UserID = '%s', "
858 "Local authenticated UserID = '%s'.",
859 (const char*) cimServerUserName.getCString(),
860 (const char*) requestUserName.getCString(),
861 (const char*) connectionUserName.getCString()
862 ));
863
|
864 kumpf 1.93 // if the request name and the user connected to the socket
865 // are the same, or if the currnet user running the
|
866 thilo.boehm 1.77 // cim server and the connected user are the same then
867 // assign the request user id as authenticated user id.
868 if( String::equalNoCase(
|
869 kumpf 1.93 requestUserName,connectionUserName) ||
|
870 thilo.boehm 1.77 String::equalNoCase(
871 cimServerUserName,connectionUserName))
872 {
873 // If the designate new authenticated user, the user of
|
874 kumpf 1.93 // the request, is not already the authenticated user
|
875 thilo.boehm 1.77 // then set the authenticated user and check CIMSERV.
876 if (!String::equalNoCase(requestUserName,
877 httpMessage->authInfo->getAuthenticatedUser()))
878 {
|
879 mike 1.2
|
880 thilo.boehm 1.77 #ifdef PEGASUS_ZOS_SECURITY
|
881 kumpf 1.93 if ( !CheckProfileCIMSERVclassWBEM(requestUserName,
|
882 thilo.boehm 1.77 __READ_RESOURCE))
883 {
|
884 kumpf 1.93 Logger::put_l(Logger::STANDARD_LOG,
885 ZOS_SECURITY_NAME,
|
886 thilo.boehm 1.77 Logger::WARNING,
|
887 kumpf 1.88 MessageLoaderParms(
|
888 thilo.boehm 1.77 "Pegasus.Server.HTTPAuthenticatorDelegator."
889 "UNIXSOCKET_NOREAD_CIMSERV_ACCESS."
890 "PEGASUS_OS_ZOS",
891 "Request UserID $0 doesn't have READ "
892 "permission to profile "
893 "CIMSERV CL(WBEM).",
|
894 kumpf 1.88 requestUserName));
|
895 thilo.boehm 1.77
896 _sendHttpError(
897 queueId,
898 HTTP_STATUS_UNAUTHORIZED,
899 String::EMPTY,
900 String::EMPTY,
901 closeConnect);
902
903 PEG_METHOD_EXIT();
|
904 kumpf 1.82 return;
|
905 thilo.boehm 1.77 }
906 #endif
|
907 kumpf 1.93 // It is not necessary to check remote privileged
908 // user access for local connections;
|
909 thilo.boehm 1.79 // set the flag to "check done"
910 httpMessage->authInfo->
911 setRemotePrivilegedUserAccessChecked();
912
|
913 thilo.boehm 1.77 httpMessage->authInfo->setAuthenticatedUser(
914 requestUserName);
|
915 mike 1.2
|
916 thilo.boehm 1.77 PEG_TRACE((TRC_HTTP, Tracer::LEVEL4,
917 "New authenticated User = '%s'.",
918 (const char*)requestUserName.getCString()
919 ));
920
921 } // end changed authenticated user
922
923 PEG_TRACE((TRC_HTTP, Tracer::LEVEL4,
924 "User authenticated for request = '%s'.",
925 (const char*)httpMessage->authInfo->
926 getAuthenticatedUser().getCString()
927 ));
|
928 thilo.boehm 1.78
929 // Write local authentication audit record.
930 PEG_AUDIT_LOG(logLocalAuthentication(
931 requestUserName,true));
932
933 } // end select authenticated user
934 else
935 {
936 PEG_AUDIT_LOG(logLocalAuthentication(
937 requestUserName,false));
938
939 PEG_TRACE((TRC_HTTP, Tracer::LEVEL4,
940 "User '%s' not authorized for request",
941 (const char*)requestUserName.getCString()));
942
943 _sendHttpError(
944 queueId,
945 HTTP_STATUS_UNAUTHORIZED,
946 String::EMPTY,
947 String::EMPTY,
948 closeConnect);
949 thilo.boehm 1.78
950 PEG_METHOD_EXIT();
951 return;
952 }
|
953 thilo.boehm 1.77 } // end lookup header
954 else
|
955 kumpf 1.93 {
|
956 thilo.boehm 1.77 MessageLoaderParms msgParms(
957 "Pegasus.Server.HTTPAuthenticatorDelegator."
958 "AUTHORIZATION_HEADER_ERROR",
959 "Authorization header error");
960 String msg(MessageLoader::getMessage(msgParms));
961 _sendHttpError(
962 queueId,
963 HTTP_STATUS_BADREQUEST,
964 String::EMPTY,
965 msg,
966 closeConnect);
|
967 kumpf 1.19
|
968 thilo.boehm 1.77 PEG_METHOD_EXIT();
969 return;
970 }
971 } // end AuthenticationInfoRep::AUTH_TYPE_ZOS_LOCAL_DOMIAN_SOCKET
972 #endif
973 } // end isRequestAuthenticated
|
974 kumpf 1.82 else
|
975 thilo.boehm 1.77 { // !isRequestAuthenticated
|
976 mike 1.56
|
977 thilo.boehm 1.77 String authorization;
|
978 mike 1.2
|
979 kumpf 1.68 //
|
980 thilo.boehm 1.77 // do Local/Pegasus authenticatio
|
981 kumpf 1.68 //
982 if (HTTPMessage::lookupHeader(headers,
|
983 thilo.boehm 1.77 _HTTP_HEADER_PEGASUSAUTHORIZATION, authorization, false))
|
984 kumpf 1.28 {
|
985 kumpf 1.68 try
986 {
987 //
988 // Do pegasus/local authentication
989 //
|
990 sushma.fernandes 1.71 isRequestAuthenticated =
|
991 kumpf 1.68 _authenticationManager->performPegasusAuthentication(
992 authorization,
993 httpMessage->authInfo);
|
994 mike 1.2
|
995 sushma.fernandes 1.71 if (!isRequestAuthenticated)
|
996 kumpf 1.68 {
997 String authChallenge;
998 String authResp;
|
999 mike 1.2
|
1000 kumpf 1.68 authResp = _authenticationManager->
1001 getPegasusAuthResponseHeader(
1002 authorization,
1003 httpMessage->authInfo);
|
1004 kumpf 1.28
|
1005 kumpf 1.68 if (!String::equal(authResp, String::EMPTY))
1006 {
1007 _sendChallenge(queueId, authResp,closeConnect);
1008 }
1009 else
1010 {
1011 MessageLoaderParms msgParms(
1012 "Pegasus.Server.HTTPAuthenticatorDelegator."
1013 "AUTHORIZATION_HEADER_ERROR",
1014 "Authorization header error");
1015 String msg(MessageLoader::getMessage(msgParms));
1016 _sendHttpError(
1017 queueId,
1018 HTTP_STATUS_BADREQUEST,
1019 String::EMPTY,
1020 msg,
1021 closeConnect);
1022 }
1023
1024 PEG_METHOD_EXIT();
1025 return;
|
1026 kumpf 1.28 }
|
1027 kumpf 1.68 }
1028 catch (const CannotOpenFile&)
1029 {
1030 _sendHttpError(
1031 queueId,
1032 HTTP_STATUS_INTERNALSERVERERROR,
1033 String::EMPTY,
1034 String::EMPTY,
1035 closeConnect);
|
1036 kumpf 1.28 PEG_METHOD_EXIT();
1037 return;
|
1038 mike 1.2 }
|
1039 thilo.boehm 1.77 } // end PEGASUS/LOCAL authentication
|
1040 mike 1.2
|
1041 thilo.boehm 1.77 //
1042 // do HTTP authentication
1043 //
|
1044 kumpf 1.68 if (HTTPMessage::lookupHeader(
|
1045 kumpf 1.93 headers, _HTTP_HEADER_AUTHORIZATION,
1046 authorization, false))
|
1047 mike 1.2 {
|
1048 kumpf 1.82 isRequestAuthenticated =
1049 _authenticationManager->performHttpAuthentication(
1050 authorization,
1051 httpMessage->authInfo);
|
1052 kumpf 1.68
|
1053 kumpf 1.82 if (!isRequestAuthenticated)
1054 {
1055 //ATTN: the number of challenges get sent for a
1056 // request on a connection can be pre-set.
|
1057 gerarda 1.22 #ifdef PEGASUS_KERBEROS_AUTHENTICATION
|
1058 kumpf 1.82 // Kerberos authentication needs access to the
1059 // AuthenticationInfo object for this session in
1060 // order to set up the reference to the
1061 // CIMKerberosSecurityAssociation object for this
1062 // session.
|
1063 kumpf 1.68
|
1064 kumpf 1.82 String authResp =
1065 _authenticationManager->getHttpAuthResponseHeader(
1066 httpMessage->authInfo);
|
1067 gerarda 1.22 #else
|
1068 kumpf 1.82 String authResp =
1069 _authenticationManager->getHttpAuthResponseHeader();
|
1070 gerarda 1.22 #endif
|
1071 kumpf 1.82 if (!String::equal(authResp, String::EMPTY))
1072 {
1073 _sendChallenge(queueId, authResp, closeConnect);
1074 }
1075 else
1076 {
1077 MessageLoaderParms msgParms(
1078 "Pegasus.Server.HTTPAuthenticatorDelegator."
1079 "AUTHORIZATION_HEADER_ERROR",
1080 "Authorization header error");
1081 String msg(MessageLoader::getMessage(msgParms));
1082 _sendHttpError(
1083 queueId,
1084 HTTP_STATUS_BADREQUEST,
1085 String::EMPTY,
1086 msg,
1087 closeConnect);
1088 }
|
1089 kumpf 1.68
|
1090 kumpf 1.82 PEG_METHOD_EXIT();
1091 return;
1092 }
|
1093 kumpf 1.93 } // End if HTTP Authorization
|
1094 thilo.boehm 1.77
1095 } //end if (!isRequestAuthenticated)
1096
1097 } //end enableAuthentication
1098
|
1099 marek 1.84 PEG_TRACE_CSTRING(
1100 TRC_AUTHENTICATION,
|
1101 marek 1.86 Tracer::LEVEL3,
|
1102 marek 1.84 "HTTPAuthenticatorDelegator - Authentication processing ended");
|
1103 thilo.boehm 1.77
|
1104 kumpf 1.68
1105 #ifdef PEGASUS_KERBEROS_AUTHENTICATION
|
1106 thilo.boehm 1.77 // The pointer to the sa is created in the authenticator so we need
1107 // to also assign it here.
1108 sa = httpMessage->authInfo->getSecurityAssociation();
1109 if (sa)
1110 {
1111 // 0 - continue, 1 = send success, 2 = send response
1112 Uint32 sendAction = 0;
1113
1114 // The following is processing to unwrap (decrypt) the request
1115 // from the client when using kerberos authentication.
1116 sa->unwrapRequestMessage(
|
1117 kumpf 1.93 httpMessage->message,
1118 contentLength,
1119 isRequestAuthenticated,
|
1120 thilo.boehm 1.77 sendAction);
|
1121 kumpf 1.68
|
1122 thilo.boehm 1.77 if (sendAction) // send success or send response
1123 {
1124 if (httpMessage->message.size() == 0)
|
1125 kumpf 1.68 {
|
1126 thilo.boehm 1.77 MessageLoaderParms msgParms(
1127 "Pegasus.Server.HTTPAuthenticatorDelegator."
1128 "AUTHORIZATION_HEADER_ERROR",
1129 "Authorization header error");
1130 String msg(MessageLoader::getMessage(msgParms));
1131 _sendHttpError(
1132 queueId,
1133 HTTP_STATUS_BADREQUEST,
1134 String::EMPTY,
1135 msg,
1136 closeConnect);
1137 }
1138 else
1139 {
1140 if (sendAction == 1) // Send success
|
1141 kumpf 1.68 {
|
1142 thilo.boehm 1.77 _sendSuccess(
|
1143 kumpf 1.68 queueId,
|
1144 thilo.boehm 1.77 String(
1145 httpMessage->message.getData(),
1146 httpMessage->message.size()),
|
1147 kumpf 1.68 closeConnect);
1148 }
|
1149 thilo.boehm 1.77
1150 if (sendAction == 2) // Send response
|
1151 kumpf 1.68 {
|
1152 thilo.boehm 1.77 _sendResponse(
1153 queueId,
1154 httpMessage->message,
1155 closeConnect);
1156 }
1157 }
|
1158 mike 1.2
|
1159 thilo.boehm 1.77 PEG_METHOD_EXIT();
1160 return;
1161 }
1162 }
1163 #endif
|
1164 gerarda 1.26
|
1165 thilo.boehm 1.77 if (isRequestAuthenticated || !enableAuthentication)
1166 {
1167 // Final bastion to ensure the remote privileged user access
1168 // check is done as it should be
1169 // check for remote privileged User Access
1170 if (!httpMessage->authInfo->getRemotePrivilegedUserAccessChecked())
1171 {
1172 // the AuthenticationHandler did not process the
1173 // enableRemotePrivilegedUserAccess check
1174 // time to do it ourselves
1175 String userName = httpMessage->authInfo->getAuthenticatedUser();
1176 if (!AuthenticationManager::isRemotePrivilegedUserAccessAllowed(
1177 userName))
1178 {
1179 // Send client a message that we can't proceed to talk
1180 // to him
1181 // HTTP 401 ?
1182 MessageLoaderParms msgParms(
1183 "Server.CIMOperationRequestAuthorizer."
1184 "REMOTE_NOT_ENABLED",
1185 "Remote privileged user access is not enabled.");
1186 thilo.boehm 1.77 String msg(MessageLoader::getMessage(msgParms));
1187 _sendHttpError(
1188 queueId,
1189 HTTP_STATUS_UNAUTHORIZED,
1190 String::EMPTY,
1191 msg,
1192 closeConnect);
|
1193 kumpf 1.68 PEG_METHOD_EXIT();
1194 return;
1195 }
|
1196 thilo.boehm 1.77 httpMessage->authInfo->setRemotePrivilegedUserAccessChecked();
|
1197 kumpf 1.68 }
|
1198 h.sterling 1.34
|
1199 thilo.boehm 1.77 //
|
1200 kumpf 1.83 // Determine the type of this request:
|
1201 thilo.boehm 1.77 //
|
1202 kumpf 1.83 // - A "CIMOperation" header indicates a CIM operation request
1203 // - A "CIMExport" header indicates a CIM export request
1204 // - A "/wsman" path in the start message indicates a WS-Man request
1205 //
1206
|
1207 kumpf 1.94 const char* cimOperation;
|
1208 thilo.boehm 1.77
1209 if (HTTPMessage::lookupHeader(
|
1210 kumpf 1.94 headers, _HTTP_HEADER_CIMOPERATION, cimOperation, true))
|
1211 mike 1.2 {
|
1212 marek 1.84 PEG_TRACE((
1213 TRC_HTTP,
1214 Tracer::LEVEL3,
|
1215 kumpf 1.94 "HTTPAuthenticatorDelegator - CIMOperation: %s",
1216 cimOperation));
|
1217 thilo.boehm 1.77
1218 MessageQueue* queue =
|
1219 kumpf 1.83 MessageQueue::lookup(_cimOperationMessageQueueId);
|
1220 thilo.boehm 1.77
1221 if (queue)
1222 {
1223 httpMessage->dest = queue->getQueueId();
1224
1225 try
1226 {
1227 queue->enqueue(httpMessage);
1228 }
1229 catch (const bad_alloc&)
|
1230 marek 1.67 {
|
1231 thilo.boehm 1.77 delete httpMessage;
|
1232 venkat.puvvada 1.96 HTTPConnection *httpQueue =
1233 dynamic_cast<HTTPConnection*>(
1234 MessageQueue::lookup(queueId));
1235 if (httpQueue)
1236 {
1237 httpQueue->handleInternalServerError(0, true);
1238 }
|
1239 marek 1.67 PEG_METHOD_EXIT();
|
1240 thilo.boehm 1.77 deleteMessage = false;
|
1241 marek 1.67 return;
1242 }
|
1243 thilo.boehm 1.77 deleteMessage = false;
|
1244 marek 1.67 }
|
1245 thilo.boehm 1.77 }
1246 else if (HTTPMessage::lookupHeader(
|
1247 kumpf 1.94 headers, _HTTP_HEADER_CIMEXPORT, cimOperation, true))
|
1248 thilo.boehm 1.77 {
|
1249 marek 1.84 PEG_TRACE((
1250 TRC_AUTHENTICATION,
1251 Tracer::LEVEL3,
|
1252 kumpf 1.94 "HTTPAuthenticatorDelegator - CIMExport: %s",
1253 cimOperation));
|
1254 marek 1.67
|
1255 thilo.boehm 1.77 MessageQueue* queue =
|
1256 kumpf 1.83 MessageQueue::lookup(_cimExportMessageQueueId);
|
1257 mike 1.2
|
1258 thilo.boehm 1.77 if (queue)
|
1259 mike 1.2 {
|
1260 thilo.boehm 1.77 httpMessage->dest = queue->getQueueId();
|
1261 mike 1.2
|
1262 thilo.boehm 1.77 queue->enqueue(httpMessage);
1263 deleteMessage = false;
|
1264 mike 1.2 }
|
1265 thilo.boehm 1.77 }
|
1266 kumpf 1.83 else if ((_wsmanOperationMessageQueueId != PEG_NOT_FOUND) &&
1267 ((requestUri == "/wsman") ||
1268 ((requestUri == "/wsman-anon") && !enableAuthentication)))
1269 {
1270 // Note: DSP0226 R5.3-1 specifies if /wsman is used,
1271 // unauthenticated access should not be allowed. This "should"
1272 // requirement is not implemented here, because it is difficult
1273 // for a client to determine whether enableAuthentication=true.
1274
1275 // DSP0226 R5.3-2 specifies if /wsman-anon is used, authenticated
1276 // access shall not be required. Unauthenticated access is
1277 // currently not allowed if enableAuthentication=true. When
1278 // support for wsmid:Identify is added, it will be necessary to
1279 // respond to that request without requiring authentication,
1280 // regardless of the CIM Server configuration.
1281
1282 MessageQueue* queue =
1283 MessageQueue::lookup(_wsmanOperationMessageQueueId);
1284
1285 if (queue)
1286 {
1287 kumpf 1.83 httpMessage->dest = queue->getQueueId();
1288
1289 try
1290 {
1291 queue->enqueue(httpMessage);
1292 }
1293 catch (const bad_alloc&)
1294 {
1295 delete httpMessage;
|
1296 venkat.puvvada 1.96 HTTPConnection *httpQueue =
1297 dynamic_cast<HTTPConnection*>(
1298 MessageQueue::lookup(queueId));
1299 if (httpQueue)
1300 {
1301 httpQueue->handleInternalServerError(0, true);
1302 }
|
1303 kumpf 1.83 PEG_METHOD_EXIT();
1304 deleteMessage = false;
1305 return;
1306 }
1307 deleteMessage = false;
1308 }
1309 }
|
1310 thilo.boehm 1.77 else
1311 {
1312 // We don't recognize this request message type
|
1313 david 1.21
|
1314 thilo.boehm 1.77 // The Specification for CIM Operations over HTTP reads:
1315 //
1316 // 3.3.4. CIMOperation
1317 //
1318 // If a CIM Server receives a CIM Operation request without
1319 // this [CIMOperation] header, it MUST NOT process it as if
1320 // it were a CIM Operation Request. The status code
1321 // returned by the CIM Server in response to such a request
1322 // is outside of the scope of this specification.
1323 //
1324 // 3.3.5. CIMExport
1325 //
1326 // If a CIM Listener receives a CIM Export request without
1327 // this [CIMExport] header, it MUST NOT process it. The
1328 // status code returned by the CIM Listener in response to
1329 // such a request is outside of the scope of this
1330 // specification.
1331 //
1332 // The author has chosen to send a 400 Bad Request error, but
1333 // without the CIMError header since this request must not be
1334 // processed as a CIM request.
1335 thilo.boehm 1.77
1336 _sendHttpError(
1337 queueId,
1338 HTTP_STATUS_BADREQUEST,
1339 String::EMPTY,
1340 String::EMPTY,
1341 closeConnect);
1342 PEG_METHOD_EXIT();
1343 return;
1344 } // bad request
1345 } // isRequestAuthenticated and enableAuthentication check
1346 else
1347 { // client not authenticated; send challenge
|
1348 gerarda 1.22 #ifdef PEGASUS_KERBEROS_AUTHENTICATION
|
1349 thilo.boehm 1.77 String authResp =
1350 _authenticationManager->getHttpAuthResponseHeader(
1351 httpMessage->authInfo);
|
1352 gerarda 1.22 #else
|
1353 thilo.boehm 1.77 String authResp =
1354 _authenticationManager->getHttpAuthResponseHeader();
|
1355 gerarda 1.22 #endif
|
1356 mike 1.2
|
1357 thilo.boehm 1.77 if (!String::equal(authResp, String::EMPTY))
1358 {
1359 _sendChallenge(queueId, authResp,closeConnect);
1360 }
1361 else
1362 {
1363 MessageLoaderParms msgParms(
1364 "Pegasus.Server.HTTPAuthenticatorDelegator."
1365 "AUTHORIZATION_HEADER_ERROR",
1366 "Authorization header error");
1367 String msg(MessageLoader::getMessage(msgParms));
1368 _sendHttpError(
1369 queueId,
1370 HTTP_STATUS_BADREQUEST,
1371 String::EMPTY,
1372 msg,
1373 closeConnect);
|
1374 mike 1.2 }
|
1375 thilo.boehm 1.77 }
|
1376 kumpf 1.11
|
1377 thilo.boehm 1.77 PEG_METHOD_EXIT();
|
1378 mike 1.2 }
1379
1380 PEGASUS_NAMESPACE_END
|