Add user-agent gathering for annna http-user-agent module. - bitreich-httpd - Bitreich HTTPD service HTML git clone git://bitreich.org/bitreich-httpd git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/bitreich-httpd DIR Log DIR Files DIR Refs DIR Tags DIR README DIR LICENSE --- DIR commit e5dfc5fbfe93266da5edb1bb2e903734738296cf DIR parent d0062f038d181b8d5eb150003ea7b50bcb5330f3 HTML Author: Christoph Lohmann <20h@r-36.net> Date: Mon, 21 Aug 2023 22:17:11 +0200 Add user-agent gathering for annna http-user-agent module. Diffstat: M bitreich-httpd.c | 89 ++++++++++++++++++++++++++++--- 1 file changed, 82 insertions(+), 7 deletions(-) --- DIR diff --git a/bitreich-httpd.c b/bitreich-httpd.c @@ -11,6 +11,7 @@ #include <sys/stat.h> #include <fcntl.h> #include <string.h> +#include <strings.h> #include <sys/socket.h> #include <netdb.h> #include <time.h> @@ -102,16 +103,48 @@ servefile(char *path, char *ctype, int sock) return 0; } +char * +read_line(int fd, int *len, int maxread) +{ + char *buf; + int r, rbytes; + + buf = xmalloc(maxread+1); + memset(buf, 0, maxread+1); + + rbytes = 0; + while (rbytes < maxread) { + r = read(fd, &buf[rbytes], 1); + if (r < 0) { + free(buf); + return NULL; + } + if (r == 0) + break; + if (buf[rbytes] == '\n') { + buf[rbytes] = '\0'; + break; + } + rbytes += r; + } + + *len = rbytes; + return buf; +} + int main(int argc, char *argv[]) { - char *wwwbase, *wwwindex, request[512], *ctype, *path, *le_file, - *le_base, clienth[NI_MAXHOST], clientp[NI_MAXSERV], *zuccbase; + char *wwwbase, *wwwindex, *request, *ctype, *path, *le_file, + *le_base, clienth[NI_MAXHOST], clientp[NI_MAXSERV], *zuccbase, + *requested, *header, *headerval, *hosthdr; int rlen; struct sockaddr_storage clt; socklen_t cltlen = sizeof(clt); time_t tim; + hosthdr = NULL; + wwwbase = "/bitreich/www"; wwwindex = "index.html"; @@ -130,11 +163,50 @@ main(int argc, char *argv[]) clienth[0] = clientp[0] = '\0'; } - rlen = read(0, request, sizeof(request)-1); - if (rlen < 0) + request = read_line(0, &rlen, 512); + if (request == NULL) return 1; + if (request[rlen-1] == '\r') + request[rlen-1] = '\0'; - request[rlen] = '\0'; + /* Header parsing. */ + for (;;) { + header = read_line(0, &rlen, 512); + if (header == NULL) + break; + if (header[rlen-1] == '\r') { + header[rlen-1] = '\0'; + if (rlen == 1) { + free(header); + break; + } + } + headerval = strchr(header, ':'); + if (headerval == NULL) { + free(header); + continue; + } + *headerval = '\0'; + headerval += 2; + if (headerval > (header + rlen)) { + free(header); + continue; + } + if (!strcasecmp(header, "user-agent")) { + asprintf(&path, + "/home/annna/bin/modules/http-user-agent/add-user-agent.sh \"%s\"", + headerval); + system(path); + free(path); + } + if (!strcasecmp(header, "host")) { + rlen = strlen(headerval); + hosthdr = xmalloc(rlen+1); + memset(hosthdr, 0, rlen+1); + strncpy(hosthdr, headerval, rlen); + } + free(header); + } if (strncmp(request, "GET ", 4)) return 1; @@ -170,7 +242,7 @@ main(int argc, char *argv[]) } else if ((le_file = strstr(request, ".well-known/acme-challenge/"))) { /* Setup for Letsencrypt */ le_file += strlen(".well-known/acme-challenge/"); - char *requested = strtok(le_file, " "); + requested = strtok(le_file, " "); if (strchr(requested, '/') != NULL) { /* Get Zucced, no path exploitation. */ asprintf(&path, "%s/zucc-job.webm", zuccbase); @@ -181,7 +253,7 @@ main(int argc, char *argv[]) ctype = "text/plain"; } } else { - if (strstr(request, "zuccless.org")) { + if (strstr(hosthdr, "zuccless.org")) { tim = time(NULL); srandom(tim); wwwbase = zuccbase; @@ -199,6 +271,9 @@ main(int argc, char *argv[]) ctype = "text/html"; } } + if (hosthdr != NULL) + free(hosthdr); + free(request); rlen = servefile(path, ctype, 1); free(path);