diff options
Diffstat (limited to 'contrib/ipfilter/lib/load_http.c')
-rw-r--r-- | contrib/ipfilter/lib/load_http.c | 97 |
1 files changed, 57 insertions, 40 deletions
diff --git a/contrib/ipfilter/lib/load_http.c b/contrib/ipfilter/lib/load_http.c index 38d0b67..88fc1e3 100644 --- a/contrib/ipfilter/lib/load_http.c +++ b/contrib/ipfilter/lib/load_http.c @@ -1,12 +1,28 @@ +/* $FreeBSD$ */ + /* - * Copyright (C) 2006 by Darren Reed. + * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * - * $Id: load_http.c,v 1.1.2.1 2006/08/25 21:13:04 darrenr Exp $ + * $Id: load_http.c,v 1.5.2.5 2012/07/22 08:04:24 darren_r Exp $ */ #include "ipf.h" +#include <ctype.h> + +/* + * Because the URL can be included twice into the buffer, once as the + * full path for the "GET" and once as the "Host:", the buffer it is + * put in needs to be larger than 512*2 to make room for the supporting + * text. Why not just use snprintf and truncate? The warning about the + * URL being too long tells you something is wrong and does not fetch + * any data - just truncating the URL (with snprintf, etc) and sending + * that to the server is allowing an unknown and unintentioned action + * to happen. + */ +#define MAX_URL_LEN 512 +#define LOAD_BUFSIZE (MAX_URL_LEN * 2 + 128) /* * Format expected is one addres per line, at the start of each line. @@ -14,19 +30,18 @@ alist_t * load_http(char *url) { - char *s, *t, *u, buffer[1044], *myurl; + int fd, len, left, port, endhdr, removed, linenum = 0; + char *s, *t, *u, buffer[LOAD_BUFSIZE], *myurl; alist_t *a, *rtop, *rbot; - struct sockaddr_in sin; - struct hostent *host; size_t avail; - int fd, len, left, port, endhdr, removed; int error; /* * More than this would just be absurd. */ - if (strlen(url) > 512) { - fprintf(stderr, "load_http has a URL > 512 bytes?!\n"); + if (strlen(url) > MAX_URL_LEN) { + fprintf(stderr, "load_http has a URL > %d bytes?!\n", + MAX_URL_LEN); return NULL; } @@ -56,6 +71,15 @@ load_http(char *url) } *t++ = '\0'; + /* + * 10 is the length of 'Host: \r\n\r\n' below. + */ + if (strlen(s) + strlen(buffer) + 10 > sizeof(buffer)) { + fprintf(stderr, "load_http has a malformed URL '%s'\n", url); + free(myurl); + return NULL; + } + u = strchr(s, '@'); if (u != NULL) s = u + 1; /* AUTH */ @@ -76,28 +100,11 @@ load_http(char *url) port = 80; } - memset(&sin, 0, sizeof(sin)); - sin.sin_family = AF_INET; - sin.sin_port = htons(port); - - if (isdigit(*s)) { - if (inet_aton(s, &sin.sin_addr) == -1) { - goto done; - } - } else { - host = gethostbyname(s); - if (host == NULL) - goto done; - memcpy(&sin.sin_addr, host->h_addr_list[0], - sizeof(sin.sin_addr)); - } - fd = socket(AF_INET, SOCK_STREAM, 0); + fd = connecttcp(s, port); if (fd == -1) goto done; - if (connect(fd, (struct sockaddr *)&sin, sizeof(sin)) == -1) - goto done; len = strlen(buffer); if (write(fd, buffer, len) != len) @@ -150,30 +157,40 @@ load_http(char *url) if (t == NULL) break; - *t++ = '\0'; - for (u = buffer; isdigit(*u) || (*u == '.'); u++) - ; - if (*u == '/') { - char *slash; - - slash = u; - u++; - while (isdigit(*u)) - u++; - if (!isspace(*u) && *u) - u = slash; + linenum++; + *t = '\0'; + + /* + * Remove comment and continue to the next line if + * the comment is at the start of the line. + */ + u = strchr(buffer, '#'); + if (u != NULL) { + *u = '\0'; + if (u == buffer) + continue; } - *u = '\0'; - a = alist_new(4, buffer); + /* + * Trim off tailing white spaces, will include \r + */ + for (u = t - 1; (u >= buffer) && ISSPACE(*u); u--) + *u = '\0'; + + a = alist_new(AF_UNSPEC, buffer); if (a != NULL) { if (rbot != NULL) rbot->al_next = a; else rtop = a; rbot = a; + } else { + fprintf(stderr, + "%s:%d unrecognised content:%s\n", + url, linenum, buffer); } + t++; removed = t - buffer; memmove(buffer, t, sizeof(buffer) - left - removed); s -= removed; |