static int htpy_connp_init(htpy_connp *self, PyObject *args, PyObject *kwds) { PyObject *cfg_obj = NULL; if (!PyArg_ParseTuple(args, "|O:htpy_connp_init", &cfg_obj)) return -1; /* * If we are not given a config object as an argument create an * htp_cfg_t and use that. */ if (!cfg_obj) cfg_obj = PyObject_CallObject((PyObject *) &htpy_config_type, NULL); else Py_XINCREF(cfg_obj); if (!cfg_obj) { PyErr_SetString(htpy_error, "Unable to create config object."); return -1; } self->cfg = cfg_obj; self->connp = htp_connp_create(((htpy_config *) cfg_obj)->cfg); if (!self->connp) { PyErr_SetString(htpy_error, "Unable to create connection parser."); return -1; } htp_connp_set_user_data(self->connp, (void *) self); return 0; }
/** * Creates a new configuration parser, making a copy of the supplied * configuration structure. * * @param cfg * @return A pointer to a newly created htp_connp_t instance. */ htp_connp_t *htp_connp_create_copycfg(htp_cfg_t *cfg) { htp_connp_t *connp = htp_connp_create(cfg); if (connp == NULL) return NULL; connp->cfg = htp_config_copy(cfg); connp->is_cfg_private = 1; return connp; }
VALUE rbhtp_connp_initialize( VALUE self, VALUE config ) { rb_iv_set( self, "@cfg", config ); htp_cfg_t* cfg = NULL; Data_Get_Struct( rb_iv_get( config, "@cfg" ), htp_cfg_t, cfg ); htp_connp_t* connp = htp_connp_create( cfg ); htp_connp_set_user_data( connp, (void*)self ); rb_iv_set( self, "@connp", Data_Wrap_Struct( rb_cObject, 0, rbhtp_connp_free, connp ) ); return Qnil; }
virtual void SetUp() { home = getenv("srcdir"); if (home == NULL) { fprintf(stderr, "This program needs environment variable 'srcdir' set."); exit(EXIT_FAILURE); } cfg = htp_config_create(); htp_config_set_server_personality(cfg, HTP_SERVER_APACHE_2); connp = htp_connp_create(cfg); tx = htp_connp_tx_create(connp); htp_tx_set_user_data(tx, &output); decompressor = htp_gzip_decompressor_create(connp, HTP_COMPRESSION_GZIP); decompressor->callback = GUnzip_decompressor_callback; o_boxing_wizards = bstr_dup_c("The five boxing wizards jump quickly."); output = NULL; }
/** * 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; } }
/** * Runs a single test. * * @param[in] filename * @param[in] cfg * @return A pointer to the instance of htp_connp_t created during * the test, or NULL if the test failed for some reason. */ int test_run_ex(const char *testsdir, const char *testname, htp_cfg_t *cfg, htp_connp_t **connp, int clone_count) { char filename[1025]; test_t test; struct timeval tv_start, tv_end; int rc; *connp = NULL; strncpy(filename, testsdir, 1024); strncat(filename, "/", 1024 - strlen(filename)); strncat(filename, testname, 1024 - strlen(filename)); // printf("Filename: %s\n", filename); // Initinialize test rc = test_init(&test, filename, clone_count); if (rc < 0) { return rc; } gettimeofday(&tv_start, NULL); test_start(&test); // Create parser *connp = htp_connp_create(cfg); if (*connp == NULL) { fprintf(stderr, "Failed to create connection parser\n"); exit(1); } htp_connp_set_user_data(*connp, (void *) 0x02); // Does the filename contain connection metdata? if (strncmp(testname, "stream", 6) == 0) { // It does; use it char *remote_addr = NULL, *local_addr = NULL; int remote_port = -1, local_port = -1; parse_filename(testname, &remote_addr, &remote_port, &local_addr, &local_port); htp_connp_open(*connp, (const char *) remote_addr, remote_port, (const char *) local_addr, local_port, &tv_start); free(remote_addr); free(local_addr); } else { // No connection metadata; provide some fake information instead htp_connp_open(*connp, (const char *) "127.0.0.1", 10000, (const char *) "127.0.0.1", 80, &tv_start); } // Find all chunks and feed them to the parser int in_data_other = 0; char *in_data = NULL; size_t in_data_len = 0; size_t in_data_offset = 0; int out_data_other = 0; char *out_data = NULL; size_t out_data_len = 0; size_t out_data_offset = 0; for (;;) { if (test_next_chunk(&test) <= 0) { break; } if (test.chunk_direction == CLIENT) { if (in_data_other) { test_destroy(&test); fprintf(stderr, "Unable to buffer more than one inbound chunk.\n"); return -1; } rc = htp_connp_req_data(*connp, &tv_start, test.chunk, test.chunk_len); if (rc == HTP_STREAM_ERROR) { test_destroy(&test); return -101; } if (rc == HTP_STREAM_DATA_OTHER) { // Parser needs to see the outbound stream in order to continue // parsing the inbound stream. in_data_other = 1; in_data = test.chunk; in_data_len = test.chunk_len; in_data_offset = htp_connp_req_data_consumed(*connp); } } else { if (out_data_other) { rc = htp_connp_res_data(*connp, &tv_start, out_data + out_data_offset, out_data_len - out_data_offset); if (rc == HTP_STREAM_ERROR) { test_destroy(&test); return -104; } out_data_other = 0; } rc = htp_connp_res_data(*connp, &tv_start, test.chunk, test.chunk_len); if (rc == HTP_STREAM_ERROR) { test_destroy(&test); return -102; } if (rc == HTP_STREAM_DATA_OTHER) { // Parser needs to see the outbound stream in order to continue // parsing the inbound stream. out_data_other = 1; out_data = test.chunk; out_data_len = test.chunk_len; out_data_offset = htp_connp_res_data_consumed(*connp); // printf("# YYY out offset is %d\n", out_data_offset); } if (in_data_other) { rc = htp_connp_req_data(*connp, &tv_start, in_data + in_data_offset, in_data_len - in_data_offset); if (rc == HTP_STREAM_ERROR) { test_destroy(&test); return -103; } in_data_other = 0; } } } if (out_data_other) { rc = htp_connp_res_data(*connp, &tv_start, out_data + out_data_offset, out_data_len - out_data_offset); if (rc == HTP_STREAM_ERROR) { test_destroy(&test); return -104; } out_data_other = 0; } gettimeofday(&tv_end, NULL); // Close the connection htp_connp_close(*connp, &tv_end); // Clean up test_destroy(&test); return 1; }