Esempio n. 1
0
/**
 * 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);
}
Esempio n. 2
0
/**
 * 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;
}
Esempio n. 3
0
/**
 * 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;
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
// 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;
}	
Esempio n. 6
0
/**
 * 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;
}
Esempio n. 7
0
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>");
}
Esempio n. 8
0
/**
 * 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);
}
Esempio n. 9
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;
}