summaryrefslogtreecommitdiff
path: root/src/wps/httpread.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/wps/httpread.c')
-rw-r--r--src/wps/httpread.c123
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 */