Mon Sep 20 21:58:43 2010 UTC ()
fix a serious error in virtual hosting support, noticed by seanb@netbsd,
and disallow ".." as a virtual host name!  also ".".

patch from sean.


(mrg)
diff -r1.22 -r1.23 src/libexec/httpd/bozohttpd.c

cvs diff -r1.22 -r1.23 src/libexec/httpd/bozohttpd.c (expand / switch to unified diff)

--- src/libexec/httpd/bozohttpd.c 2010/07/11 03:13:08 1.22
+++ src/libexec/httpd/bozohttpd.c 2010/09/20 21:58:43 1.23
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: bozohttpd.c,v 1.22 2010/07/11 03:13:08 mrg Exp $ */ 1/* $NetBSD: bozohttpd.c,v 1.23 2010/09/20 21:58:43 mrg Exp $ */
2 2
3/* $eterna: bozohttpd.c,v 1.174 2010/06/21 06:47:23 mrg Exp $ */ 3/* $eterna: bozohttpd.c,v 1.174 2010/06/21 06:47:23 mrg Exp $ */
4 4
5/* 5/*
6 * Copyright (c) 1997-2010 Matthew R. Green 6 * Copyright (c) 1997-2010 Matthew R. Green
7 * All rights reserved. 7 * All rights reserved.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
@@ -981,38 +981,50 @@ check_virtual(bozo_httpreq_t *request) @@ -981,38 +981,50 @@ check_virtual(bozo_httpreq_t *request)
981 /* 981 /*
982 * ok, we have a virtual host, use scandir(3) to find a case 982 * ok, we have a virtual host, use scandir(3) to find a case
983 * insensitive match for the virtual host we are asked for. 983 * insensitive match for the virtual host we are asked for.
984 * note that if the virtual host is the same as the master, 984 * note that if the virtual host is the same as the master,
985 * we don't need to do anything special. 985 * we don't need to do anything special.
986 */ 986 */
987 len = strlen(request->hr_host); 987 len = strlen(request->hr_host);
988 debug((httpd, DEBUG_OBESE, 988 debug((httpd, DEBUG_OBESE,
989 "check_virtual: checking host `%s' under httpd->virtbase `%s' " 989 "check_virtual: checking host `%s' under httpd->virtbase `%s' "
990 "for file `%s'", 990 "for file `%s'",
991 request->hr_host, httpd->virtbase, request->hr_file)); 991 request->hr_host, httpd->virtbase, request->hr_file));
992 if (strncasecmp(httpd->virthostname, request->hr_host, len) != 0) { 992 if (strncasecmp(httpd->virthostname, request->hr_host, len) != 0) {
993 s = 0; 993 s = 0;
994 for (i = scandir(httpd->virtbase, &list, 0, 0); i--; list++) { 994 if ((dirp = opendir(httpd->virtbase)) != NULL) {
995 debug((httpd, DEBUG_OBESE, "looking at dir``%s''", 995 while ((d = readdir(dirp)) != NULL) {
996 (*list)->d_name)); 996 if (strcmp(d->d_name, ".") == 0 ||
997 if (strncasecmp((*list)->d_name, request->hr_host, 997 strcmp(d->d_name, "..") == 0) {
998 len) == 0) { 998 continue;
999 /* found it, punch it */ 999 }
1000 httpd->virthostname = (*list)->d_name; 1000 debug((httpd, DEBUG_OBESE, "looking at dir``%s''",
1001 if (asprintf(&s, "%s/%s", httpd->virtbase, 1001 d->d_name));
1002 httpd->virthostname) < 0) 1002 if (strncasecmp(d->d_name, request->hr_host,
1003 bozo_err(httpd, 1, "asprintf"); 1003 len) == 0) {
1004 break; 1004 /* found it, punch it */
 1005 debug((httpd, DEBUG_OBESE, "found it punch it"));
 1006 httpd->virthostname = d->d_name;
 1007 if (asprintf(&s, "%s/%s", httpd->virtbase,
 1008 httpd->virthostname) < 0)
 1009 bozo_err(httpd, 1, "asprintf");
 1010 break;
 1011 }
1005 } 1012 }
 1013 closedir(dirp);
 1014 }
 1015 else {
 1016 debug((httpd, DEBUG_FAT, "opendir %s failed: %s",
 1017 httpd->virtbase, strerror(errno)));
1006 } 1018 }
1007 if (s == 0) { 1019 if (s == 0) {
1008 if (httpd->unknown_slash) 1020 if (httpd->unknown_slash)
1009 goto use_slashdir; 1021 goto use_slashdir;
1010 return bozo_http_error(httpd, 404, request, 1022 return bozo_http_error(httpd, 404, request,
1011 "unknown URL"); 1023 "unknown URL");
1012 } 1024 }
1013 } else 1025 } else
1014use_slashdir: 1026use_slashdir:
1015 s = httpd->slashdir; 1027 s = httpd->slashdir;
1016 1028
1017 /* 1029 /*
1018 * ok, nailed the correct slashdir, chdir to it 1030 * ok, nailed the correct slashdir, chdir to it