mirror of https://github.com/OISF/suricata
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
183 lines
5.1 KiB
C
183 lines
5.1 KiB
C
/*
|
|
* LibHTP (http://www.libhtp.org)
|
|
* Copyright 2009,2010 Ivan Ristic <ivanr@webkreator.com>
|
|
*
|
|
* LibHTP is an open source product, released under terms of the General Public Licence
|
|
* version 2 (GPLv2). Please refer to the file LICENSE, which contains the complete text
|
|
* of the license.
|
|
*
|
|
* In addition, there is a special exception that allows LibHTP to be freely
|
|
* used with any OSI-approved open source licence. Please refer to the file
|
|
* LIBHTP_LICENSING_EXCEPTION for the full text of the exception.
|
|
*
|
|
*/
|
|
|
|
#include "htp.h"
|
|
|
|
/**
|
|
* Creates a new transaction structure.
|
|
*
|
|
* @param cfg
|
|
* @param is_cfg_shared
|
|
* @param conn
|
|
* @return The newly created transaction, or NULL on memory allocation failure.
|
|
*/
|
|
htp_tx_t *htp_tx_create(htp_cfg_t *cfg, int is_cfg_shared, htp_conn_t *conn) {
|
|
htp_tx_t *tx = calloc(1, sizeof (htp_tx_t));
|
|
if (tx == NULL) return NULL;
|
|
|
|
tx->conn = conn;
|
|
tx->cfg = cfg;
|
|
tx->is_cfg_shared = is_cfg_shared;
|
|
|
|
tx->conn = conn;
|
|
|
|
tx->request_header_lines = list_array_create(32);
|
|
tx->request_headers = table_create(32);
|
|
tx->request_line_nul_offset = -1;
|
|
tx->parsed_uri = calloc(1, sizeof (htp_uri_t));
|
|
tx->parsed_uri_incomplete = calloc(1, sizeof (htp_uri_t));
|
|
|
|
tx->response_header_lines = list_array_create(32);
|
|
tx->response_headers = table_create(32);
|
|
|
|
tx->request_protocol_number = -1;
|
|
|
|
return tx;
|
|
}
|
|
|
|
/**
|
|
* 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;
|
|
list_iterator_reset(tx->request_header_lines);
|
|
while ((hl = list_iterator_next(tx->request_header_lines)) != NULL) {
|
|
bstr_free(hl->line);
|
|
// 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;
|
|
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);
|
|
|
|
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;
|
|
list_iterator_reset(tx->response_header_lines);
|
|
while ((hl = list_iterator_next(tx->response_header_lines)) != NULL) {
|
|
bstr_free(hl->line);
|
|
// 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;
|
|
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);
|
|
}
|
|
|
|
/**
|
|
* Returns the user data associated with this transaction.
|
|
*
|
|
* @param tx
|
|
* @return A pointer to user data or NULL
|
|
*/
|
|
void *htp_tx_get_user_data(htp_tx_t *tx) {
|
|
return tx->user_data;
|
|
}
|
|
|
|
/**
|
|
* Sets the configuration that is to be used for this transaction.
|
|
*
|
|
* @param tx
|
|
* @param cfg
|
|
* @param is_cfg_shared
|
|
*/
|
|
void htp_tx_set_config(htp_tx_t *tx, htp_cfg_t *cfg, int is_cfg_shared) {
|
|
tx->cfg = cfg;
|
|
tx->is_cfg_shared = is_cfg_shared;
|
|
}
|
|
|
|
/**
|
|
* Associates user data with this transaction.
|
|
*
|
|
* @param tx
|
|
* @param user_data
|
|
*/
|
|
void htp_tx_set_user_data(htp_tx_t *tx, void *user_data) {
|
|
tx->user_data = user_data;
|
|
}
|