1 karl 1.38 //%2006////////////////////////////////////////////////////////////////////////
|
2 mike 1.2 //
|
3 karl 1.31 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
4 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
5 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
|
6 karl 1.21 // IBM Corp.; EMC Corporation, The Open Group.
|
7 karl 1.31 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
|
9 karl 1.33 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 karl 1.38 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
|
13 mike 1.2 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
|
15 kumpf 1.8 // of this software and associated documentation files (the "Software"), to
16 // deal in the Software without restriction, including without limitation the
17 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
18 mike 1.2 // sell copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
20 //
|
21 kumpf 1.8 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
|
22 mike 1.2 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
23 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
24 kumpf 1.8 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
25 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
27 mike 1.2 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
|
30 kumpf 1.42 //==============================================================================
31 //
|
32 mike 1.2 //%/////////////////////////////////////////////////////////////////////////////
33
34 #include <Pegasus/ExportClient/CIMExportClient.h>
35 #include <Pegasus/Handler/CIMHandler.h>
36 #include <Pegasus/Repository/CIMRepository.h>
|
37 kumpf 1.15 #include <Pegasus/Config/ConfigManager.h>
|
38 kumpf 1.20 #include <Pegasus/Common/Config.h>
39 #include <Pegasus/Common/PegasusVersion.h>
|
40 kumpf 1.16 #include <Pegasus/Common/Constants.h>
|
41 kumpf 1.20 #include <Pegasus/Common/SSLContext.h>
|
42 kumpf 1.16 #include <Pegasus/Common/System.h>
|
43 kumpf 1.20 #include <Pegasus/Common/Tracer.h>
|
44 mike 1.2
45 PEGASUS_NAMESPACE_BEGIN
46
47 PEGASUS_USING_STD;
48
49
|
50 kumpf 1.42 static Boolean verifyListenerCertificate(SSLCertificateInfo& certInfo)
|
51 kumpf 1.13 {
52 // ATTN: Add code to handle listener certificate verification.
53 //
54 return true;
55 }
56
57
|
58 mike 1.2 class PEGASUS_HANDLER_LINKAGE CIMxmlIndicationHandler: public CIMHandler
59 {
60 public:
61
62 CIMxmlIndicationHandler()
63 {
|
64 kumpf 1.42 PEG_METHOD_ENTER(TRC_IND_HANDLER,
|
65 kumpf 1.20 "CIMxmlIndicationHandler::CIMxmlIndicationHandler");
66 PEG_METHOD_EXIT();
|
67 mike 1.2 }
68
69 virtual ~CIMxmlIndicationHandler()
70 {
|
71 kumpf 1.42 PEG_METHOD_ENTER(TRC_IND_HANDLER,
|
72 kumpf 1.20 "CIMxmlIndicationHandler::~CIMxmlIndicationHandler");
73 PEG_METHOD_EXIT();
|
74 mike 1.2 }
75
76 void initialize(CIMRepository* repository)
77 {
|
78 kumpf 1.20
|
79 mike 1.2 }
80
81 void terminate()
82 {
|
83 kumpf 1.20
|
84 mike 1.2 }
85
86 void handleIndication(
|
87 kumpf 1.20 const OperationContext& context,
|
88 yi.zhou 1.34 const String nameSpace,
|
89 kumpf 1.42 CIMInstance& indicationInstance,
90 CIMInstance& indicationHandlerInstance,
|
91 yi.zhou 1.34 CIMInstance& indicationSubscriptionInstance,
|
92 kumpf 1.37 ContentLanguageList& contentLanguages)
|
93 mike 1.2 {
|
94 kumpf 1.42 PEG_METHOD_ENTER(TRC_IND_HANDLER,
|
95 kumpf 1.28 "CIMxmlIndicationHandler::handleIndication()");
|
96 kumpf 1.20
97 //get destination for the indication
|
98 denise.eckstein 1.39 Uint32 pos = indicationHandlerInstance.findProperty(
99 CIMName ("destination"));
|
100 mike 1.2 if (pos == PEG_NOT_FOUND)
101 {
|
102 carolann.graves 1.43 MessageLoaderParms param(
103 "Handler.CIMxmlIndicationHandler.CIMxmlIndicationHandler."
104 "MALFORMED_HANDLER_INSTANCE",
105 "Malformed CIM-XML handler instance, "
106 "\'Destination\' property is not found.");
107
108 String msg = String(MessageLoader::getMessage(param));
|
109 kumpf 1.20
110 PEG_TRACE_STRING(TRC_IND_HANDLER, Tracer::LEVEL4, msg);
111
|
112 kumpf 1.42 PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
|
113 carolann.graves 1.35 "CIMxmlIndicationHandler::handleIndication failed to deliver "
114 "indication: Destination property missing");
115
|
116 kumpf 1.20 PEG_METHOD_EXIT();
117 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, msg);
|
118 mike 1.2 }
119
|
120 kumpf 1.20 CIMProperty prop = indicationHandlerInstance.getProperty(pos);
|
121 mike 1.2
122 String dest;
123 try
124 {
125 prop.getValue().get(dest);
126 }
|
127 kumpf 1.9 catch (TypeMismatchException& e)
|
128 mike 1.2 {
|
129 kumpf 1.20 MessageLoaderParms param(
|
130 carolann.graves 1.43 "Handler.CIMxmlIndicationHandler.CIMxmlIndicationHandler."
131 "DESTINATION_TYPE_MISMATCH",
132 "Malformed CIM-XML handler instance, "
133 "\'Destination\' property type mismatch.");
|
134 kumpf 1.20
|
135 carolann.graves 1.43 String msg = MessageLoader::getMessage(param);
|
136 kumpf 1.20
137 PEG_TRACE_STRING(TRC_IND_HANDLER, Tracer::LEVEL4, msg);
138
|
139 kumpf 1.42 PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
|
140 carolann.graves 1.35 "CIMxmlIndicationHandler::handleIndication failed to deliver "
141 "indication: Destination property type mismatch");
142
|
143 kumpf 1.20 PEG_METHOD_EXIT();
144 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, msg);
|
145 mike 1.2 }
|
146 kumpf 1.42
|
147 kumpf 1.20 try
|
148 mike 1.2 {
|
149 denise.eckstein 1.39 static String PROPERTY_NAME__SSLCERT_FILEPATH =
150 "sslCertificateFilePath";
|
151 kumpf 1.13 static String PROPERTY_NAME__SSLKEY_FILEPATH = "sslKeyFilePath";
152
153 //
154 // Get the sslCertificateFilePath property from the Config Manager.
155 //
|
156 kumpf 1.20 ConfigManager* configManager = ConfigManager::getInstance();
|
157 kumpf 1.15
|
158 kumpf 1.13 String certPath;
|
159 denise.eckstein 1.36 certPath = ConfigManager::getHomedPath(
160 configManager->getCurrentValue(
161 PROPERTY_NAME__SSLCERT_FILEPATH));
|
162 kumpf 1.13
163 //
164 // Get the sslKeyFilePath property from the Config Manager.
165 //
166 String keyPath;
|
167 denise.eckstein 1.36 keyPath = ConfigManager::getHomedPath(
168 configManager->getCurrentValue(
169 PROPERTY_NAME__SSLKEY_FILEPATH));
|
170 kumpf 1.13
171 String trustPath = String::EMPTY;
172
173 String randFile = String::EMPTY;
174
175 #ifdef PEGASUS_SSL_RANDOMFILE
|
176 kumpf 1.42 randFile =
177 ConfigManager::getHomedPath(PEGASUS_SSLSERVER_RANDOMFILE);
|
178 kumpf 1.13 #endif
179
|
180 kumpf 1.20 Monitor monitor;
|
181 kumpf 1.42 HTTPConnector httpConnector(&monitor);
|
182 dj.gorey 1.22
|
183 kumpf 1.42 CIMExportClient exportclient(&monitor, &httpConnector);
|
184 kumpf 1.11 Uint32 colon = dest.find (":");
185 Uint32 portNumber = 0;
|
186 kumpf 1.13 Boolean useHttps = false;
187 String destStr = dest;
|
188 kumpf 1.25 String hostStr;
|
189 kumpf 1.13
190 //
|
191 kumpf 1.16 // If the URL has https (https://hostname:port/... or
|
192 kumpf 1.42 // https://hostname/...) then use SSL for Indication delivery.
|
193 kumpf 1.20 // If it has http (http://hostname:port/...
194 // or http://hostname/...) then do not use SSL.
|
195 kumpf 1.13 //
|
196 kumpf 1.42 if (colon != PEG_NOT_FOUND)
|
197 kumpf 1.13 {
|
198 kumpf 1.42 String httpStr = dest.subString(0, colon);
|
199 a.dunfey 1.29 if (String::equalNoCase(httpStr, "https"))
|
200 kumpf 1.13 {
201 useHttps = true;
202 }
|
203 a.dunfey 1.29 else if (String::equalNoCase(httpStr, "http"))
|
204 kumpf 1.16 {
205 useHttps = false;
206 }
|
207 kumpf 1.20 else
208 {
|
209 carolann.graves 1.43 String msg = _getMalformedExceptionMsg(dest);
|
210 kumpf 1.20
|
211 denise.eckstein 1.39 PEG_TRACE_STRING(TRC_IND_HANDLER, Tracer::LEVEL4, msg+dest);
|
212 kumpf 1.42 PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
|
213 carolann.graves 1.35 "CIMxmlIndicationHandler::handleIndication failed to "
214 "deliver indication: "
215 "missing http or https "
216 "in Destination " + dest);
|
217 kumpf 1.20
218 PEG_METHOD_EXIT();
|
219 denise.eckstein 1.39 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED,
|
220 carolann.graves 1.43 msg);
|
221 kumpf 1.20 }
222 }
223 else
224 {
|
225 carolann.graves 1.43 String msg = _getMalformedExceptionMsg(dest);
|
226 kumpf 1.20
227 PEG_TRACE_STRING(TRC_IND_HANDLER, Tracer::LEVEL4, msg + dest);
228
|
229 kumpf 1.42 PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
|
230 carolann.graves 1.35 "CIMxmlIndicationHandler::handleIndication failed to "
231 "deliver indication: "
232 "missing colon "
233 "in Destination " + dest);
234
|
235 kumpf 1.20 PEG_METHOD_EXIT();
|
236 carolann.graves 1.43 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, msg);
|
237 kumpf 1.20 }
238
|
239 kumpf 1.42 String doubleSlash = dest.subString(colon + 1, 2);
|
240 kumpf 1.20
241 if (String::equalNoCase(doubleSlash, "//"))
242 {
243 destStr = dest.subString(colon + 3, PEG_NOT_FOUND);
244 }
245 else
246 {
|
247 carolann.graves 1.43 String msg = _getMalformedExceptionMsg(dest);
|
248 kumpf 1.20
249 PEG_TRACE_STRING(TRC_IND_HANDLER, Tracer::LEVEL4, msg + dest);
250
|
251 kumpf 1.42 PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
|
252 carolann.graves 1.35 "CIMxmlIndicationHandler::handleIndication failed to "
253 "deliver indication: "
254 "missing double slash "
255 "in Destination " + dest);
256
|
257 kumpf 1.20 PEG_METHOD_EXIT();
|
258 carolann.graves 1.43 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, msg);
|
259 kumpf 1.13 }
260
|
261 denise.eckstein 1.39 bool parseError = false;
|
262 kumpf 1.13 colon = destStr.find (":");
|
263 kumpf 1.20 //
264 // get hostname and port number from destination string
265 //
266 if (colon != PEG_NOT_FOUND)
267 {
|
268 kumpf 1.25 hostStr = destStr.subString (0, colon);
|
269 kumpf 1.20 destStr = destStr.subString(colon + 1, PEG_NOT_FOUND);
|
270 denise.eckstein 1.39 String portStr = destStr.subString (0, destStr.find ("/"));
|
271 kumpf 1.20
|
272 denise.eckstein 1.39 char dummy;
273 int noOfConversions = sscanf(portStr.getCString (), "%u%c",
274 &portNumber, &dummy);
275 parseError = (noOfConversions != 1);
|
276 kumpf 1.20 }
277 //
278 // There is no port number in the destination string,
279 // get port number from system
280 //
281 else
282 {
|
283 denise.eckstein 1.39 hostStr = destStr.subString(0, destStr.find ("/"));
|
284 kumpf 1.20 if (useHttps)
285 {
286 portNumber = System::lookupPort(WBEM_HTTPS_SERVICE_NAME,
|
287 kumpf 1.42 WBEM_DEFAULT_HTTPS_PORT);
|
288 kumpf 1.20 }
289 else
290 {
291 portNumber = System::lookupPort(WBEM_HTTP_SERVICE_NAME,
292 WBEM_DEFAULT_HTTP_PORT);
293 }
|
294 kumpf 1.42 }
|
295 kumpf 1.25
|
296 kumpf 1.42 char hostName[PEGASUS_MAXHOSTNAMELEN];
|
297 denise.eckstein 1.39 if (!parseError)
298 {
299 char dummy;
300 int noOfConversions = sscanf(hostStr.getCString (), "%s%c",
301 hostName, &dummy);
302 parseError = (noOfConversions != 1);
303 }
|
304 kumpf 1.25
|
305 kumpf 1.42 if (parseError)
306 {
|
307 carolann.graves 1.43 String msg = _getMalformedExceptionMsg(dest);
|
308 kumpf 1.25
309 PEG_TRACE_STRING(TRC_IND_HANDLER, Tracer::LEVEL4, msg + dest);
310
|
311 kumpf 1.42 PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
|
312 carolann.graves 1.35 "CIMxmlIndicationHandler::handleIndication failed to "
313 "deliver indication: "
314 "invalid host name or port number "
315 "in Destination " + dest);
316
|
317 kumpf 1.25 PEG_METHOD_EXIT();
|
318 carolann.graves 1.43 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, msg);
|
319 kumpf 1.42 }
|
320 kumpf 1.13
|
321 thilo.boehm 1.40 #ifndef PEGASUS_OS_ZOS
322
|
323 kumpf 1.13 if (useHttps)
324 {
325 #ifdef PEGASUS_HAS_SSL
|
326 kumpf 1.42 PEG_TRACE_STRING(TRC_IND_HANDLER, Tracer::LEVEL4,
327 "Build SSL Context...");
|
328 kumpf 1.28
|
329 kumpf 1.42 SSLContext sslcontext(trustPath,
|
330 kumpf 1.28 certPath, keyPath, verifyListenerCertificate, randFile);
|
331 kumpf 1.16 exportclient.connect (hostName, portNumber, sslcontext);
|
332 kumpf 1.13 #else
|
333 kumpf 1.20 MessageLoaderParms param(
|
334 carolann.graves 1.43 "Handler.CIMxmlIndicationHandler.CIMxmlIndicationHandler."
335 "CANNOT_DO_HTTPS_CONNECTION",
336 "SSL is not available. "
337 "Cannot support an HTTPS connection.");
|
338 kumpf 1.20
339 PEG_TRACE_STRING(TRC_IND_HANDLER, Tracer::LEVEL3,
|
340 carolann.graves 1.43 MessageLoader::getMessage(param));
|
341 kumpf 1.20
|
342 carolann.graves 1.43 String msg = MessageLoader::getMessage(param);
|
343 kumpf 1.20
|
344 kumpf 1.42 PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
|
345 carolann.graves 1.35 "CIMxmlIndicationHandler::handleIndication failed to "
346 "deliver indication: "
347 "https not supported "
348 "in Destination " + dest);
349
|
350 kumpf 1.20 PEG_METHOD_EXIT();
351 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, msg);
|
352 kumpf 1.13 #endif
353 }
354 else
355 {
|
356 kumpf 1.16 exportclient.connect (hostName, portNumber);
|
357 kumpf 1.13 }
|
358 thilo.boehm 1.40 #else
|
359 kumpf 1.42 // On zOS the ATTLS facility is using the port number(s) defined
360 // of the outbound policy to decide if the indication is
361 // delivered through a SSL secured socket. This is totally
|
362 thilo.boehm 1.40 // transparent to the CIM Server.
363 exportclient.connect (hostName, portNumber);
|
364 kumpf 1.13
|
365 kumpf 1.42 #endif
366 // check destStr, if no path is specified, use "/" for the URI
|
367 kumpf 1.24 Uint32 slash = destStr.find ("/");
368 if (slash != PEG_NOT_FOUND)
|
369 kumpf 1.42 {
|
370 kumpf 1.24 exportclient.exportIndication(
371 destStr.subString(slash), indicationInstance,
372 contentLanguages);
373 }
|
374 kumpf 1.42 else
375 {
|
376 kumpf 1.24 exportclient.exportIndication(
377 "/", indicationInstance, contentLanguages);
|
378 kumpf 1.42 }
|
379 nag.boranna 1.30 exportclient.disconnect();
|
380 kumpf 1.20 }
381 catch(Exception& e)
|
382 mike 1.2 {
|
383 kumpf 1.42 //ATTN: Catch specific exceptions and log the error message
|
384 kumpf 1.13 // as Indication delivery failed.
|
385 carolann.graves 1.43 String msg = e.getMessage();
|
386 kumpf 1.20
|
387 kumpf 1.42 PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
|
388 carolann.graves 1.35 "CIMxmlIndicationHandler::handleIndication failed to deliver "
389 "indication due to Exception: " + e.getMessage ());
390
|
391 kumpf 1.20 PEG_METHOD_EXIT();
392 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, msg);
|
393 mike 1.2 }
|
394 kumpf 1.20
395 PEG_METHOD_EXIT();
396 }
397
398 private:
|
399 carolann.graves 1.43 String _getMalformedExceptionMsg(
400 String destinationValue)
|
401 kumpf 1.20 {
402 MessageLoaderParms param(
|
403 carolann.graves 1.43 "Handler.CIMxmlIndicationHandler.CIMxmlIndicationHandler."
404 "DESTINATION_NOT_VALID",
405 "Malformed CIM-XML handler instance, "
406 "\'Destination\' property \"$0\" is not valid.",
407 destinationValue);
408 return (String(MessageLoader::getMessage(param)));
|
409 mike 1.2 }
|
410 kumpf 1.20
|
411 mike 1.2 };
412
|
413 kumpf 1.41 PEGASUS_NAMESPACE_END
414
415 PEGASUS_USING_PEGASUS;
416
417 // This is the entry point into this dynamic module.
|
418 mike 1.2
|
419 kumpf 1.41 extern "C" PEGASUS_EXPORT CIMHandler* PegasusCreateHandler(
420 const String& handlerName)
421 {
422 if (handlerName == "CIMxmlIndicationHandler")
423 {
424 return new CIMxmlIndicationHandler;
425 }
426
427 return 0;
|
428 mike 1.2 }
|