/** * Destroys multipart part. * * @param part */ void htp_mpart_part_destroy(htp_mpart_part_t *part) { if (part == NULL) return; if (part->file != NULL) { bstr_free(&part->file->filename); if (part->file->tmpname != NULL) { unlink(part->file->tmpname); free(part->file->tmpname); } free(part->file); part->file = NULL; } bstr_free(&part->name); bstr_free(&part->value); if (part->headers != NULL) { // Destroy request_headers htp_header_t *h = NULL; table_iterator_reset(part->headers); while (table_iterator_next(part->headers, (void **) & h) != NULL) { bstr_free(&h->name); bstr_free(&h->value); free(h); } table_destroy(&part->headers); } free(part); }
/** * Destroys an existing URLENCODED parser. * * @param urlenp */ void htp_urlenp_destroy(htp_urlenp_t **_urlenp) { if ((_urlenp == NULL)||(*_urlenp == NULL)) return; htp_urlenp_t *urlenp = *_urlenp; if (urlenp->_name != NULL) { bstr_free(&urlenp->_name); } bstr_builder_destroy(urlenp->_bb); if (urlenp->params != NULL) { // Destroy parameters bstr *value = NULL; table_iterator_reset(urlenp->params); while (table_iterator_next(urlenp->params, (void **) & value) != NULL) { bstr_free(&value); } table_destroy(&urlenp->params); } free(urlenp); *_urlenp = NULL; }
/** * Invoked to process a part of request body data. * * @param d */ int htp_ch_urlencoded_callback_request_body_data(htp_tx_data_t *d) { if (d->data != NULL) { // Process one chunk of data htp_urlenp_parse_partial(d->tx->request_urlenp_body, d->data, d->len); } else { // Finalize parsing htp_urlenp_finalize(d->tx->request_urlenp_body); if (d->tx->connp->cfg->parameter_processor == NULL) { // We are going to use the parser table directly d->tx->request_params_body = d->tx->request_urlenp_body->params; d->tx->request_params_body_reused = 1; htp_transcode_params(d->tx->connp, &d->tx->request_params_body, 0); } else { // We have a parameter processor defined, which means we'll // need to create a new table d->tx->request_params_body = d->tx->cfg->create_table(table_size(d->tx->request_urlenp_body->params)); // Transform parameters and store them into the new table bstr *name; void *tvalue; table_iterator_reset(d->tx->request_urlenp_body->params); while ((name = table_iterator_next(d->tx->request_urlenp_body->params, & tvalue)) != NULL) { d->tx->connp->cfg->parameter_processor(d->tx->request_params_body, name, (bstr *)tvalue); // TODO Check return code } htp_transcode_params(d->tx->connp, &d->tx->request_params_body, 1); } } return HOOK_OK; }
static VALUE rbhtp_r_string_table( table_t* table ) { if ( table == NULL ) return Qnil; bstr k, v; VALUE r = rb_ary_new(); table_iterator_reset( table ); while ( ( k = table_iterator_next( table, &v ) ) != NULL ) { rb_ary_push( r, rb_ary_new3( 2, BSTR_TO_RSTR( k ), BSTR_TO_RSTR( v ) ) ); } return r; }
// We don't push the keys as they are duplicated in the header. static VALUE rbhtp_r_header_table( table_t* table ) { if ( table == NULL ) return Qnil; bstr k; htp_header_t* v; VALUE r = rb_ary_new(); table_iterator_reset( table ); while ( ( k = table_iterator_next( table, (void**)&v ) ) != NULL ) { rb_ary_push( r, rb_funcall( cHeader, rb_intern( "new" ), 1, Data_Wrap_Struct( rb_cObject, 0, 0, v ) ) ); } return r; }
/** * 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; }
static void LogFilestoreMetaGetReferer(FILE *fp, Packet *p, File *ff) { HtpState *htp_state = (HtpState *)p->flow->alstate; if (htp_state != NULL) { htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, ff->txid); if (tx != NULL) { table_t *headers; headers = tx->request_headers; htp_header_t *h = NULL; table_iterator_reset(headers); while (table_iterator_next(headers, (void **)&h) != NULL) { if (bstr_len(h->name) >= 7 && SCMemcmpLowercase((uint8_t *)"referer", (uint8_t *)bstr_ptr(h->name), bstr_len(h->name)) == 0) { PrintRawUriFp(fp, (uint8_t *)bstr_ptr(h->value), bstr_len(h->value)); return; } } } } fprintf(fp, "<unknown>"); }
/** * Destroys the supplied transaction. * * @param tx */ void htp_tx_destroy(htp_tx_t *tx) { bstr_free(tx->request_line); bstr_free(tx->request_method); bstr_free(tx->request_uri); bstr_free(tx->request_uri_normalized); bstr_free(tx->request_protocol); if (tx->parsed_uri != NULL) { bstr_free(tx->parsed_uri->scheme); bstr_free(tx->parsed_uri->username); bstr_free(tx->parsed_uri->password); bstr_free(tx->parsed_uri->hostname); bstr_free(tx->parsed_uri->port); bstr_free(tx->parsed_uri->path); bstr_free(tx->parsed_uri->query); bstr_free(tx->parsed_uri->fragment); free(tx->parsed_uri); } if (tx->parsed_uri_incomplete != NULL) { bstr_free(tx->parsed_uri_incomplete->scheme); bstr_free(tx->parsed_uri_incomplete->username); bstr_free(tx->parsed_uri_incomplete->password); bstr_free(tx->parsed_uri_incomplete->hostname); bstr_free(tx->parsed_uri_incomplete->port); bstr_free(tx->parsed_uri_incomplete->path); bstr_free(tx->parsed_uri_incomplete->query); bstr_free(tx->parsed_uri_incomplete->fragment); free(tx->parsed_uri_incomplete); } // Destroy request_header_lines htp_header_line_t *hl = NULL; if (tx->request_header_lines != NULL) { list_iterator_reset(tx->request_header_lines); while ((hl = list_iterator_next(tx->request_header_lines)) != NULL) { bstr_free(hl->line); bstr_free(hl->terminators); // No need to destroy hl->header because // htp_header_line_t does not own it. free(hl); } list_destroy(tx->request_header_lines); } // Destroy request_headers htp_header_t *h = NULL; if (tx->request_headers != NULL) { table_iterator_reset(tx->request_headers); while (table_iterator_next(tx->request_headers, (void **) & h) != NULL) { bstr_free(h->name); bstr_free(h->value); free(h); } table_destroy(tx->request_headers); } if (tx->request_headers_raw != NULL) { bstr_free(tx->request_headers_raw); } bstr_free(tx->response_line); bstr_free(tx->response_protocol); bstr_free(tx->response_status); bstr_free(tx->response_message); // Destroy response_header_lines hl = NULL; if (tx->response_header_lines != NULL) { list_iterator_reset(tx->response_header_lines); while ((hl = list_iterator_next(tx->response_header_lines)) != NULL) { bstr_free(hl->line); bstr_free(hl->terminators); // No need to destroy hl->header because // htp_header_line_t does not own it. free(hl); } list_destroy(tx->response_header_lines); } // Destroy response headers h = NULL; if (tx->response_headers) { table_iterator_reset(tx->response_headers); while (table_iterator_next(tx->response_headers, (void **) & h) != NULL) { bstr_free(h->name); bstr_free(h->value); free(h); } table_destroy(tx->response_headers); } // Tell the connection to remove this transaction // from the list htp_conn_remove_tx(tx->conn, tx); // Invalidate the pointer to this transactions held // by the connection parser. This is to allow a transaction // to be destroyed from within the final response callback. if (tx->connp != NULL) { if (tx->connp->out_tx == tx) { tx->connp->out_tx = NULL; } } free(tx); }
/** * 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; }