int WS_ParseWSHeader()

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;
}