diff options
author | Nick White <git@njw.me.uk> | 2012-07-10 20:57:07 +0100 |
---|---|---|
committer | Nick White <git@njw.me.uk> | 2012-07-10 20:57:07 +0100 |
commit | 4e6b01857db64898a4619415543eefca771a527e (patch) | |
tree | 776ceb6e824099b41bbc43e985c1ec98e55ce672 /util.c | |
parent | e7a7e29a59be8bd43f09938c623b093e162ddf92 (diff) |
Fix potential bug in HTTP code
Diffstat (limited to 'util.c')
-rw-r--r-- | util.c | 113 |
1 files changed, 67 insertions, 46 deletions
@@ -49,14 +49,17 @@ int dial(char *host, char *port) { return srv; } -int get(char *host, char *path, char *sendcookie, char *savecookie, char **buf) { +int get(char *host, char *path, char *sendcookie, char *savecookie, char **body) { size_t l, res; int fd, i, p; char h[BUFSIZ] = ""; char c[COOKIEMAX] = ""; - char t[BUFSIZ]; - char *t2; char m[256]; + char *headpos; + size_t headsize; + char headline[BUFSIZ] = ""; + char *buf; + char *cur, *pos; if((fd = dial(host, "80")) == -1) return 0; @@ -66,40 +69,42 @@ int get(char *host, char *path, char *sendcookie, char *savecookie, char **buf) " (not mozilla)\r\nHost: %s%s\r\n\r\n", path, host, c); if(!send(fd, h, strlen(h), 0)) return 0; - *buf = NULL; + /* download everything into buf */ l = 0; - h[0] = 0; - snprintf(m, 256, "Set-Cookie: %%%ds;", COOKIEMAX-1); + buf = malloc(sizeof(char *) * BUFSIZ); + for(; buf != NULL && (res = recv(fd, buf+l, BUFSIZ, 0)) > 0; l+=res) + buf = realloc(buf, sizeof(char *) * (l+BUFSIZ)); - while((res = recv(fd, t, BUFSIZ, 0)) > 0) { - strncat(h, t, BUFSIZ - strlen(h) - 1); - if((t2 = strstr(t, "\r\n\r\n")) != NULL && (t2 - t) < (signed)res) { - /* end of header, save rest to buffer */ - t2+=4; - l = res - (t2 - t); - *buf = malloc(sizeof(char *) * l); - memcpy(*buf, t2, l); - break; - } - } + /* strstr to find end of header */ + if((headpos = strstr(buf, "\r\n\r\n")) == NULL) + return 0; + headpos += 4; + headsize = headpos - buf; - if(sscanf(h, "HTTP/%d.%d %d", &i, &i, &p) == 3 && p != 200) { - if(p == 403) - fprintf(stderr, "403 forbidden: your IP address may be temporarily blocked\n"); + /* memcopy from there into a large enough buf */ + if((*body = malloc(sizeof(char *) * (l - headsize))) == NULL) return 0; - } - t2 = h; - if(savecookie != NULL) { - while((t2 = strstr(t2, "Set-Cookie: ")) && sscanf(t2, m, c)) { + memcpy(*body, headpos, sizeof(char *) * (l - headsize)); + + /* parse header as needed */ + snprintf(m, 256, "Set-Cookie: %%%ds;", COOKIEMAX-1); + cur = buf; + while((pos = strstr(cur, "\r\n")) != NULL && cur < (headpos - 4)) { + strncpy(headline, cur, pos - cur); + headline[pos - cur] = '\0'; + cur = pos + 2; + + if(sscanf(headline, "HTTP/%d.%d %d", &i, &i, &p) == 3 && p != 200) { + if(p == 403) + fprintf(stderr, "403 forbidden: your IP address may be temporarily blocked\n"); + return 0; + } + + if(savecookie != NULL && sscanf(headline, m, c)) { strncat(savecookie, c, COOKIEMAX - strlen(savecookie) - 1); - t2++; } } - *buf = realloc(*buf, sizeof(char *) * (l+BUFSIZ)); - for(; buf != NULL && (res = recv(fd, *buf+l, BUFSIZ, 0)) > 0; l+=res) - *buf = realloc(*buf, sizeof(char *) * (l+BUFSIZ)); - return l; } @@ -129,12 +134,16 @@ int gettofile(char *host, char *url, char *sendcookie, char *savecookie, char *s return 0; } -int post(char *host, char *path, char *data, char **buf) { +/* TODO: merge this with get(); almost all code is the same */ +int post(char *host, char *path, char *data, char **body) { size_t l, res; int fd, i, p; char h[BUFSIZ] = ""; - char t[BUFSIZ]; - char *t2; + char *headpos; + size_t headsize; + char headline[BUFSIZ] = ""; + char *buf; + char *cur, *pos; if((fd = dial(host, "80")) == -1) return 0; @@ -145,25 +154,37 @@ int post(char *host, char *path, char *data, char **buf) { path, (int)strlen(data), host, data); if(!send(fd, h, strlen(h), 0)) return 0; - *buf = NULL; + /* download everything into buf */ l = 0; - while((res = recv(fd, t, BUFSIZ, 0)) > 0) { - if(sscanf(t, "HTTP/%d.%d %d", &i, &i, &p) == 3 && p != 200) + buf = malloc(sizeof(char *) * BUFSIZ); + for(; buf != NULL && (res = recv(fd, buf+l, BUFSIZ, 0)) > 0; l+=res) + buf = realloc(buf, sizeof(char *) * (l+BUFSIZ)); + + /* strstr to find end of header */ + if((headpos = strstr(buf, "\r\n\r\n")) == NULL) + return 0; + headpos += 4; + headsize = headpos - buf; + + /* memcopy from there into a large enough buf */ + if((*body = malloc(sizeof(char *) * (l - headsize))) == NULL) + return 0; + memcpy(*body, headpos, sizeof(char *) * (l - headsize)); + + /* parse header as needed */ + cur = buf; + while((pos = strstr(cur, "\r\n")) != NULL && cur < (headpos - 4)) { + strncpy(headline, cur, pos - cur); + headline[pos - cur] = '\0'; + cur = pos + 2; + + if(sscanf(headline, "HTTP/%d.%d %d", &i, &i, &p) == 3 && p != 200) { + if(p == 403) + fprintf(stderr, "403 forbidden: your IP address may be temporarily blocked\n"); return 0; - t2 = t; - if((t2 = strstr(t, "\r\n\r\n")) != NULL && (t2 - t) < (signed)res) { - t2+=4; - l = res - (t2 - t); - *buf = malloc(sizeof(char *) * l); - memcpy(*buf, t2, l); - break; } } - *buf = realloc(*buf, sizeof(char *) * (l+BUFSIZ)); - for(; (res = recv(fd, *buf+l, BUFSIZ, 0)) > 0; l+=res) - *buf = realloc(*buf, sizeof(char *) * (l+BUFSIZ)); - return l; } |