Index: CHANGES =================================================================== RCS file: /cvsroot/src/libexec/httpd/CHANGES,v retrieving revision 1.25.4.2 diff -p -u -r1.25.4.2 CHANGES --- CHANGES 28 Nov 2018 19:50:37 -0000 1.25.4.2 +++ CHANGES 12 Jun 2019 08:01:02 -0000 @@ -1,5 +1,25 @@ $NetBSD: CHANGES,v 1.25.4.2 2018/11/28 19:50:37 martin Exp $ +changes in bozohttpd 20190228: + o extend timeout facility to ssl and stop servers hanging forever + if the client never sends anything. reported by Steffen in netbsd + PR#50655. + o don't display special files in the directory index. they aren't + served, but links to them are generated. + o fix CGI '+' parameter handling, some error checking, and a double + free. from rajeev_v_pillai@yahoo.com + o more directory indexing clean up. from rajeev_v_pillai@yahoo.com + +changes in bozohttpd 20181215: + o fix .htpasswd bypass for authenticated users. reported by JP, + from leot@netbsd.org + o avoid possible null dereference when receiving a big request that + timeout. reported by maya@netbsd.org, from leot@netbsd.org + o fix handling of -T option, from leot@netbsd.org + o cleanups and portability improvements, from maya@netbsd.org + o change directory indexing to use html tables, from + rajeev_v_pillai@yahoo.com + changes in bozohttpd 20181125: o fixes for option parsing introduced in bozohttpd 20181123 @@ -293,7 +313,7 @@ changes in bozohttpd 5.07 (20010610): - add many new content-types, now support most common ones changes in bozohttpd 5.06 (20000825): - - add IPv6 suppor from itojun@iijlab.net + - add IPv6 support from itojun@iijlab.net - man page fixes from jlam@netbsd.org changes in bozohttpd 5.05 (20000815): Index: Makefile =================================================================== RCS file: /cvsroot/src/libexec/httpd/Makefile,v retrieving revision 1.27 diff -p -u -r1.27 Makefile --- Makefile 21 May 2017 15:28:41 -0000 1.27 +++ Makefile 12 Jun 2019 08:01:02 -0000 @@ -77,6 +77,9 @@ bozohttpd.8.txt: bozohttpd.8 CLEANFILES+= bozohttpd.8.html bozohttpd.8.txt +check: + cd ${.CURDIR}/testsuite && ${MAKE} check + # Create a distfile: uses /tmp BASE=bozohttpd-${BOZOVER} TAR=${BASE}.tar Index: auth-bozo.c =================================================================== RCS file: /cvsroot/src/libexec/httpd/auth-bozo.c,v retrieving revision 1.18.8.1 diff -p -u -r1.18.8.1 auth-bozo.c --- auth-bozo.c 24 Nov 2018 17:13:51 -0000 1.18.8.1 +++ auth-bozo.c 12 Jun 2019 08:01:02 -0000 @@ -3,7 +3,7 @@ /* $eterna: auth-bozo.c,v 1.17 2011/11/18 09:21:15 mrg Exp $ */ /* - * Copyright (c) 1997-2018 Matthew R. Green + * Copyright (c) 1997-2019 Matthew R. Green * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -64,7 +64,7 @@ bozo_auth_check(bozo_httpreq_t *request, strcpy(dir, "."); else { *basename++ = '\0'; - if (bozo_check_special_files(request, basename)) + if (bozo_check_special_files(request, basename, true)) return 1; } request->hr_authrealm = bozostrdup(httpd, request, dir); Index: bozohttpd.8 =================================================================== RCS file: /cvsroot/src/libexec/httpd/bozohttpd.8,v retrieving revision 1.65.4.1 diff -p -u -r1.65.4.1 bozohttpd.8 --- bozohttpd.8 24 Nov 2018 17:13:51 -0000 1.65.4.1 +++ bozohttpd.8 12 Jun 2019 08:01:02 -0000 @@ -2,7 +2,7 @@ .\" .\" $eterna: bozohttpd.8,v 1.101 2011/11/18 01:25:11 mrg Exp $ .\" -.\" Copyright (c) 1997-2018 Matthew R. Green +.\" Copyright (c) 1997-2019 Matthew R. Green .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd November 19, 2018 +.Dd February 27, 2019 .Dt BOZOHTTPD 8 .Os .Sh NAME @@ -245,11 +245,13 @@ to The valid values of .Ar type are +.Dq ssl timeout , .Dq initial timeout , .Dq header timeout , and .Dq request timeout . -The default values are 30 seconds, 10 seconds and 600 seconds, respectively. +The default values are 30 seconds, 30 seconds, 10 seconds and 600 seconds, +respectively. .It Fl t Ar chrootdir Makes .Nm @@ -477,9 +479,7 @@ if a .Pa .bzdirect file is found (contents are irrelevant) .Nm -will allow direct access even with the -.Fl r -option. +will allow direct access. If a .Pa .bzredirect symbolic link is found, @@ -599,7 +599,7 @@ The focus has always been simplicity and and regular code audits. This manual documents .Nm -version 20181123. +version 20190116. .Sh AUTHORS .An -nosplit .Nm @@ -610,14 +610,14 @@ was written by The large list of contributors includes: .Bl -dash .It -.An Marc Balmer -.Aq Mt mbalmer@NetBSD.org -added Lua support for dynamic content creation -.It .An Christoph Badura .Aq Mt bad@bsd.de provided Range: header support .It +.An Marc Balmer +.Aq Mt mbalmer@NetBSD.org +added Lua support for dynamic content creation +.It .An Sean Boudreau .Aq Mt seanb@NetBSD.org provided a security fix for virtual hosting @@ -634,7 +634,7 @@ provided cgi-bin support fixes, and more .Aq Mt agc@NetBSD.org cleaned up many internal interfaces, made .Nm -linkable as a library and provided the Lua binding. +linkable as a library and provided the Lua binding .It .An DEGROOTE Arnaud .Aq Mt degroote@NetBSD.org @@ -644,14 +644,14 @@ provided a fix for daemon mode .Aq Mt ad@NetBSD.org provided directory indexing support .It -.An Per Ekman -.Aq Mt pek@pdc.kth.se -provided a fix for a minor (non-security) buffer overflow condition -.It .An Roland Dowdeswell .Aq Mt elric@NetBSD.org added support for serving gzipped files and better SSL handling .It +.An Per Ekman +.Aq Mt pek@pdc.kth.se +provided a fix for a minor (non-security) buffer overflow condition +.It .An Jun-ichiro itojun Hagino, KAME .Aq Mt itojun@iijlab.net provided initial IPv6 support @@ -690,7 +690,7 @@ provided many fixes and enhancements for fixed memory leaks, various issues with userdir support, information disclosure issues, added support for using CGI handlers with directory indexing, found several security issues and provided -various other fixes. +various other fixes .It .An Arnaud Lacombe .Aq Mt alc@NetBSD.org @@ -708,7 +708,7 @@ provided a cgi-bin fix .Aq Mt jmmv@NetBSD.org Added the .Fl P -option (pidfile support) and provided some man page fixes. +option (pidfile support) and provided some man page fixes .It .An Luke Mewburn .Aq Mt lukem@NetBSD.org @@ -717,7 +717,8 @@ HTTP basic authorization support and muc .It .An Rajeev V. Pillai .Aq Mt rajeev_v_pillai@yahoo.com -provided several fixes for virtual hosting +provided several fixes for virtual hosting and directory indexing and +fixes for CGI .It .An Jeremy C. Reed .Aq Mt reed@NetBSD.org @@ -739,11 +740,11 @@ provided minor compile fixes and a CGI c .Aq Mt rumble@ephemeral.org provided the .Fl V -option. +option .It .An Thor Lancelot Simon .Aq Mt tls@NetBSD.org -enhanced cgi-bin support. +enhanced cgi-bin support .It .An Joerg Sonnenberger .Aq Mt joerg@NetBSD.org @@ -760,7 +761,7 @@ provided http authorization fixes .Aq Mt xs@kittenz.org provided chroot and change-to-user support, and other various fixes .It -Coyote Point provided various CGI fixes. +Coyote Point provided various CGI fixes .El .Pp There are probably others I have forgotten (let me know if you care) Index: bozohttpd.c =================================================================== RCS file: /cvsroot/src/libexec/httpd/bozohttpd.c,v retrieving revision 1.86.4.3 diff -p -u -r1.86.4.3 bozohttpd.c --- bozohttpd.c 28 Nov 2018 19:50:37 -0000 1.86.4.3 +++ bozohttpd.c 12 Jun 2019 08:01:02 -0000 @@ -3,7 +3,7 @@ /* $eterna: bozohttpd.c,v 1.178 2011/11/18 09:21:15 mrg Exp $ */ /* - * Copyright (c) 1997-2018 Matthew R. Green + * Copyright (c) 1997-2019 Matthew R. Green * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -109,7 +109,7 @@ #define INDEX_HTML "index.html" #endif #ifndef SERVER_SOFTWARE -#define SERVER_SOFTWARE "bozohttpd/20181125" +#define SERVER_SOFTWARE "bozohttpd/20190228" #endif #ifndef PUBLIC_HTML #define PUBLIC_HTML "public_html" @@ -137,10 +137,9 @@ #include #include #include -#include #include #include -#include +#include #include #include #include @@ -148,6 +147,9 @@ #include "bozohttpd.h" +#ifndef SSL_TIMEOUT +#define SSL_TIMEOUT "30" /* wait for 30 seconds for ssl handshake */ +#endif #ifndef INITIAL_TIMEOUT #define INITIAL_TIMEOUT "30" /* wait for 30 seconds initially */ #endif @@ -183,39 +185,27 @@ struct { { NULL, NULL }, }; -volatile sig_atomic_t timeout_hit; +volatile sig_atomic_t bozo_timeout_hit; /* * check there's enough space in the prefs and names arrays. */ static int -size_arrays(bozoprefs_t *bozoprefs, size_t needed) +size_arrays(bozohttpd_t *httpd, bozoprefs_t *bozoprefs, size_t needed) { - char **temp; + size_t len = sizeof(char *) * needed; if (bozoprefs->size == 0) { /* only get here first time around */ - bozoprefs->name = calloc(sizeof(char *), needed); - if (bozoprefs->name == NULL) - return 0; - bozoprefs->value = calloc(sizeof(char *), needed); - if (bozoprefs->value == NULL) { - free(bozoprefs->name); - return 0; - } - bozoprefs->size = needed; + bozoprefs->name = bozomalloc(httpd, len); + bozoprefs->value = bozomalloc(httpd, len); } else if (bozoprefs->count == bozoprefs->size) { /* only uses 'needed' when filled array */ - temp = realloc(bozoprefs->name, sizeof(char *) * needed); - if (temp == NULL) - return 0; - bozoprefs->name = temp; - temp = realloc(bozoprefs->value, sizeof(char *) * needed); - if (temp == NULL) - return 0; - bozoprefs->value = temp; - bozoprefs->size += needed; + bozoprefs->name = bozorealloc(httpd, bozoprefs->name, len); + bozoprefs->value = bozorealloc(httpd, bozoprefs->value, len); } + + bozoprefs->size = needed; return 1; } @@ -238,16 +228,13 @@ bozo_set_pref(bozohttpd_t *httpd, bozopr if ((i = findvar(bozoprefs, name)) < 0) { /* add the element to the array */ - if (!size_arrays(bozoprefs, bozoprefs->size + 15)) + if (!size_arrays(httpd, bozoprefs, bozoprefs->size + 15)) return 0; i = bozoprefs->count++; bozoprefs->name[i] = bozostrdup(httpd, NULL, name); } else { /* replace the element in the array */ - if (bozoprefs->value[i]) { - free(bozoprefs->value[i]); - bozoprefs->value[i] = NULL; - } + free(bozoprefs->value[i]); } bozoprefs->value[i] = bozostrdup(httpd, NULL, value); return 1; @@ -296,7 +283,7 @@ parse_request(bozohttpd_t *httpd, char * len = (ssize_t)strlen(in); val = bozostrnsep(&in, " \t\n\r", &len); - if (len < 1 || val == NULL) + if (len < 1 || val == NULL || in == NULL) return; *method = val; @@ -386,18 +373,19 @@ bozo_clean_request(bozo_httpreq_t *reque static void alarmer(int sig) { - timeout_hit = 1; + bozo_timeout_hit = 1; } /* - * set a timeout for "initial", "header", or "request". + * set a timeout for "ssl", "initial", "header", or "request". */ int bozo_set_timeout(bozohttpd_t *httpd, bozoprefs_t *prefs, const char *target, const char *val) { - const char *cur, *timeouts[] = { + const char **cur, *timeouts[] = { + "ssl timeout", "initial timeout", "header timeout", "request timeout", @@ -407,9 +395,9 @@ bozo_set_timeout(bozohttpd_t *httpd, boz const size_t minlen = 1; size_t len = strlen(target); - for (cur = timeouts[0]; len >= minlen && *cur; cur++) { - if (strncmp(target, cur, len) == 0) { - bozo_set_pref(httpd, prefs, cur, val); + for (cur = timeouts; len >= minlen && *cur; cur++) { + if (strncmp(target, *cur, len) == 0) { + bozo_set_pref(httpd, prefs, *cur, val); return 0; } } @@ -585,12 +573,14 @@ process_method(bozo_httpreq_t *request, static int bozo_got_header_length(bozo_httpreq_t *request, size_t len) { + + if (len > BOZO_HEADERS_MAX_SIZE - request->hr_header_bytes) + return bozo_http_error(request->hr_httpd, 413, request, + "too many headers"); + request->hr_header_bytes += len; - if (request->hr_header_bytes < BOZO_HEADERS_MAX_SIZE) - return 0; - return bozo_http_error(request->hr_httpd, 413, request, - "too many headers"); + return 0; } /* @@ -615,14 +605,10 @@ bozo_read_request(bozohttpd_t *httpd) /* * if we're in daemon mode, bozo_daemon_fork() will return here twice * for each call. once in the child, returning 0, and once in the - * parent, returning 1. for each child, then we can setup SSL, and - * the parent can signal the caller there was no request to process - * and it will wait for another. + * parent, returning 1 for each child. */ if (bozo_daemon_fork(httpd)) return NULL; - if (bozo_ssl_accept(httpd)) - return NULL; request = bozomalloc(httpd, sizeof(*request)); memset(request, 0, sizeof(*request)); @@ -698,6 +684,14 @@ bozo_read_request(bozohttpd_t *httpd) goto cleanup; } + /* + * now to try to setup SSL, and upon failure parent can signal the + * caller there was no request to process and it will wait for + * another. + */ + if (bozo_ssl_accept(httpd)) + return NULL; + alarm(httpd->initial_timeout); while ((str = bozodgetln(httpd, STDIN_FILENO, &len, bozo_read)) != NULL) { alarm(0); @@ -720,9 +714,9 @@ bozo_read_request(bozohttpd_t *httpd) if (ts.tv_sec > ots.tv_sec && ts.tv_sec > httpd->request_timeout && ts.tv_sec - httpd->request_timeout > ots.tv_sec) - timeout_hit = 1; + bozo_timeout_hit = 1; - if (timeout_hit) { + if (bozo_timeout_hit) { bozo_http_error(httpd, 408, NULL, "request timed out"); goto cleanup; } @@ -993,7 +987,7 @@ bozo_escape_rfc3986(bozohttpd_t *httpd, buf = bozorealloc(httpd, buf, buflen); } - for (len = 0, s = url, d = buf; *s;) { + for (s = url, d = buf; *s;) { if (*s & 0x80) goto encode_it; switch (*s) { @@ -1023,18 +1017,16 @@ bozo_escape_rfc3986(bozohttpd_t *httpd, case '\r': case ' ': encode_it: - snprintf(d, 4, "%%%02X", *s++); + snprintf(d, 4, "%%%02X", (unsigned char)*s++); d += 3; - len += 3; break; default: leave_it: *d++ = *s++; - len++; break; } } - buf[len] = 0; + *d = 0; return buf; } @@ -1192,7 +1184,7 @@ check_remap(bozo_httpreq_t *request) bozohttpd_t *httpd = request->hr_httpd; char *file = request->hr_file, *newfile; void *fmap; - const char *replace, *map_to, *p; + const char *replace = NULL, *map_to = NULL, *p; struct stat st; int mapfile; size_t avail, len, rlen, reqlen, num_esc = 0; @@ -1321,6 +1313,9 @@ check_virtual(bozo_httpreq_t *request) debug((httpd, DEBUG_OBESE, "checking for http:// virtual host in '%s'", file)); if (strncasecmp(file, "http://", 7) == 0) { + /* bozostrdup() might access it. */ + char *old_file = request->hr_file; + /* we would do virtual hosting here? */ file += 7; /* RFC 2616 (HTTP/1.1), 5.2: URI takes precedence over Host: */ @@ -1329,8 +1324,8 @@ check_virtual(bozo_httpreq_t *request) if ((s = strchr(request->hr_host, '/')) != NULL) *s = '\0'; s = strchr(file, '/'); - free(request->hr_file); request->hr_file = bozostrdup(httpd, request, s ? s : "/"); + free(old_file); debug((httpd, DEBUG_OBESE, "got host '%s' file is now '%s'", request->hr_host, request->hr_file)); } else if (!request->hr_host) @@ -1354,7 +1349,10 @@ check_virtual(bozo_httpreq_t *request) if (request->hr_host) { s = strrchr(request->hr_host, ':'); if (s != NULL) - /* truncate Host: as we want to copy it without port part */ + /* + * truncate Host: as we want to copy it + * without port part + */ *s = '\0'; request->hr_virthostname = bozostrdup(httpd, request, request->hr_host); @@ -1441,7 +1439,7 @@ check_bzredirect(bozo_httpreq_t *request bozohttpd_t *httpd = request->hr_httpd; struct stat sb; char dir[MAXPATHLEN], redir[MAXPATHLEN], redirpath[MAXPATHLEN + 1], - path[MAXPATHLEN]; + path[MAXPATHLEN + 1]; char *basename, *finalredir; int rv, absolute; @@ -1464,12 +1462,12 @@ check_bzredirect(bozo_httpreq_t *request } else if (basename == NULL) { strcpy(path, "."); strcpy(dir, ""); - basename = dir; + basename = request->hr_file + 1; } else { *basename++ = '\0'; strcpy(path, dir); } - if (bozo_check_special_files(request, basename)) + if (bozo_check_special_files(request, basename, true)) return -1; debug((httpd, DEBUG_FAT, "check_bzredirect: path %s", path)); @@ -1921,17 +1919,24 @@ bozo_process_request(bozo_httpreq_t *req /* make sure we're not trying to access special files */ int -bozo_check_special_files(bozo_httpreq_t *request, const char *name) +bozo_check_special_files(bozo_httpreq_t *request, const char *name, bool doerror) { bozohttpd_t *httpd = request->hr_httpd; size_t i; + int error = 0; - for (i = 0; specials[i].file; i++) - if (strcmp(name, specials[i].file) == 0) - return bozo_http_error(httpd, 403, request, + for (i = 0; specials[i].file; i++) { + if (strcmp(name, specials[i].file) == 0) { + if (doerror) { + error = bozo_http_error(httpd, 403, request, specials[i].name); + } else { + error = -1; + } + } + } - return 0; + return error; } /* generic header printing routine */ @@ -2076,6 +2081,9 @@ bozo_escape_html(bozohttpd_t *httpd, con case '&': j += 5; break; + case '"': + j += 6; + break; } } @@ -2106,6 +2114,10 @@ bozo_escape_html(bozohttpd_t *httpd, con memcpy(tmp + j, "&", 5); j += 5; break; + case '"': + memcpy(tmp + j, """, 6); + j += 6; + break; default: tmp[j++] = url[i]; } @@ -2250,7 +2262,8 @@ bozo_http_error(bozohttpd_t *httpd, int if (request && request->hr_allow) bozo_printf(httpd, "Allow: %s\r\n", request->hr_allow); /* RFC 7231 (HTTP/1.1) 6.5.7 */ - if (code == 408 && request->hr_proto == httpd->consts.http_11) + if (code == 408 && request && + request->hr_proto == httpd->consts.http_11) bozo_printf(httpd, "Connection: close\r\n"); bozo_printf(httpd, "\r\n"); /* According to the RFC 2616 sec. 9.4 HEAD method MUST NOT return a @@ -2458,6 +2471,8 @@ bozo_init_prefs(bozohttpd_t *httpd, bozo rv = 1; if (!bozo_set_pref(httpd, prefs, "public_html", PUBLIC_HTML)) rv = 1; + if (!bozo_set_pref(httpd, prefs, "ssl timeout", SSL_TIMEOUT)) + rv = 1; if (!bozo_set_pref(httpd, prefs, "initial timeout", INITIAL_TIMEOUT)) rv = 1; if (!bozo_set_pref(httpd, prefs, "header timeout", HEADER_WAIT_TIME)) @@ -2558,6 +2573,9 @@ bozo_setup(bozohttpd_t *httpd, bozoprefs if ((cp = bozo_get_pref(prefs, "public_html")) != NULL) { httpd->public_html = bozostrdup(httpd, NULL, cp); } + if ((cp = bozo_get_pref(prefs, "ssl timeout")) != NULL) { + httpd->ssl_timeout = atoi(cp); + } if ((cp = bozo_get_pref(prefs, "initial timeout")) != NULL) { httpd->initial_timeout = atoi(cp); } Index: bozohttpd.h =================================================================== RCS file: /cvsroot/src/libexec/httpd/bozohttpd.h,v retrieving revision 1.47.4.2 diff -p -u -r1.47.4.2 bozohttpd.h --- bozohttpd.h 28 Nov 2018 19:50:37 -0000 1.47.4.2 +++ bozohttpd.h 12 Jun 2019 08:01:02 -0000 @@ -3,7 +3,7 @@ /* $eterna: bozohttpd.h,v 1.39 2011/11/18 09:21:15 mrg Exp $ */ /* - * Copyright (c) 1997-2018 Matthew R. Green + * Copyright (c) 1997-2019 Matthew R. Green * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -34,6 +34,9 @@ #include "netbsd_queue.h" +#include +#include + #include #ifndef NO_LUA_SUPPORT @@ -117,6 +120,7 @@ typedef struct bozohttpd_t { int hide_dots; /* hide .* */ int process_cgi; /* use the cgi handler */ char *cgibin; /* cgi-bin directory */ + unsigned ssl_timeout; /* ssl timeout */ unsigned initial_timeout;/* first line timeout */ unsigned header_timeout; /* header lines timeout */ unsigned request_timeout;/* total session timeout */ @@ -195,6 +199,16 @@ typedef struct bozoprefs_t { char **value; /* values for the name entries */ } bozoprefs_t; +/* sun2 has a tiny VA range */ +#ifdef __mc68010__ +#ifndef BOZO_WRSZ +#define BOZO_WRSZ (16 * 1024) +#endif +#ifndef BOZO_MMAPSZ +#define BOZO_MMAPSZ (BOZO_WRSZ * 4) +#endif +#endif + /* by default write in upto 64KiB chunks, and mmap in upto 64MiB chunks */ #ifndef BOZO_WRSZ #define BOZO_WRSZ (64 * 1024) @@ -259,7 +273,7 @@ void debug__(bozohttpd_t *, int, const c /* be sure to always return this error up */ int bozo_http_error(bozohttpd_t *, int, bozo_httpreq_t *, const char *); -int bozo_check_special_files(bozo_httpreq_t *, const char *) BOZO_CHECKRET; +int bozo_check_special_files(bozo_httpreq_t *, const char *, bool) BOZO_CHECKRET; char *bozo_http_date(char *, size_t); void bozo_print_header(bozo_httpreq_t *, struct stat *, const char *, const char *); @@ -432,4 +446,6 @@ char *bozo_get_pref(bozoprefs_t *, const int bozo_get_version(char */*buf*/, size_t /*size*/); +extern volatile sig_atomic_t bozo_timeout_hit; + #endif /* BOZOHTTOPD_H_ */ Index: cgi-bozo.c =================================================================== RCS file: /cvsroot/src/libexec/httpd/cgi-bozo.c,v retrieving revision 1.37.4.3 diff -p -u -r1.37.4.3 cgi-bozo.c --- cgi-bozo.c 28 Nov 2018 19:50:37 -0000 1.37.4.3 +++ cgi-bozo.c 12 Jun 2019 08:01:02 -0000 @@ -3,7 +3,7 @@ /* $eterna: cgi-bozo.c,v 1.40 2011/11/18 09:21:15 mrg Exp $ */ /* - * Copyright (c) 1997-2018 Matthew R. Green + * Copyright (c) 1997-2019 Matthew R. Green * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -241,10 +241,10 @@ parse_search_string(bozo_httpreq_t *requ args[0] = str; args[*args_len] = NULL; - for (s = str, i = 0; (s = strchr(s, '+')) != NULL;) { + for (s = str, i = 1; (s = strchr(s, '+')) != NULL; i++) { *s = '\0'; s++; - args[i++] = s; + args[i] = s; } /* @@ -333,8 +333,7 @@ parse_search_string(bozo_httpreq_t *requ parse_err: - free (str); - free (*args); + free(str); free(args); *args_len = 0; @@ -494,6 +493,7 @@ bozo_process_cgi(bozo_httpreq_t *request (clen && *clen ? 1 : 0) + (request->hr_remotehost && *request->hr_remotehost ? 1 : 0) + (request->hr_remoteaddr && *request->hr_remoteaddr ? 1 : 0) + + (cgihandler ? 1 : 0) + bozo_auth_cgi_count(request) + (request->hr_serverport && *request->hr_serverport ? 1 : 0); @@ -610,9 +610,12 @@ bozo_process_cgi(bozo_httpreq_t *request closelog(); bozo_daemon_closefds(httpd); - if (-1 == execve(path, argv, envp)) + if (-1 == execve(path, argv, envp)) { + bozo_http_error(httpd, 404, request, + "Cannot execute CGI"); bozoerr(httpd, 1, "child exec failed: %s: %s", path, strerror(errno)); + } /* NOT REACHED */ bozoerr(httpd, 1, "child execve returned?!"); } Index: daemon-bozo.c =================================================================== RCS file: /cvsroot/src/libexec/httpd/daemon-bozo.c,v retrieving revision 1.17.8.1 diff -p -u -r1.17.8.1 daemon-bozo.c --- daemon-bozo.c 24 Nov 2018 17:13:51 -0000 1.17.8.1 +++ daemon-bozo.c 12 Jun 2019 08:01:02 -0000 @@ -3,7 +3,7 @@ /* $eterna: daemon-bozo.c,v 1.24 2011/11/18 09:21:15 mrg Exp $ */ /* - * Copyright (c) 1997-2018 Matthew R. Green + * Copyright (c) 1997-2019 Matthew R. Green * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -205,7 +205,7 @@ daemon_runchild(bozohttpd_t *httpd, int } static int -daemon_poll_err(bozohttpd_t *httpd, int fd, int idx) +daemon_poll_err(bozohttpd_t *httpd, int idx) { if ((httpd->fds[idx].revents & (POLLNVAL|POLLERR|POLLHUP)) == 0) return 0; @@ -284,7 +284,7 @@ again: } for (i = 0; i < httpd->nsock; i++) { - if (daemon_poll_err(httpd, fd, i)) + if (daemon_poll_err(httpd, i)) break; if (httpd->fds[i].revents == 0) continue; Index: dir-index-bozo.c =================================================================== RCS file: /cvsroot/src/libexec/httpd/dir-index-bozo.c,v retrieving revision 1.25.8.1 diff -p -u -r1.25.8.1 dir-index-bozo.c --- dir-index-bozo.c 24 Nov 2018 17:13:51 -0000 1.25.8.1 +++ dir-index-bozo.c 12 Jun 2019 08:01:02 -0000 @@ -3,7 +3,7 @@ /* $eterna: dir-index-bozo.c,v 1.20 2011/11/18 09:21:15 mrg Exp $ */ /* - * Copyright (c) 1997-2018 Matthew R. Green + * Copyright (c) 1997-2019 Matthew R. Green * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -45,14 +45,6 @@ #include "bozohttpd.h" -static void -directory_hr(bozohttpd_t *httpd) -{ - - bozo_printf(httpd, - "
\r\n\r\n"); -} - /* * output a directory index. return 1 if it actually did something.. */ @@ -62,12 +54,10 @@ bozo_dir_index(bozo_httpreq_t *request, bozohttpd_t *httpd = request->hr_httpd; struct stat sb; struct dirent **de, **deo; - struct tm *tm; DIR *dp; char buf[MAXPATHLEN]; - char spacebuf[48]; - char *file = NULL, *printname = NULL; - int l, k, j, i; + char *file = NULL, *printname = NULL, *p; + int k, j; if (!isindex || !httpd->dir_indexing) return 0; @@ -116,21 +106,36 @@ bozo_dir_index(bozo_httpreq_t *request, #else printname = bozostrdup(httpd, request, request->hr_file); #endif /* !NO_USER_SUPPORT */ + if ((p = strstr(printname, httpd->index_html)) != NULL) { + if (strcmp(printname, httpd->index_html) == 0) + strcpy(printname, "/"); /* is ``slashdir'' */ + else + *p = '\0'; /* strip unwanted ``index_html'' */ + } + if ((p = bozo_escape_html(httpd, printname)) != NULL) { + free(printname); + printname = p; + } bozo_printf(httpd, - "Index of %s\r\n", + "\r\n" + "\r\n" + "\r\n"); + bozo_printf(httpd, "Index of %s\r\n", printname); bozo_printf(httpd, "

