1 a.rachapudi 1.1 //%LICENSE////////////////////////////////////////////////////////////////
2 //
3 // 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 //
10 // 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 //
17 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 a.rachapudi 1.1 // 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 //
28 //////////////////////////////////////////////////////////////////////////
29
30 ///////////////////////////////////////////////////////////////////////////
31 // Dispatcher.cpp: implementation of the CDispatcher class.
32 //
33 //////////////////////////////////////////////////////////////////////////
34
35 #include "stdafx.h"
36 #include "Dispatcher.h"
37
38 #include <Pegasus/Common/CIMInstance.h>
39 #include <Pegasus/Common/CIMIndication.h>
40 #include <Pegasus/Common/SSLContext.h>
41 #include <Pegasus/Common/FileSystem.h>
42 #include <Pegasus/ExportClient/CIMExportClient.h>
43 a.rachapudi 1.1 #include <Pegasus/Common/Config.h>
44 #include <Pegasus/Common/Tracer.h>
45 #include <Pegasus/Common/ContentLanguageList.h>
46
47 #include "ConsumerTracer.h"
48
49 PEGASUS_NAMESPACE_BEGIN
50
51 /////////////////////////////////////////////////////////////////////////////
52 // verifyCertificate
53 //
54 // If server certificate was found in CA trust store and validated, then
55 // return 'true' to accept the certificate, otherwise return 'false'.
56 //
57 /////////////////////////////////////////////////////////////////////////////
58 static Boolean verifyCertificate(SSLCertificateInfo &certInfo)
59 {
60 return true;
61 if (certInfo.getResponseCode() == 1)
62 {
63 return true;
64 a.rachapudi 1.1 }
65 else
66 {
67 return false;
68 }
69 }
70
71 //////////////////////////////////////////////////////////////////////
72 // Construction/Destruction
73 //////////////////////////////////////////////////////////////////////
74 CDispatcher::CDispatcher()
75 {
76
77 }
78
79 CDispatcher::~CDispatcher()
80 {
81
82 }
83
84 /////////////////////////////////////////////////////////////////////////////
85 a.rachapudi 1.1 // _getRegInfo()
86 //
87 /////////////////////////////////////////////////////////////////////////////
88 bool CDispatcher::_getPegasusHome(char *lpchRetValue)
89 {
90 HKEY hKey;
91 DWORD dw = _MAX_PATH;
92 char subKey[_MAX_PATH] = {0};
93
94 CNS_METHOD_ENTER(TRC_WMI_MAPPER_CONSUMER,
95 "CDispatcher::_getPegasusHome");
96
97 sprintf(subKey,
98 TEXT("SYSTEM\\CurrentControlSet\\"
99 "Control\\Session Manager\\Environment"));
100
101 if ((RegOpenKeyEx(HKEY_LOCAL_MACHINE,
102 subKey,
103 0,
104 KEY_READ,
105 &hKey)) != ERROR_SUCCESS)
106 a.rachapudi 1.1 {
107
108 CNS_TRACE((Pegasus::TRC_WMI_MAPPER_CONSUMER,
109 Pegasus::Tracer::LEVEL4,
110 "CDispatcher::_getPegasusHome, \
111 error in RegOpenKeyEx"));
112
113 CNS_METHOD_EXIT();
114 return false;
115 }
116
117 if ((RegQueryValueEx(hKey,
118 TEXT("PEGASUS_HOME"),
119 NULL,
120 NULL,
121 (LPBYTE)lpchRetValue,
122 &dw)) != ERROR_SUCCESS)
123 {
124 RegCloseKey(hKey);
125
126 CNS_TRACE((Pegasus::TRC_WMI_MAPPER_CONSUMER,
127 a.rachapudi 1.1 Pegasus::Tracer::LEVEL4,
128 "CDispatcher::_getPegasusHome, \
129 error in RegQueryValueEx"));
130
131 CNS_METHOD_EXIT();
132 return false;
133 }
134
135 RegCloseKey(hKey);
136
137 CNS_METHOD_EXIT();
138 return true;
139 }
140
141
142 /////////////////////////////////////////////////////////////////////////////
143 // String _getMalformedExceptionMsg()
144 //
145 /////////////////////////////////////////////////////////////////////////////
146 String CDispatcher::_getMalformedExceptionMsg()
147 {
148 a.rachapudi 1.1 MessageLoaderParms param(
149 "Handler.CIMxmlIndicationHandler.CIMxmlIndicationHandler.ERROR",
150 "CIMxmlIndicationHandler Error: ");
151
152 MessageLoaderParms param1(
153 "Handler.CIMxmlIndicationHandler.CIMxmlIndicationHandler."
154 "MALFORMED_HANDLER_INSTANCE",
155 "Malformed handler instance.");
156
157 return (String(MessageLoader::getMessage(param) +
158 MessageLoader::getMessage(param1)));
159 }
160
161 /////////////////////////////////////////////////////////////////////////////
162 //dispatchIndication
163 //
164 // Connect and send indication over HTTP. The property "destination" of
165 // indicationHandlerInstance indicates the host and port that will receive the
166 // indicatioInstance. The method verfies if the host will be acessed by http or
167 // https using "destination" and use SSL if necessary.
168 //
169 a.rachapudi 1.1 /////////////////////////////////////////////////////////////////////////////
170 void CDispatcher::dispatchIndication(
171 CIMInstance& indicationHandlerInstance,
172 CIMInstance& indicationInstance)
173 {
174 CNS_METHOD_ENTER(TRC_WMI_MAPPER_CONSUMER,
175 "CDispatcher::_dispatchIndication");
176 //get destination for the indication
177 Uint32 pos = indicationHandlerInstance.findProperty(CIMName("Destination"));
178 if (pos == PEG_NOT_FOUND)
179 {
180 String msg = _getMalformedExceptionMsg();
181
182 CNS_METHOD_EXIT();
183 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, msg);
184 }
185
186 CIMProperty prop = indicationHandlerInstance.getProperty(pos);
187
188 String dest;
189 try
190 a.rachapudi 1.1 {
191 prop.getValue().get(dest);
192 }
193 catch (TypeMismatchException& e)
194 {
195 MessageLoaderParms param(
196 "Handler.CIMxmlIndicationHandler.CIMxmlIndicationHandler.ERROR",
197 "CIMxmlIndicationHandler Error: ");
198
199 String msg = String(MessageLoader::getMessage(param) + e.getMessage());
200
201 CNS_METHOD_EXIT();
202 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, msg);
203 }
204
205 try
206 {
207 const char* pegasusHome;
208 char tmpHome[512];
209
210 if (GetEnvironmentVariable("PEGASUS_HOME", tmpHome, 512)) {
211 a.rachapudi 1.1 pegasusHome = tmpHome;
212 CNS_TRACE((Pegasus::TRC_WMI_MAPPER_CONSUMER,
213 Pegasus::Tracer::LEVEL4,
214 "CDispatcher::_dispatchIndication, PEGASUS_HOME: %s",
215 pegasusHome));
216 }
217 else if (_getPegasusHome(tmpHome))
218 {
219 pegasusHome = tmpHome;
220 CNS_TRACE((Pegasus::TRC_WMI_MAPPER_CONSUMER,
221 Pegasus::Tracer::LEVEL4,
222 "CDispatcher::_dispatchIndication, PEGASUS_HOME: %s",
223 pegasusHome));
224 }
225 else
226 {
227 CNS_TRACE((Pegasus::TRC_WMI_MAPPER_CONSUMER,
228 Pegasus::Tracer::LEVEL4,
229 "CDispatcher::_dispatchIndication, PEGASUS_HOME env variable "
230 "not found"));
231
232 a.rachapudi 1.1 pegasusHome = "";
233 }
234
235 String trustPath = FileSystem::getAbsolutePath(
236 pegasusHome,
237 PEGASUS_SSLCLIENT_CERTIFICATEFILE);
238
239 String certPath = FileSystem::getAbsolutePath(
240 pegasusHome,
241 "server.pem");
242
243 String keyPath = FileSystem::getAbsolutePath(
244 pegasusHome, "file.pem");
245
246 String randFile = String::EMPTY;
247
248 #ifdef PEGASUS_SSL_RANDOMFILE
249 randFile = FileSystem::getAbsolutePath(
250 pegasusHome,
251 PEGASUS_SSLCLIENT_RANDOMFILE);
252 #endif
253 a.rachapudi 1.1
254 SSLContext sslContext(
255 trustPath,
256 certPath,
257 keyPath,
258 verifyCertificate,
259 randFile);
260
261 #ifdef PEGASUS_USE_23HTTPMONITOR_CLIENT
262 Monitor monitor;
263 HTTPConnector httpConnector( &monitor );
264 #else
265 monitor_2 monitor;
266 HTTPConnector2 httpConnector( &monitor );
267 #endif
268
269 CIMExportClient exportclient( &monitor, &httpConnector);
270 Uint32 colon = dest.find (":");
271 Uint32 portNumber = 0;
272 Boolean useHttps = false;
273 String destStr = dest;
274 a.rachapudi 1.1 String hostStr;
275 Uint32 openBracket = PEG_NOT_FOUND;
276 Uint32 closeBracket = PEG_NOT_FOUND;
277
278
279 //
280 // If the URL has https (https://hostname:port/... or
281 // https://hostname/...) then use SSL for Indication delivery.
282 // If it has http (http://hostname:port/...
283 // or http://hostname/...) then do not use SSL.
284 //
285 if (colon != PEG_NOT_FOUND)
286 {
287 String httpStr = dest.subString(0, colon);
288 if (String::equalNoCase(httpStr, "https"))
289 {
290 useHttps = true;
291 }
292 else if (String::equalNoCase(httpStr, "http"))
293 {
294 useHttps = false;
295 a.rachapudi 1.1 }
296 else
297 {
298 String msg = _getMalformedExceptionMsg();
299
300 CNS_METHOD_EXIT();
301 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, msg + dest);
302 }
303 }
304 else
305 {
306 String msg = _getMalformedExceptionMsg();
307
308 CNS_METHOD_EXIT();
309 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, msg + dest);
310 }
311
312 String doubleSlash = dest.subString(colon + 1, 2);
313
314 if (String::equalNoCase(doubleSlash, "//"))
315 {
316 a.rachapudi 1.1 destStr = dest.subString(colon + 3, PEG_NOT_FOUND);
317 }
318 else
319 {
320 String msg = _getMalformedExceptionMsg();
321
322 CNS_METHOD_EXIT();
323 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, msg + dest);
324 }
325
326 char dummy[64];
327 dummy[0] = 0;
328 openBracket = destStr.find ("[");
329
330 if (openBracket != PEG_NOT_FOUND) // IPv6 Address
331 {
332 closeBracket = destStr.find ("]");
333 hostStr = destStr.subString(openBracket + 1, closeBracket - 1);
334 destStr = destStr.subString(closeBracket + 1, PEG_NOT_FOUND);
335 colon = destStr.find (":");
336
337 a.rachapudi 1.1 destStr = destStr.subString(colon + 1, PEG_NOT_FOUND);
338 }
339 else // IPv4 / hostname Address
340 {
341 colon = destStr.find (":");
342 hostStr = destStr.subString(0, colon);
343 destStr = destStr.subString(colon + 1, PEG_NOT_FOUND);
344 }
345
346 if (colon != PEG_NOT_FOUND)
347 {
348 Uint32 slash = destStr.find ("/");
349 String portStr;
350
351 if (slash != PEG_NOT_FOUND)
352 {
353 portStr = destStr.subString (0, slash);
354 }
355 else
356 {
357 portStr = destStr.subString (0, PEG_NOT_FOUND);
358 a.rachapudi 1.1 }
359
360 sscanf (portStr.getCString (), "%u%s", &portNumber, dummy);
361 }
362
363 //
364 // There is no port number in the destination string,
365 // get port number from system
366 //
367 else
368 {
369 Uint32 slash = destStr.find ("/");
370 if (slash != PEG_NOT_FOUND)
371 {
372 hostStr = destStr.subString (0, slash);
373 }
374 else
375 {
376 hostStr = destStr.subString (0, PEG_NOT_FOUND);
377 }
378
379 a.rachapudi 1.1 if (useHttps)
380 {
381 portNumber = System::lookupPort(
382 WBEM_HTTPS_SERVICE_NAME,
383 WBEM_DEFAULT_HTTPS_PORT);
384 }
385 else
386 {
387 portNumber = System::lookupPort(
388 WBEM_HTTP_SERVICE_NAME,
389 WBEM_DEFAULT_HTTP_PORT);
390 }
391 }
392
393 char hostName[64];
394 char dummy2[64];
395 dummy2[0] = 0;
396
397 sscanf (hostStr.getCString (), "%s%s", hostName, dummy2);
398
399 if (dummy[0] != 0 || dummy2[0] != 0)
400 a.rachapudi 1.1 {
401 String msg = _getMalformedExceptionMsg();
402
403 CNS_METHOD_EXIT();
404 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, msg + dest);
405 }
406
407 CNS_TRACE((
408 Pegasus::TRC_WMI_MAPPER_CONSUMER,
409 Pegasus::Tracer::LEVEL4,
410 "CDispatcher::_dispatchIndication, hostname:%s portnumer:%u",
411 hostName, portNumber));
412
413 if (useHttps)
414 {
415 #ifdef PEGASUS_HAS_SSL
416 exportclient.connect (hostName, portNumber, sslContext);
417 #else
418
419 MessageLoaderParms param(
420 "Handler.CIMxmlIndicationHandler."
421 a.rachapudi 1.1 "CIMxmlIndicationHandler.ERROR",
422 "CIMxmlIndicationHandler Error: ");
423 MessageLoaderParms param1(
424 "Handler.CIMxmlIndicationHandler.CIMxmlIndicationHandler."
425 "CANNOT_DO_HTTPS_CONNECTION",
426 "Cannot do https connection.");
427
428 PEG_TRACE_STRING(
429 TRC_WMI_MAPPER_CONSUMER,
430 Tracer::LEVEL3,
431 MessageLoader::getMessage(param) +
432 MessageLoader::getMessage(param1));
433
434 String msg = String(
435 MessageLoader::getMessage(param) +
436 MessageLoader::getMessage(param1));
437
438 CNS_METHOD_EXIT();
439 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, msg);
440 #endif
441 }
442 a.rachapudi 1.1 else
443 {
444 exportclient.connect (hostName, portNumber);
445 }
446
447
448 // check destStr, if no path is specified, use "/" for the URI
449 Uint32 slash = destStr.find ("/");
450 ContentLanguageList contentLanguages = ContentLanguageList();
451 if (slash != PEG_NOT_FOUND)
452 {
453 exportclient.exportIndication(
454 destStr.subString(slash), indicationInstance,
455 contentLanguages);
456 }
457 else
458 {
459 exportclient.exportIndication(
460 "/", indicationInstance, contentLanguages);
461 }
462 }
463 a.rachapudi 1.1 catch(Exception& e)
464 {
465 //ATTN: Catch specific exceptions and log the error message
466 // as Indication delivery failed.
467
468 String msg = String(e.getMessage());
469
470 CNS_TRACE((
471 Pegasus::TRC_WMI_MAPPER_CONSUMER,
472 Pegasus::Tracer::LEVEL4,
473 "CDispatcher::_dispatchIndication, Dispatch failed: %s", msg));
474
475 CNS_METHOD_EXIT();
476 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, msg);
477 }
478
479 CNS_METHOD_EXIT();
480 }
481
482 PEGASUS_NAMESPACE_END
|