예제 #1
0
/**
 * This method is invoked whenever a piece of data, belonging to a single field (name or value)
 * becomes available. It will either create a new parameter or store the transient information
 * until a parameter can be created.
 *
 * @param urlenp
 * @param data
 * @param startpos
 * @param endpos
 * @param c Should contain -1 if the reason this function is called is because the end of
 *          the current data chunk is reached.
 */
static void htp_urlenp_add_field_piece(htp_urlenp_t *urlenp, unsigned char *data, size_t startpos, size_t endpos, int c) {
    // Add field if we know it ended or if we know that
    // we've used all of the input data
    if ((c != -1) || (urlenp->_complete)) {
        // Add field
        bstr *field = NULL;

        // Did we use the string builder for this field?
        if (bstr_builder_size(urlenp->_bb) > 0) {
            // The current field consists of more than once piece,
            // we have to use the string builder

            // Add current piece to string builder
            if (endpos - startpos > 0) {
                bstr_builder_append_mem(urlenp->_bb, (char *) data + startpos, endpos - startpos);
            }

            // Generate the field and clear the string builder
            field = bstr_builder_to_str(urlenp->_bb);
            if (field == NULL) return;
            bstr_builder_clear(urlenp->_bb);
        } else {
            // We only have the current piece to work with, so
            // no need to involve the string builder
            field = bstr_dup_mem((char *) data + startpos, endpos - startpos);
            if (field == NULL) return;
        }

        // Process the field differently, depending on the current state
        if (urlenp->_state == HTP_URLENP_STATE_KEY) {
            // Store the name for later
            urlenp->_name = field;

            if (urlenp->_complete) {
                // Param with key but no value
                bstr *name = urlenp->_name;
                bstr *value = bstr_dup_c("");

                if (urlenp->decode_url_encoding) {                    
                    // htp_uriencoding_normalize_inplace(name);
                    htp_decode_urlencoded_inplace(urlenp->tx->connp->cfg, urlenp->tx, name);
                }
                
                table_addn(urlenp->params, name, value);
                urlenp->_name = NULL;

                #ifdef HTP_DEBUG
                fprint_raw_data(stderr, "NAME", (unsigned char *) bstr_ptr(name), bstr_len(name));
                fprint_raw_data(stderr, "VALUE", (unsigned char *) bstr_ptr(value), bstr_len(value));
                #endif
            }
        } else {
            // Param with key and value                        
            bstr *name = urlenp->_name;
            bstr *value = field;
            
            if (urlenp->decode_url_encoding) {                
                htp_decode_urlencoded_inplace(urlenp->tx->connp->cfg, urlenp->tx, name);
                htp_decode_urlencoded_inplace(urlenp->tx->connp->cfg, urlenp->tx, value);
            }

            table_addn(urlenp->params, name, value);
            urlenp->_name = NULL;

            #ifdef HTP_DEBUG
            fprint_raw_data(stderr, "NAME", (unsigned char *) bstr_ptr(name), bstr_len(name));
            fprint_raw_data(stderr, "VALUE", (unsigned char *) bstr_ptr(value), bstr_len(value));
            #endif
        }
    } else {
        // Make a copy of the data and store it in an array for later
        if (endpos - startpos > 0) {
            bstr_builder_append_mem(urlenp->_bb, (char *) data + startpos, endpos - startpos);
        }
    }
}
예제 #2
0
/**
 * Transcode all parameters supplied in the table.
 *
 * @param connp
 * @param params
 * @param destroy_old
 */
int htp_transcode_params(htp_connp_t *connp, table_t **params, int destroy_old) {
    table_t *input_params = *params;

    // No transcoding unless necessary
    if (connp->cfg->internal_encoding == NULL) {
        return HTP_OK;
    }

    // Create a new table that will hold transcoded parameters
    table_t *output_params = connp->cfg->create_table(table_size(input_params));
    if (output_params == NULL) {
        return HTP_ERROR;
    }

    // Initialize iconv
    iconv_t cd = iconv_open(connp->cfg->internal_encoding, connp->cfg->request_encoding);
    if (cd == (iconv_t) -1) {
        // TODO Report iconv initialization error
        table_destroy(&output_params);
        return HTP_ERROR;
    }

    #if (_LIBICONV_VERSION >= 0x0108)
    int iconv_param = 0;
    iconvctl(cd, ICONV_SET_TRANSLITERATE, &iconv_param);
    iconv_param = 1;
    iconvctl(cd, ICONV_SET_DISCARD_ILSEQ, &iconv_param);
    #endif

    // Convert the parameters, one by one
    bstr *name;
    void *tvalue;
    table_iterator_reset(input_params);
    while ((name = table_iterator_next(input_params, &tvalue)) != NULL) {
        bstr *new_name = NULL, *new_value = NULL;
        bstr *value = (bstr *)tvalue;

        // Convert name
        htp_transcode_bstr(cd, name, &new_name);
        if (new_name == NULL) {
            iconv_close(cd);

            table_iterator_reset(output_params);
            while(table_iterator_next(output_params, &tvalue) != NULL) {
                bstr *b = (bstr *)tvalue;
                bstr_free(&b);
            }

            table_destroy(&output_params);
            return HTP_ERROR;
        }

        // Convert value
        htp_transcode_bstr(cd, value, &new_value);
        if (new_value == NULL) {
            bstr_free(&new_name);
            iconv_close(cd);

            table_iterator_reset(output_params);
            while(table_iterator_next(output_params, &tvalue) != NULL) {
                bstr *b = (bstr *)tvalue;
                bstr_free(&b);
            }

            table_destroy(&output_params);
            return HTP_ERROR;
        }

        // Add to new table
        table_addn(output_params, new_name, new_value);
    }

    // Replace the old parameter table
    *params = output_params;

    // Destroy the old parameter table if necessary
    if (destroy_old) {
        table_iterator_reset(input_params);
        while(table_iterator_next(input_params, &tvalue) != NULL) {
            bstr *b = (bstr *)tvalue;
            bstr_free(&b);
        }

        table_destroy(&input_params);
    }

    iconv_close(cd);

    return HTP_OK;
}