Index of %s

\r\n", printname); - bozo_printf(httpd, "
\r\n");
-#define NAMELEN 40
-#define LMODLEN 19
-	bozo_printf(httpd, "Name                                     "
-	    "Last modified          "
-	    "Size\n");
-	bozo_printf(httpd, "
"); - directory_hr(httpd); - bozo_printf(httpd, "
");
+	bozo_printf(httpd,
+		"\r\n\r\n"
+		"\r\n");
 
 	for (j = k = scandir(dirpath, &de, NULL, alphasort), deo = de;
 	    j--; de++) {
@@ -143,66 +148,46 @@ bozo_dir_index(bozo_httpreq_t *request, 
 		     httpd->hide_dots && name[0] == '.'))
 			continue;
 
+		if (bozo_check_special_files(request, name, false))
+			continue;
+
 		snprintf(buf, sizeof buf, "%s/%s", dirpath, name);
 		if (stat(buf, &sb))
 			nostat = 1;
 
-		l = 0;
-
 		urlname = bozo_escape_rfc3986(httpd, name, 0);
 		htmlname = bozo_escape_html(httpd, name);
 		if (htmlname == NULL)
 			htmlname = name;
+		bozo_printf(httpd, "
NameLast modifiedSize\r\n" + "
"); if (strcmp(name, "..") == 0) { bozo_printf(httpd, ""); - l += bozo_printf(httpd, "Parent Directory"); + bozo_printf(httpd, "Parent Directory"); } else if (!nostat && S_ISDIR(sb.st_mode)) { bozo_printf(httpd, "", urlname); - l += bozo_printf(httpd, "%s/", htmlname); + bozo_printf(httpd, "%s/", htmlname); } else if (strchr(name, ':') != NULL) { /* RFC 3986 4.2 */ bozo_printf(httpd, "", urlname); - l += bozo_printf(httpd, "%s", htmlname); + bozo_printf(httpd, "%s", htmlname); } else { bozo_printf(httpd, "", urlname); - l += bozo_printf(httpd, "%s", htmlname); + bozo_printf(httpd, "%s", htmlname); } if (htmlname != name) free(htmlname); bozo_printf(httpd, ""); - /* NAMELEN spaces */ - /*LINTED*/ - assert(/*CONSTCOND*/sizeof(spacebuf) > NAMELEN); - i = (l < NAMELEN) ? (NAMELEN - l) : 0; - i++; - memset(spacebuf, ' ', (size_t)i); - spacebuf[i] = '\0'; - bozo_printf(httpd, "%s", spacebuf); - l += i; - if (nostat) - bozo_printf(httpd, "? ?"); + bozo_printf(httpd, "??\r\n"); else { unsigned long long len; - len = ((unsigned long long)sb.st_size + 1023) / 1024; - - tm = gmtime(&sb.st_mtime); - strftime(buf, sizeof buf, "%d-%b-%Y %R", tm); - l += bozo_printf(httpd, "%s", buf); - - /* LMODLEN spaces */ - /*LINTED*/ - assert(/*CONSTCOND*/sizeof(spacebuf) > LMODLEN); - i = (l < (LMODLEN+NAMELEN+1)) ? - ((LMODLEN+NAMELEN+1) - l) : 0; - i++; - memset(spacebuf, ' ', (size_t)i); - spacebuf[i] = '\0'; - bozo_printf(httpd, "%s", spacebuf); + strftime(buf, sizeof buf, "%d-%b-%Y %R", gmtime(&sb.st_mtime)); + bozo_printf(httpd, "%s", buf); - bozo_printf(httpd, "%12llukB", len); + len = ((unsigned long long)sb.st_size + 1023) / 1024; + bozo_printf(httpd, "%llukB", len); } bozo_printf(httpd, "\r\n"); } @@ -211,8 +196,7 @@ bozo_dir_index(bozo_httpreq_t *request, while (k--) free(deo[k]); free(deo); - bozo_printf(httpd, ""); - directory_hr(httpd); + bozo_printf(httpd, "
\r\n"); bozo_printf(httpd, "\r\n\r\n"); bozo_flush(httpd, stdout); @@ -222,4 +206,3 @@ done: return 1; } #endif /* NO_DIRINDEX_SUPPORT */ - Index: ssl-bozo.c =================================================================== RCS file: /cvsroot/src/libexec/httpd/ssl-bozo.c,v retrieving revision 1.22.8.1 diff -p -u -r1.22.8.1 ssl-bozo.c --- ssl-bozo.c 24 Nov 2018 17:13:51 -0000 1.22.8.1 +++ ssl-bozo.c 12 Jun 2019 08:01:02 -0000 @@ -3,7 +3,7 @@ /* $eterna: ssl-bozo.c,v 1.15 2011/11/18 09:21:15 mrg Exp $ */ /* - * Copyright (c) 1997-2018 Matthew R. Green + * Copyright (c) 1997-2019 Matthew R. Green * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -263,6 +263,8 @@ bozo_ssl_accept(bozohttpd_t *httpd) if (sslinfo == NULL || !sslinfo->ssl_context) return 0; + alarm(httpd->ssl_timeout); + sslinfo->bozossl = SSL_new(sslinfo->ssl_context); if (sslinfo->bozossl == NULL) bozoerr(httpd, 1, "SSL_new failed"); @@ -273,6 +275,14 @@ bozo_ssl_accept(bozohttpd_t *httpd) const int ret = SSL_accept(sslinfo->bozossl); bozo_check_error_queue(httpd, "accept", ret); + alarm(0); + + if (bozo_timeout_hit) { + SSL_free(sslinfo->bozossl); + sslinfo->bozossl = NULL; + return 1; + } + return ret != 1; } Index: testsuite/Makefile =================================================================== RCS file: /cvsroot/src/libexec/httpd/testsuite/Makefile,v retrieving revision 1.7.4.1 diff -p -u -r1.7.4.1 Makefile --- testsuite/Makefile 24 Nov 2018 17:13:51 -0000 1.7.4.1 +++ testsuite/Makefile 12 Jun 2019 08:01:02 -0000 @@ -1,3 +1,4 @@ +# $NetBSD$ # $eterna: Makefile,v 1.14 2009/05/22 21:51:39 mrg Exp $ SIMPLETESTS= t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t12 t13 t14 t15 @@ -9,7 +10,6 @@ BOZOHTTPD?= ../debug/bozohttpd-debug WGET?= wget DATA?= $(.CURDIR)/data VERBOSE?= yes -HOST?= test.eterna .if ${VERBOSE} != "yes" SILENT= @ @@ -28,17 +28,17 @@ check: check-simple check-cgi check-bigf check-simple: .for a in $(SIMPLETESTS) - ${SILENT}$(.CURDIR)/test-simple "$a" "${BOZOHTTPD}" "${DATA}" "${.CURDIR}" "${VERBOSE}" "${HOST}" + ${SILENT}$(.CURDIR)/test-simple "$a" "${BOZOHTTPD}" "${DATA}" "${.CURDIR}" "${VERBOSE}" .endfor check-cgi: .for a in $(CGITESTS) - ${SILENT}$(.CURDIR)/test-simple "$a" "${BOZOHTTPD}" "${DATA}" "${.CURDIR}" "${VERBOSE}" "${HOST}" -c "${.CURDIR}/cgi-bin" + ${SILENT}$(.CURDIR)/test-simple "$a" "${BOZOHTTPD}" "${DATA}" "${.CURDIR}" "${VERBOSE}" -c "${.CURDIR}/cgi-bin" .endfor check-bigfile: .for a in $(BIGFILETESTS) - ${SILENT}$(.CURDIR)/test-bigfile "$a" "${BOZOHTTPD}" "${WGET}" "${DATA}" "${VERBOSE}" "${HOST}" + ${SILENT}$(.CURDIR)/test-bigfile "$a" "${BOZOHTTPD}" "${WGET}" "${DATA}" "${VERBOSE}" .endfor .include Index: testsuite/t11.out =================================================================== RCS file: /cvsroot/src/libexec/httpd/testsuite/t11.out,v retrieving revision 1.1 diff -p -u -r1.1 t11.out --- testsuite/t11.out 31 Jan 2017 14:33:54 -0000 1.1 +++ testsuite/t11.out 12 Jun 2019 08:01:02 -0000 @@ -1 +1,11 @@ HTTP/1.1 200 OK +Content-Type: text/html +Content-Length: 194 +Server: bozohttpd/20181215 +Allow: GET, HEAD, POST + +404 Not Found +

404 Not Found

+cgi-bin/echo.bat:
This item has not been found
+
+ Index: testsuite/test-bigfile =================================================================== RCS file: /cvsroot/src/libexec/httpd/testsuite/test-bigfile,v retrieving revision 1.4.4.1 diff -p -u -r1.4.4.1 test-bigfile --- testsuite/test-bigfile 24 Nov 2018 17:13:51 -0000 1.4.4.1 +++ testsuite/test-bigfile 12 Jun 2019 08:01:02 -0000 @@ -6,7 +6,6 @@ bozohttpd="$1"; shift wget="$1"; shift datadir="$1"; shift verbose="$1"; shift -host="$1"; shift tmperr="tmp.$test.err" Index: testsuite/test-simple =================================================================== RCS file: /cvsroot/src/libexec/httpd/testsuite/test-simple,v retrieving revision 1.4.10.1 diff -p -u -r1.4.10.1 test-simple --- testsuite/test-simple 24 Nov 2018 17:13:51 -0000 1.4.10.1 +++ testsuite/test-simple 12 Jun 2019 08:01:02 -0000 @@ -6,7 +6,6 @@ bozohttpd="$1"; shift datadir="$1"; shift curdir="$1"; shift verbose="$1"; shift -host="$1"; shift in="$curdir/$test.in" out="$curdir/$test.out" @@ -21,7 +20,7 @@ fi bozotestport=11111 -${bozohttpd} "$@" "${datadir}" "${host}" < "$in" > "$tmpout" +${bozohttpd} "$@" "${datadir}" < "$in" > "$tmpout" if "$curdir/html_cmp" cmp "$out" "$tmpout"; then exit 0 else