in Unix/wsman/wsmanparser.c [1193:1537]
int WS_ParseWSHeader(
XML* xml,
WSMAN_WSHeader* wsheader,
UserAgent userAgent)
{
XML_Elem e;
if (wsheader->instanceBatch)
{
Batch_Delete(wsheader->instanceBatch);
}
memset(wsheader, 0, sizeof(WSMAN_WSHeader));
// WinRM client assumes that ClassOrigin is true by default on the server
// by standards, a wsman option is false by default so in non-WinRM case,
// the includeClassOrigin and all others are set to 0
wsheader->includeClassOrigin = (userAgent == USERAGENT_WINRM) ? 1 : 0;
wsheader->includeInheritanceHierarchy = 0;
wsheader->includeInheritedElements = 0;
wsheader->includeQualifiers = 0;
/* Expect <s:Header> */
if (XML_Expect(xml, &e, XML_START, PAL_T('s'), PAL_T("Header")) != 0)
RETURN(-1);
for (;;)
{
if (GetNextSkipCharsAndComments(xml, &e) != 0)
RETURN(-1);
if (e.type == XML_END)// && strcmp(e.data, "s:Header") == 0)
{
int tag = HashStr(e.data.namespaceId, e.data.data, e.data.size);
if (WSMANTAG_HEADER != tag)
{
trace_Wsman_UnexpectedCloseTag(tcs(e.data.data));
RETURN(-1);
}
//printf("DONE\n");
break;
}
/* skip possible comments */
if (e.type != XML_START)
continue;
switch (HashStr(e.data.namespaceId, e.data.data, e.data.size))
{
case WSMANTAG_TO:
{
if (XML_Expect(xml, &e, XML_CHARS, 0, NULL) != 0)
RETURN(-1);
if (XML_Expect(xml, &e, XML_END, PAL_T('a'), PAL_T("To")) != 0)
RETURN(-1);
}
break;
case WSMANTAG_RESOURCE_URI:
{
int resourceUriHash = 0;
if (XML_Expect(xml, &e, XML_CHARS, 0, NULL) != 0)
RETURN(-1);
if (XML_StripWhitespace(&e) != 0)
RETURN(-1);
wsheader->schemaRequestType = NOT_A_SCHEMA_REQUEST;
resourceUriHash = HashStr(0, e.data.data, e.data.size);
if(resourceUriHash == WSMAN_RESOURCE_URI_CIM_XML_SCHEMA)
{
wsheader->schemaRequestType = CIM_XML_SCHEMA_REQUEST;
}
else if(resourceUriHash == WSMAN_RESOURCE_URI_WS_CIM_SCHEMA)
{
wsheader->schemaRequestType = WS_CIM_SCHEMA_REQEUST;
}
wsheader->rqtResourceUri = e.data.data;
#ifndef DISABLE_SHELL
if (!wsheader->isShellOperation)
{
#endif
wsheader->rqtClassname = Tcsrchr(e.data.data, '/');
/* skip '/' */
if (wsheader->rqtClassname)
wsheader->rqtClassname++;
#ifndef DISABLE_SHELL
}
else
{
wsheader->rqtClassname = PAL_T("Shell");
}
#endif
if (XML_Expect(xml, &e, XML_END, PAL_T('w'), PAL_T("ResourceURI")) != 0)
RETURN(-1);
}
break;
case WSMANTAG_REPLY_TO:
{
if (XML_Expect(xml, &e, XML_START, PAL_T('a'), PAL_T("Address")) != 0)
RETURN(-1);
if (HashStr(e.data.namespaceId, e.data.data, e.data.size) != WSMANTAG_ADDRESS)
RETURN(-1);
if (XML_Expect(xml, &e, XML_CHARS, 0, NULL) != 0)
RETURN(-1);
if (XML_Expect(xml, &e, XML_END, PAL_T('a'), PAL_T("Address")) != 0)
RETURN(-1);
if (XML_Expect(xml, &e, XML_END, PAL_T('a'), PAL_T("ReplyTo")) != 0)
RETURN(-1);
if (HashStr(e.data.namespaceId, e.data.data, e.data.size) != WSMANTAG_REPLY_TO)
RETURN(-1);
}
break;
case WSMANTAG_ACTION:
{
wsheader->foundAction = MI_TRUE;
if (XML_Expect(xml, &e, XML_CHARS, 0, NULL) != 0)
RETURN(-1);
if (XML_StripWhitespace(&e) != 0)
RETURN(-1);
wsheader->rqtAction = HashStr(e.data.namespaceId, e.data.data, e.data.size);
switch (wsheader->rqtAction)
{
#ifndef DISABLE_SHELL
case WSMANTAG_ACTION_SHELL_COMMAND:
case WSMANTAG_ACTION_SHELL_SIGNAL:
case WSMANTAG_ACTION_SHELL_RECEIVE:
case WSMANTAG_ACTION_SHELL_SEND:
case WSMANTAG_ACTION_SHELL_CONNECT:
case WSMANTAG_ACTION_SHELL_RECONNECT:
case WSMANTAG_ACTION_SHELL_DISCONNECT:
#endif
case 0:
{
TChar* s;
/* DSP0226; 9: Custom Actions (Methods) just need to have unique URI.
We are assuming it has format like http://<server>/wbem/wscim/1/cim-schema/2/<class-name>/<method-name> */
if (0 != Tcsncmp(e.data.data, PAL_T("http://"), 7))
RETURN(-1);
wsheader->rqtServer = e.data.data + 7;
s = Tcschr(wsheader->rqtServer, '/');
if (!s)
RETURN(-1);
*s = 0;
s++;
if (0 == Tcsncmp(s, PAL_T("wbem/wscim/1/cim-schema/2/"), 26))
{
s += 26;
}
#ifndef DISABLE_SHELL
else if (0 == Tcsncmp(s, PAL_T("wbem/wsman/1/windows/"), 21))
{
s += 21;
wsheader->isShellOperation = MI_TRUE;
}
#endif
else
{
RETURN(-1);
}
wsheader->rqtClassname = s;
s = Tcschr(s, '/');
if (!s)
RETURN(-1);
*s = 0;
s++;
wsheader->rqtMethod = s;
}
}
if (XML_Expect(xml, &e, XML_END, PAL_T('a'), PAL_T("Action")) != 0)
RETURN(-1);
break;
}
case WSMANTAG_SELECTOR_SET:
{
if (_GetSelectorSet(xml, wsheader) != 0)
RETURN(-1);
}
break;
case WSMANTAG_OPTION_SET:
{
if (_GetOptionSet(xml, wsheader) != 0)
RETURN(-1);
}
break;
case WSMANTAG_MESSAGE_ID:
{
if (XML_Expect(xml, &e, XML_CHARS, 0, NULL) != 0)
RETURN(-1);
if (XML_StripWhitespace(&e) != 0)
RETURN(-1);
wsheader->rqtMessageID = e.data.data;
if (XML_Expect(xml, &e, XML_END, PAL_T('a'), PAL_T("MessageID")) != 0)
RETURN(-1);
}
break;
case WSMANTAG_MAX_ENVELOPE_SIZE:
{
if (XML_Expect(xml, &e, XML_CHARS, 0, NULL) != 0)
RETURN(-1);
if (XML_StripWhitespace(&e) != 0)
RETURN(-1);
wsheader->maxEnvelopeSize = (MI_Uint32)Tcstoull(
e.data.data, NULL, 10);
if (XML_Expect(xml, &e, XML_END, PAL_T('w'), PAL_T("MaxEnvelopeSize")) != 0)
RETURN(-1);
}
break;
#ifndef DISABLE_INDICATION
case WSMANTAG_OPERATION_TIMEOUT:
{
/* Expect an xs:duration of form: PnYnMnDTnHnMnS */
if (XML_Expect(xml, &e, XML_CHARS, 0, NULL) != 0)
RETURN(-1);
if (XML_StripWhitespace(&e) != 0)
RETURN(-1);
if (-1 == ParseWSManDatetime( e.data.data, &wsheader->operationTimeout.value ) )
RETURN(-1);
wsheader->operationTimeout.exists = MI_TRUE;
if (XML_Expect(xml, &e, XML_END, MI_T('w'), MI_T("OperationTimeout")) != 0)
RETURN(-1);
}
break;
case WSMANTAG_SUBSCRIBE_IDENTIFIER:
{
/* For unsubscribe, parse subscribe identifier from header */
if (XML_Expect(xml, &e, XML_CHARS, 0, NULL) != 0)
RETURN(-1);
wsheader->contextID = (MI_Uint32)Tcstoull(e.data.data, NULL, 10);
trace_WsmanUnsubscribe( wsheader->contextID );
if (XML_Expect(xml, &e, XML_END, MI_T('e'), MI_T("Identifier")) != 0)
RETURN(-1);
}
break;
#endif /* ifndef DISABLE_INDICATION */
#ifndef DISABLE_SHELL
case WSMANTAG_COMPRESSION_TYPE:
{
if (XML_Expect(xml, &e, XML_CHARS, 0, MI_T("xpress")) != 0)
RETURN(-1);
if (XML_Expect(xml, &e, XML_END, MI_T('h'), MI_T("CompressionType")) != 0)
RETURN(-1);
wsheader->isCompressed = MI_TRUE;
}
break;
#endif
case WSMANTAG_LOCALE:
{
const TChar* p = XML_Elem_GetAttr(&e, 0, MI_T("lang"));
if (p == NULL)
RETURN(-1);
if (XML_Expect(xml, &e, XML_END, MI_T('w'), MI_T("Locale")) != 0)
RETURN(-1);
wsheader->rqtLocale = p;
}
break;
case WSMANTAG_DATA_LOCALE:
{
const TChar* p = XML_Elem_GetAttr(&e, 0, MI_T("lang"));
if (p == NULL)
RETURN(-1);
if (XML_Expect(xml, &e, XML_END, MI_T('p'), MI_T("DataLocale")) != 0)
RETURN(-1);
wsheader->rqtDataLocale = p;
}
break;
case WSMANTAG_RELATES_TO:
{
if (XML_Expect(xml, &e, XML_CHARS, 0, NULL) != 0)
RETURN(-1);
if (XML_StripWhitespace(&e) != 0)
RETURN(-1);
wsheader->rspRelatesTo = e.data.data;
if (XML_Expect(xml, &e, XML_END, PAL_T('a'), PAL_T("RelatesTo")) != 0)
RETURN(-1);
}
break;
default:
{
if (_MustUnderstandCanBeIgnored(&e) != 0)
{
wsheader->unknownMandatoryTag = e.data.data;
trace_Wsman_UnknownMandatoryTag(tcs(e.data.data));
/* validate header will send correct repsonse to the client */
}
if (XML_Skip(xml) != 0)
RETURN(-1);
}
break;
}
}
/* DMTF standard requires default namespace to be used */
/* if _cimnamespace selector is not specified as part of request */
if (!wsheader->rqtNamespace)
wsheader->rqtNamespace = DEFAULT_CIMNAMESPACE;
return 0;
}