/** * Determine if the request has a URLENCODED body, then * create and attach the URLENCODED parser if it does. */ int htp_ch_urlencoded_callback_request_headers(htp_connp_t *connp) { // Check the request content type to see if it matches our MIME type if ((connp->in_tx->request_content_type == NULL) || (bstr_cmp_c(connp->in_tx->request_content_type, HTP_URLENCODED_MIME_TYPE) != 0)) { #ifdef HTP_DEBUG fprintf(stderr, "htp_ch_urlencoded_callback_request_headers: Body not URLENCODED\n"); #endif return HOOK_OK; } #ifdef HTP_DEBUG fprintf(stderr, "htp_ch_urlencoded_callback_request_headers: Parsing URLENCODED body\n"); #endif // Create parser instance connp->in_tx->request_urlenp_body = htp_urlenp_create(connp->in_tx); if (connp->in_tx->request_urlenp_body == NULL) { return HOOK_ERROR; } // Register request body data callbacks htp_tx_register_request_body_data(connp->in_tx, htp_ch_urlencoded_callback_request_body_data); return HOOK_OK; }
/** * Parses request query string, if present. * * @param[in] connp * @param[in] raw_data * @param[in] raw_len * @return HTP_OK if query string was parsed, HTP_DECLINED if there was no query * string, and HTP_ERROR on failure. */ htp_status_t htp_ch_urlencoded_callback_request_line(htp_tx_t *tx) { // Proceed only if there's something for us to parse. if ((tx->parsed_uri->query == NULL) || (bstr_len(tx->parsed_uri->query) == 0)) { return HTP_DECLINED; } // We have a non-zero length query string. tx->request_urlenp_query = htp_urlenp_create(tx); if (tx->request_urlenp_query == NULL) return HTP_ERROR; if (htp_urlenp_parse_complete(tx->request_urlenp_query, bstr_ptr(tx->parsed_uri->query), bstr_len(tx->parsed_uri->query)) != HTP_OK) { htp_urlenp_destroy(tx->request_urlenp_query); return HTP_ERROR; } // Add all parameters to the transaction. bstr *name = NULL; bstr *value = NULL; for (size_t i = 0, n = htp_table_size(tx->request_urlenp_query->params); i < n; i++) { value = htp_table_get_index(tx->request_urlenp_query->params, i, &name); htp_param_t *param = calloc(1, sizeof (htp_param_t)); if (param == NULL) return HTP_ERROR; param->name = name; param->value = value; param->source = HTP_SOURCE_QUERY_STRING; param->parser_id = HTP_PARSER_URLENCODED; param->parser_data = NULL; if (htp_tx_req_add_param(tx, param) != HTP_OK) { free(param); return HTP_ERROR; } } // All the parameter data is now owned by the transaction, and // the parser table used to store it is no longer needed. The // line below will destroy just the table, leaving keys intact. htp_table_destroy_ex(tx->request_urlenp_query->params); tx->request_urlenp_query->params = NULL; htp_urlenp_destroy(tx->request_urlenp_query); tx->request_urlenp_query = NULL; return HTP_OK; }
/** * Parse query string, if available. This method is invoked after the * request line has been processed. * * @param connp */ int htp_ch_urlencoded_callback_request_line(htp_connp_t *connp) { // Parse query string, when available if ((connp->in_tx->parsed_uri->query != NULL) && (bstr_len(connp->in_tx->parsed_uri->query) > 0)) { connp->in_tx->request_urlenp_query = htp_urlenp_create(connp->in_tx); if (connp->in_tx->request_urlenp_query == NULL) { return HOOK_ERROR; } htp_urlenp_parse_complete(connp->in_tx->request_urlenp_query, (unsigned char *) bstr_ptr(connp->in_tx->parsed_uri->query), bstr_len(connp->in_tx->parsed_uri->query)); // Is there a parameter processor? if (connp->cfg->parameter_processor == NULL) { // There's no parameter processor if (connp->cfg->internal_encoding == NULL) { // No transcoding; use the parser table directly connp->in_tx->request_params_query = connp->in_tx->request_urlenp_query->params; connp->in_tx->request_params_query_reused = 1; } else { // Transcode values connp->in_tx->request_params_query = connp->in_tx->request_urlenp_query->params; htp_transcode_params(connp, &connp->in_tx->request_params_query, 0); } } else { // We have a parameter processor defined, which // means we'll need to create a new table connp->in_tx->request_params_query = connp->cfg->create_table(table_size(connp->in_tx->request_urlenp_query->params)); // Use the parameter processor on each parameter, storing // the results in the newly created table bstr *name; void *tvalue; table_iterator_reset(connp->in_tx->request_urlenp_query->params); while ((name = table_iterator_next(connp->in_tx->request_urlenp_query->params, & tvalue)) != NULL) { connp->cfg->parameter_processor(connp->in_tx->request_params_query, name, (bstr *)tvalue); // TODO Check return code } // Transcode as necessary htp_transcode_params(connp, &connp->in_tx->request_params_query, 1); } } return HOOK_OK; }
/** * Determine if the request has a Urlencoded body, and, if it does, create and * attach an instance of the Urlencoded parser to the transaction. * * @param[in] connp * @return HTP_OK if a new parser has been setup, HTP_DECLINED if the MIME type * is not appropriate for this parser, and HTP_ERROR on failure. */ htp_status_t htp_ch_urlencoded_callback_request_headers(htp_tx_t *tx) { // Check the request content type to see if it matches our MIME type. if ((tx->request_content_type == NULL) || (!bstr_begins_with_c(tx->request_content_type, HTP_URLENCODED_MIME_TYPE))) { #ifdef HTP_DEBUG fprintf(stderr, "htp_ch_urlencoded_callback_request_headers: Body not URLENCODED\n"); #endif return HTP_DECLINED; } #ifdef HTP_DEBUG fprintf(stderr, "htp_ch_urlencoded_callback_request_headers: Parsing URLENCODED body\n"); #endif // Create parser instance. tx->request_urlenp_body = htp_urlenp_create(tx); if (tx->request_urlenp_body == NULL) return HTP_ERROR; // Register a request body data callback. htp_tx_register_request_body_data(tx, htp_ch_urlencoded_callback_request_body_data); return HTP_OK; }