unsigned long wsman_get_max_envelope_size(WsContextH cntx, WsXmlDocH doc) { unsigned long size = 0; WsXmlNodeH header, maxsize; char *mu = NULL; if (doc == NULL) doc = cntx->indoc; header = ws_xml_get_soap_header(doc); maxsize = ws_xml_get_child(header, 0, XML_NS_WS_MAN, WSM_MAX_ENVELOPE_SIZE); mu = ws_xml_find_attr_value(maxsize, XML_NS_SOAP_1_2, SOAP_MUST_UNDERSTAND); if (mu != NULL && strcmp(mu, "true") == 0) { size = ws_deserialize_uint32(NULL, header, 0, XML_NS_WS_MAN, WSM_MAX_ENVELOPE_SIZE); } return size; }
/** * Enumerate Children * @param parent XML node parent * @param callback Enumeration callback * @param data Callback data * @param bRecursive Recursive flag * @return * */ int ws_xml_enum_children(WsXmlNodeH parent, WsXmlEnumCallback callback, void *data, int bRecursive) { int retVal = 0; int i; WsXmlNodeH child; for (i = 0; (child = ws_xml_get_child(parent, i, NULL, NULL)) != NULL; i++) { if ((retVal = ws_xml_enum_tree(child, callback, data, bRecursive))) { break; } } return retVal; }
void wsman_set_estimated_total(WsXmlDocH in_doc, WsXmlDocH out_doc, WsEnumerateInfo * enumInfo) { WsXmlNodeH header = ws_xml_get_soap_header(in_doc); if (ws_xml_get_child(header, 0, XML_NS_WS_MAN, WSM_REQUEST_TOTAL) != NULL) { if (out_doc) { WsXmlNodeH response_header = ws_xml_get_soap_header(out_doc); if (enumInfo->totalItems >= 0) ws_xml_add_child_format(response_header, XML_NS_WS_MAN, WSM_TOTAL_ESTIMATE, "%d", enumInfo-> totalItems); } } return; }
hash_t * wsman_get_selector_list_from_filter(WsContextH cntx, WsXmlDocH doc) { WsXmlNodeH body; WsXmlNodeH node, assInst, object; if (doc == NULL) { doc = cntx->indoc; if (!doc) return NULL; } body = ws_xml_get_soap_body(doc); node = ws_xml_get_child(body, 0, XML_NS_ENUMERATION, WSENUM_ENUMERATE); if(!node) { debug("no SelectorSet defined. Missing Enumerate"); return NULL; } node = ws_xml_get_child(node, 0, XML_NS_WS_MAN, WSENUM_FILTER); if(!node) { debug("no SelectorSet defined. Missing Filter"); return NULL; } assInst = ws_xml_get_child(node, 0, XML_NS_CIM_BINDING, WSMB_ASSOCIATION_INSTANCES); if(!assInst) { assInst = ws_xml_get_child(node, 0, XML_NS_CIM_BINDING, WSMB_ASSOCIATED_INSTANCES); if(!assInst) { debug("no SelectorSet defined. Missing AssociationInstances / AssociatedInstances"); return NULL; } } object = ws_xml_get_child(assInst, 0, XML_NS_CIM_BINDING, WSMB_OBJECT); if(!node) { debug("no SelectorSet defined. Missing Object"); return NULL; } node = ws_xml_get_child(object, 0, XML_NS_ADDRESSING, WSA_REFERENCE_PARAMETERS); if(!node) { debug("no SelectorSet defined. Missing ReferenceParameters"); return NULL; } return wsman_get_selectors_from_epr(cntx, node); }
static void wsman_set_enumeration_options(WsManClient * cl, WsXmlNodeH body, const char* resource_uri, client_opt_t *options, filter_t *filter) { WsXmlNodeH node = ws_xml_get_child(body, 0, NULL, NULL); if ((options->flags & FLAG_ENUMERATION_OPTIMIZATION) == FLAG_ENUMERATION_OPTIMIZATION) { ws_xml_add_child(node, XML_NS_WS_MAN, WSM_OPTIMIZE_ENUM, NULL); } if ((options->flags & FLAG_ENUMERATION_ENUM_EPR) == FLAG_ENUMERATION_ENUM_EPR) { ws_xml_add_child(node, XML_NS_WS_MAN, WSM_ENUM_MODE, WSM_ENUM_EPR); } else if ((options->flags & FLAG_ENUMERATION_ENUM_OBJ_AND_EPR) == FLAG_ENUMERATION_ENUM_OBJ_AND_EPR) { ws_xml_add_child(node, XML_NS_WS_MAN, WSM_ENUM_MODE, WSM_ENUM_OBJ_AND_EPR); } // Polymorphism if ((options->flags & FLAG_IncludeSubClassProperties) == FLAG_IncludeSubClassProperties) { ws_xml_add_child(node, XML_NS_CIM_BINDING, WSMB_POLYMORPHISM_MODE, WSMB_INCLUDE_SUBCLASS_PROP); } else if ((options->flags & FLAG_ExcludeSubClassProperties) == FLAG_ExcludeSubClassProperties) { ws_xml_add_child(node, XML_NS_CIM_BINDING, WSMB_POLYMORPHISM_MODE, WSMB_EXCLUDE_SUBCLASS_PROP); } else if ((options->flags & FLAG_POLYMORPHISM_NONE) == FLAG_POLYMORPHISM_NONE) { ws_xml_add_child(node, XML_NS_CIM_BINDING, WSMB_POLYMORPHISM_MODE, "None"); } if (filter != NULL) { filter_serialize(node, filter, XML_NS_WS_MAN); } return; }
WsXmlNodeH ws_xml_add_child_sort(WsXmlNodeH node, const char *nsUri, const char *localName, const char *val, int xmlescape) { int i; WsXmlNodeH child, newNode = NULL; int count = ws_xml_get_child_count(node) ; if ( count == 0 ) { newNode = xml_parser_node_add(node, XML_LAST_CHILD, nsUri, localName, val, xmlescape); } else { for (i = 0; (child = ws_xml_get_child(node, i, NULL, NULL)) != NULL; i++) { char *name = ws_xml_get_node_local_name(child); if (strcmp(localName, name) < 0 ) { newNode = xml_parser_node_add(child, XML_ELEMENT_PREV, nsUri, localName, val, xmlescape); break; } } if (newNode == NULL) { newNode = xml_parser_node_add(node, XML_LAST_CHILD, nsUri, localName, val, xmlescape); } } return newNode; }
static WsXmlNodeH validate_mustunderstand_headers(op_t * op) { WsXmlNodeH child = NULL, header = NULL; int i; char *nsUri; header = wsman_get_soap_header_element(op->in_doc, NULL, NULL); nsUri = ws_xml_get_node_name_ns(header); for (i = 0;(child = ws_xml_get_child(header, i, NULL, NULL)) != NULL; i++) { if (ws_xml_find_attr_bool(child, nsUri, SOAP_MUST_UNDERSTAND)) { if (!is_mu_header(child)) { break; } } } if (child != NULL) { debug("Mustunderstand Fault: %s", ws_xml_get_node_text(child)); } return child; }
/** * Check for duplicate Message ID * @param op operation * @return status */ static int check_unsupported_features(op_t * op) { WsXmlNodeH enumurate; WsXmlNodeH subscribe; WsXmlNodeH header = wsman_get_soap_header_element( op->in_doc, NULL, NULL); WsXmlNodeH body = ws_xml_get_soap_body(op->in_doc); int retVal = 0; WsXmlNodeH n, m, k; char *resource_uri = NULL, *mu = NULL; WsXmlAttrH attr = NULL; n = ws_xml_get_child(header, 0, XML_NS_ADDRESSING, WSA_FAULT_TO); if (n != NULL) { retVal = 1; generate_op_fault(op, WSMAN_UNSUPPORTED_FEATURE, WSMAN_DETAIL_ADDRESSING_MODE); goto DONE; } n = ws_xml_get_child(header, 0, XML_NS_WS_MAN, WSM_LOCALE); if (n != NULL) { debug("Locale header found"); mu = ws_xml_find_attr_value(n, XML_NS_SOAP_1_2, SOAP_MUST_UNDERSTAND); if (mu != NULL && strcmp(mu, "true") == 0) { retVal = 1; generate_op_fault(op, WSMAN_UNSUPPORTED_FEATURE, WSMAN_DETAIL_LOCALE); goto DONE; } } #if 0 n = ws_xml_get_child(header, 0, XML_NS_WS_MAN, WSM_FRAGMENT_TRANSFER); if (n != NULL) { debug("FragmentTransfer header found"); mu = ws_xml_find_attr_value(n, XML_NS_SOAP_1_2, SOAP_MUST_UNDERSTAND); if (mu != NULL && strcmp(mu, "true") == 0) { retVal = 1; generate_op_fault(op, WSMAN_UNSUPPORTED_FEATURE, WSMAN_DETAIL_FRAGMENT_LEVEL_ACCESS); goto DONE; } } #endif enumurate = ws_xml_get_child(body, 0, XML_NS_ENUMERATION, WSENUM_ENUMERATE); if (enumurate) { n = ws_xml_get_child(enumurate, 0, XML_NS_ENUMERATION, WSENUM_END_TO); if (n != NULL) { retVal = 1; generate_op_fault(op, WSMAN_UNSUPPORTED_FEATURE, WSMAN_DETAIL_ADDRESSING_MODE); } n = ws_xml_get_child(enumurate, 0, XML_NS_ENUMERATION, WSENUM_FILTER); m = ws_xml_get_child(enumurate, 0, XML_NS_WS_MAN, WSM_FILTER); if (n != NULL && m != NULL) { retVal = 1; generate_op_fault(op, WSEN_CANNOT_PROCESS_FILTER, 0); goto DONE; } else if (n || m) { char *dia = NULL; if (n) { dia = ws_xml_find_attr_value(n, NULL, WSM_DIALECT); } else if (m) { dia = ws_xml_find_attr_value(m, NULL, WSM_DIALECT); } if (dia) retVal = check_supported_dialect(dia); else retVal = check_supported_dialect (WSM_XPATH_FILTER_DIALECT); if (retVal) { retVal = 1; generate_op_fault(op, WSEN_FILTER_DIALECT_REQUESTED_UNAVAILABLE, 0); goto DONE; } } k = ws_xml_get_child(header, 0, XML_NS_WS_MAN, WSM_RESOURCE_URI); if (k) resource_uri = ws_xml_get_node_text(k); if (resource_uri && (strcmp(resource_uri, CIM_ALL_AVAILABLE_CLASSES) == 0)) { if (!n && !m) { retVal = 1; generate_op_fault(op, WSMAN_UNSUPPORTED_FEATURE, WSMAN_DETAIL_FILTERING_REQUIRED); goto DONE; } } } subscribe = ws_xml_get_child(body, 0, XML_NS_EVENTING, WSEVENT_SUBSCRIBE); if(subscribe) { /* n = ws_xml_get_child(subscribe, 0, XML_NS_EVENTING, WSEVENT_ENDTO); if(n) { retVal = 1; generate_op_fault(op, WSMAN_UNSUPPORTED_FEATURE, WSMAN_DETAIL_ADDRESSING_MODE); goto DONE; } */ n = ws_xml_get_child(subscribe, 0, XML_NS_EVENTING, WSEVENT_DELIVERY); if(n == NULL) { retVal = 1; generate_op_fault(op, WSE_INVALID_MESSAGE, 0); goto DONE; } attr = ws_xml_find_node_attr(n, NULL,WSEVENT_DELIVERY_MODE); if(attr) { mu = ws_xml_get_attr_value(attr); if (strcasecmp(mu, WSEVENT_DELIVERY_MODE_PUSH) && strcasecmp(mu, WSEVENT_DELIVERY_MODE_PUSHWITHACK) && strcasecmp(mu, WSEVENT_DELIVERY_MODE_EVENTS) && strcasecmp(mu, WSEVENT_DELIVERY_MODE_PULL)) { debug("Unsupported delivery mode : %s",ws_xml_get_attr_value(attr)); retVal = 1; generate_op_fault(op, WSE_DELIVERY_MODE_REQUESTED_UNAVAILABLE, 0); goto DONE; } } m = ws_xml_get_child(n, 0, XML_NS_WS_MAN, WSM_CONNECTIONRETRY); if(m) { retVal = 1; generate_op_fault(op, WSMAN_UNSUPPORTED_FEATURE, WSMAN_DETAIL_DELIVERY_RETRIES); goto DONE; } } DONE: return retVal; }
int Redirect_Enumerate_EP(WsContextH cntx, WsEnumerateInfo* enumInfo, WsmanStatus *status, void *opaqueData) { WsXmlNodeH r_header=NULL, r_node=NULL, r_body=NULL, r_opt=NULL; WsXmlDocH r_response=NULL; char *resource_uri, *remote_enumContext; int op; WsManClient *cl=NULL; //The redirected Enumeration request must have RequestTotalItemsCountEstimate enabled r_header = ws_xml_get_soap_header(cntx->indoc); if ( (r_node = ws_xml_get_child(r_header,0,XML_NS_WS_MAN, WSM_REQUEST_TOTAL )) == NULL ) ws_xml_add_child(r_header, XML_NS_WS_MAN, WSM_REQUEST_TOTAL, NULL); cl = setup_redirect_client(cntx, enumInfo->auth_data.username, enumInfo->auth_data.password); //Set the enumInfo flags based on the indoc. This is required while handling the response in wsenum_eunmerate_stub r_body=ws_xml_get_soap_body(cntx->indoc); if ( ( r_node = ws_xml_get_child(r_body ,0, XML_NS_ENUMERATION, WSENUM_ENUMERATE )) != NULL ) { if ( (r_opt = ws_xml_get_child(r_node,0,XML_NS_WS_MAN,WSM_OPTIMIZE_ENUM )) != NULL ) enumInfo->flags |= WSMAN_ENUMINFO_OPT ; } wsman_send_request(cl,cntx->indoc); if (wsmc_get_last_error(cl) != WS_LASTERR_OK ){ //CURL or HTTP errors enumInfo->pullResultPtr = NULL; status->fault_code = WSMAN_INTERNAL_ERROR; status->fault_detail_code = 0; status->fault_msg = redirect_fault_msg( wsman_transport_get_last_error_string( wsmc_get_last_error(cl) ) ); return 1; } r_response = ws_xml_duplicate_doc(wsmc_build_envelope_from_response(cl)); if ( wsman_is_fault_envelope(r_response)){ enumInfo->pullResultPtr = NULL; wsman_get_fault_status_from_doc(r_response, status); return 1; } //Get the Estimated Total No.of Items from the response. r_header=ws_xml_get_soap_header(r_response); r_node=ws_xml_get_child(r_header,0,XML_NS_WS_MAN, WSM_TOTAL_ESTIMATE ); enumInfo->totalItems=(!r_node) ? 0: atoi(ws_xml_get_node_text(r_node)); //Get the remote context remote_enumContext = wsmc_get_enum_context(r_response); //Set the pullResultPtr only if some Enum Items are returned, in optimized mode. r_body= ws_xml_get_soap_body(r_response); if ( (r_node = ws_xml_get_child(r_body,0,XML_NS_ENUMERATION, WSENUM_ENUMERATE_RESP )) != NULL && ( ws_xml_get_child(r_node,0,XML_NS_WS_MAN,WSENUM_ITEMS) != NULL) ) { enumInfo->pullResultPtr = r_response; if( strlen(remote_enumContext) != 0 ) strncpy(enumInfo->enumId, remote_enumContext, strlen(remote_enumContext)+1); else // If all the instances are returned, the context will be NULL enumInfo->enumId[0]='\0'; } else{ //If not items are returned, set the context and return. strncpy(enumInfo->enumId, remote_enumContext, strlen(remote_enumContext)+1); ws_xml_destroy_doc(r_response); } wsmc_release(cl); return 0; }
static WsNotificationInfoH create_notification_entity(WsSubscribeInfo *subsInfo, WsXmlNodeH node) { char *classname = NULL; char *class_namespace = NULL; WsXmlNodeH indicationnode = NULL; WsNotificationInfoH notificationinfo = NULL; notificationinfo = u_zalloc(sizeof(*notificationinfo)); if (notificationinfo == NULL) { return NULL; } WsXmlNodeH instance = ws_xml_get_child(node, 0, NULL, CIMXML_EXPMETHODCALL); if (instance == NULL) { u_free(notificationinfo); return NULL; } instance = ws_xml_get_child(instance, 0, NULL, CIMXML_EXPPARAMVALUE); if (instance == NULL) { u_free(notificationinfo); return NULL; } instance = ws_xml_get_child(instance, 0, NULL, CIMXML_INSTANCE); if (instance == NULL) { u_free(notificationinfo); return NULL; } WsXmlAttrH attr = ws_xml_find_node_attr(instance, NULL, CIMXML_CLASSNAME); if (attr) { classname = ws_xml_get_attr_value(attr); class_namespace = get_cim_indication_namespace(subsInfo, classname); notificationinfo->EventAction = u_strdup_printf("%s/%s", class_namespace, classname); } notificationinfo->EventContent = ws_xml_create_doc(notificationinfo->EventAction, classname); indicationnode = ws_xml_get_doc_root(notificationinfo->EventContent); //Parse "PROPERTY" int n = 0; while ( (node = ws_xml_get_child(instance, n++, NULL, CIMXML_PROPERTY)) ) { attr = ws_xml_find_node_attr(node, NULL, CIMXML_NAME); char *property = NULL; char *value = NULL; if ( attr ) { property = ws_xml_get_attr_value(attr); } value = ws_xml_get_node_text(node); ws_xml_add_child(indicationnode, notificationinfo->EventAction, property, value); } //Parse "PROPERTY.ARRAY" n = 0; while ( (node = ws_xml_get_child(instance, n++, NULL, CIMXML_PROPERTYARRAY)) ) { attr = ws_xml_find_node_attr(node, NULL, CIMXML_NAME); char *property = NULL; if ( attr ) { property = ws_xml_get_attr_value(attr); WsXmlNodeH valarraynode = ws_xml_get_child(node, 0, NULL, CIMXML_VALUEARRAY); if ( valarraynode ) { int m = 0; WsXmlNodeH valnode = NULL; while ( (valnode = ws_xml_get_child(valarraynode, m++, NULL, CIMXML_VALUE)) ) { char *value = ws_xml_get_node_text(valnode); ws_xml_add_child(indicationnode, notificationinfo->EventAction, property, value); } } } } if (class_namespace) u_free(class_namespace); return notificationinfo; }
WsXmlDocH wsmc_create_request(WsManClient * cl, const char *resource_uri, client_opt_t *options, filter_t *filter, WsmanAction action, char *method, void *data) { WsXmlDocH request; WsXmlNodeH body; WsXmlNodeH header; WsXmlNodeH node; char *_action = NULL; char buf[20]; if (action == WSMAN_ACTION_IDENTIFY) { request = ws_xml_create_envelope(); } else { if (method) { if (strchr(method, '/')) _action = u_strdup(method); else _action = wsman_make_action((char *)resource_uri, method); } else { _action = wsmc_create_action_str(action); } if (_action) { request = wsmc_build_envelope(cl->serctx, _action, WSA_TO_ANONYMOUS, (char *)resource_uri, cl->data.endpoint, options); } else { return NULL; } u_free(_action); } body = ws_xml_get_soap_body(request); header = ws_xml_get_soap_header(request); if (!body || !header ) return NULL; /* * flags to be passed as <w:OptionSet ...> <w:Option Name="..." ...> > */ if (options && (options->flags & (FLAG_CIM_EXTENSIONS|FLAG_EXCLUDE_NIL_PROPS))) { WsXmlNodeH opset = ws_xml_add_child(header, XML_NS_WS_MAN, WSM_OPTION_SET, NULL); if ((options->flags & FLAG_CIM_EXTENSIONS) == FLAG_CIM_EXTENSIONS) { WsXmlNodeH op = ws_xml_add_child(opset, XML_NS_WS_MAN, WSM_OPTION, NULL); ws_xml_add_node_attr(op, NULL, WSM_NAME, WSMB_SHOW_EXTENSION); } if ((options->flags & FLAG_EXCLUDE_NIL_PROPS) == FLAG_EXCLUDE_NIL_PROPS) { /* ExcludeNilProperties is non-standard, so put it under an openwsman namespace */ WsXmlNodeH op = ws_xml_add_child(opset, XML_NS_OPENWSMAN, WSM_OPTION, NULL); ws_xml_add_node_attr(op, NULL, WSM_NAME, WSMB_EXCLUDE_NIL_PROPS); } } switch (action) { case WSMAN_ACTION_IDENTIFY: case WSMAN_ACTION_ANON_IDENTIFY: ws_xml_add_child(body, XML_NS_WSMAN_ID, WSMID_IDENTIFY, NULL); break; case WSMAN_ACTION_CUSTOM: break; case WSMAN_ACTION_ENUMERATION: case WSMAN_ACTION_ASSOCIATORS: case WSMAN_ACTION_REFERENCES: node = ws_xml_add_child(body, XML_NS_ENUMERATION, WSENUM_ENUMERATE, NULL); wsman_set_enumeration_options(cl, body, resource_uri, options, filter); break; case WSMAN_ACTION_PULL: node = ws_xml_add_child(body, XML_NS_ENUMERATION, WSENUM_PULL, NULL); if (data) { ws_xml_add_child(node, XML_NS_ENUMERATION, WSENUM_ENUMERATION_CONTEXT, (char *) data); } break; case WSMAN_ACTION_RELEASE: node = ws_xml_add_child(body, XML_NS_ENUMERATION, WSENUM_RELEASE, NULL); if (data) { ws_xml_add_child(node, XML_NS_ENUMERATION, WSENUM_ENUMERATION_CONTEXT, (char *) data); } break; case WSMAN_ACTION_SUBSCRIBE: wsman_set_subscribe_options(cl, request, resource_uri, options, filter); break; case WSMAN_ACTION_UNSUBSCRIBE: node = ws_xml_add_child(body, XML_NS_EVENTING, WSEVENT_UNSUBSCRIBE,NULL); if(data) { if(((char *)data)[0] != 0) add_subscription_context(ws_xml_get_soap_header(request), (char *)data); } break; case WSMAN_ACTION_RENEW: node = ws_xml_add_child(body, XML_NS_EVENTING, WSEVENT_RENEW, NULL); sprintf(buf, "PT%fS", options->expires); ws_xml_add_child(node, XML_NS_EVENTING, WSEVENT_EXPIRES, buf); if(data) { if(((char *)data)[0] != 0) add_subscription_context(ws_xml_get_soap_header(request), (char *)data); } break; case WSMAN_ACTION_NONE: case WSMAN_ACTION_TRANSFER_CREATE: case WSMAN_ACTION_TEST: case WSMAN_ACTION_TRANSFER_GET: case WSMAN_ACTION_TRANSFER_PUT: case WSMAN_ACTION_TRANSFER_DELETE: break; } if (action == WSMAN_ACTION_PULL || action == WSMAN_ACTION_ENUMERATION) { if (options->max_elements > 0 ) { node = ws_xml_get_child(body, 0, NULL, NULL); if (action == WSMAN_ACTION_ENUMERATION) { if ((options->flags & FLAG_ENUMERATION_OPTIMIZATION) == FLAG_ENUMERATION_OPTIMIZATION ) { /* wsman:MaxElements is for Enumerate */ ws_xml_add_child_format(node, XML_NS_WS_MAN, WSENUM_MAX_ELEMENTS, "%d", options->max_elements); } } else { /* wsen:MaxElements is for Pull */ ws_xml_add_child_format(node, XML_NS_ENUMERATION, WSENUM_MAX_ELEMENTS, "%d", options->max_elements); } } if ((options->flags & FLAG_ENUMERATION_COUNT_ESTIMATION) == FLAG_ENUMERATION_COUNT_ESTIMATION) { ws_xml_add_child(header, XML_NS_WS_MAN, WSM_REQUEST_TOTAL, NULL); } } if (action != WSMAN_ACTION_TRANSFER_CREATE && action != WSMAN_ACTION_TRANSFER_PUT && action != WSMAN_ACTION_CUSTOM) { if ((options->flags & FLAG_DUMP_REQUEST) == FLAG_DUMP_REQUEST) { ws_xml_dump_node_tree(cl->dumpfile, ws_xml_get_doc_root(request)); } } return request; }
SoapDispatchH wsman_dispatcher(WsContextH cntx, void *data, WsXmlDocH doc) { SoapDispatchH disp = NULL; char *uri = NULL, *action; WsManDispatcherInfo *dispInfo = (WsManDispatcherInfo *) data; WsDispatchEndPointInfo *ep = NULL; WsDispatchEndPointInfo *ep_custom = NULL; WsXmlDocH notdoc = NULL; #ifdef ENABLE_EVENTING_SUPPORT WsXmlNodeH nodedoc = NULL; #endif int i; /*, resUriMatch = 0; */ char *ns = NULL; WsDispatchInterfaceInfo *r = NULL; lnode_t *node = list_first((list_t *) dispInfo->interfaces); if (doc == NULL) { error("doc is null"); u_free(data); goto cleanup; } uri = wsman_get_resource_uri(cntx, doc); action = wsman_get_action(cntx, doc); #ifdef ENABLE_EVENTING_SUPPORT if(wsman_is_event_related_request(doc)) { WsXmlNodeH temp = ws_xml_get_child( ws_xml_get_soap_header(doc), 0, XML_NS_EVENTING, WSEVENT_IDENTIFIER); char *uuid = ws_xml_get_node_text(temp); debug("Request uuid: %s", uuid ? uuid : "NULL"); if(uuid) { lnode_t *t = list_first(cntx->subscriptionMemList); while(t != NULL) { WsSubscribeInfo *subsInfo = (WsSubscribeInfo *)t->list_data; if(!strcmp(uuid+5, subsInfo->subsId)) { uri = subsInfo->uri; break; } else t = list_next(cntx->subscriptionMemList, t); } if(t == NULL) { unsigned char *buf = NULL; int len; if(cntx->soap->subscriptionOpSet->get_subscription(cntx->soap->uri_subsRepository, uuid+5, &buf, &len) == 0) { notdoc = ws_xml_read_memory( (char *)buf, len, "UTF-8", 0); if(notdoc) { nodedoc = ws_xml_get_soap_header(notdoc); if(nodedoc) { nodedoc = ws_xml_get_child(nodedoc, 0, XML_NS_WS_MAN, WSM_RESOURCE_URI); if(nodedoc) { uri = ws_xml_get_node_text(nodedoc); } } } u_free(buf); } } } } #endif debug("uri: %s, action: %s", uri ? uri : "NULL", action ? action : "NULL"); if ((!uri || !action) && !wsman_is_identify_request(doc)) { goto cleanup; } while (node != NULL) { WsDispatchInterfaceInfo *ifc = (WsDispatchInterfaceInfo *) node->list_data; if (wsman_is_identify_request(doc)) { if ((ns = wsman_dispatcher_match_ns(ifc, XML_NS_WSMAN_ID))) { r = ifc; /* resUriMatch = 1; */ break; } debug("ns did not match"); } /* * If Resource URI is null then most likely we are dealing * with a generic plugin supporting a namespace with * multiple Resource URIs (e.g. CIM) **/ else if (ifc->wsmanResourceUri == NULL && (ns = wsman_dispatcher_match_ns(ifc, uri))) { r = ifc; /* resUriMatch = 1; */ break; } else if (ifc->wsmanResourceUri && !strcmp(uri, ifc->wsmanResourceUri)) { r = ifc; /* resUriMatch = 1; */ break; } node = list_next((list_t *) dispInfo->interfaces, node); } if (wsman_is_identify_request(doc) && r != NULL) { ep = &r->endPoints[0]; } else if (r != NULL) { char *ptr = action; /* * See if the action is part of the namespace which means that * we are dealing with a custom action */ if (ns != NULL) { size_t len = strlen(ns); if (!strncmp(action, ns, len) && action[len] == '/') ptr = &action[len + 1]; } for (i = 0; r->endPoints[i].serviceEndPoint != NULL; i++) { if (r->endPoints[i].inAction != NULL && !strcmp(ptr, r->endPoints[i].inAction)) { ep = &r->endPoints[i]; break; } else if (r->endPoints[i].inAction == NULL) { /* * Just store it for later * in case no match is found for above condition */ ep_custom = &r->endPoints[i]; } } } ws_remove_context_val(cntx, WSM_RESOURCE_URI); if (ep != NULL) { for (i = 0; i < dispInfo->mapCount; i++) { if (dispInfo->map[i].ep == ep) { disp = dispInfo->map[i].disp; break; } } } else if (ep_custom != NULL) { for (i = 0; i < dispInfo->mapCount; i++) { if (dispInfo->map[i].ep == ep_custom) { disp = dispInfo->map[i].disp; break; } } } cleanup: if(notdoc) ws_xml_destroy_doc(notdoc); if (ns) u_free(ns); return disp; }
/** * Check if Envelope is valid * @param msg Message data * @param doc XML document * @return 1 if envelope is valid, 0 if not */ int wsman_is_valid_envelope(WsmanMessage * msg, WsXmlDocH doc) { int retval = 1; char *soapNsUri; WsXmlNodeH header; WsXmlNodeH root = ws_xml_get_doc_root(doc); if (strcmp(SOAP_ENVELOPE, ws_xml_get_node_local_name(root)) != 0) { wsman_set_fault(msg, WSA_INVALID_MESSAGE_INFORMATION_HEADER, 0, "No Envelope"); retval = 0; debug("no envelope"); goto cleanup; } soapNsUri = ws_xml_get_node_name_ns(root); if (strcmp(soapNsUri, XML_NS_SOAP_1_2) != 0) { wsman_set_fault(msg, SOAP_FAULT_VERSION_MISMATCH, 0, NULL); retval = 0; debug("version mismatch"); goto cleanup; } if (ws_xml_get_soap_body(doc) == NULL) { wsman_set_fault(msg, WSA_INVALID_MESSAGE_INFORMATION_HEADER, 0, "No Body"); retval = 0; debug("no body"); goto cleanup; } header = ws_xml_get_soap_header(doc); if (!header) { wsman_set_fault(msg, WSA_INVALID_MESSAGE_INFORMATION_HEADER, 0, "No Header"); retval = 0; debug("no header"); goto cleanup; } else { if (!wsman_is_identify_request(doc) && !wsman_is_event_related_request(doc)) { WsXmlNodeH resource_uri = ws_xml_get_child(header, 0, XML_NS_WS_MAN, WSM_RESOURCE_URI); WsXmlNodeH action = ws_xml_get_child(header, 0, XML_NS_ADDRESSING, WSA_ACTION); WsXmlNodeH reply = ws_xml_get_child(header, 0, XML_NS_ADDRESSING, WSA_REPLY_TO); WsXmlNodeH to = ws_xml_get_child(header, 0, XML_NS_ADDRESSING, WSA_TO); if (!resource_uri) { wsman_set_fault(msg, WSA_DESTINATION_UNREACHABLE, WSMAN_DETAIL_INVALID_RESOURCEURI, NULL); retval = 0; debug("no wsman:ResourceURI"); goto cleanup; } if (!action) { wsman_set_fault(msg, WSA_ACTION_NOT_SUPPORTED, 0, NULL); retval = 0; debug("no wsa:Action"); goto cleanup; } if (!reply) { wsman_set_fault(msg, WSA_MESSAGE_INFORMATION_HEADER_REQUIRED, 0, NULL); retval = 0; debug("no wsa:ReplyTo"); goto cleanup; } if (!to) { wsman_set_fault(msg, WSA_DESTINATION_UNREACHABLE, 0, NULL); retval = 0; debug("no wsa:To"); goto cleanup; } } } cleanup: return retval; }
epr_t *epr_deserialize(WsXmlNodeH node, const char *ns, const char *epr_node_name, int embedded) { int i; epr_t *epr = u_malloc(sizeof(epr_t)); WsXmlNodeH eprnode = NULL; WsXmlNodeH refparamnode = NULL; WsXmlNodeH temp = NULL; WsXmlNodeH selectorsetnode = NULL; WsXmlAttrH attr = NULL; Selector *p = NULL; if(epr_node_name) { eprnode = ws_xml_get_child(node, 0, ns, epr_node_name); if(eprnode == NULL) goto CLEANUP; } else { eprnode = node; } if(embedded) { temp = ws_xml_get_child(eprnode, 0, XML_NS_ADDRESSING, WSA_ADDRESS); } else { temp = ws_xml_get_child(eprnode, 0, XML_NS_ADDRESSING, WSA_TO); } if(temp == NULL) goto CLEANUP; epr->address = u_strdup(ws_xml_get_node_text(temp)); if(embedded) { refparamnode = ws_xml_get_child(eprnode, 0, XML_NS_ADDRESSING, WSA_REFERENCE_PARAMETERS); } else { refparamnode = node; } if(refparamnode == NULL) goto CLEANUP; temp = ws_xml_get_child(refparamnode, 0, XML_NS_WS_MAN, WSM_RESOURCE_URI); if(temp == NULL) goto CLEANUP; epr->refparams.uri = u_strdup(ws_xml_get_node_text(temp)); selectorsetnode = ws_xml_get_child(refparamnode, 0, XML_NS_WS_MAN, WSM_SELECTOR_SET); epr->refparams.selectorset.count = ws_xml_get_child_count(selectorsetnode); epr->refparams.selectorset.selectors = u_malloc(epr->refparams.selectorset.count * sizeof(Selector)); p = epr->refparams.selectorset.selectors; for(i = 0; i < epr->refparams.selectorset.count; i++) { temp = ws_xml_get_child(selectorsetnode, i, XML_NS_WS_MAN, WSM_SELECTOR); attr = ws_xml_find_node_attr(temp, NULL, "Name"); if(attr) { p->name = u_strdup(ws_xml_get_attr_value(attr)); } if(ws_xml_get_child(temp, 0, XML_NS_ADDRESSING, WSA_EPR)) { p->type = 1; p->value = (char *)epr_deserialize(temp, XML_NS_ADDRESSING, WSA_EPR, 1); } else { p->type = 0; p->value = u_strdup(ws_xml_get_node_text(temp)); } p++; } return epr; CLEANUP: u_free(epr); return NULL; }
hash_t * wsman_get_method_args(WsContextH cntx, const char *resource_uri) { char *input = NULL; WsXmlDocH doc = cntx->indoc; hash_t *h = hash_create(HASHCOUNT_T_MAX, 0, 0); hash_set_allocator(h, NULL, wsman_free_method_hnode, NULL); if (doc) { WsXmlNodeH in_node; WsXmlNodeH body = ws_xml_get_soap_body(doc); char *mn = wsman_get_method_name(cntx); input = u_strdup_printf("%s_INPUT", mn); in_node = ws_xml_get_child(body, 0, resource_uri, input); if (!in_node) { char *xsd = u_strdup_printf("%s.xsd", resource_uri); in_node = ws_xml_get_child(body, 0, xsd, input); u_free(xsd); } if (in_node) { WsXmlNodeH arg, epr; int index = 0; list_t *arglist = list_create(LISTCOUNT_T_MAX); lnode_t *argnode; while ((arg = ws_xml_get_child(in_node, index++, NULL, NULL))) { char *key = ws_xml_get_node_local_name(arg); selector_entry *sentry = u_malloc(sizeof(*sentry)); methodarglist_t *nodeval = u_malloc(sizeof(methodarglist_t)); epr = ws_xml_get_child(arg, 0, XML_NS_ADDRESSING, WSA_REFERENCE_PARAMETERS); nodeval->key = u_strdup(key); nodeval->arraycount = 0; argnode = lnode_create(nodeval); if (epr) { debug("epr: %s", key); sentry->type = 1; sentry->entry.eprp = epr_deserialize(arg, NULL, NULL, 1); //wsman_get_epr(cntx, arg, key, XML_NS_CIM_CLASS); } else { debug("text: %s", key); sentry->type = 0; sentry->entry.text = u_strdup(ws_xml_get_node_text(arg)); } nodeval->data = sentry; list_append(arglist, argnode); } if (!hash_alloc_insert(h, METHOD_ARGS_KEY, arglist)) { error("hash_alloc_insert failed"); wsman_free_method_list(arglist); } } u_free(mn); u_free(input); } else { error("error: xml document is NULL"); } if (!hash_isempty(h)) return h; hash_destroy(h); return NULL; }
int wsman_parse_enum_request(WsContextH cntx, WsEnumerateInfo * enumInfo) { filter_t *filter = NULL; WsXmlNodeH node; WsXmlDocH doc = cntx->indoc; if (!doc) return 0; node = ws_xml_get_soap_body(doc); if (node && (node = ws_xml_get_child(node, 0, XML_NS_ENUMERATION, WSENUM_ENUMERATE))) { WsXmlNodeH opt = ws_xml_get_child(node, 0, XML_NS_WS_MAN, WSM_ENUM_MODE); /* Enumeration mode */ if (opt) { char *text = ws_xml_get_node_text(opt); if (text != NULL) { if (strcmp(text, WSM_ENUM_EPR) == 0) enumInfo->flags |= WSMAN_ENUMINFO_EPR; else if (strcmp(text, WSM_ENUM_OBJ_AND_EPR) == 0) enumInfo->flags |= WSMAN_ENUMINFO_OBJEPR; } } /* Polymorphism */ opt = ws_xml_get_child(node, 0, XML_NS_CIM_BINDING, WSMB_POLYMORPHISM_MODE); if (opt) { char *mode = ws_xml_get_node_text(opt); if (strcmp(mode, WSMB_EXCLUDE_SUBCLASS_PROP) == 0) { enumInfo->flags |= WSMAN_ENUMINFO_POLY_EXCLUDE; } else if (strcmp(mode, WSMB_INCLUDE_SUBCLASS_PROP) == 0) { enumInfo->flags |= WSMAN_ENUMINFO_POLY_INCLUDE; } else if (strcmp(mode, WSMB_NONE) == 0) { enumInfo->flags |= WSMAN_ENUMINFO_POLY_NONE; } } else { enumInfo->flags |= WSMAN_ENUMINFO_POLY_INCLUDE; } /* Enum Optimization ? * wsen:Enum/wsman:Optimize * wsen:Enum/wsman:MaxElements <optional> */ opt = ws_xml_get_child(node, 0, XML_NS_WS_MAN, WSM_OPTIMIZE_ENUM); if (opt) { WsXmlNodeH max = ws_xml_get_child(node, 0, XML_NS_WS_MAN, WSM_MAX_ELEMENTS); enumInfo->flags |= WSMAN_ENUMINFO_OPT; if (max) { char *text = ws_xml_get_node_text(max); if (text != NULL) { enumInfo->maxItems = atoi(text); } } else { enumInfo->maxItems = 1; } } /* Filter */ filter = filter_deserialize(node, XML_NS_WS_MAN); enumInfo->filter = filter; if(filter) { if(strcmp(filter->dialect, WSM_ASSOCIATION_FILTER_DIALECT) == 0) { if(filter->assocType == 0) enumInfo->flags |= WSMAN_ENUMINFO_ASSOC; else enumInfo->flags |= WSMAN_ENUMINFO_REF; } else if(strcmp(filter->dialect, WSM_CQL_FILTER_DIALECT) ==0) enumInfo->flags |= WSMAN_ENUMINFO_CQL; else if(strcmp(filter->dialect, WSM_WQL_FILTER_DIALECT) == 0) enumInfo->flags |= WSMAN_ENUMINFO_WQL; else if(strcmp(filter->dialect, WSM_SELECTOR_FILTER_DIALECT) == 0) enumInfo->flags |= WSMAN_ENUMINFO_SELECTOR; else { if(interpretxpath(&filter->query)) enumInfo->flags |= WSMAN_ENUMINFO_WQL; else return 0; } } } return 1; }
int wsman_parse_credentials(WsXmlDocH doc, WsSubscribeInfo * subsInfo, WsmanFaultCodeType *faultcode, WsmanFaultDetailType *detailcode) { int i = 0; WsXmlNodeH tnode = NULL, snode = NULL, node = NULL, temp = NULL; char *value = NULL; snode = ws_xml_get_soap_header(doc); snode = ws_xml_get_child(snode, 0, XML_NS_TRUST, WST_ISSUEDTOKENS); if(snode == NULL) return 0; tnode = ws_xml_get_child(snode, i, XML_NS_TRUST, WST_REQUESTSECURITYTOKENRESPONSE); while(tnode) { i++; node = ws_xml_get_child(tnode, 0, XML_NS_POLICY, WSP_APPLIESTO); if(node) { node = ws_xml_get_child(node, 0, XML_NS_ADDRESSING, WSA_EPR); if(node) { node = ws_xml_get_child(node, 0, XML_NS_ADDRESSING, WSA_ADDRESS); if(node) if(strcmp(ws_xml_get_node_text(node), subsInfo->epr_notifyto)) { *faultcode = WSMAN_INVALID_PARAMETER; *detailcode = WSMAN_DETAIL_INVALID_ADDRESS; return -1; } } } node = ws_xml_get_child(tnode, 0, XML_NS_TRUST, WST_TOKENTYPE); value = ws_xml_get_node_text(node); if(strcmp(value, WST_USERNAMETOKEN) == 0) { node = ws_xml_get_child(tnode, 0, XML_NS_TRUST, WST_REQUESTEDSECURITYTOKEN); if(node) { node = ws_xml_get_child(node, 0, XML_NS_SE, WSSE_USERNAMETOKEN); if(node) { temp = ws_xml_get_child(node, 0, XML_NS_SE, WSSE_USERNAME); if(temp) subsInfo->username = u_strdup(ws_xml_get_node_text(temp)); temp = ws_xml_get_child(node, 0, XML_NS_SE, WSSE_PASSWORD); if(temp) subsInfo->password = u_strdup(ws_xml_get_node_text(temp)); } } debug("subsInfo->username = %s, subsInfo->password = %s", subsInfo->username, \ subsInfo->password); } else if(strcmp(value, WST_CERTIFICATETHUMBPRINT) == 0) { node = ws_xml_get_child(tnode, 0, XML_NS_TRUST, WST_REQUESTEDSECURITYTOKEN); if(node) { node = ws_xml_get_child(node, 0, XML_NS_WS_MAN, WSM_CERTIFICATETHUMBPRINT); if(node) subsInfo->certificate_thumbprint = u_strdup(ws_xml_get_node_text(node)); } } else { *faultcode = WSMAN_INVALID_OPTIONS; *detailcode = WST_DETAIL_UNSUPPORTED_TOKENTYPE; return -1; } tnode = ws_xml_get_child(snode, i, XML_NS_TRUST, WST_REQUESTSECURITYTOKENRESPONSE); } return 0; }
/* This function guarantees that query is freed, even on failure */ int hypervEnumAndPull(hypervPrivate *priv, virBufferPtr query, const char *root, XmlSerializerInfo *serializerInfo, const char *resourceUri, const char *className, hypervObject **list) { int result = -1; WsSerializerContextH serializerContext; client_opt_t *options = NULL; char *query_string = NULL; filter_t *filter = NULL; WsXmlDocH response = NULL; char *enumContext = NULL; hypervObject *head = NULL; hypervObject *tail = NULL; WsXmlNodeH node = NULL; XML_TYPE_PTR data = NULL; hypervObject *object; if (virBufferCheckError(query) < 0) { virBufferFreeAndReset(query); return -1; } query_string = virBufferContentAndReset(query); if (list == NULL || *list != NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument")); VIR_FREE(query_string); return -1; } serializerContext = wsmc_get_serialization_context(priv->client); options = wsmc_options_init(); if (options == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not initialize options")); goto cleanup; } filter = filter_create_simple(WSM_WQL_FILTER_DIALECT, query_string); if (filter == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not create filter")); goto cleanup; } response = wsmc_action_enumerate(priv->client, root, options, filter); if (hyperyVerifyResponse(priv->client, response, "enumeration") < 0) goto cleanup; enumContext = wsmc_get_enum_context(response); ws_xml_destroy_doc(response); response = NULL; while (enumContext != NULL && *enumContext != '\0') { response = wsmc_action_pull(priv->client, resourceUri, options, filter, enumContext); if (hyperyVerifyResponse(priv->client, response, "pull") < 0) goto cleanup; node = ws_xml_get_soap_body(response); if (node == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not lookup SOAP body")); goto cleanup; } node = ws_xml_get_child(node, 0, XML_NS_ENUMERATION, WSENUM_PULL_RESP); if (node == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not lookup pull response")); goto cleanup; } node = ws_xml_get_child(node, 0, XML_NS_ENUMERATION, WSENUM_ITEMS); if (node == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not lookup pull response items")); goto cleanup; } if (ws_xml_get_child(node, 0, resourceUri, className) == NULL) break; data = ws_deserialize(serializerContext, node, serializerInfo, className, resourceUri, NULL, 0, 0); if (data == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not deserialize pull response item")); goto cleanup; } if (VIR_ALLOC(object) < 0) goto cleanup; object->serializerInfo = serializerInfo; object->data = data; data = NULL; if (head == NULL) { head = object; } else { tail->next = object; } tail = object; VIR_FREE(enumContext); enumContext = wsmc_get_enum_context(response); ws_xml_destroy_doc(response); response = NULL; } *list = head; head = NULL; result = 0; cleanup: if (options != NULL) wsmc_options_destroy(options); if (filter != NULL) filter_destroy(filter); if (data != NULL) { #if WS_SERIALIZER_FREE_MEM_WORKS /* FIXME: ws_serializer_free_mem is broken in openwsman <= 2.2.6, * see hypervFreeObject for a detailed explanation. */ if (ws_serializer_free_mem(serializerContext, data, serializerInfo) < 0) { VIR_ERROR(_("Could not free deserialized data")); } #endif } VIR_FREE(query_string); ws_xml_destroy_doc(response); VIR_FREE(enumContext); hypervFreeObject(priv, head); return result; }
/** * Check for duplicate Message ID * @param op operation * @return status */ static int wsman_is_duplicate_message_id(op_t * op) { WsXmlNodeH header = wsman_get_soap_header_element(op->in_doc, NULL, NULL); int retVal = 0; SoapH soap; WsXmlNodeH msgIdNode; soap = op->dispatch->soap; msgIdNode = ws_xml_get_child(header, 0, XML_NS_ADDRESSING, WSA_MESSAGE_ID); if (msgIdNode != NULL) { lnode_t *node; char *msgId; msgId = ws_xml_get_node_text(msgIdNode); if (msgId[0] == 0 ) { generate_op_fault(op, WSA_INVALID_MESSAGE_INFORMATION_HEADER, 0 ); debug("MessageId missing"); return 1; } debug("Checking Message ID: %s", msgId); u_lock(soap); if (soap->processedMsgIdList == NULL) { soap->processedMsgIdList = list_create(LISTCOUNT_T_MAX); } #ifndef IGNORE_DUPLICATE_ID node = list_first(soap->processedMsgIdList); while (node != NULL) { if (!strcmp(msgId, (char *) node->list_data)) { debug("Duplicate Message ID: %s", msgId); retVal = 1; generate_op_fault(op, WSA_INVALID_MESSAGE_INFORMATION_HEADER, WSA_DETAIL_DUPLICATE_MESSAGE_ID); break; } node = list_next(soap->processedMsgIdList, node); } #endif if (!retVal) { while (list_count(soap->processedMsgIdList) >= PROCESSED_MSG_ID_MAX_SIZE) { node = list_del_first(soap->processedMsgIdList); u_free(node->list_data); u_free(node); } node = lnode_create(NULL); if (node) { node->list_data = u_str_clone(msgId); if (node->list_data == NULL) { u_free(node); } else { list_append(soap->processedMsgIdList, node); } } } u_unlock(soap); } else if (!wsman_is_identify_request(op->in_doc)) { generate_op_fault(op, WSA_MESSAGE_INFORMATION_HEADER_REQUIRED, 0); debug("No MessageId Header found"); return 1; } return retVal; }