Example #1
0
/**
 * Creates a new hook.
 *
 * @return New htp_hook_t structure on success, NULL on failure
 */
htp_hook_t *hook_create(void) {
    htp_hook_t *hook = calloc(1, sizeof (htp_hook_t));
    if (hook == NULL) return NULL;

    hook->callbacks = list_array_create(4);
    if (hook->callbacks == NULL) {
        free(hook);
        return NULL;
    }   

    return hook;
}
Example #2
0
/**
 * Creates a new connection structure.
 *
 * @param connp
 * @return A new htp_connp_t structure on success, NULL on memory allocation failure.
 */
htp_conn_t *htp_conn_create(htp_connp_t *connp) {
    htp_conn_t *conn = calloc(1, sizeof (htp_conn_t));
    if (conn == NULL) return NULL;

    conn->connp = connp;

    conn->transactions = list_array_create(16);
    if (conn->transactions == NULL) {
        free(conn);
        return NULL;
    }

    conn->messages = list_array_create(8);
    if (conn->messages == NULL) {
        list_destroy(conn->transactions);
        free(conn);
        return NULL;
    }

    return conn;
}
Example #3
0
/**
 * Creates a new multipart/form-data parser.
 *
 * @param boundary
 * @return New parser, or NULL on memory allocation failure.
 */
htp_mpartp_t * htp_mpartp_create(htp_connp_t *connp, char *boundary) {
    if ((connp == NULL)||(boundary == NULL)) return NULL;
    htp_mpartp_t *mpartp = calloc(1, sizeof (htp_mpartp_t));
    if (mpartp == NULL) return NULL;

    mpartp->connp = connp;

    mpartp->boundary_pieces = bstr_builder_create();
    if (mpartp->boundary_pieces == NULL) {
        htp_mpartp_destroy(&mpartp);
        return NULL;
    }

    mpartp->part_pieces = bstr_builder_create();
    if (mpartp->part_pieces == NULL) {
        htp_mpartp_destroy(&mpartp);
        return NULL;
    }

    mpartp->parts = list_array_create(64);
    if (mpartp->parts == NULL) {
        htp_mpartp_destroy(&mpartp);
        return NULL;
    }

    // Copy the boundary and convert it to lowercase    
    mpartp->boundary_len = strlen(boundary) + 4 + 1;
    mpartp->boundary = malloc(mpartp->boundary_len + 1);
    if (mpartp->boundary == NULL) {
        htp_mpartp_destroy(&mpartp);
        return NULL;
    }

    mpartp->boundary[0] = CR;
    mpartp->boundary[1] = LF;
    mpartp->boundary[2] = '-';
    mpartp->boundary[3] = '-';

    size_t i = 4;
    while (i < mpartp->boundary_len) {
        mpartp->boundary[i] = tolower((int) ((unsigned char) boundary[i - 4]));
        i++;
    }

    mpartp->state = MULTIPART_STATE_BOUNDARY;
    mpartp->bpos = 2;
    mpartp->extract_limit = MULTIPART_DEFAULT_FILE_EXTRACT_LIMIT;
    mpartp->handle_data = htp_mpartp_handle_data;
    mpartp->handle_boundary = htp_mpartp_handle_boundary;

    return mpartp;
}
Example #4
0
/**
 * 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;
}
Example #5
0
/**
 * Called by libnids whenever it has an event we have to handle.
 *
 * @param tcp
 * @param user_data
 */
void tcp_callback (struct tcp_stream *tcp, void **user_data) {
    stream_data *sd = *user_data;

    // New connection
    if (tcp->nids_state == NIDS_JUST_EST) {
        tcp->client.collect++;
        tcp->server.collect++;
        tcp->server.collect_urg++;
        tcp->client.collect_urg++;

        // Allocate custom per-stream data
        sd = calloc(1, sizeof(stream_data));
        sd->id = counter++;
        sd->direction = -1;
        sd->fd = -1;
        sd->log_level = -1;
        sd->chunks = list_array_create(16);
        sd->inbound_chunks = list_array_create(16);
        sd->outbound_chunks = list_array_create(16);
        sd->req_count = 1;

        // Init LibHTP parser
        sd->connp = htp_connp_create(cfg);
        if (sd->connp == NULL) {
            fprintf(stderr, "Failed to create LibHTP parser instance.\n");
            exit(1);
        }

        // Associate TCP stream information with the HTTP connection parser
        htp_connp_set_user_data(sd->connp, sd);

        // Associate TCP stream information with the libnids structures
        *user_data = sd;

        return;
    }

    // Connection close
    if (tcp->nids_state == NIDS_CLOSE) {
        if (sd == NULL) return;

        // Destroy parser
        htp_connp_destroy_all(sd->connp);

        // Free custom per-stream data
        free_stream_data(sd);

        return;
    }

    // Connection close (RST)
    if (tcp->nids_state == NIDS_RESET) {
        if (sd == NULL) return;

        // Destroy parser
        htp_connp_destroy_all(sd->connp);

        // Free custom per-stream data
        free_stream_data(sd);

        return;
    }

    if (tcp->nids_state == NIDS_DATA) {
        struct half_stream *hlf;
        int direction;

        if (tcp->client.count_new) {
            hlf = &tcp->client;
            direction = DIRECTION_SERVER;
        } else {
            hlf = &tcp->server;
            direction = DIRECTION_CLIENT;
        }

        if (sd == NULL) return;

        if (sd->direction == -1) {
            sd->direction = direction;
        }

        // Write data to disk or store for later
        if (sd->fd == -1) {
            // Store data, as we may need it later
            chunk_t *chunk = calloc(1, sizeof(chunk_t));
            // TODO
            chunk->direction = direction;
            chunk->data = malloc(hlf->count_new);
            // TODO
            chunk->len = hlf->count_new;
            memcpy(chunk->data, hlf->data, chunk->len);

            list_add(sd->chunks, chunk);
        } else {
            // No need to store, write directly to file

            if (sd->chunk_counter != 0) {
                write(sd->fd, "\r\n", 2);
            }

            if (sd->direction == direction) {
                write(sd->fd, ">>>\r\n", 5);
            } else {
                write(sd->fd, "<<<\r\n", 5);
            }

            write(sd->fd, hlf->data, hlf->count_new);

            sd->chunk_counter++;
        }

        // Process data
        process_stream_data(sd, direction, hlf);

        return;
    }
}