From 729eb50738777d6dbc27f81d854c824b32bebb05 Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Fri, 6 May 2016 15:14:16 +0200 Subject: ripe-atlas-fw: imported version 4730 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Bjørn Mork --- eperd/httpget.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 110 insertions(+), 13 deletions(-) (limited to 'eperd/httpget.c') diff --git a/eperd/httpget.c b/eperd/httpget.c index 92ce453..aed596e 100644 --- a/eperd/httpget.c +++ b/eperd/httpget.c @@ -92,6 +92,8 @@ struct hgstate size_t read_limit; unsigned timeout; char *infname; + char *response_in; /* Fuzzing */ + char *response_out; /* State */ char busy; @@ -150,6 +152,8 @@ struct hgstate char *result2; size_t reslen2; size_t resmax2; + + FILE *resp_file; /* Fuzzing */ }; static struct hgbase *hg_base; @@ -332,7 +336,7 @@ static void timeout_callback(int __attribute((unused)) unused, break; case READ_HEADER: if (state->max_headers) - add_str(s, " ], "); + add_str(state, " ], "); add_str(state, ", " DBQ(err) ":" DBQ(timeout reading headers)); report(state); break; @@ -381,7 +385,7 @@ static void *httpget_init(int __attribute((unused)) argc, char *argv[], char *url, *check; char *post_file, *output_file, *post_footer, *post_header, *A_arg, *store_headers, *store_body, *read_limit_str, - *timeout_str, *infname; + *timeout_str, *infname, *response_in, *response_out; const char *user_agent; char *host, *port, *hostport, *path; struct hgstate *state; @@ -404,6 +408,8 @@ static void *httpget_init(int __attribute((unused)) argc, char *argv[], timeout_str= NULL; A_arg= NULL; infname= NULL; + response_in= NULL; + response_out= NULL; only_v4= 0; only_v6= 0; do_etim= 0; @@ -420,7 +426,8 @@ static void *httpget_init(int __attribute((unused)) argc, char *argv[], /* Allow us to be called directly by another program in busybox */ optind= 0; - while (c= getopt_long(argc, argv, "01aA:cI:O:46", longopts, NULL), c != -1) + while (c= getopt_long(argc, argv, "01aA:cI:O:R:W:46", longopts, NULL), + c != -1) { switch(c) { @@ -441,6 +448,12 @@ static void *httpget_init(int __attribute((unused)) argc, char *argv[], case 'A': A_arg= optarg; break; + case 'R': + response_in= optarg; + break; + case 'W': + response_out= optarg; + break; case 'a': /* --all */ do_all= 1; break; @@ -511,6 +524,23 @@ static void *httpget_init(int __attribute((unused)) argc, char *argv[], } url= argv[optind]; + if (response_in) + { + if (!validate_filename(response_in, ATLAS_FUZZING)) + { + crondlog(LVL8 "insecure fuzzing file '%s'", response_in); + return NULL; + } + } + if (response_out) + { + if (!validate_filename(response_out, ATLAS_FUZZING)) + { + crondlog(LVL8 "insecure fuzzing file '%s'", response_out); + return NULL; + } + } + if (output_file) { if (!validate_filename(output_file, SAFE_PREFIX_OUT)) @@ -621,6 +651,8 @@ static void *httpget_init(int __attribute((unused)) argc, char *argv[], state->base= hg_base; state->atlas= A_arg ? strdup(A_arg) : NULL; state->output_file= output_file ? strdup(output_file) : NULL; + state->response_in= response_in ? strdup(response_in) : NULL; + state->response_out= response_out ? strdup(response_out) : NULL; state->host= host; state->port= port; state->hostport= hostport; @@ -859,6 +891,12 @@ static void report(struct hgstate *state) tu_cleanup(&state->tu_env); + if (state->resp_file) + { + fclose(state->resp_file); + state->resp_file= NULL; + } + state->busy= 0; if (state->base->done) state->base->done(state); @@ -914,11 +952,33 @@ static int get_input(struct hgstate *state) state->report_roffset= 0; } - n= bufferevent_read(state->bev, - &state->line[state->linelen], - state->linemax-state->linelen); + if (state->response_in) + { + if (!state->resp_file) + abort(); + n= fread(&state->line[state->linelen], 1, 1, state->resp_file); + if (n == -1 || n == 0) + { + fclose(state->resp_file); + state->resp_file= NULL; + timeout_callback(0, 0, &state->tu_env); + report(state); + return -1; + } + } + else + { + n= bufferevent_read(state->bev, + &state->line[state->linelen], + state->linemax-state->linelen); + } if (n < 0) return -1; + if (state->response_out) + { + fwrite(&state->line[state->linelen], n, 1, + state->resp_file); + } state->linelen += n; state->roffset += n; return 0; @@ -1556,7 +1616,7 @@ static void readcb(struct bufferevent *bev UNUSED_PARAM, void *ptr) continue; case READ_DONE: - if (state->bev) + if (state->bev || state->response_in) { state->bev= NULL; clock_gettime(CLOCK_MONOTONIC_RAW, &endtime); @@ -1637,6 +1697,11 @@ static void writecb(struct bufferevent *bev, void *ptr) state->writestate= WRITE_HEADER; continue; case WRITE_HEADER: + if (state->response_in) + { + state->writestate = WRITE_DONE; + continue; + } output= bufferevent_get_output(bev); evbuffer_add_printf(output, "%s %s HTTP/1.%c\r\n", state->do_get ? "GET" : @@ -1892,8 +1957,11 @@ static void connected(struct tu_env *env, struct bufferevent *bev) state->bev= bev; state->loc_socklen= sizeof(state->loc_sin6); - getsockname(bufferevent_getfd(bev), - &state->loc_sin6, &state->loc_socklen); + if (!state->response_in) + { + getsockname(bufferevent_getfd(bev), + &state->loc_sin6, &state->loc_socklen); + } } static void httpget_start(void *state) @@ -1919,6 +1987,16 @@ static void httpget_start(void *state) clock_gettime(CLOCK_MONOTONIC_RAW, &hgstate->start); hgstate->first_connect= 1; + if (hgstate->response_out) + { + hgstate->resp_file= fopen(hgstate->response_out, "w"); + if (!hgstate->resp_file) + { + crondlog(DIE9 "unable to write to '%s'", + hgstate->response_out); + } + } + memset(&hints, '\0', sizeof(hints)); hints.ai_socktype= SOCK_STREAM; if (hgstate->only_v4) @@ -1927,10 +2005,29 @@ static void httpget_start(void *state) hints.ai_family= AF_INET6; interval.tv_sec= hgstate->timeout / 1000; interval.tv_usec= (hgstate->timeout % 1000) * 1000; - tu_connect_to_name(&hgstate->tu_env, hgstate->host, hgstate->port, - &interval, &hints, hgstate->infname, timeout_callback, - reporterr, dnscount, beforeconnect, - connected, readcb, writecb); + + if (hgstate->response_in) + { + hgstate->resp_file= fopen(hgstate->response_in, "r"); + if (!hgstate->resp_file) + { + crondlog(DIE9 "unable to read from '%s'", + hgstate->response_in); + } + connected(&hgstate->tu_env, NULL); + writecb(NULL, &hgstate->tu_env); + while(hgstate->resp_file != NULL) + readcb(NULL, &hgstate->tu_env); + report(hgstate); + } + else + { + tu_connect_to_name(&hgstate->tu_env, hgstate->host, + hgstate->port, + &interval, &hints, hgstate->infname, timeout_callback, + reporterr, dnscount, beforeconnect, + connected, readcb, writecb); + } } static int httpget_delete(void *state) -- cgit v1.2.3