int hash_response_body_links()

in apache2/msc_crypt.c [673:1016]


int hash_response_body_links(modsec_rec *msr)   {
    int lsize = 0, fsize = 0, lcount = 0, fcount = 0, i;
    int isize = 0, icount = 0, frsize = 0, frcount = 0;
    int bytes = 0;
    xmlXPathContextPtr  xpathCtx = NULL;
    xmlXPathObjectPtr   xpathObj = NULL;
    xmlChar *content_option = NULL;
    char *mac_link = NULL;
    int rc, elts = 0;

    if(msr == NULL)
        return -1;

    if (msr->crypto_html_tree == NULL) {
        if (msr->txcfg->debuglog_level >= 4)
            msr_log(msr, 4, "hash_response_body_links: Cannot parse NULL html tree");
        return -1;
    }

    if(msr->txcfg->crypto_hash_href_rx == 0 && msr->txcfg->crypto_hash_href_pm == 0
            && msr->txcfg->crypto_hash_faction_rx == 0 && msr->txcfg->crypto_hash_faction_pm == 0
            && msr->txcfg->crypto_hash_iframesrc_rx == 0 && msr->txcfg->crypto_hash_iframesrc_pm == 0
            && msr->txcfg->crypto_hash_framesrc_rx == 0 && msr->txcfg->crypto_hash_framesrc_pm == 0)
        return -1;

    xpathCtx = xmlXPathNewContext(msr->crypto_html_tree);
    if(xpathCtx == NULL) {
        if (msr->txcfg->debuglog_level >= 4)
            msr_log(msr, 4, "hash_response_body_links: Unable to create Xpath context.");
        goto ctx_error;
    }

    lcount=fcount=0;

    if(msr->txcfg->crypto_hash_href_rx == 1 || msr->txcfg->crypto_hash_href_pm == 1)    {

        xpathObj = xmlXPathEvalExpression((xmlChar*)"//*[@href]", xpathCtx);
        if(xpathObj == NULL) {
            if (msr->txcfg->debuglog_level >= 4)
                msr_log(msr, 4,
                        "hash_response_body_links: Unable to evaluate xpath expression.");
            goto obj_error;
        }

        lsize = (xpathObj->nodesetval) ? xpathObj->nodesetval->nodeNr : 0;
        for(i = lsize - 1; i >=0; i--) {
            register xmlNodePtr cur;

            cur = xpathObj->nodesetval->nodeTab[i];
            if(cur != NULL){
                xmlChar *href = xmlGetProp(cur, (const xmlChar *) "href");
                char *content_href = normalize_path(msr, (char *)href);

                if(content_href != NULL && strstr(content_href,msr->txcfg->crypto_param_name) == NULL) {
                    if(msr->txcfg->crypto_hash_href_rx == 1)    {
                        rc = do_hash_method(msr, (char *)content_href, HASH_URL_HREF_HASH_RX);
                        if(rc > 0)  {
                            mac_link = NULL;
                            mac_link = do_hash_link(msr, (char *)content_href, FULL_LINK);
                            if(mac_link != NULL) {
                                xmlSetProp(cur, (const xmlChar *) "href", (const xmlChar *) mac_link);
                                lcount++;
                                bytes += strlen(mac_link);
                                msr->of_stream_changed = 1;
                            }
                            mac_link = NULL;
                            if(href != NULL)
                                xmlFree(href);
                            continue;
                        }
                    }
                    if(msr->txcfg->crypto_hash_href_pm == 1)    {
                        rc = do_hash_method(msr, (char *)content_href, HASH_URL_HREF_HASH_PM);
                        if(rc > 0)  {
                            mac_link = NULL;
                            mac_link = do_hash_link(msr, (char *)content_href, FULL_LINK);
                            if(mac_link != NULL) {
                                xmlSetProp(cur, (const xmlChar *) "href", (const xmlChar *) mac_link);
                                lcount++;
                                bytes += strlen(mac_link);
                                msr->of_stream_changed = 1;
                            }
                            mac_link = NULL;
                            if(href != NULL)
                                xmlFree(href);
                            continue;
                        }
                    }
                }

                if(href != NULL)    {
                    xmlFree(href);
                    href = NULL;
                }
            }
        }

        if(xpathObj != NULL)
            xmlXPathFreeObject(xpathObj);
    }

    if(msr->txcfg->crypto_hash_faction_rx == 1 || msr->txcfg->crypto_hash_faction_pm == 1) {
        xpathObj = xmlXPathEvalExpression((xmlChar*)"//form", xpathCtx);
        if(xpathObj == NULL) {
            if (msr->txcfg->debuglog_level >= 4)
                msr_log(msr, 4,
                        "hash_response_body_links: Unable to evaluate xpath expression.");
            goto obj_error;
        }

        fsize = (xpathObj->nodesetval) ? xpathObj->nodesetval->nodeNr : 0;
        for(i = fsize - 1; i >=0; i--) {
            register xmlNodePtr cur;

            cur = xpathObj->nodesetval->nodeTab[i];
            if((cur != NULL)){
                xmlChar *action = NULL;
                char *content_action = NULL;

                if(content_option)
                    xmlFree(content_option);

                action = xmlGetProp(cur, (const xmlChar *) "action");
                content_action = normalize_path(msr, (char *)action);
                content_option = xmlGetProp(cur, (const xmlChar *) "option");

                if(content_action != NULL && content_option == NULL && strstr(content_action,msr->txcfg->crypto_param_name) == NULL) {
                    if(msr->txcfg->crypto_hash_faction_rx == 1) {
                        rc = do_hash_method(msr, (char *)content_action, HASH_URL_FACTION_HASH_RX);
                        if(rc > 0)  {
                            mac_link = NULL;
                            mac_link = do_hash_link(msr, (char *)content_action, FULL_LINK);
                            if(mac_link != NULL) {
                                xmlSetProp(cur, (const xmlChar *) "action", (const xmlChar *) mac_link);
                                fcount++;
                                bytes += strlen(mac_link);
                                msr->of_stream_changed = 1;
                            }
                            mac_link = NULL;
                            if(action != NULL)
                                xmlFree(action);
                            continue;
                        }
                    }
                    if(msr->txcfg->crypto_hash_faction_pm == 1) {
                        rc = do_hash_method(msr, (char *)content_action, HASH_URL_FACTION_HASH_PM);
                        if(rc > 0)  {
                            mac_link = NULL;
                            mac_link = do_hash_link(msr, (char *)content_action, FULL_LINK);
                            if(mac_link != NULL) {
                                xmlSetProp(cur, (const xmlChar *) "action", (const xmlChar *) mac_link);
                                fcount++;
                                bytes += strlen(mac_link);
                                msr->of_stream_changed = 1;
                            }
                            mac_link = NULL;
                            if(action != NULL)
                                xmlFree(action);
                            continue;
                        }
                    }
                }

                if(action != NULL)  {
                    xmlFree(action);
                    action = NULL;
                }

                if(content_option)  {
                    xmlFree(content_option);
                    content_option = NULL;
                }
            }
        }

        if(xpathObj != NULL)
            xmlXPathFreeObject(xpathObj);
    }

    if(msr->txcfg->crypto_hash_iframesrc_rx == 1 || msr->txcfg->crypto_hash_iframesrc_pm == 1) {
        xpathObj = xmlXPathEvalExpression((xmlChar*)"//iframe", xpathCtx);
        if(xpathObj == NULL) {
            if (msr->txcfg->debuglog_level >= 4)
                msr_log(msr, 4,
                        "hash_response_body_links: Unable to evaluate xpath expression.");
            goto obj_error;
        }

        isize = (xpathObj->nodesetval) ? xpathObj->nodesetval->nodeNr : 0;
        for(i = isize - 1; i >=0; i--) {
            register xmlNodePtr cur;

            cur = xpathObj->nodesetval->nodeTab[i];
            if((cur != NULL)){

                xmlChar *src = xmlGetProp(cur, (const xmlChar *) "src");
                char *content_src = normalize_path(msr, (char *)src);

                if(content_src != NULL && strstr(content_src,msr->txcfg->crypto_param_name) == NULL) {
                    if(msr->txcfg->crypto_hash_iframesrc_rx == 1) {
                        rc = do_hash_method(msr, (char *)content_src, HASH_URL_IFRAMESRC_HASH_RX);
                        if(rc > 0)  {
                            mac_link = NULL;
                            mac_link = do_hash_link(msr, (char *)content_src, FULL_LINK);
                            if(mac_link != NULL) {
                                xmlSetProp(cur, (const xmlChar *) "src", (const xmlChar *) mac_link);
                                icount++;
                                bytes += strlen(mac_link);
                                msr->of_stream_changed = 1;
                            }
                            mac_link = NULL;
                            if(src != NULL)
                                xmlFree(src);
                            continue;
                        }
                    }
                    if(msr->txcfg->crypto_hash_iframesrc_pm == 1) {
                        rc = do_hash_method(msr, (char *)content_src, HASH_URL_IFRAMESRC_HASH_PM);
                        if(rc > 0)  {
                            mac_link = NULL;
                            mac_link = do_hash_link(msr, (char *)content_src, FULL_LINK);
                            if(mac_link != NULL) {
                                xmlSetProp(cur, (const xmlChar *) "src", (const xmlChar *) mac_link);
                                icount++;
                                bytes += strlen(mac_link);
                                msr->of_stream_changed = 1;
                            }
                            mac_link = NULL;
                            if(src != NULL)
                                xmlFree(src);
                            continue;
                        }
                    }
                }

                if(src != NULL) {
                    xmlFree(src);
                    src = NULL;
                }
            }
        }

        if(xpathObj != NULL)
            xmlXPathFreeObject(xpathObj);
    }

    if(msr->txcfg->crypto_hash_framesrc_rx == 1 || msr->txcfg->crypto_hash_framesrc_pm == 1) {
        xpathObj = xmlXPathEvalExpression((xmlChar*)"//frame", xpathCtx);
        if(xpathObj == NULL) {
            if (msr->txcfg->debuglog_level >= 4)
                msr_log(msr, 4,
                        "hash_response_body_links: Unable to evaluate xpath expression.");
            goto obj_error;
        }

        frsize = (xpathObj->nodesetval) ? xpathObj->nodesetval->nodeNr : 0;
        for(i = frsize - 1; i >=0; i--) {
            register xmlNodePtr cur;

            cur = xpathObj->nodesetval->nodeTab[i];
            if((cur != NULL)){

                xmlChar *src = xmlGetProp(cur, (const xmlChar *) "src");
                char *content_src = normalize_path(msr, (char *)src);

                if(content_src != NULL && strstr(content_src,msr->txcfg->crypto_param_name) == NULL) {
                    if(msr->txcfg->crypto_hash_framesrc_rx == 1) {
                        rc = do_hash_method(msr, (char *)content_src, HASH_URL_FRAMESRC_HASH_RX);
                        if(rc > 0)  {
                            mac_link = NULL;
                            mac_link = do_hash_link(msr, (char *)content_src, FULL_LINK);
                            if(mac_link != NULL) {
                                xmlSetProp(cur, (const xmlChar *) "src", (const xmlChar *) mac_link);
                                frcount++;
                                bytes += strlen(mac_link);
                                msr->of_stream_changed = 1;
                            }
                            mac_link = NULL;
                            if(src != NULL)
                                xmlFree(src);
                            continue;
                        }
                    }
                    if(msr->txcfg->crypto_hash_framesrc_pm == 1) {
                        rc = do_hash_method(msr, (char *)content_src, HASH_URL_FRAMESRC_HASH_PM);
                        if(rc > 0)  {
                            mac_link = NULL;
                            mac_link = do_hash_link(msr, (char *)content_src, FULL_LINK);
                            if(mac_link != NULL) {
                                xmlSetProp(cur, (const xmlChar *) "src", (const xmlChar *) mac_link);
                                frcount++;
                                bytes += strlen(mac_link);
                                msr->of_stream_changed = 1;
                            }
                            mac_link = NULL;
                            if(src != NULL)
                                xmlFree(src);
                            continue;
                        }
                    }
                }

                if(src != NULL) {
                    xmlFree(src);
                    src = NULL;
                }
            }
        }

        if(xpathObj != NULL)
            xmlXPathFreeObject(xpathObj);
    }

    if(xpathCtx != NULL)
        xmlXPathFreeContext(xpathCtx);

    if (msr->txcfg->debuglog_level >= 4)    {
        msr_log(msr, 4, "hash_response_body_links: Processed [%d] iframe src, [%d] hashed.",isize, icount);
        msr_log(msr, 4, "hash_response_body_links: Processed [%d] frame src, [%d] hashed.",frsize, frcount);
        msr_log(msr, 4, "hash_response_body_links: Processed [%d] form actions, [%d] hashed.",fsize, fcount);
        msr_log(msr, 4, "hash_response_body_links: Processed [%d] links, [%d] hashed.",lsize, lcount);
    }

    if(msr->of_stream_changed == 0) {
        if(msr->crypto_html_tree != NULL)   {
            xmlFreeDoc(msr->crypto_html_tree);
            msr->crypto_html_tree = NULL;
        }
        return 0;
    }

    elts = (icount+frcount+fcount+lcount);

    if((elts >= INT32_MAX) || (elts < 0))
        return 0;

    return bytes;

obj_error:
    if(xpathCtx != NULL)
    xmlXPathFreeContext(xpathCtx);
ctx_error:
    return -1;
}