diff options
Diffstat (limited to 'src/wps/httpread.c')
| -rw-r--r-- | src/wps/httpread.c | 123 |
1 files changed, 73 insertions, 50 deletions
diff --git a/src/wps/httpread.c b/src/wps/httpread.c index 2f08f37275c0..7a2ba50a9f31 100644 --- a/src/wps/httpread.c +++ b/src/wps/httpread.c @@ -44,16 +44,6 @@ #define HTTPREAD_HEADER_MAX_SIZE 4096 /* max allowed for headers */ #define HTTPREAD_BODYBUF_DELTA 4096 /* increase allocation by this */ -#if 0 -/* httpread_debug -- set this global variable > 0 e.g. from debugger - * to enable debugs (larger numbers for more debugs) - * Make this a #define of 0 to eliminate the debugging code. - */ -int httpread_debug = 99; -#else -#define httpread_debug 0 /* eliminates even the debugging code */ -#endif - /* control instance -- actual definition (opaque to application) */ @@ -136,8 +126,7 @@ static void httpread_timeout_handler(void *eloop_data, void *user_ctx); */ void httpread_destroy(struct httpread *h) { - if (httpread_debug >= 10) - wpa_printf(MSG_DEBUG, "ENTER httpread_destroy(%p)", h); + wpa_printf(MSG_DEBUG, "httpread_destroy(%p)", h); if (!h) return; @@ -177,6 +166,12 @@ static int httpread_hdr_option_analyze( if (!isdigit(*hbp)) return -1; h->content_length = atol(hbp); + if (h->content_length < 0 || h->content_length > h->max_bytes) { + wpa_printf(MSG_DEBUG, + "httpread: Unacceptable Content-Length %d", + h->content_length); + return -1; + } h->got_content_length = 1; return 0; } @@ -283,8 +278,6 @@ static int httpread_hdr_analyze(struct httpread *h) } } *uri = 0; /* null terminate */ - while (isgraph(*hbp)) - hbp++; while (*hbp == ' ' || *hbp == '\t') hbp++; /* get version */ @@ -380,15 +373,16 @@ static void httpread_read_handler(int sd, void *eloop_ctx, void *sock_ctx) char *bbp; /* pointer into body buffer */ char readbuf[HTTPREAD_READBUF_SIZE]; /* temp use to read into */ - if (httpread_debug >= 20) - wpa_printf(MSG_DEBUG, "ENTER httpread_read_handler(%p)", h); - /* read some at a time, then search for the interal * boundaries between header and data and etc. */ + wpa_printf(MSG_DEBUG, "httpread: Trying to read more data(%p)", h); nread = read(h->sd, readbuf, sizeof(readbuf)); - if (nread < 0) + if (nread < 0) { + wpa_printf(MSG_DEBUG, "httpread failed: %s", strerror(errno)); goto bad; + } + wpa_hexdump_ascii(MSG_MSGDUMP, "httpread - read", readbuf, nread); if (nread == 0) { /* end of transmission... this may be normal * or may be an error... in some cases we can't @@ -411,8 +405,7 @@ static void httpread_read_handler(int sd, void *eloop_ctx, void *sock_ctx) * although dropped connections can cause false * end */ - if (httpread_debug >= 10) - wpa_printf(MSG_DEBUG, "httpread ok eof(%p)", h); + wpa_printf(MSG_DEBUG, "httpread ok eof(%p)", h); h->got_body = 1; goto got_file; } @@ -432,6 +425,8 @@ static void httpread_read_handler(int sd, void *eloop_ctx, void *sock_ctx) if (nread == 0) goto get_more; if (h->hdr_nbytes == HTTPREAD_HEADER_MAX_SIZE) { + wpa_printf(MSG_DEBUG, + "httpread: Too long header"); goto bad; } *hbp++ = *rbp++; @@ -453,16 +448,13 @@ static void httpread_read_handler(int sd, void *eloop_ctx, void *sock_ctx) goto bad; } if (h->max_bytes == 0) { - if (httpread_debug >= 10) - wpa_printf(MSG_DEBUG, - "httpread no body hdr end(%p)", h); + wpa_printf(MSG_DEBUG, "httpread no body hdr end(%p)", + h); goto got_file; } if (h->got_content_length && h->content_length == 0) { - if (httpread_debug >= 10) - wpa_printf(MSG_DEBUG, - "httpread zero content length(%p)", - h); + wpa_printf(MSG_DEBUG, + "httpread zero content length(%p)", h); goto got_file; } } @@ -475,9 +467,7 @@ static void httpread_read_handler(int sd, void *eloop_ctx, void *sock_ctx) !os_strncasecmp(h->hdr, "HEAD", 4) || !os_strncasecmp(h->hdr, "GET", 3)) { if (!h->got_body) { - if (httpread_debug >= 10) - wpa_printf(MSG_DEBUG, - "httpread NO BODY for sp. type"); + wpa_printf(MSG_DEBUG, "httpread NO BODY for sp. type"); } h->got_body = 1; goto got_file; @@ -498,8 +488,12 @@ static void httpread_read_handler(int sd, void *eloop_ctx, void *sock_ctx) char *new_body; int new_alloc_nbytes; - if (h->body_nbytes >= h->max_bytes) + if (h->body_nbytes >= h->max_bytes) { + wpa_printf(MSG_DEBUG, + "httpread: body_nbytes=%d >= max_bytes=%d", + h->body_nbytes, h->max_bytes); goto bad; + } new_alloc_nbytes = h->body_alloc_nbytes + HTTPREAD_BODYBUF_DELTA; /* For content-length case, the first time @@ -509,9 +503,23 @@ static void httpread_read_handler(int sd, void *eloop_ctx, void *sock_ctx) if (h->got_content_length && new_alloc_nbytes < (h->content_length + 1)) new_alloc_nbytes = h->content_length + 1; + if (new_alloc_nbytes < h->body_alloc_nbytes || + new_alloc_nbytes > h->max_bytes + + HTTPREAD_BODYBUF_DELTA) { + wpa_printf(MSG_DEBUG, + "httpread: Unacceptable body length %d (body_alloc_nbytes=%u max_bytes=%u)", + new_alloc_nbytes, + h->body_alloc_nbytes, + h->max_bytes); + goto bad; + } if ((new_body = os_realloc(h->body, new_alloc_nbytes)) - == NULL) + == NULL) { + wpa_printf(MSG_DEBUG, + "httpread: Failed to reallocate buffer (len=%d)", + new_alloc_nbytes); goto bad; + } h->body = new_body; h->body_alloc_nbytes = new_alloc_nbytes; @@ -530,9 +538,19 @@ static void httpread_read_handler(int sd, void *eloop_ctx, void *sock_ctx) /* hdr line consists solely * of a hex numeral and CFLF */ - if (!isxdigit(*cbp)) + if (!isxdigit(*cbp)) { + wpa_printf(MSG_DEBUG, + "httpread: Unexpected chunk header value (not a hex digit)"); goto bad; + } h->chunk_size = strtoul(cbp, NULL, 16); + if (h->chunk_size < 0 || + h->chunk_size > h->max_bytes) { + wpa_printf(MSG_DEBUG, + "httpread: Invalid chunk size %d", + h->chunk_size); + goto bad; + } /* throw away chunk header * so we have only real data */ @@ -542,10 +560,9 @@ static void httpread_read_handler(int sd, void *eloop_ctx, void *sock_ctx) /* end of chunking */ /* trailer follows */ h->in_trailer = 1; - if (httpread_debug >= 20) - wpa_printf( - MSG_DEBUG, - "httpread end chunks(%p)", h); + wpa_printf(MSG_DEBUG, + "httpread end chunks(%p)", + h); break; } h->in_chunk_data = 1; @@ -563,8 +580,11 @@ static void httpread_read_handler(int sd, void *eloop_ctx, void *sock_ctx) */ if (bbp[-1] == '\n' && bbp[-2] == '\r') { - } else + } else { + wpa_printf(MSG_DEBUG, + "httpread: Invalid chunk end"); goto bad; + } h->body_nbytes -= 2; bbp -= 2; h->chunk_start = h->body_nbytes; @@ -574,10 +594,8 @@ static void httpread_read_handler(int sd, void *eloop_ctx, void *sock_ctx) } else if (h->got_content_length && h->body_nbytes >= h->content_length) { h->got_body = 1; - if (httpread_debug >= 10) - wpa_printf( - MSG_DEBUG, - "httpread got content(%p)", h); + wpa_printf(MSG_DEBUG, + "httpread got content(%p)", h); goto got_file; } if (nread <= 0) @@ -601,6 +619,11 @@ static void httpread_read_handler(int sd, void *eloop_ctx, void *sock_ctx) ncopy = nread; } /* Note: should never be 0 */ + if (ncopy < 0) { + wpa_printf(MSG_DEBUG, + "httpread: Invalid ncopy=%d", ncopy); + goto bad; + } if (ncopy > nread) ncopy = nread; os_memcpy(bbp, rbp, ncopy); @@ -635,10 +658,9 @@ static void httpread_read_handler(int sd, void *eloop_ctx, void *sock_ctx) if (c == '\n') { h->trailer_state = trailer_line_begin; h->in_trailer = 0; - if (httpread_debug >= 10) - wpa_printf( - MSG_DEBUG, - "httpread got content(%p)", h); + wpa_printf(MSG_DEBUG, + "httpread got content(%p)", + h); h->got_body = 1; goto got_file; } @@ -666,13 +688,14 @@ bad: return; get_more: + wpa_printf(MSG_DEBUG, "httpread: get more (%p)", h); return; got_file: - if (httpread_debug >= 10) - wpa_printf(MSG_DEBUG, - "httpread got file %d bytes type %d", - h->body_nbytes, h->hdr_type); + wpa_printf(MSG_DEBUG, "httpread got file %d bytes type %d", + h->body_nbytes, h->hdr_type); + wpa_hexdump_ascii(MSG_MSGDUMP, "httpread: body", + h->body, h->body_nbytes); /* Null terminate for convenience of some applications */ if (h->body) h->body[h->body_nbytes] = 0; /* null terminate */ |
